2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
55 #include <cam/cam_debug.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/scsi/scsi_all.h>
58 #include <cam/scsi/scsi_da.h>
59 #include <cam/scsi/scsi_pass.h>
60 #include <cam/scsi/scsi_message.h>
61 #include <cam/scsi/smp_all.h>
62 #include <cam/ata/ata_all.h>
64 #include "camcontrol.h"
67 CAM_CMD_NONE = 0x00000000,
68 CAM_CMD_DEVLIST = 0x00000001,
69 CAM_CMD_TUR = 0x00000002,
70 CAM_CMD_INQUIRY = 0x00000003,
71 CAM_CMD_STARTSTOP = 0x00000004,
72 CAM_CMD_RESCAN = 0x00000005,
73 CAM_CMD_READ_DEFECTS = 0x00000006,
74 CAM_CMD_MODE_PAGE = 0x00000007,
75 CAM_CMD_SCSI_CMD = 0x00000008,
76 CAM_CMD_DEVTREE = 0x00000009,
77 CAM_CMD_USAGE = 0x0000000a,
78 CAM_CMD_DEBUG = 0x0000000b,
79 CAM_CMD_RESET = 0x0000000c,
80 CAM_CMD_FORMAT = 0x0000000d,
81 CAM_CMD_TAG = 0x0000000e,
82 CAM_CMD_RATE = 0x0000000f,
83 CAM_CMD_DETACH = 0x00000010,
84 CAM_CMD_REPORTLUNS = 0x00000011,
85 CAM_CMD_READCAP = 0x00000012,
86 CAM_CMD_IDENTIFY = 0x00000013,
87 CAM_CMD_IDLE = 0x00000014,
88 CAM_CMD_STANDBY = 0x00000015,
89 CAM_CMD_SLEEP = 0x00000016,
90 CAM_CMD_SMP_CMD = 0x00000017,
91 CAM_CMD_SMP_RG = 0x00000018,
92 CAM_CMD_SMP_PC = 0x00000019,
93 CAM_CMD_SMP_PHYLIST = 0x0000001a,
94 CAM_CMD_SMP_MANINFO = 0x0000001b,
95 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
96 CAM_CMD_SECURITY = 0x0000001d,
97 CAM_CMD_HPA = 0x0000001e,
98 CAM_CMD_SANITIZE = 0x0000001f,
99 CAM_CMD_PERSIST = 0x00000020,
100 CAM_CMD_APM = 0x00000021,
101 CAM_CMD_AAM = 0x00000022,
102 CAM_CMD_ATTRIB = 0x00000023,
103 CAM_CMD_OPCODES = 0x00000024,
104 CAM_CMD_REPROBE = 0x00000025,
105 CAM_CMD_ZONE = 0x00000026,
106 CAM_CMD_EPC = 0x00000027,
107 CAM_CMD_TIMESTAMP = 0x00000028
111 CAM_ARG_NONE = 0x00000000,
112 CAM_ARG_VERBOSE = 0x00000001,
113 CAM_ARG_DEVICE = 0x00000002,
114 CAM_ARG_BUS = 0x00000004,
115 CAM_ARG_TARGET = 0x00000008,
116 CAM_ARG_LUN = 0x00000010,
117 CAM_ARG_EJECT = 0x00000020,
118 CAM_ARG_UNIT = 0x00000040,
119 CAM_ARG_FORMAT_BLOCK = 0x00000080,
120 CAM_ARG_FORMAT_BFI = 0x00000100,
121 CAM_ARG_FORMAT_PHYS = 0x00000200,
122 CAM_ARG_PLIST = 0x00000400,
123 CAM_ARG_GLIST = 0x00000800,
124 CAM_ARG_GET_SERIAL = 0x00001000,
125 CAM_ARG_GET_STDINQ = 0x00002000,
126 CAM_ARG_GET_XFERRATE = 0x00004000,
127 CAM_ARG_INQ_MASK = 0x00007000,
128 CAM_ARG_TIMEOUT = 0x00020000,
129 CAM_ARG_CMD_IN = 0x00040000,
130 CAM_ARG_CMD_OUT = 0x00080000,
131 CAM_ARG_ERR_RECOVER = 0x00200000,
132 CAM_ARG_RETRIES = 0x00400000,
133 CAM_ARG_START_UNIT = 0x00800000,
134 CAM_ARG_DEBUG_INFO = 0x01000000,
135 CAM_ARG_DEBUG_TRACE = 0x02000000,
136 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
137 CAM_ARG_DEBUG_CDB = 0x08000000,
138 CAM_ARG_DEBUG_XPT = 0x10000000,
139 CAM_ARG_DEBUG_PERIPH = 0x20000000,
140 CAM_ARG_DEBUG_PROBE = 0x40000000,
143 struct camcontrol_opts {
151 struct ata_res_pass16 {
152 u_int16_t reserved[5];
155 u_int8_t sector_count_exp;
156 u_int8_t sector_count;
157 u_int8_t lba_low_exp;
159 u_int8_t lba_mid_exp;
161 u_int8_t lba_high_exp;
167 struct ata_set_max_pwd
170 u_int8_t password[32];
171 u_int16_t reserved2[239];
174 static struct scsi_nv task_attrs[] = {
175 { "simple", MSG_SIMPLE_Q_TAG },
176 { "head", MSG_HEAD_OF_Q_TAG },
177 { "ordered", MSG_ORDERED_Q_TAG },
178 { "iwr", MSG_IGN_WIDE_RESIDUE },
179 { "aca", MSG_ACA_TASK }
182 static const char scsicmd_opts[] = "a:c:dfi:o:r";
183 static const char readdefect_opts[] = "f:GPqsS:X";
184 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
185 static const char smprg_opts[] = "l";
186 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
187 static const char smpphylist_opts[] = "lq";
191 static struct camcontrol_opts option_table[] = {
193 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
194 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
195 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
196 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
197 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
198 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
199 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
200 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
201 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
202 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
203 #endif /* MINIMALISTIC */
204 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
205 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
207 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
208 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
209 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
210 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
211 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
212 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
213 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
214 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
215 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
216 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
217 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
218 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
219 #endif /* MINIMALISTIC */
220 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
222 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
223 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
224 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
225 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
226 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
227 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
228 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
229 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
230 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
231 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
232 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
233 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
234 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
235 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
236 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
237 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
238 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
239 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
240 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
241 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
242 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
243 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
244 #endif /* MINIMALISTIC */
245 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
246 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
247 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
252 struct device_match_result dev_match;
254 struct periph_match_result *periph_matches;
255 struct scsi_vpd_device_id *device_id;
257 STAILQ_ENTRY(cam_devitem) links;
261 STAILQ_HEAD(, cam_devitem) dev_queue;
265 static cam_cmdmask cmdlist;
266 static cam_argmask arglist;
268 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
269 uint32_t *cmdnum, cam_argmask *argnum,
270 const char **subopt);
272 static int getdevlist(struct cam_device *device);
273 #endif /* MINIMALISTIC */
274 static int getdevtree(int argc, char **argv, char *combinedopt);
276 static int testunitready(struct cam_device *device, int task_attr,
277 int retry_count, int timeout, int quiet);
278 static int scsistart(struct cam_device *device, int startstop, int loadeject,
279 int task_attr, int retry_count, int timeout);
280 static int scsiinquiry(struct cam_device *device, int task_attr,
281 int retry_count, int timeout);
282 static int scsiserial(struct cam_device *device, int task_attr,
283 int retry_count, int timeout);
284 #endif /* MINIMALISTIC */
285 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
286 lun_id_t *lun, cam_argmask *arglst);
287 static int dorescan_or_reset(int argc, char **argv, int rescan);
288 static int rescan_or_reset_bus(path_id_t bus, int rescan);
289 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
290 lun_id_t lun, int scan);
292 static int readdefects(struct cam_device *device, int argc, char **argv,
293 char *combinedopt, int task_attr, int retry_count,
295 static void modepage(struct cam_device *device, int argc, char **argv,
296 char *combinedopt, int task_attr, int retry_count,
298 static int scsicmd(struct cam_device *device, int argc, char **argv,
299 char *combinedopt, int task_attr, int retry_count,
301 static int smpcmd(struct cam_device *device, int argc, char **argv,
302 char *combinedopt, int retry_count, int timeout);
303 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
304 char *combinedopt, int retry_count, int timeout);
305 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
306 char *combinedopt, int retry_count, int timeout);
307 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
308 char *combinedopt, int retry_count, int timeout);
309 static int getdevid(struct cam_devitem *item);
310 static int buildbusdevlist(struct cam_devlist *devlist);
311 static void freebusdevlist(struct cam_devlist *devlist);
312 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
314 static int smpphylist(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int retry_count, int timeout);
316 static int tagcontrol(struct cam_device *device, int argc, char **argv,
318 static void cts_print(struct cam_device *device,
319 struct ccb_trans_settings *cts);
320 static void cpi_print(struct ccb_pathinq *cpi);
321 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
322 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
323 static int get_print_cts(struct cam_device *device, int user_settings,
324 int quiet, struct ccb_trans_settings *cts);
325 static int ratecontrol(struct cam_device *device, int task_attr,
326 int retry_count, int timeout, int argc, char **argv,
328 static int scsiformat(struct cam_device *device, int argc, char **argv,
329 char *combinedopt, int task_attr, int retry_count,
331 static int scsisanitize(struct cam_device *device, int argc, char **argv,
332 char *combinedopt, int task_attr, int retry_count,
334 static int scsireportluns(struct cam_device *device, int argc, char **argv,
335 char *combinedopt, int task_attr, int retry_count,
337 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
338 char *combinedopt, int task_attr, int retry_count,
340 static int atapm(struct cam_device *device, int argc, char **argv,
341 char *combinedopt, int retry_count, int timeout);
342 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
343 int argc, char **argv, char *combinedopt);
344 static int atahpa(struct cam_device *device, int retry_count, int timeout,
345 int argc, char **argv, char *combinedopt);
346 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
347 int sa_set, int req_sa, uint8_t *buf,
349 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
351 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
352 char *combinedopt, int task_attr, int retry_count,
353 int timeout, int verbose);
354 static int scsireprobe(struct cam_device *device);
356 #endif /* MINIMALISTIC */
358 #define min(a,b) (((a)<(b))?(a):(b))
361 #define max(a,b) (((a)>(b))?(a):(b))
365 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
366 cam_argmask *argnum, const char **subopt)
368 struct camcontrol_opts *opts;
371 for (opts = table; (opts != NULL) && (opts->optname != NULL);
373 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
374 *cmdnum = opts->cmdnum;
375 *argnum = opts->argnum;
376 *subopt = opts->subopt;
377 if (++num_matches > 1)
378 return(CC_OR_AMBIGUOUS);
385 return(CC_OR_NOT_FOUND);
390 getdevlist(struct cam_device *device)
396 ccb = cam_getccb(device);
398 ccb->ccb_h.func_code = XPT_GDEVLIST;
399 ccb->ccb_h.flags = CAM_DIR_NONE;
400 ccb->ccb_h.retry_count = 1;
402 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
403 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
404 if (cam_send_ccb(device, ccb) < 0) {
405 perror("error getting device list");
412 switch (ccb->cgdl.status) {
413 case CAM_GDEVLIST_MORE_DEVS:
414 strcpy(status, "MORE");
416 case CAM_GDEVLIST_LAST_DEVICE:
417 strcpy(status, "LAST");
419 case CAM_GDEVLIST_LIST_CHANGED:
420 strcpy(status, "CHANGED");
422 case CAM_GDEVLIST_ERROR:
423 strcpy(status, "ERROR");
428 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
429 ccb->cgdl.periph_name,
430 ccb->cgdl.unit_number,
431 ccb->cgdl.generation,
436 * If the list has changed, we need to start over from the
439 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
447 #endif /* MINIMALISTIC */
450 getdevtree(int argc, char **argv, char *combinedopt)
461 while ((c = getopt(argc, argv, combinedopt)) != -1) {
464 if ((arglist & CAM_ARG_VERBOSE) == 0)
472 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
473 warn("couldn't open %s", XPT_DEVICE);
477 bzero(&ccb, sizeof(union ccb));
479 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
480 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
481 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
483 ccb.ccb_h.func_code = XPT_DEV_MATCH;
484 bufsize = sizeof(struct dev_match_result) * 100;
485 ccb.cdm.match_buf_len = bufsize;
486 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
487 if (ccb.cdm.matches == NULL) {
488 warnx("can't malloc memory for matches");
492 ccb.cdm.num_matches = 0;
495 * We fetch all nodes, since we display most of them in the default
496 * case, and all in the verbose case.
498 ccb.cdm.num_patterns = 0;
499 ccb.cdm.pattern_buf_len = 0;
502 * We do the ioctl multiple times if necessary, in case there are
503 * more than 100 nodes in the EDT.
506 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
507 warn("error sending CAMIOCOMMAND ioctl");
512 if ((ccb.ccb_h.status != CAM_REQ_CMP)
513 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
514 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
515 warnx("got CAM error %#x, CDM error %d\n",
516 ccb.ccb_h.status, ccb.cdm.status);
521 for (i = 0; i < ccb.cdm.num_matches; i++) {
522 switch (ccb.cdm.matches[i].type) {
523 case DEV_MATCH_BUS: {
524 struct bus_match_result *bus_result;
527 * Only print the bus information if the
528 * user turns on the verbose flag.
530 if ((busonly == 0) &&
531 (arglist & CAM_ARG_VERBOSE) == 0)
535 &ccb.cdm.matches[i].result.bus_result;
538 fprintf(stdout, ")\n");
542 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
544 bus_result->dev_name,
545 bus_result->unit_number,
547 (busonly ? "" : ":"));
550 case DEV_MATCH_DEVICE: {
551 struct device_match_result *dev_result;
552 char vendor[16], product[48], revision[16];
553 char fw[5], tmpstr[256];
559 &ccb.cdm.matches[i].result.device_result;
561 if ((dev_result->flags
562 & DEV_RESULT_UNCONFIGURED)
563 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
569 if (dev_result->protocol == PROTO_SCSI) {
570 cam_strvis(vendor, dev_result->inq_data.vendor,
571 sizeof(dev_result->inq_data.vendor),
574 dev_result->inq_data.product,
575 sizeof(dev_result->inq_data.product),
578 dev_result->inq_data.revision,
579 sizeof(dev_result->inq_data.revision),
581 sprintf(tmpstr, "<%s %s %s>", vendor, product,
583 } else if (dev_result->protocol == PROTO_ATA ||
584 dev_result->protocol == PROTO_SATAPM) {
586 dev_result->ident_data.model,
587 sizeof(dev_result->ident_data.model),
590 dev_result->ident_data.revision,
591 sizeof(dev_result->ident_data.revision),
593 sprintf(tmpstr, "<%s %s>", product,
595 } else if (dev_result->protocol == PROTO_SEMB) {
596 struct sep_identify_data *sid;
598 sid = (struct sep_identify_data *)
599 &dev_result->ident_data;
600 cam_strvis(vendor, sid->vendor_id,
601 sizeof(sid->vendor_id),
603 cam_strvis(product, sid->product_id,
604 sizeof(sid->product_id),
606 cam_strvis(revision, sid->product_rev,
607 sizeof(sid->product_rev),
609 cam_strvis(fw, sid->firmware_rev,
610 sizeof(sid->firmware_rev),
612 sprintf(tmpstr, "<%s %s %s %s>",
613 vendor, product, revision, fw);
615 sprintf(tmpstr, "<>");
618 fprintf(stdout, ")\n");
622 fprintf(stdout, "%-33s at scbus%d "
623 "target %d lun %jx (",
626 dev_result->target_id,
627 (uintmax_t)dev_result->target_lun);
633 case DEV_MATCH_PERIPH: {
634 struct periph_match_result *periph_result;
637 &ccb.cdm.matches[i].result.periph_result;
639 if (busonly || skip_device != 0)
643 fprintf(stdout, ",");
645 fprintf(stdout, "%s%d",
646 periph_result->periph_name,
647 periph_result->unit_number);
653 fprintf(stdout, "unknown match type\n");
658 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
659 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
662 fprintf(stdout, ")\n");
671 testunitready(struct cam_device *device, int task_attr, int retry_count,
672 int timeout, int quiet)
677 ccb = cam_getccb(device);
679 scsi_test_unit_ready(&ccb->csio,
680 /* retries */ retry_count,
682 /* tag_action */ task_attr,
683 /* sense_len */ SSD_FULL_SIZE,
684 /* timeout */ timeout ? timeout : 5000);
686 /* Disable freezing the device queue */
687 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
689 if (arglist & CAM_ARG_ERR_RECOVER)
690 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
692 if (cam_send_ccb(device, ccb) < 0) {
694 perror("error sending test unit ready");
696 if (arglist & CAM_ARG_VERBOSE) {
697 cam_error_print(device, ccb, CAM_ESF_ALL,
698 CAM_EPF_ALL, stderr);
705 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
707 fprintf(stdout, "Unit is ready\n");
710 fprintf(stdout, "Unit is not ready\n");
713 if (arglist & CAM_ARG_VERBOSE) {
714 cam_error_print(device, ccb, CAM_ESF_ALL,
715 CAM_EPF_ALL, stderr);
725 scsistart(struct cam_device *device, int startstop, int loadeject,
726 int task_attr, int retry_count, int timeout)
731 ccb = cam_getccb(device);
734 * If we're stopping, send an ordered tag so the drive in question
735 * will finish any previously queued writes before stopping. If
736 * the device isn't capable of tagged queueing, or if tagged
737 * queueing is turned off, the tag action is a no-op. We override
738 * the default simple tag, although this also has the effect of
739 * overriding the user's wishes if he wanted to specify a simple
743 && (task_attr == MSG_SIMPLE_Q_TAG))
744 task_attr = MSG_ORDERED_Q_TAG;
746 scsi_start_stop(&ccb->csio,
747 /* retries */ retry_count,
749 /* tag_action */ task_attr,
750 /* start/stop */ startstop,
751 /* load_eject */ loadeject,
753 /* sense_len */ SSD_FULL_SIZE,
754 /* timeout */ timeout ? timeout : 120000);
756 /* Disable freezing the device queue */
757 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
759 if (arglist & CAM_ARG_ERR_RECOVER)
760 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
762 if (cam_send_ccb(device, ccb) < 0) {
763 perror("error sending start unit");
765 if (arglist & CAM_ARG_VERBOSE) {
766 cam_error_print(device, ccb, CAM_ESF_ALL,
767 CAM_EPF_ALL, stderr);
774 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
776 fprintf(stdout, "Unit started successfully");
778 fprintf(stdout,", Media loaded\n");
780 fprintf(stdout,"\n");
782 fprintf(stdout, "Unit stopped successfully");
784 fprintf(stdout, ", Media ejected\n");
786 fprintf(stdout, "\n");
792 "Error received from start unit command\n");
795 "Error received from stop unit command\n");
797 if (arglist & CAM_ARG_VERBOSE) {
798 cam_error_print(device, ccb, CAM_ESF_ALL,
799 CAM_EPF_ALL, stderr);
809 scsidoinquiry(struct cam_device *device, int argc, char **argv,
810 char *combinedopt, int task_attr, int retry_count, int timeout)
815 while ((c = getopt(argc, argv, combinedopt)) != -1) {
818 arglist |= CAM_ARG_GET_STDINQ;
821 arglist |= CAM_ARG_GET_XFERRATE;
824 arglist |= CAM_ARG_GET_SERIAL;
832 * If the user didn't specify any inquiry options, he wants all of
835 if ((arglist & CAM_ARG_INQ_MASK) == 0)
836 arglist |= CAM_ARG_INQ_MASK;
838 if (arglist & CAM_ARG_GET_STDINQ)
839 error = scsiinquiry(device, task_attr, retry_count, timeout);
844 if (arglist & CAM_ARG_GET_SERIAL)
845 scsiserial(device, task_attr, retry_count, timeout);
847 if (arglist & CAM_ARG_GET_XFERRATE)
848 error = camxferrate(device);
854 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
858 struct scsi_inquiry_data *inq_buf;
861 ccb = cam_getccb(device);
864 warnx("couldn't allocate CCB");
868 /* cam_getccb cleans up the header, caller has to zero the payload */
869 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
871 inq_buf = (struct scsi_inquiry_data *)malloc(
872 sizeof(struct scsi_inquiry_data));
874 if (inq_buf == NULL) {
876 warnx("can't malloc memory for inquiry\n");
879 bzero(inq_buf, sizeof(*inq_buf));
882 * Note that although the size of the inquiry buffer is the full
883 * 256 bytes specified in the SCSI spec, we only tell the device
884 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
885 * two reasons for this:
887 * - The SCSI spec says that when a length field is only 1 byte,
888 * a value of 0 will be interpreted as 256. Therefore
889 * scsi_inquiry() will convert an inq_len (which is passed in as
890 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
891 * to 0. Evidently, very few devices meet the spec in that
892 * regard. Some devices, like many Seagate disks, take the 0 as
893 * 0, and don't return any data. One Pioneer DVD-R drive
894 * returns more data than the command asked for.
896 * So, since there are numerous devices that just don't work
897 * right with the full inquiry size, we don't send the full size.
899 * - The second reason not to use the full inquiry data length is
900 * that we don't need it here. The only reason we issue a
901 * standard inquiry is to get the vendor name, device name,
902 * and revision so scsi_print_inquiry() can print them.
904 * If, at some point in the future, more inquiry data is needed for
905 * some reason, this code should use a procedure similar to the
906 * probe code. i.e., issue a short inquiry, and determine from
907 * the additional length passed back from the device how much
908 * inquiry data the device supports. Once the amount the device
909 * supports is determined, issue an inquiry for that amount and no
914 scsi_inquiry(&ccb->csio,
915 /* retries */ retry_count,
917 /* tag_action */ task_attr,
918 /* inq_buf */ (u_int8_t *)inq_buf,
919 /* inq_len */ SHORT_INQUIRY_LENGTH,
922 /* sense_len */ SSD_FULL_SIZE,
923 /* timeout */ timeout ? timeout : 5000);
925 /* Disable freezing the device queue */
926 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
928 if (arglist & CAM_ARG_ERR_RECOVER)
929 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
931 if (cam_send_ccb(device, ccb) < 0) {
932 perror("error sending SCSI inquiry");
934 if (arglist & CAM_ARG_VERBOSE) {
935 cam_error_print(device, ccb, CAM_ESF_ALL,
936 CAM_EPF_ALL, stderr);
943 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
946 if (arglist & CAM_ARG_VERBOSE) {
947 cam_error_print(device, ccb, CAM_ESF_ALL,
948 CAM_EPF_ALL, stderr);
959 fprintf(stdout, "%s%d: ", device->device_name,
960 device->dev_unit_num);
961 scsi_print_inquiry(inq_buf);
969 scsiserial(struct cam_device *device, int task_attr, int retry_count,
973 struct scsi_vpd_unit_serial_number *serial_buf;
974 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
977 ccb = cam_getccb(device);
980 warnx("couldn't allocate CCB");
984 /* cam_getccb cleans up the header, caller has to zero the payload */
985 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
987 serial_buf = (struct scsi_vpd_unit_serial_number *)
988 malloc(sizeof(*serial_buf));
990 if (serial_buf == NULL) {
992 warnx("can't malloc memory for serial number");
996 scsi_inquiry(&ccb->csio,
997 /*retries*/ retry_count,
999 /* tag_action */ task_attr,
1000 /* inq_buf */ (u_int8_t *)serial_buf,
1001 /* inq_len */ sizeof(*serial_buf),
1003 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1004 /* sense_len */ SSD_FULL_SIZE,
1005 /* timeout */ timeout ? timeout : 5000);
1007 /* Disable freezing the device queue */
1008 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1010 if (arglist & CAM_ARG_ERR_RECOVER)
1011 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1013 if (cam_send_ccb(device, ccb) < 0) {
1014 warn("error getting serial number");
1016 if (arglist & CAM_ARG_VERBOSE) {
1017 cam_error_print(device, ccb, CAM_ESF_ALL,
1018 CAM_EPF_ALL, stderr);
1026 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1029 if (arglist & CAM_ARG_VERBOSE) {
1030 cam_error_print(device, ccb, CAM_ESF_ALL,
1031 CAM_EPF_ALL, stderr);
1042 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1043 serial_num[serial_buf->length] = '\0';
1045 if ((arglist & CAM_ARG_GET_STDINQ)
1046 || (arglist & CAM_ARG_GET_XFERRATE))
1047 fprintf(stdout, "%s%d: Serial Number ",
1048 device->device_name, device->dev_unit_num);
1050 fprintf(stdout, "%.60s\n", serial_num);
1058 camxferrate(struct cam_device *device)
1060 struct ccb_pathinq cpi;
1062 u_int32_t speed = 0;
1067 if ((retval = get_cpi(device, &cpi)) != 0)
1070 ccb = cam_getccb(device);
1073 warnx("couldn't allocate CCB");
1077 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1079 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1080 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1082 if (((retval = cam_send_ccb(device, ccb)) < 0)
1083 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1084 const char error_string[] = "error getting transfer settings";
1089 warnx(error_string);
1091 if (arglist & CAM_ARG_VERBOSE)
1092 cam_error_print(device, ccb, CAM_ESF_ALL,
1093 CAM_EPF_ALL, stderr);
1097 goto xferrate_bailout;
1101 speed = cpi.base_transfer_speed;
1103 if (ccb->cts.transport == XPORT_SPI) {
1104 struct ccb_trans_settings_spi *spi =
1105 &ccb->cts.xport_specific.spi;
1107 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1108 freq = scsi_calc_syncsrate(spi->sync_period);
1111 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1112 speed *= (0x01 << spi->bus_width);
1114 } else if (ccb->cts.transport == XPORT_FC) {
1115 struct ccb_trans_settings_fc *fc =
1116 &ccb->cts.xport_specific.fc;
1118 if (fc->valid & CTS_FC_VALID_SPEED)
1119 speed = fc->bitrate;
1120 } else if (ccb->cts.transport == XPORT_SAS) {
1121 struct ccb_trans_settings_sas *sas =
1122 &ccb->cts.xport_specific.sas;
1124 if (sas->valid & CTS_SAS_VALID_SPEED)
1125 speed = sas->bitrate;
1126 } else if (ccb->cts.transport == XPORT_ATA) {
1127 struct ccb_trans_settings_pata *pata =
1128 &ccb->cts.xport_specific.ata;
1130 if (pata->valid & CTS_ATA_VALID_MODE)
1131 speed = ata_mode2speed(pata->mode);
1132 } else if (ccb->cts.transport == XPORT_SATA) {
1133 struct ccb_trans_settings_sata *sata =
1134 &ccb->cts.xport_specific.sata;
1136 if (sata->valid & CTS_SATA_VALID_REVISION)
1137 speed = ata_revision2speed(sata->revision);
1142 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1143 device->device_name, device->dev_unit_num,
1146 fprintf(stdout, "%s%d: %dKB/s transfers",
1147 device->device_name, device->dev_unit_num,
1151 if (ccb->cts.transport == XPORT_SPI) {
1152 struct ccb_trans_settings_spi *spi =
1153 &ccb->cts.xport_specific.spi;
1155 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1156 && (spi->sync_offset != 0))
1157 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1158 freq % 1000, spi->sync_offset);
1160 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1161 && (spi->bus_width > 0)) {
1162 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1163 && (spi->sync_offset != 0)) {
1164 fprintf(stdout, ", ");
1166 fprintf(stdout, " (");
1168 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1169 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1170 && (spi->sync_offset != 0)) {
1171 fprintf(stdout, ")");
1173 } else if (ccb->cts.transport == XPORT_ATA) {
1174 struct ccb_trans_settings_pata *pata =
1175 &ccb->cts.xport_specific.ata;
1178 if (pata->valid & CTS_ATA_VALID_MODE)
1179 printf("%s, ", ata_mode2string(pata->mode));
1180 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1181 printf("ATAPI %dbytes, ", pata->atapi);
1182 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1183 printf("PIO %dbytes", pata->bytecount);
1185 } else if (ccb->cts.transport == XPORT_SATA) {
1186 struct ccb_trans_settings_sata *sata =
1187 &ccb->cts.xport_specific.sata;
1190 if (sata->valid & CTS_SATA_VALID_REVISION)
1191 printf("SATA %d.x, ", sata->revision);
1194 if (sata->valid & CTS_SATA_VALID_MODE)
1195 printf("%s, ", ata_mode2string(sata->mode));
1196 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1197 printf("ATAPI %dbytes, ", sata->atapi);
1198 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1199 printf("PIO %dbytes", sata->bytecount);
1203 if (ccb->cts.protocol == PROTO_SCSI) {
1204 struct ccb_trans_settings_scsi *scsi =
1205 &ccb->cts.proto_specific.scsi;
1206 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1207 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1208 fprintf(stdout, ", Command Queueing Enabled");
1213 fprintf(stdout, "\n");
1223 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1225 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1226 ((u_int32_t)parm->lba_size_2 << 16);
1228 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1229 ((u_int64_t)parm->lba_size48_2 << 16) |
1230 ((u_int64_t)parm->lba_size48_3 << 32) |
1231 ((u_int64_t)parm->lba_size48_4 << 48);
1235 "Support Enabled Value\n");
1238 printf("Host Protected Area (HPA) ");
1239 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1240 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1241 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1244 printf("HPA - Security ");
1245 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1255 atasata(struct ata_params *parm)
1259 if (parm->satacapabilities != 0xffff &&
1260 parm->satacapabilities != 0x0000)
1267 atacapprint(struct ata_params *parm)
1269 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1270 ((u_int32_t)parm->lba_size_2 << 16);
1272 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1273 ((u_int64_t)parm->lba_size48_2 << 16) |
1274 ((u_int64_t)parm->lba_size48_3 << 32) |
1275 ((u_int64_t)parm->lba_size48_4 << 48);
1278 printf("protocol ");
1279 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1280 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1281 if (parm->satacapabilities & ATA_SATA_GEN3)
1282 printf(" SATA 3.x\n");
1283 else if (parm->satacapabilities & ATA_SATA_GEN2)
1284 printf(" SATA 2.x\n");
1285 else if (parm->satacapabilities & ATA_SATA_GEN1)
1286 printf(" SATA 1.x\n");
1292 printf("device model %.40s\n", parm->model);
1293 printf("firmware revision %.8s\n", parm->revision);
1294 printf("serial number %.20s\n", parm->serial);
1295 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1296 printf("WWN %04x%04x%04x%04x\n",
1297 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1299 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1300 printf("media serial number %.30s\n",
1301 parm->media_serial);
1304 printf("cylinders %d\n", parm->cylinders);
1305 printf("heads %d\n", parm->heads);
1306 printf("sectors/track %d\n", parm->sectors);
1307 printf("sector size logical %u, physical %lu, offset %lu\n",
1308 ata_logical_sector_size(parm),
1309 (unsigned long)ata_physical_sector_size(parm),
1310 (unsigned long)ata_logical_sector_offset(parm));
1312 if (parm->config == ATA_PROTO_CFA ||
1313 (parm->support.command2 & ATA_SUPPORT_CFA))
1314 printf("CFA supported\n");
1316 printf("LBA%ssupported ",
1317 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1319 printf("%d sectors\n", lbasize);
1323 printf("LBA48%ssupported ",
1324 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1326 printf("%ju sectors\n", (uintmax_t)lbasize48);
1330 printf("PIO supported PIO");
1331 switch (ata_max_pmode(parm)) {
1347 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1348 printf(" w/o IORDY");
1351 printf("DMA%ssupported ",
1352 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1353 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1354 if (parm->mwdmamodes & 0xff) {
1356 if (parm->mwdmamodes & 0x04)
1358 else if (parm->mwdmamodes & 0x02)
1360 else if (parm->mwdmamodes & 0x01)
1364 if ((parm->atavalid & ATA_FLAG_88) &&
1365 (parm->udmamodes & 0xff)) {
1367 if (parm->udmamodes & 0x40)
1369 else if (parm->udmamodes & 0x20)
1371 else if (parm->udmamodes & 0x10)
1373 else if (parm->udmamodes & 0x08)
1375 else if (parm->udmamodes & 0x04)
1377 else if (parm->udmamodes & 0x02)
1379 else if (parm->udmamodes & 0x01)
1386 if (parm->media_rotation_rate == 1) {
1387 printf("media RPM non-rotating\n");
1388 } else if (parm->media_rotation_rate >= 0x0401 &&
1389 parm->media_rotation_rate <= 0xFFFE) {
1390 printf("media RPM %d\n",
1391 parm->media_rotation_rate);
1395 "Support Enabled Value Vendor\n");
1396 printf("read ahead %s %s\n",
1397 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1398 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1399 printf("write cache %s %s\n",
1400 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1401 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1402 printf("flush cache %s %s\n",
1403 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1404 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1405 printf("overlap %s\n",
1406 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1407 printf("Tagged Command Queuing (TCQ) %s %s",
1408 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1409 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1410 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1411 printf(" %d tags\n",
1412 ATA_QUEUE_LEN(parm->queue) + 1);
1415 printf("Native Command Queuing (NCQ) ");
1416 if (parm->satacapabilities != 0xffff &&
1417 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1418 printf("yes %d tags\n",
1419 ATA_QUEUE_LEN(parm->queue) + 1);
1423 printf("NCQ Queue Management %s\n", atasata(parm) &&
1424 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1426 printf("NCQ Streaming %s\n", atasata(parm) &&
1427 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1429 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1430 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1433 printf("SMART %s %s\n",
1434 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1435 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1436 printf("microcode download %s %s\n",
1437 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1438 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1439 printf("security %s %s\n",
1440 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1441 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1442 printf("power management %s %s\n",
1443 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1444 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1445 printf("advanced power management %s %s",
1446 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1447 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1448 if (parm->support.command2 & ATA_SUPPORT_APM) {
1449 printf(" %d/0x%02X\n",
1450 parm->apm_value & 0xff, parm->apm_value & 0xff);
1453 printf("automatic acoustic management %s %s",
1454 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1455 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1456 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1457 printf(" %d/0x%02X %d/0x%02X\n",
1458 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1459 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1460 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1461 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1464 printf("media status notification %s %s\n",
1465 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1466 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1467 printf("power-up in Standby %s %s\n",
1468 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1469 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1470 printf("write-read-verify %s %s",
1471 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1472 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1473 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1474 printf(" %d/0x%x\n",
1475 parm->wrv_mode, parm->wrv_mode);
1478 printf("unload %s %s\n",
1479 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1480 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1481 printf("general purpose logging %s %s\n",
1482 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1483 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1484 printf("free-fall %s %s\n",
1485 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1486 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1487 printf("Data Set Management (DSM/TRIM) ");
1488 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1490 printf("DSM - max 512byte blocks ");
1491 if (parm->max_dsm_blocks == 0x00)
1492 printf("yes not specified\n");
1495 parm->max_dsm_blocks);
1497 printf("DSM - deterministic read ");
1498 if (parm->support3 & ATA_SUPPORT_DRAT) {
1499 if (parm->support3 & ATA_SUPPORT_RZAT)
1500 printf("yes zeroed\n");
1502 printf("yes any value\n");
1512 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1514 struct ata_pass_16 *ata_pass_16;
1515 struct ata_cmd ata_cmd;
1517 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1518 ata_cmd.command = ata_pass_16->command;
1519 ata_cmd.control = ata_pass_16->control;
1520 ata_cmd.features = ata_pass_16->features;
1522 if (arglist & CAM_ARG_VERBOSE) {
1523 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1524 ata_op_string(&ata_cmd),
1525 ccb->csio.ccb_h.timeout);
1528 /* Disable freezing the device queue */
1529 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1531 if (arglist & CAM_ARG_ERR_RECOVER)
1532 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1534 if (cam_send_ccb(device, ccb) < 0) {
1535 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1536 warn("error sending ATA %s via pass_16",
1537 ata_op_string(&ata_cmd));
1540 if (arglist & CAM_ARG_VERBOSE) {
1541 cam_error_print(device, ccb, CAM_ESF_ALL,
1542 CAM_EPF_ALL, stderr);
1548 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1549 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1550 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1551 warnx("ATA %s via pass_16 failed",
1552 ata_op_string(&ata_cmd));
1554 if (arglist & CAM_ARG_VERBOSE) {
1555 cam_error_print(device, ccb, CAM_ESF_ALL,
1556 CAM_EPF_ALL, stderr);
1567 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1569 if (arglist & CAM_ARG_VERBOSE) {
1570 warnx("sending ATA %s with timeout of %u msecs",
1571 ata_op_string(&(ccb->ataio.cmd)),
1572 ccb->ataio.ccb_h.timeout);
1575 /* Disable freezing the device queue */
1576 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1578 if (arglist & CAM_ARG_ERR_RECOVER)
1579 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1581 if (cam_send_ccb(device, ccb) < 0) {
1582 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1583 warn("error sending ATA %s",
1584 ata_op_string(&(ccb->ataio.cmd)));
1587 if (arglist & CAM_ARG_VERBOSE) {
1588 cam_error_print(device, ccb, CAM_ESF_ALL,
1589 CAM_EPF_ALL, stderr);
1595 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1596 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1597 warnx("ATA %s failed: %d",
1598 ata_op_string(&(ccb->ataio.cmd)), quiet);
1601 if (arglist & CAM_ARG_VERBOSE) {
1602 cam_error_print(device, ccb, CAM_ESF_ALL,
1603 CAM_EPF_ALL, stderr);
1613 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1614 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1615 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1616 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1617 u_int16_t dxfer_len, int timeout, int quiet)
1619 if (data_ptr != NULL) {
1620 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1621 AP_FLAG_TLEN_SECT_CNT;
1622 if (flags & CAM_DIR_OUT)
1623 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1625 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1627 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1630 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1632 scsi_ata_pass_16(&ccb->csio,
1646 /*sense_len*/SSD_FULL_SIZE,
1649 return scsi_cam_pass_16_send(device, ccb, quiet);
1653 ata_try_pass_16(struct cam_device *device)
1655 struct ccb_pathinq cpi;
1657 if (get_cpi(device, &cpi) != 0) {
1658 warnx("couldn't get CPI");
1662 if (cpi.protocol == PROTO_SCSI) {
1663 /* possibly compatible with pass_16 */
1667 /* likely not compatible with pass_16 */
1672 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1673 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1674 u_int8_t command, u_int8_t features, u_int32_t lba,
1675 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1676 int timeout, int quiet)
1680 switch (ata_try_pass_16(device)) {
1684 /* Try using SCSI Passthrough */
1685 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1686 0, tag_action, command, features, lba,
1687 sector_count, data_ptr, dxfer_len,
1691 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1692 cam_fill_ataio(&ccb->ataio,
1701 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1702 return ata_cam_send(device, ccb, quiet);
1706 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1707 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1708 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1709 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1710 u_int16_t dxfer_len, int timeout, int force48bit)
1714 retval = ata_try_pass_16(device);
1721 /* Try using SCSI Passthrough */
1722 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1723 ata_flags, tag_action, command, features,
1724 lba, sector_count, data_ptr, dxfer_len,
1727 if (ata_flags & AP_FLAG_CHK_COND) {
1728 /* Decode ata_res from sense data */
1729 struct ata_res_pass16 *res_pass16;
1730 struct ata_res *res;
1734 /* sense_data is 4 byte aligned */
1735 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1736 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1737 ptr[i] = le16toh(ptr[i]);
1739 /* sense_data is 4 byte aligned */
1740 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1741 &ccb->csio.sense_data;
1742 res = &ccb->ataio.res;
1743 res->flags = res_pass16->flags;
1744 res->status = res_pass16->status;
1745 res->error = res_pass16->error;
1746 res->lba_low = res_pass16->lba_low;
1747 res->lba_mid = res_pass16->lba_mid;
1748 res->lba_high = res_pass16->lba_high;
1749 res->device = res_pass16->device;
1750 res->lba_low_exp = res_pass16->lba_low_exp;
1751 res->lba_mid_exp = res_pass16->lba_mid_exp;
1752 res->lba_high_exp = res_pass16->lba_high_exp;
1753 res->sector_count = res_pass16->sector_count;
1754 res->sector_count_exp = res_pass16->sector_count_exp;
1760 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1761 cam_fill_ataio(&ccb->ataio,
1770 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1771 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1773 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1775 if (ata_flags & AP_FLAG_CHK_COND)
1776 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1778 return ata_cam_send(device, ccb, 0);
1782 dump_data(uint16_t *ptr, uint32_t len)
1786 for (i = 0; i < len / 2; i++) {
1788 printf(" %3d: ", i);
1789 printf("%04hx ", ptr[i]);
1798 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1799 int is48bit, u_int64_t *hpasize)
1801 struct ata_res *res;
1803 res = &ccb->ataio.res;
1804 if (res->status & ATA_STATUS_ERROR) {
1805 if (arglist & CAM_ARG_VERBOSE) {
1806 cam_error_print(device, ccb, CAM_ESF_ALL,
1807 CAM_EPF_ALL, stderr);
1808 printf("error = 0x%02x, sector_count = 0x%04x, "
1809 "device = 0x%02x, status = 0x%02x\n",
1810 res->error, res->sector_count,
1811 res->device, res->status);
1814 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1815 warnx("Max address has already been set since "
1816 "last power-on or hardware reset");
1822 if (arglist & CAM_ARG_VERBOSE) {
1823 fprintf(stdout, "%s%d: Raw native max data:\n",
1824 device->device_name, device->dev_unit_num);
1825 /* res is 4 byte aligned */
1826 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1828 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1829 "status = 0x%02x\n", res->error, res->sector_count,
1830 res->device, res->status);
1833 if (hpasize != NULL) {
1835 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1836 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1837 ((res->lba_high << 16) | (res->lba_mid << 8) |
1840 *hpasize = (((res->device & 0x0f) << 24) |
1841 (res->lba_high << 16) | (res->lba_mid << 8) |
1850 ata_read_native_max(struct cam_device *device, int retry_count,
1851 u_int32_t timeout, union ccb *ccb,
1852 struct ata_params *parm, u_int64_t *hpasize)
1858 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1859 protocol = AP_PROTO_NON_DATA;
1862 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1863 protocol |= AP_EXTEND;
1865 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1868 error = ata_do_cmd(device,
1871 /*flags*/CAM_DIR_NONE,
1872 /*protocol*/protocol,
1873 /*ata_flags*/AP_FLAG_CHK_COND,
1874 /*tag_action*/MSG_SIMPLE_Q_TAG,
1881 timeout ? timeout : 1000,
1887 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1891 atahpa_set_max(struct cam_device *device, int retry_count,
1892 u_int32_t timeout, union ccb *ccb,
1893 int is48bit, u_int64_t maxsize, int persist)
1899 protocol = AP_PROTO_NON_DATA;
1902 cmd = ATA_SET_MAX_ADDRESS48;
1903 protocol |= AP_EXTEND;
1905 cmd = ATA_SET_MAX_ADDRESS;
1908 /* lba's are zero indexed so the max lba is requested max - 1 */
1912 error = ata_do_cmd(device,
1915 /*flags*/CAM_DIR_NONE,
1916 /*protocol*/protocol,
1917 /*ata_flags*/AP_FLAG_CHK_COND,
1918 /*tag_action*/MSG_SIMPLE_Q_TAG,
1920 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1922 /*sector_count*/persist,
1925 timeout ? timeout : 1000,
1931 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1935 atahpa_password(struct cam_device *device, int retry_count,
1936 u_int32_t timeout, union ccb *ccb,
1937 int is48bit, struct ata_set_max_pwd *pwd)
1943 protocol = AP_PROTO_PIO_OUT;
1944 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1946 error = ata_do_cmd(device,
1949 /*flags*/CAM_DIR_OUT,
1950 /*protocol*/protocol,
1951 /*ata_flags*/AP_FLAG_CHK_COND,
1952 /*tag_action*/MSG_SIMPLE_Q_TAG,
1954 /*features*/ATA_HPA_FEAT_SET_PWD,
1957 /*data_ptr*/(u_int8_t*)pwd,
1958 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1959 timeout ? timeout : 1000,
1965 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1969 atahpa_lock(struct cam_device *device, int retry_count,
1970 u_int32_t timeout, union ccb *ccb, int is48bit)
1976 protocol = AP_PROTO_NON_DATA;
1977 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1979 error = ata_do_cmd(device,
1982 /*flags*/CAM_DIR_NONE,
1983 /*protocol*/protocol,
1984 /*ata_flags*/AP_FLAG_CHK_COND,
1985 /*tag_action*/MSG_SIMPLE_Q_TAG,
1987 /*features*/ATA_HPA_FEAT_LOCK,
1992 timeout ? timeout : 1000,
1998 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2002 atahpa_unlock(struct cam_device *device, int retry_count,
2003 u_int32_t timeout, union ccb *ccb,
2004 int is48bit, struct ata_set_max_pwd *pwd)
2010 protocol = AP_PROTO_PIO_OUT;
2011 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2013 error = ata_do_cmd(device,
2016 /*flags*/CAM_DIR_OUT,
2017 /*protocol*/protocol,
2018 /*ata_flags*/AP_FLAG_CHK_COND,
2019 /*tag_action*/MSG_SIMPLE_Q_TAG,
2021 /*features*/ATA_HPA_FEAT_UNLOCK,
2024 /*data_ptr*/(u_int8_t*)pwd,
2025 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2026 timeout ? timeout : 1000,
2032 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2036 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2037 u_int32_t timeout, union ccb *ccb, int is48bit)
2043 protocol = AP_PROTO_NON_DATA;
2044 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2046 error = ata_do_cmd(device,
2049 /*flags*/CAM_DIR_NONE,
2050 /*protocol*/protocol,
2051 /*ata_flags*/AP_FLAG_CHK_COND,
2052 /*tag_action*/MSG_SIMPLE_Q_TAG,
2054 /*features*/ATA_HPA_FEAT_FREEZE,
2059 timeout ? timeout : 1000,
2065 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2070 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2071 union ccb *ccb, struct ata_params** ident_bufp)
2073 struct ata_params *ident_buf;
2074 struct ccb_pathinq cpi;
2075 struct ccb_getdev cgd;
2078 u_int8_t command, retry_command;
2080 if (get_cpi(device, &cpi) != 0) {
2081 warnx("couldn't get CPI");
2085 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2086 if (cpi.protocol == PROTO_ATA) {
2087 if (get_cgd(device, &cgd) != 0) {
2088 warnx("couldn't get CGD");
2092 command = (cgd.protocol == PROTO_ATA) ?
2093 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2096 /* We don't know which for sure so try both */
2097 command = ATA_ATA_IDENTIFY;
2098 retry_command = ATA_ATAPI_IDENTIFY;
2101 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2103 warnx("can't calloc memory for identify\n");
2107 error = ata_do_28bit_cmd(device,
2109 /*retries*/retry_count,
2110 /*flags*/CAM_DIR_IN,
2111 /*protocol*/AP_PROTO_PIO_IN,
2112 /*tag_action*/MSG_SIMPLE_Q_TAG,
2116 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2117 /*data_ptr*/(u_int8_t *)ptr,
2118 /*dxfer_len*/sizeof(struct ata_params),
2119 /*timeout*/timeout ? timeout : 30 * 1000,
2123 if (retry_command == 0) {
2127 error = ata_do_28bit_cmd(device,
2129 /*retries*/retry_count,
2130 /*flags*/CAM_DIR_IN,
2131 /*protocol*/AP_PROTO_PIO_IN,
2132 /*tag_action*/MSG_SIMPLE_Q_TAG,
2133 /*command*/retry_command,
2136 /*sector_count*/(u_int8_t)
2137 sizeof(struct ata_params),
2138 /*data_ptr*/(u_int8_t *)ptr,
2139 /*dxfer_len*/sizeof(struct ata_params),
2140 /*timeout*/timeout ? timeout : 30 * 1000,
2150 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2151 ptr[i] = le16toh(ptr[i]);
2156 if (arglist & CAM_ARG_VERBOSE) {
2157 fprintf(stdout, "%s%d: Raw identify data:\n",
2158 device->device_name, device->dev_unit_num);
2159 dump_data(ptr, sizeof(struct ata_params));
2162 /* check for invalid (all zero) response */
2164 warnx("Invalid identify response detected");
2169 ident_buf = (struct ata_params *)ptr;
2170 if (strncmp(ident_buf->model, "FX", 2) &&
2171 strncmp(ident_buf->model, "NEC", 3) &&
2172 strncmp(ident_buf->model, "Pioneer", 7) &&
2173 strncmp(ident_buf->model, "SHARP", 5)) {
2174 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2175 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2176 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2177 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2179 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2180 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2181 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2182 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2183 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2184 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2185 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2186 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2187 sizeof(ident_buf->media_serial));
2189 *ident_bufp = ident_buf;
2196 ataidentify(struct cam_device *device, int retry_count, int timeout)
2199 struct ata_params *ident_buf;
2202 if ((ccb = cam_getccb(device)) == NULL) {
2203 warnx("couldn't allocate CCB");
2207 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2212 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2213 if (ata_read_native_max(device, retry_count, timeout, ccb,
2214 ident_buf, &hpasize) != 0) {
2222 printf("%s%d: ", device->device_name, device->dev_unit_num);
2223 ata_print_ident(ident_buf);
2224 camxferrate(device);
2225 atacapprint(ident_buf);
2226 atahpa_print(ident_buf, hpasize, 0);
2233 #endif /* MINIMALISTIC */
2236 #ifndef MINIMALISTIC
2238 ATA_SECURITY_ACTION_PRINT,
2239 ATA_SECURITY_ACTION_FREEZE,
2240 ATA_SECURITY_ACTION_UNLOCK,
2241 ATA_SECURITY_ACTION_DISABLE,
2242 ATA_SECURITY_ACTION_ERASE,
2243 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2244 ATA_SECURITY_ACTION_SET_PASSWORD
2248 atasecurity_print_time(u_int16_t tw)
2252 printf("unspecified");
2254 printf("> 508 min");
2256 printf("%i min", 2 * tw);
2260 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2264 return 2 * 3600 * 1000; /* default: two hours */
2265 else if (timeout > 255)
2266 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2268 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2273 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2277 bzero(&cmd, sizeof(cmd));
2278 cmd.command = command;
2279 printf("Issuing %s", ata_op_string(&cmd));
2282 char pass[sizeof(pwd->password)+1];
2284 /* pwd->password may not be null terminated */
2285 pass[sizeof(pwd->password)] = '\0';
2286 strncpy(pass, pwd->password, sizeof(pwd->password));
2287 printf(" password='%s', user='%s'",
2289 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2292 if (command == ATA_SECURITY_SET_PASSWORD) {
2293 printf(", mode='%s'",
2294 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2295 "maximum" : "high");
2303 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2304 int retry_count, u_int32_t timeout, int quiet)
2308 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2310 return ata_do_28bit_cmd(device,
2313 /*flags*/CAM_DIR_NONE,
2314 /*protocol*/AP_PROTO_NON_DATA,
2315 /*tag_action*/MSG_SIMPLE_Q_TAG,
2316 /*command*/ATA_SECURITY_FREEZE_LOCK,
2327 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2328 int retry_count, u_int32_t timeout,
2329 struct ata_security_password *pwd, int quiet)
2333 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2335 return ata_do_28bit_cmd(device,
2338 /*flags*/CAM_DIR_OUT,
2339 /*protocol*/AP_PROTO_PIO_OUT,
2340 /*tag_action*/MSG_SIMPLE_Q_TAG,
2341 /*command*/ATA_SECURITY_UNLOCK,
2345 /*data_ptr*/(u_int8_t *)pwd,
2346 /*dxfer_len*/sizeof(*pwd),
2352 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2353 int retry_count, u_int32_t timeout,
2354 struct ata_security_password *pwd, int quiet)
2358 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2359 return ata_do_28bit_cmd(device,
2362 /*flags*/CAM_DIR_OUT,
2363 /*protocol*/AP_PROTO_PIO_OUT,
2364 /*tag_action*/MSG_SIMPLE_Q_TAG,
2365 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2369 /*data_ptr*/(u_int8_t *)pwd,
2370 /*dxfer_len*/sizeof(*pwd),
2377 atasecurity_erase_confirm(struct cam_device *device,
2378 struct ata_params* ident_buf)
2381 printf("\nYou are about to ERASE ALL DATA from the following"
2382 " device:\n%s%d,%s%d: ", device->device_name,
2383 device->dev_unit_num, device->given_dev_name,
2384 device->given_unit_number);
2385 ata_print_ident(ident_buf);
2389 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2391 if (fgets(str, sizeof(str), stdin) != NULL) {
2392 if (strncasecmp(str, "yes", 3) == 0) {
2394 } else if (strncasecmp(str, "no", 2) == 0) {
2397 printf("Please answer \"yes\" or "
2408 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2409 int retry_count, u_int32_t timeout,
2410 u_int32_t erase_timeout,
2411 struct ata_security_password *pwd, int quiet)
2416 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2418 error = ata_do_28bit_cmd(device,
2421 /*flags*/CAM_DIR_NONE,
2422 /*protocol*/AP_PROTO_NON_DATA,
2423 /*tag_action*/MSG_SIMPLE_Q_TAG,
2424 /*command*/ATA_SECURITY_ERASE_PREPARE,
2437 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2439 error = ata_do_28bit_cmd(device,
2442 /*flags*/CAM_DIR_OUT,
2443 /*protocol*/AP_PROTO_PIO_OUT,
2444 /*tag_action*/MSG_SIMPLE_Q_TAG,
2445 /*command*/ATA_SECURITY_ERASE_UNIT,
2449 /*data_ptr*/(u_int8_t *)pwd,
2450 /*dxfer_len*/sizeof(*pwd),
2451 /*timeout*/erase_timeout,
2454 if (error == 0 && quiet == 0)
2455 printf("\nErase Complete\n");
2461 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2462 int retry_count, u_int32_t timeout,
2463 struct ata_security_password *pwd, int quiet)
2467 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2469 return ata_do_28bit_cmd(device,
2472 /*flags*/CAM_DIR_OUT,
2473 /*protocol*/AP_PROTO_PIO_OUT,
2474 /*tag_action*/MSG_SIMPLE_Q_TAG,
2475 /*command*/ATA_SECURITY_SET_PASSWORD,
2479 /*data_ptr*/(u_int8_t *)pwd,
2480 /*dxfer_len*/sizeof(*pwd),
2486 atasecurity_print(struct ata_params *parm)
2489 printf("\nSecurity Option Value\n");
2490 if (arglist & CAM_ARG_VERBOSE) {
2491 printf("status %04x\n",
2492 parm->security_status);
2494 printf("supported %s\n",
2495 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2496 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2498 printf("enabled %s\n",
2499 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2500 printf("drive locked %s\n",
2501 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2502 printf("security config frozen %s\n",
2503 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2504 printf("count expired %s\n",
2505 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2506 printf("security level %s\n",
2507 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2508 printf("enhanced erase supported %s\n",
2509 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2510 printf("erase time ");
2511 atasecurity_print_time(parm->erase_time);
2513 printf("enhanced erase time ");
2514 atasecurity_print_time(parm->enhanced_erase_time);
2516 printf("master password rev %04x%s\n",
2517 parm->master_passwd_revision,
2518 parm->master_passwd_revision == 0x0000 ||
2519 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2523 * Validates and copies the password in optarg to the passed buffer.
2524 * If the password in optarg is the same length as the buffer then
2525 * the data will still be copied but no null termination will occur.
2528 ata_getpwd(u_int8_t *passwd, int max, char opt)
2532 len = strlen(optarg);
2534 warnx("-%c password is too long", opt);
2536 } else if (len == 0) {
2537 warnx("-%c password is missing", opt);
2539 } else if (optarg[0] == '-'){
2540 warnx("-%c password starts with '-' (generic arg?)", opt);
2542 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2543 warnx("-%c password conflicts with existing password from -%c",
2548 /* Callers pass in a buffer which does NOT need to be terminated */
2549 strncpy(passwd, optarg, max);
2556 ATA_HPA_ACTION_PRINT,
2557 ATA_HPA_ACTION_SET_MAX,
2558 ATA_HPA_ACTION_SET_PWD,
2559 ATA_HPA_ACTION_LOCK,
2560 ATA_HPA_ACTION_UNLOCK,
2561 ATA_HPA_ACTION_FREEZE_LOCK
2565 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2566 u_int64_t maxsize, int persist)
2568 printf("\nYou are about to configure HPA to limit the user accessible\n"
2569 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2570 persist ? "persistently" : "temporarily",
2571 device->device_name, device->dev_unit_num,
2572 device->given_dev_name, device->given_unit_number);
2573 ata_print_ident(ident_buf);
2577 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2579 if (NULL != fgets(str, sizeof(str), stdin)) {
2580 if (0 == strncasecmp(str, "yes", 3)) {
2582 } else if (0 == strncasecmp(str, "no", 2)) {
2585 printf("Please answer \"yes\" or "
2596 atahpa(struct cam_device *device, int retry_count, int timeout,
2597 int argc, char **argv, char *combinedopt)
2600 struct ata_params *ident_buf;
2601 struct ccb_getdev cgd;
2602 struct ata_set_max_pwd pwd;
2603 int error, confirm, quiet, c, action, actions, persist;
2604 int security, is48bit, pwdsize;
2605 u_int64_t hpasize, maxsize;
2614 memset(&pwd, 0, sizeof(pwd));
2616 /* default action is to print hpa information */
2617 action = ATA_HPA_ACTION_PRINT;
2618 pwdsize = sizeof(pwd.password);
2620 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2623 action = ATA_HPA_ACTION_SET_MAX;
2624 maxsize = strtoumax(optarg, NULL, 0);
2629 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2631 action = ATA_HPA_ACTION_SET_PWD;
2637 action = ATA_HPA_ACTION_LOCK;
2643 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2645 action = ATA_HPA_ACTION_UNLOCK;
2651 action = ATA_HPA_ACTION_FREEZE_LOCK;
2671 warnx("too many hpa actions specified");
2675 if (get_cgd(device, &cgd) != 0) {
2676 warnx("couldn't get CGD");
2680 ccb = cam_getccb(device);
2682 warnx("couldn't allocate CCB");
2686 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2693 printf("%s%d: ", device->device_name, device->dev_unit_num);
2694 ata_print_ident(ident_buf);
2695 camxferrate(device);
2698 if (action == ATA_HPA_ACTION_PRINT) {
2699 error = ata_read_native_max(device, retry_count, timeout, ccb,
2700 ident_buf, &hpasize);
2702 atahpa_print(ident_buf, hpasize, 1);
2709 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2710 warnx("HPA is not supported by this device");
2716 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2717 warnx("HPA Security is not supported by this device");
2723 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2726 * The ATA spec requires:
2727 * 1. Read native max addr is called directly before set max addr
2728 * 2. Read native max addr is NOT called before any other set max call
2731 case ATA_HPA_ACTION_SET_MAX:
2733 atahpa_set_confirm(device, ident_buf, maxsize,
2740 error = ata_read_native_max(device, retry_count, timeout,
2741 ccb, ident_buf, &hpasize);
2743 error = atahpa_set_max(device, retry_count, timeout,
2744 ccb, is48bit, maxsize, persist);
2746 /* redo identify to get new lba values */
2747 error = ata_do_identify(device, retry_count,
2750 atahpa_print(ident_buf, hpasize, 1);
2755 case ATA_HPA_ACTION_SET_PWD:
2756 error = atahpa_password(device, retry_count, timeout,
2757 ccb, is48bit, &pwd);
2759 printf("HPA password has been set\n");
2762 case ATA_HPA_ACTION_LOCK:
2763 error = atahpa_lock(device, retry_count, timeout,
2766 printf("HPA has been locked\n");
2769 case ATA_HPA_ACTION_UNLOCK:
2770 error = atahpa_unlock(device, retry_count, timeout,
2771 ccb, is48bit, &pwd);
2773 printf("HPA has been unlocked\n");
2776 case ATA_HPA_ACTION_FREEZE_LOCK:
2777 error = atahpa_freeze_lock(device, retry_count, timeout,
2780 printf("HPA has been frozen\n");
2784 errx(1, "Option currently not supported");
2794 atasecurity(struct cam_device *device, int retry_count, int timeout,
2795 int argc, char **argv, char *combinedopt)
2798 struct ata_params *ident_buf;
2799 int error, confirm, quiet, c, action, actions, setpwd;
2800 int security_enabled, erase_timeout, pwdsize;
2801 struct ata_security_password pwd;
2809 memset(&pwd, 0, sizeof(pwd));
2811 /* default action is to print security information */
2812 action = ATA_SECURITY_ACTION_PRINT;
2814 /* user is master by default as its safer that way */
2815 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2816 pwdsize = sizeof(pwd.password);
2818 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2821 action = ATA_SECURITY_ACTION_FREEZE;
2826 if (strcasecmp(optarg, "user") == 0) {
2827 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2828 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2829 } else if (strcasecmp(optarg, "master") == 0) {
2830 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2831 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2833 warnx("-U argument '%s' is invalid (must be "
2834 "'user' or 'master')", optarg);
2840 if (strcasecmp(optarg, "high") == 0) {
2841 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2842 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2843 } else if (strcasecmp(optarg, "maximum") == 0) {
2844 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2845 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2847 warnx("-l argument '%s' is unknown (must be "
2848 "'high' or 'maximum')", optarg);
2854 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2856 action = ATA_SECURITY_ACTION_UNLOCK;
2861 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2863 action = ATA_SECURITY_ACTION_DISABLE;
2868 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2870 action = ATA_SECURITY_ACTION_ERASE;
2875 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2877 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2878 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2883 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2886 if (action == ATA_SECURITY_ACTION_PRINT)
2887 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2889 * Don't increment action as this can be combined
2890 * with other actions.
2903 erase_timeout = atoi(optarg) * 1000;
2909 warnx("too many security actions specified");
2913 if ((ccb = cam_getccb(device)) == NULL) {
2914 warnx("couldn't allocate CCB");
2918 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2925 printf("%s%d: ", device->device_name, device->dev_unit_num);
2926 ata_print_ident(ident_buf);
2927 camxferrate(device);
2930 if (action == ATA_SECURITY_ACTION_PRINT) {
2931 atasecurity_print(ident_buf);
2937 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2938 warnx("Security not supported");
2944 /* default timeout 15 seconds the same as linux hdparm */
2945 timeout = timeout ? timeout : 15 * 1000;
2947 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2949 /* first set the password if requested */
2951 /* confirm we can erase before setting the password if erasing */
2953 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2954 action == ATA_SECURITY_ACTION_ERASE) &&
2955 atasecurity_erase_confirm(device, ident_buf) == 0) {
2961 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2962 pwd.revision = ident_buf->master_passwd_revision;
2963 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2964 --pwd.revision == 0) {
2965 pwd.revision = 0xfffe;
2968 error = atasecurity_set_password(device, ccb, retry_count,
2969 timeout, &pwd, quiet);
2975 security_enabled = 1;
2979 case ATA_SECURITY_ACTION_FREEZE:
2980 error = atasecurity_freeze(device, ccb, retry_count,
2984 case ATA_SECURITY_ACTION_UNLOCK:
2985 if (security_enabled) {
2986 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2987 error = atasecurity_unlock(device, ccb,
2988 retry_count, timeout, &pwd, quiet);
2990 warnx("Can't unlock, drive is not locked");
2994 warnx("Can't unlock, security is disabled");
2999 case ATA_SECURITY_ACTION_DISABLE:
3000 if (security_enabled) {
3001 /* First unlock the drive if its locked */
3002 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3003 error = atasecurity_unlock(device, ccb,
3011 error = atasecurity_disable(device,
3019 warnx("Can't disable security (already disabled)");
3024 case ATA_SECURITY_ACTION_ERASE:
3025 if (security_enabled) {
3026 if (erase_timeout == 0) {
3027 erase_timeout = atasecurity_erase_timeout_msecs(
3028 ident_buf->erase_time);
3031 error = atasecurity_erase(device, ccb, retry_count,
3032 timeout, erase_timeout, &pwd,
3035 warnx("Can't secure erase (security is disabled)");
3040 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3041 if (security_enabled) {
3042 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3043 if (erase_timeout == 0) {
3045 atasecurity_erase_timeout_msecs(
3046 ident_buf->enhanced_erase_time);
3049 error = atasecurity_erase(device, ccb,
3050 retry_count, timeout,
3051 erase_timeout, &pwd,
3054 warnx("Enhanced erase is not supported");
3058 warnx("Can't secure erase (enhanced), "
3059 "(security is disabled)");
3070 #endif /* MINIMALISTIC */
3073 * Parse out a bus, or a bus, target and lun in the following
3079 * Returns the number of parsed components, or 0.
3082 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3083 cam_argmask *arglst)
3088 while (isspace(*tstr) && (*tstr != '\0'))
3091 tmpstr = (char *)strtok(tstr, ":");
3092 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3093 *bus = strtol(tmpstr, NULL, 0);
3094 *arglst |= CAM_ARG_BUS;
3096 tmpstr = (char *)strtok(NULL, ":");
3097 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3098 *target = strtol(tmpstr, NULL, 0);
3099 *arglst |= CAM_ARG_TARGET;
3101 tmpstr = (char *)strtok(NULL, ":");
3102 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3103 *lun = strtol(tmpstr, NULL, 0);
3104 *arglst |= CAM_ARG_LUN;
3114 dorescan_or_reset(int argc, char **argv, int rescan)
3116 static const char must[] =
3117 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3119 path_id_t bus = CAM_BUS_WILDCARD;
3120 target_id_t target = CAM_TARGET_WILDCARD;
3121 lun_id_t lun = CAM_LUN_WILDCARD;
3125 warnx(must, rescan? "rescan" : "reset");
3129 tstr = argv[optind];
3130 while (isspace(*tstr) && (*tstr != '\0'))
3132 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3133 arglist |= CAM_ARG_BUS;
3134 else if (isdigit(*tstr)) {
3135 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3136 if (rv != 1 && rv != 3) {
3137 warnx(must, rescan? "rescan" : "reset");
3147 * Note that resetting or rescanning a device used to
3148 * require a bus or bus:target:lun. This is because the
3149 * device in question may not exist and you're trying to
3150 * get the controller to rescan to find it. It may also be
3151 * because the device is hung / unresponsive, and opening
3152 * an unresponsive device is not desireable.
3154 * It can be more convenient to reference a device by
3155 * peripheral name and unit number, though, and it is
3156 * possible to get the bus:target:lun for devices that
3157 * currently exist in the EDT. So this can work for
3158 * devices that we want to reset, or devices that exist
3159 * that we want to rescan, but not devices that do not
3162 * So, we are careful here to look up the bus/target/lun
3163 * for the device the user wants to operate on, specified
3164 * by peripheral instance (e.g. da0, pass32) without
3165 * actually opening that device. The process is similar to
3166 * what cam_lookup_pass() does, except that we don't
3167 * actually open the passthrough driver instance in the end.
3170 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3171 warnx("%s", cam_errbuf);
3176 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3177 warn("Unable to open %s", XPT_DEVICE);
3182 bzero(&ccb, sizeof(ccb));
3185 * The function code isn't strictly necessary for the
3186 * GETPASSTHRU ioctl.
3188 ccb.ccb_h.func_code = XPT_GDEVLIST;
3191 * These two are necessary for the GETPASSTHRU ioctl to
3194 strlcpy(ccb.cgdl.periph_name, name,
3195 sizeof(ccb.cgdl.periph_name));
3196 ccb.cgdl.unit_number = unit;
3199 * Attempt to get the passthrough device. This ioctl will
3200 * fail if the device name is null, if the device doesn't
3201 * exist, or if the passthrough driver isn't in the kernel.
3203 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3204 warn("Unable to find bus:target:lun for device %s%d",
3210 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3211 const struct cam_status_entry *entry;
3213 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3214 warnx("Unable to find bus:target_lun for device %s%d, "
3215 "CAM status: %s (%#x)", name, unit,
3216 entry ? entry->status_text : "Unknown",
3224 * The kernel fills in the bus/target/lun. We don't
3225 * need the passthrough device name and unit number since
3226 * we aren't going to open it.
3228 bus = ccb.ccb_h.path_id;
3229 target = ccb.ccb_h.target_id;
3230 lun = ccb.ccb_h.target_lun;
3232 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3237 if ((arglist & CAM_ARG_BUS)
3238 && (arglist & CAM_ARG_TARGET)
3239 && (arglist & CAM_ARG_LUN))
3240 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3242 error = rescan_or_reset_bus(bus, rescan);
3250 rescan_or_reset_bus(path_id_t bus, int rescan)
3252 union ccb *ccb = NULL, *matchccb = NULL;
3253 int fd = -1, retval;
3258 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3259 warnx("error opening transport layer device %s", XPT_DEVICE);
3260 warn("%s", XPT_DEVICE);
3264 ccb = malloc(sizeof(*ccb));
3266 warn("failed to allocate CCB");
3270 bzero(ccb, sizeof(*ccb));
3272 if (bus != CAM_BUS_WILDCARD) {
3273 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3274 ccb->ccb_h.path_id = bus;
3275 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3276 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3277 ccb->crcn.flags = CAM_FLAG_NONE;
3279 /* run this at a low priority */
3280 ccb->ccb_h.pinfo.priority = 5;
3282 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3283 warn("CAMIOCOMMAND ioctl failed");
3288 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3289 fprintf(stdout, "%s of bus %d was successful\n",
3290 rescan ? "Re-scan" : "Reset", bus);
3292 fprintf(stdout, "%s of bus %d returned error %#x\n",
3293 rescan ? "Re-scan" : "Reset", bus,
3294 ccb->ccb_h.status & CAM_STATUS_MASK);
3303 * The right way to handle this is to modify the xpt so that it can
3304 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3305 * that isn't implemented, so instead we enumerate the buses and
3306 * send the rescan or reset to those buses in the case where the
3307 * given bus is -1 (wildcard). We don't send a rescan or reset
3308 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3309 * no-op, sending a rescan to the xpt bus would result in a status of
3312 matchccb = malloc(sizeof(*matchccb));
3313 if (matchccb == NULL) {
3314 warn("failed to allocate CCB");
3318 bzero(matchccb, sizeof(*matchccb));
3319 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3320 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3321 bufsize = sizeof(struct dev_match_result) * 20;
3322 matchccb->cdm.match_buf_len = bufsize;
3323 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3324 if (matchccb->cdm.matches == NULL) {
3325 warnx("can't malloc memory for matches");
3329 matchccb->cdm.num_matches = 0;
3331 matchccb->cdm.num_patterns = 1;
3332 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3334 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3335 matchccb->cdm.pattern_buf_len);
3336 if (matchccb->cdm.patterns == NULL) {
3337 warnx("can't malloc memory for patterns");
3341 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3342 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3347 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3348 warn("CAMIOCOMMAND ioctl failed");
3353 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3354 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3355 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3356 warnx("got CAM error %#x, CDM error %d\n",
3357 matchccb->ccb_h.status, matchccb->cdm.status);
3362 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3363 struct bus_match_result *bus_result;
3365 /* This shouldn't happen. */
3366 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3369 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3372 * We don't want to rescan or reset the xpt bus.
3375 if (bus_result->path_id == CAM_XPT_PATH_ID)
3378 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3380 ccb->ccb_h.path_id = bus_result->path_id;
3381 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3382 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3383 ccb->crcn.flags = CAM_FLAG_NONE;
3385 /* run this at a low priority */
3386 ccb->ccb_h.pinfo.priority = 5;
3388 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3389 warn("CAMIOCOMMAND ioctl failed");
3394 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3395 fprintf(stdout, "%s of bus %d was successful\n",
3396 rescan? "Re-scan" : "Reset",
3397 bus_result->path_id);
3400 * Don't bail out just yet, maybe the other
3401 * rescan or reset commands will complete
3404 fprintf(stderr, "%s of bus %d returned error "
3405 "%#x\n", rescan? "Re-scan" : "Reset",
3406 bus_result->path_id,
3407 ccb->ccb_h.status & CAM_STATUS_MASK);
3411 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3412 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3419 if (matchccb != NULL) {
3420 free(matchccb->cdm.patterns);
3421 free(matchccb->cdm.matches);
3430 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3433 struct cam_device *device;
3438 if (bus == CAM_BUS_WILDCARD) {
3439 warnx("invalid bus number %d", bus);
3443 if (target == CAM_TARGET_WILDCARD) {
3444 warnx("invalid target number %d", target);
3448 if (lun == CAM_LUN_WILDCARD) {
3449 warnx("invalid lun number %jx", (uintmax_t)lun);
3455 bzero(&ccb, sizeof(union ccb));
3458 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3459 warnx("error opening transport layer device %s\n",
3461 warn("%s", XPT_DEVICE);
3465 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3466 if (device == NULL) {
3467 warnx("%s", cam_errbuf);
3472 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3473 ccb.ccb_h.path_id = bus;
3474 ccb.ccb_h.target_id = target;
3475 ccb.ccb_h.target_lun = lun;
3476 ccb.ccb_h.timeout = 5000;
3477 ccb.crcn.flags = CAM_FLAG_NONE;
3479 /* run this at a low priority */
3480 ccb.ccb_h.pinfo.priority = 5;
3483 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3484 warn("CAMIOCOMMAND ioctl failed");
3489 if (cam_send_ccb(device, &ccb) < 0) {
3490 warn("error sending XPT_RESET_DEV CCB");
3491 cam_close_device(device);
3499 cam_close_device(device);
3502 * An error code of CAM_BDR_SENT is normal for a BDR request.
3504 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3506 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3507 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3508 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3511 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3512 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3513 ccb.ccb_h.status & CAM_STATUS_MASK);
3518 #ifndef MINIMALISTIC
3520 static struct scsi_nv defect_list_type_map[] = {
3521 { "block", SRDD10_BLOCK_FORMAT },
3522 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3523 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3524 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3525 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3526 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3530 readdefects(struct cam_device *device, int argc, char **argv,
3531 char *combinedopt, int task_attr, int retry_count, int timeout)
3533 union ccb *ccb = NULL;
3534 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3535 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3536 size_t hdr_size = 0, entry_size = 0;
3539 u_int8_t *defect_list = NULL;
3540 u_int8_t list_format = 0;
3541 int list_type_set = 0;
3542 u_int32_t dlist_length = 0;
3543 u_int32_t returned_length = 0, valid_len = 0;
3544 u_int32_t num_returned = 0, num_valid = 0;
3545 u_int32_t max_possible_size = 0, hdr_max = 0;
3546 u_int32_t starting_offset = 0;
3547 u_int8_t returned_format, returned_type;
3549 int summary = 0, quiet = 0;
3551 int lists_specified = 0;
3552 int get_length = 1, first_pass = 1;
3555 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3559 scsi_nv_status status;
3562 status = scsi_get_nv(defect_list_type_map,
3563 sizeof(defect_list_type_map) /
3564 sizeof(defect_list_type_map[0]), optarg,
3565 &entry_num, SCSI_NV_FLAG_IG_CASE);
3567 if (status == SCSI_NV_FOUND) {
3568 list_format = defect_list_type_map[
3572 warnx("%s: %s %s option %s", __func__,
3573 (status == SCSI_NV_AMBIGUOUS) ?
3574 "ambiguous" : "invalid", "defect list type",
3577 goto defect_bailout;
3582 arglist |= CAM_ARG_GLIST;
3585 arglist |= CAM_ARG_PLIST;
3596 starting_offset = strtoul(optarg, &endptr, 0);
3597 if (*endptr != '\0') {
3599 warnx("invalid starting offset %s", optarg);
3600 goto defect_bailout;
3612 if (list_type_set == 0) {
3614 warnx("no defect list format specified");
3615 goto defect_bailout;
3618 if (arglist & CAM_ARG_PLIST) {
3619 list_format |= SRDD10_PLIST;
3623 if (arglist & CAM_ARG_GLIST) {
3624 list_format |= SRDD10_GLIST;
3629 * This implies a summary, and was the previous behavior.
3631 if (lists_specified == 0)
3634 ccb = cam_getccb(device);
3639 * We start off asking for just the header to determine how much
3640 * defect data is available. Some Hitachi drives return an error
3641 * if you ask for more data than the drive has. Once we know the
3642 * length, we retry the command with the returned length.
3644 if (use_12byte == 0)
3645 dlist_length = sizeof(*hdr10);
3647 dlist_length = sizeof(*hdr12);
3650 if (defect_list != NULL) {
3654 defect_list = malloc(dlist_length);
3655 if (defect_list == NULL) {
3656 warnx("can't malloc memory for defect list");
3658 goto defect_bailout;
3662 bzero(defect_list, dlist_length);
3665 * cam_getccb() zeros the CCB header only. So we need to zero the
3666 * payload portion of the ccb.
3668 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3670 scsi_read_defects(&ccb->csio,
3671 /*retries*/ retry_count,
3673 /*tag_action*/ task_attr,
3674 /*list_format*/ list_format,
3675 /*addr_desc_index*/ starting_offset,
3676 /*data_ptr*/ defect_list,
3677 /*dxfer_len*/ dlist_length,
3678 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3679 /*sense_len*/ SSD_FULL_SIZE,
3680 /*timeout*/ timeout ? timeout : 5000);
3682 /* Disable freezing the device queue */
3683 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3685 if (cam_send_ccb(device, ccb) < 0) {
3686 perror("error reading defect list");
3688 if (arglist & CAM_ARG_VERBOSE) {
3689 cam_error_print(device, ccb, CAM_ESF_ALL,
3690 CAM_EPF_ALL, stderr);
3694 goto defect_bailout;
3697 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3699 if (use_12byte == 0) {
3700 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3701 hdr_size = sizeof(*hdr10);
3702 hdr_max = SRDDH10_MAX_LENGTH;
3704 if (valid_len >= hdr_size) {
3705 returned_length = scsi_2btoul(hdr10->length);
3706 returned_format = hdr10->format;
3708 returned_length = 0;
3709 returned_format = 0;
3712 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3713 hdr_size = sizeof(*hdr12);
3714 hdr_max = SRDDH12_MAX_LENGTH;
3716 if (valid_len >= hdr_size) {
3717 returned_length = scsi_4btoul(hdr12->length);
3718 returned_format = hdr12->format;
3720 returned_length = 0;
3721 returned_format = 0;
3725 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3726 switch (returned_type) {
3727 case SRDD10_BLOCK_FORMAT:
3728 entry_size = sizeof(struct scsi_defect_desc_block);
3730 case SRDD10_LONG_BLOCK_FORMAT:
3731 entry_size = sizeof(struct scsi_defect_desc_long_block);
3733 case SRDD10_EXT_PHYS_FORMAT:
3734 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3735 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3737 case SRDD10_EXT_BFI_FORMAT:
3738 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3739 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3742 warnx("Unknown defect format 0x%x\n", returned_type);
3744 goto defect_bailout;
3748 max_possible_size = (hdr_max / entry_size) * entry_size;
3749 num_returned = returned_length / entry_size;
3750 num_valid = min(returned_length, valid_len - hdr_size);
3751 num_valid /= entry_size;
3753 if (get_length != 0) {
3756 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3757 CAM_SCSI_STATUS_ERROR) {
3758 struct scsi_sense_data *sense;
3759 int error_code, sense_key, asc, ascq;
3761 sense = &ccb->csio.sense_data;
3762 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3763 ccb->csio.sense_resid, &error_code, &sense_key,
3764 &asc, &ascq, /*show_errors*/ 1);
3767 * If the drive is reporting that it just doesn't
3768 * support the defect list format, go ahead and use
3769 * the length it reported. Otherwise, the length
3770 * may not be valid, so use the maximum.
3772 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3773 && (asc == 0x1c) && (ascq == 0x00)
3774 && (returned_length > 0)) {
3775 if ((use_12byte == 0)
3776 && (returned_length >= max_possible_size)) {
3781 dlist_length = returned_length + hdr_size;
3782 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3783 && (asc == 0x1f) && (ascq == 0x00)
3784 && (returned_length > 0)) {
3785 /* Partial defect list transfer */
3787 * Hitachi drives return this error
3788 * along with a partial defect list if they
3789 * have more defects than the 10 byte
3790 * command can support. Retry with the 12
3793 if (use_12byte == 0) {
3798 dlist_length = returned_length + hdr_size;
3799 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3800 && (asc == 0x24) && (ascq == 0x00)) {
3801 /* Invalid field in CDB */
3803 * SBC-3 says that if the drive has more
3804 * defects than can be reported with the
3805 * 10 byte command, it should return this
3806 * error and no data. Retry with the 12
3809 if (use_12byte == 0) {
3814 dlist_length = returned_length + hdr_size;
3817 * If we got a SCSI error and no valid length,
3818 * just use the 10 byte maximum. The 12
3819 * byte maximum is too large.
3821 if (returned_length == 0)
3822 dlist_length = SRDD10_MAX_LENGTH;
3824 if ((use_12byte == 0)
3825 && (returned_length >=
3826 max_possible_size)) {
3831 dlist_length = returned_length +
3835 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3838 warnx("Error reading defect header");
3839 if (arglist & CAM_ARG_VERBOSE)
3840 cam_error_print(device, ccb, CAM_ESF_ALL,
3841 CAM_EPF_ALL, stderr);
3842 goto defect_bailout;
3844 if ((use_12byte == 0)
3845 && (returned_length >= max_possible_size)) {
3850 dlist_length = returned_length + hdr_size;
3853 fprintf(stdout, "%u", num_returned);
3855 fprintf(stdout, " defect%s",
3856 (num_returned != 1) ? "s" : "");
3858 fprintf(stdout, "\n");
3860 goto defect_bailout;
3864 * We always limit the list length to the 10-byte maximum
3865 * length (0xffff). The reason is that some controllers
3866 * can't handle larger I/Os, and we can transfer the entire
3867 * 10 byte list in one shot. For drives that support the 12
3868 * byte read defects command, we'll step through the list
3869 * by specifying a starting offset. For drives that don't
3870 * support the 12 byte command's starting offset, we'll
3871 * just display the first 64K.
3873 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3879 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3880 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3881 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3882 struct scsi_sense_data *sense;
3883 int error_code, sense_key, asc, ascq;
3885 sense = &ccb->csio.sense_data;
3886 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3887 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3888 &ascq, /*show_errors*/ 1);
3891 * According to the SCSI spec, if the disk doesn't support
3892 * the requested format, it will generally return a sense
3893 * key of RECOVERED ERROR, and an additional sense code
3894 * of "DEFECT LIST NOT FOUND". HGST drives also return
3895 * Primary/Grown defect list not found errors. So just
3896 * check for an ASC of 0x1c.
3898 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3900 const char *format_str;
3902 format_str = scsi_nv_to_str(defect_list_type_map,
3903 sizeof(defect_list_type_map) /
3904 sizeof(defect_list_type_map[0]),
3905 list_format & SRDD10_DLIST_FORMAT_MASK);
3906 warnx("requested defect format %s not available",
3907 format_str ? format_str : "unknown");
3909 format_str = scsi_nv_to_str(defect_list_type_map,
3910 sizeof(defect_list_type_map) /
3911 sizeof(defect_list_type_map[0]), returned_type);
3912 if (format_str != NULL) {
3913 warnx("Device returned %s format",
3917 warnx("Device returned unknown defect"
3918 " data format %#x", returned_type);
3919 goto defect_bailout;
3923 warnx("Error returned from read defect data command");
3924 if (arglist & CAM_ARG_VERBOSE)
3925 cam_error_print(device, ccb, CAM_ESF_ALL,
3926 CAM_EPF_ALL, stderr);
3927 goto defect_bailout;
3929 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3931 warnx("Error returned from read defect data command");
3932 if (arglist & CAM_ARG_VERBOSE)
3933 cam_error_print(device, ccb, CAM_ESF_ALL,
3934 CAM_EPF_ALL, stderr);
3935 goto defect_bailout;
3938 if (first_pass != 0) {
3939 fprintf(stderr, "Got %d defect", num_returned);
3941 if ((lists_specified == 0) || (num_returned == 0)) {
3942 fprintf(stderr, "s.\n");
3943 goto defect_bailout;
3944 } else if (num_returned == 1)
3945 fprintf(stderr, ":\n");
3947 fprintf(stderr, "s:\n");
3953 * XXX KDM I should probably clean up the printout format for the
3956 switch (returned_type) {
3957 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3958 case SRDD10_EXT_PHYS_FORMAT:
3960 struct scsi_defect_desc_phys_sector *dlist;
3962 dlist = (struct scsi_defect_desc_phys_sector *)
3963 (defect_list + hdr_size);
3965 for (i = 0; i < num_valid; i++) {
3968 sector = scsi_4btoul(dlist[i].sector);
3969 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3970 mads = (sector & SDD_EXT_PHYS_MADS) ?
3972 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3974 if (hex_format == 0)
3975 fprintf(stdout, "%d:%d:%d%s",
3976 scsi_3btoul(dlist[i].cylinder),
3978 scsi_4btoul(dlist[i].sector),
3979 mads ? " - " : "\n");
3981 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3982 scsi_3btoul(dlist[i].cylinder),
3984 scsi_4btoul(dlist[i].sector),
3985 mads ? " - " : "\n");
3988 if (num_valid < num_returned) {
3989 starting_offset += num_valid;
3994 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3995 case SRDD10_EXT_BFI_FORMAT:
3997 struct scsi_defect_desc_bytes_from_index *dlist;
3999 dlist = (struct scsi_defect_desc_bytes_from_index *)
4000 (defect_list + hdr_size);
4002 for (i = 0; i < num_valid; i++) {
4005 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4006 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4007 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4008 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4010 if (hex_format == 0)
4011 fprintf(stdout, "%d:%d:%d%s",
4012 scsi_3btoul(dlist[i].cylinder),
4014 scsi_4btoul(dlist[i].bytes_from_index),
4015 mads ? " - " : "\n");
4017 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4018 scsi_3btoul(dlist[i].cylinder),
4020 scsi_4btoul(dlist[i].bytes_from_index),
4021 mads ? " - " : "\n");
4025 if (num_valid < num_returned) {
4026 starting_offset += num_valid;
4031 case SRDDH10_BLOCK_FORMAT:
4033 struct scsi_defect_desc_block *dlist;
4035 dlist = (struct scsi_defect_desc_block *)
4036 (defect_list + hdr_size);
4038 for (i = 0; i < num_valid; i++) {
4039 if (hex_format == 0)
4040 fprintf(stdout, "%u\n",
4041 scsi_4btoul(dlist[i].address));
4043 fprintf(stdout, "0x%x\n",
4044 scsi_4btoul(dlist[i].address));
4047 if (num_valid < num_returned) {
4048 starting_offset += num_valid;
4054 case SRDD10_LONG_BLOCK_FORMAT:
4056 struct scsi_defect_desc_long_block *dlist;
4058 dlist = (struct scsi_defect_desc_long_block *)
4059 (defect_list + hdr_size);
4061 for (i = 0; i < num_valid; i++) {
4062 if (hex_format == 0)
4063 fprintf(stdout, "%ju\n",
4064 (uintmax_t)scsi_8btou64(
4067 fprintf(stdout, "0x%jx\n",
4068 (uintmax_t)scsi_8btou64(
4072 if (num_valid < num_returned) {
4073 starting_offset += num_valid;
4079 fprintf(stderr, "Unknown defect format 0x%x\n",
4086 if (defect_list != NULL)
4094 #endif /* MINIMALISTIC */
4098 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4102 ccb = cam_getccb(device);
4108 #ifndef MINIMALISTIC
4110 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4111 int task_attr, int retry_count, int timeout, u_int8_t *data,
4117 ccb = cam_getccb(device);
4120 errx(1, "mode_sense: couldn't allocate CCB");
4122 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4124 scsi_mode_sense_subpage(&ccb->csio,
4125 /* retries */ retry_count,
4127 /* tag_action */ task_attr,
4131 /* subpage */ subpage,
4132 /* param_buf */ data,
4133 /* param_len */ datalen,
4134 /* minimum_cmd_size */ 0,
4135 /* sense_len */ SSD_FULL_SIZE,
4136 /* timeout */ timeout ? timeout : 5000);
4138 if (arglist & CAM_ARG_ERR_RECOVER)
4139 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4141 /* Disable freezing the device queue */
4142 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4144 if (((retval = cam_send_ccb(device, ccb)) < 0)
4145 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4146 if (arglist & CAM_ARG_VERBOSE) {
4147 cam_error_print(device, ccb, CAM_ESF_ALL,
4148 CAM_EPF_ALL, stderr);
4151 cam_close_device(device);
4153 err(1, "error sending mode sense command");
4155 errx(1, "error sending mode sense command");
4162 mode_select(struct cam_device *device, int save_pages, int task_attr,
4163 int retry_count, int timeout, u_int8_t *data, int datalen)
4168 ccb = cam_getccb(device);
4171 errx(1, "mode_select: couldn't allocate CCB");
4173 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4175 scsi_mode_select(&ccb->csio,
4176 /* retries */ retry_count,
4178 /* tag_action */ task_attr,
4179 /* scsi_page_fmt */ 1,
4180 /* save_pages */ save_pages,
4181 /* param_buf */ data,
4182 /* param_len */ datalen,
4183 /* sense_len */ SSD_FULL_SIZE,
4184 /* timeout */ timeout ? timeout : 5000);
4186 if (arglist & CAM_ARG_ERR_RECOVER)
4187 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4189 /* Disable freezing the device queue */
4190 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4192 if (((retval = cam_send_ccb(device, ccb)) < 0)
4193 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4194 if (arglist & CAM_ARG_VERBOSE) {
4195 cam_error_print(device, ccb, CAM_ESF_ALL,
4196 CAM_EPF_ALL, stderr);
4199 cam_close_device(device);
4202 err(1, "error sending mode select command");
4204 errx(1, "error sending mode select command");
4212 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4213 int task_attr, int retry_count, int timeout)
4216 int c, page = -1, subpage = -1, pc = 0;
4217 int binary = 0, dbd = 0, edit = 0, list = 0;
4219 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4234 str_subpage = optarg;
4235 strsep(&str_subpage, ",");
4236 page = strtol(optarg, NULL, 0);
4238 subpage = strtol(str_subpage, NULL, 0);
4242 errx(1, "invalid mode page %d", page);
4244 errx(1, "invalid mode subpage %d", subpage);
4247 pc = strtol(optarg, NULL, 0);
4248 if ((pc < 0) || (pc > 3))
4249 errx(1, "invalid page control field %d", pc);
4256 if (page == -1 && list == 0)
4257 errx(1, "you must specify a mode page!");
4260 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4263 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4264 task_attr, retry_count, timeout);
4269 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4270 int task_attr, int retry_count, int timeout)
4273 u_int32_t flags = CAM_DIR_NONE;
4274 u_int8_t *data_ptr = NULL;
4276 u_int8_t atacmd[12];
4277 struct get_hook hook;
4278 int c, data_bytes = 0, valid_bytes;
4284 char *datastr = NULL, *tstr, *resstr = NULL;
4286 int fd_data = 0, fd_res = 0;
4289 ccb = cam_getccb(device);
4292 warnx("scsicmd: error allocating ccb");
4296 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4298 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4302 while (isspace(*tstr) && (*tstr != '\0'))
4304 hook.argc = argc - optind;
4305 hook.argv = argv + optind;
4307 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4310 * Increment optind by the number of arguments the
4311 * encoding routine processed. After each call to
4312 * getopt(3), optind points to the argument that
4313 * getopt should process _next_. In this case,
4314 * that means it points to the first command string
4315 * argument, if there is one. Once we increment
4316 * this, it should point to either the next command
4317 * line argument, or it should be past the end of
4324 while (isspace(*tstr) && (*tstr != '\0'))
4326 hook.argc = argc - optind;
4327 hook.argv = argv + optind;
4329 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4332 * Increment optind by the number of arguments the
4333 * encoding routine processed. After each call to
4334 * getopt(3), optind points to the argument that
4335 * getopt should process _next_. In this case,
4336 * that means it points to the first command string
4337 * argument, if there is one. Once we increment
4338 * this, it should point to either the next command
4339 * line argument, or it should be past the end of
4351 if (arglist & CAM_ARG_CMD_OUT) {
4352 warnx("command must either be "
4353 "read or write, not both");
4355 goto scsicmd_bailout;
4357 arglist |= CAM_ARG_CMD_IN;
4359 data_bytes = strtol(optarg, NULL, 0);
4360 if (data_bytes <= 0) {
4361 warnx("invalid number of input bytes %d",
4364 goto scsicmd_bailout;
4366 hook.argc = argc - optind;
4367 hook.argv = argv + optind;
4370 datastr = cget(&hook, NULL);
4372 * If the user supplied "-" instead of a format, he
4373 * wants the data to be written to stdout.
4375 if ((datastr != NULL)
4376 && (datastr[0] == '-'))
4379 data_ptr = (u_int8_t *)malloc(data_bytes);
4380 if (data_ptr == NULL) {
4381 warnx("can't malloc memory for data_ptr");
4383 goto scsicmd_bailout;
4387 if (arglist & CAM_ARG_CMD_IN) {
4388 warnx("command must either be "
4389 "read or write, not both");
4391 goto scsicmd_bailout;
4393 arglist |= CAM_ARG_CMD_OUT;
4394 flags = CAM_DIR_OUT;
4395 data_bytes = strtol(optarg, NULL, 0);
4396 if (data_bytes <= 0) {
4397 warnx("invalid number of output bytes %d",
4400 goto scsicmd_bailout;
4402 hook.argc = argc - optind;
4403 hook.argv = argv + optind;
4405 datastr = cget(&hook, NULL);
4406 data_ptr = (u_int8_t *)malloc(data_bytes);
4407 if (data_ptr == NULL) {
4408 warnx("can't malloc memory for data_ptr");
4410 goto scsicmd_bailout;
4412 bzero(data_ptr, data_bytes);
4414 * If the user supplied "-" instead of a format, he
4415 * wants the data to be read from stdin.
4417 if ((datastr != NULL)
4418 && (datastr[0] == '-'))
4421 buff_encode_visit(data_ptr, data_bytes, datastr,
4427 hook.argc = argc - optind;
4428 hook.argv = argv + optind;
4430 resstr = cget(&hook, NULL);
4431 if ((resstr != NULL) && (resstr[0] == '-'))
4441 * If fd_data is set, and we're writing to the device, we need to
4442 * read the data the user wants written from stdin.
4444 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4446 int amt_to_read = data_bytes;
4447 u_int8_t *buf_ptr = data_ptr;
4449 for (amt_read = 0; amt_to_read > 0;
4450 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4451 if (amt_read == -1) {
4452 warn("error reading data from stdin");
4454 goto scsicmd_bailout;
4456 amt_to_read -= amt_read;
4457 buf_ptr += amt_read;
4461 if (arglist & CAM_ARG_ERR_RECOVER)
4462 flags |= CAM_PASS_ERR_RECOVER;
4464 /* Disable freezing the device queue */
4465 flags |= CAM_DEV_QFRZDIS;
4469 * This is taken from the SCSI-3 draft spec.
4470 * (T10/1157D revision 0.3)
4471 * The top 3 bits of an opcode are the group code.
4472 * The next 5 bits are the command code.
4473 * Group 0: six byte commands
4474 * Group 1: ten byte commands
4475 * Group 2: ten byte commands
4477 * Group 4: sixteen byte commands
4478 * Group 5: twelve byte commands
4479 * Group 6: vendor specific
4480 * Group 7: vendor specific
4482 switch((cdb[0] >> 5) & 0x7) {
4493 /* computed by buff_encode_visit */
4504 * We should probably use csio_build_visit or something like that
4505 * here, but it's easier to encode arguments as you go. The
4506 * alternative would be skipping the CDB argument and then encoding
4507 * it here, since we've got the data buffer argument by now.
4509 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4511 cam_fill_csio(&ccb->csio,
4512 /*retries*/ retry_count,
4515 /*tag_action*/ task_attr,
4516 /*data_ptr*/ data_ptr,
4517 /*dxfer_len*/ data_bytes,
4518 /*sense_len*/ SSD_FULL_SIZE,
4519 /*cdb_len*/ cdb_len,
4520 /*timeout*/ timeout ? timeout : 5000);
4523 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4525 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4527 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4529 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4531 cam_fill_ataio(&ccb->ataio,
4532 /*retries*/ retry_count,
4536 /*data_ptr*/ data_ptr,
4537 /*dxfer_len*/ data_bytes,
4538 /*timeout*/ timeout ? timeout : 5000);
4541 if (((retval = cam_send_ccb(device, ccb)) < 0)
4542 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4543 const char warnstr[] = "error sending command";
4550 if (arglist & CAM_ARG_VERBOSE) {
4551 cam_error_print(device, ccb, CAM_ESF_ALL,
4552 CAM_EPF_ALL, stderr);
4556 goto scsicmd_bailout;
4559 if (atacmd_len && need_res) {
4561 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4563 fprintf(stdout, "\n");
4566 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4567 ccb->ataio.res.status,
4568 ccb->ataio.res.error,
4569 ccb->ataio.res.lba_low,
4570 ccb->ataio.res.lba_mid,
4571 ccb->ataio.res.lba_high,
4572 ccb->ataio.res.device,
4573 ccb->ataio.res.lba_low_exp,
4574 ccb->ataio.res.lba_mid_exp,
4575 ccb->ataio.res.lba_high_exp,
4576 ccb->ataio.res.sector_count,
4577 ccb->ataio.res.sector_count_exp);
4583 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4585 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4586 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4587 && (arglist & CAM_ARG_CMD_IN)
4588 && (valid_bytes > 0)) {
4590 buff_decode_visit(data_ptr, valid_bytes, datastr,
4592 fprintf(stdout, "\n");
4594 ssize_t amt_written;
4595 int amt_to_write = valid_bytes;
4596 u_int8_t *buf_ptr = data_ptr;
4598 for (amt_written = 0; (amt_to_write > 0) &&
4599 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4600 amt_to_write -= amt_written;
4601 buf_ptr += amt_written;
4603 if (amt_written == -1) {
4604 warn("error writing data to stdout");
4606 goto scsicmd_bailout;
4607 } else if ((amt_written == 0)
4608 && (amt_to_write > 0)) {
4609 warnx("only wrote %u bytes out of %u",
4610 valid_bytes - amt_to_write, valid_bytes);
4617 if ((data_bytes > 0) && (data_ptr != NULL))
4626 camdebug(int argc, char **argv, char *combinedopt)
4629 path_id_t bus = CAM_BUS_WILDCARD;
4630 target_id_t target = CAM_TARGET_WILDCARD;
4631 lun_id_t lun = CAM_LUN_WILDCARD;
4632 char *tstr, *tmpstr = NULL;
4636 bzero(&ccb, sizeof(union ccb));
4638 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4641 arglist |= CAM_ARG_DEBUG_INFO;
4642 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4645 arglist |= CAM_ARG_DEBUG_PERIPH;
4646 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4649 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4650 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4653 arglist |= CAM_ARG_DEBUG_TRACE;
4654 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4657 arglist |= CAM_ARG_DEBUG_XPT;
4658 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4661 arglist |= CAM_ARG_DEBUG_CDB;
4662 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4665 arglist |= CAM_ARG_DEBUG_PROBE;
4666 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4673 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4674 warnx("error opening transport layer device %s", XPT_DEVICE);
4675 warn("%s", XPT_DEVICE);
4682 warnx("you must specify \"off\", \"all\" or a bus,");
4683 warnx("bus:target, or bus:target:lun");
4690 while (isspace(*tstr) && (*tstr != '\0'))
4693 if (strncmp(tstr, "off", 3) == 0) {
4694 ccb.cdbg.flags = CAM_DEBUG_NONE;
4695 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4696 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4697 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4698 } else if (strncmp(tstr, "all", 3) != 0) {
4699 tmpstr = (char *)strtok(tstr, ":");
4700 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4701 bus = strtol(tmpstr, NULL, 0);
4702 arglist |= CAM_ARG_BUS;
4703 tmpstr = (char *)strtok(NULL, ":");
4704 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4705 target = strtol(tmpstr, NULL, 0);
4706 arglist |= CAM_ARG_TARGET;
4707 tmpstr = (char *)strtok(NULL, ":");
4708 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4709 lun = strtol(tmpstr, NULL, 0);
4710 arglist |= CAM_ARG_LUN;
4715 warnx("you must specify \"all\", \"off\", or a bus,");
4716 warnx("bus:target, or bus:target:lun to debug");
4722 ccb.ccb_h.func_code = XPT_DEBUG;
4723 ccb.ccb_h.path_id = bus;
4724 ccb.ccb_h.target_id = target;
4725 ccb.ccb_h.target_lun = lun;
4727 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4728 warn("CAMIOCOMMAND ioctl failed");
4733 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4734 CAM_FUNC_NOTAVAIL) {
4735 warnx("CAM debugging not available");
4736 warnx("you need to put options CAMDEBUG in"
4737 " your kernel config file!");
4739 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4741 warnx("XPT_DEBUG CCB failed with status %#x",
4745 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4747 "Debugging turned off\n");
4750 "Debugging enabled for "
4752 bus, target, (uintmax_t)lun);
4763 tagcontrol(struct cam_device *device, int argc, char **argv,
4773 ccb = cam_getccb(device);
4776 warnx("tagcontrol: error allocating ccb");
4780 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4783 numtags = strtol(optarg, NULL, 0);
4785 warnx("tag count %d is < 0", numtags);
4787 goto tagcontrol_bailout;
4798 cam_path_string(device, pathstr, sizeof(pathstr));
4801 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4802 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4803 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4804 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4805 ccb->crs.openings = numtags;
4808 if (cam_send_ccb(device, ccb) < 0) {
4809 perror("error sending XPT_REL_SIMQ CCB");
4811 goto tagcontrol_bailout;
4814 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4815 warnx("XPT_REL_SIMQ CCB failed");
4816 cam_error_print(device, ccb, CAM_ESF_ALL,
4817 CAM_EPF_ALL, stderr);
4819 goto tagcontrol_bailout;
4824 fprintf(stdout, "%stagged openings now %d\n",
4825 pathstr, ccb->crs.openings);
4828 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4830 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4832 if (cam_send_ccb(device, ccb) < 0) {
4833 perror("error sending XPT_GDEV_STATS CCB");
4835 goto tagcontrol_bailout;
4838 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4839 warnx("XPT_GDEV_STATS CCB failed");
4840 cam_error_print(device, ccb, CAM_ESF_ALL,
4841 CAM_EPF_ALL, stderr);
4843 goto tagcontrol_bailout;
4846 if (arglist & CAM_ARG_VERBOSE) {
4847 fprintf(stdout, "%s", pathstr);
4848 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4849 fprintf(stdout, "%s", pathstr);
4850 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4851 fprintf(stdout, "%s", pathstr);
4852 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4853 fprintf(stdout, "%s", pathstr);
4854 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4855 fprintf(stdout, "%s", pathstr);
4856 fprintf(stdout, "held %d\n", ccb->cgds.held);
4857 fprintf(stdout, "%s", pathstr);
4858 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4859 fprintf(stdout, "%s", pathstr);
4860 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4863 fprintf(stdout, "%s", pathstr);
4864 fprintf(stdout, "device openings: ");
4866 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4867 ccb->cgds.dev_active);
4877 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4881 cam_path_string(device, pathstr, sizeof(pathstr));
4883 if (cts->transport == XPORT_SPI) {
4884 struct ccb_trans_settings_spi *spi =
4885 &cts->xport_specific.spi;
4887 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4889 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4892 if (spi->sync_offset != 0) {
4895 freq = scsi_calc_syncsrate(spi->sync_period);
4896 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4897 pathstr, freq / 1000, freq % 1000);
4901 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4902 fprintf(stdout, "%soffset: %d\n", pathstr,
4906 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4907 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4908 (0x01 << spi->bus_width) * 8);
4911 if (spi->valid & CTS_SPI_VALID_DISC) {
4912 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4913 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4914 "enabled" : "disabled");
4917 if (cts->transport == XPORT_FC) {
4918 struct ccb_trans_settings_fc *fc =
4919 &cts->xport_specific.fc;
4921 if (fc->valid & CTS_FC_VALID_WWNN)
4922 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4923 (long long) fc->wwnn);
4924 if (fc->valid & CTS_FC_VALID_WWPN)
4925 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4926 (long long) fc->wwpn);
4927 if (fc->valid & CTS_FC_VALID_PORT)
4928 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4929 if (fc->valid & CTS_FC_VALID_SPEED)
4930 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4931 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4933 if (cts->transport == XPORT_SAS) {
4934 struct ccb_trans_settings_sas *sas =
4935 &cts->xport_specific.sas;
4937 if (sas->valid & CTS_SAS_VALID_SPEED)
4938 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4939 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4941 if (cts->transport == XPORT_ATA) {
4942 struct ccb_trans_settings_pata *pata =
4943 &cts->xport_specific.ata;
4945 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4946 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4947 ata_mode2string(pata->mode));
4949 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4950 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4953 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4954 fprintf(stdout, "%sPIO transaction length: %d\n",
4955 pathstr, pata->bytecount);
4958 if (cts->transport == XPORT_SATA) {
4959 struct ccb_trans_settings_sata *sata =
4960 &cts->xport_specific.sata;
4962 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4963 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4966 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4967 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4968 ata_mode2string(sata->mode));
4970 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4971 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4974 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4975 fprintf(stdout, "%sPIO transaction length: %d\n",
4976 pathstr, sata->bytecount);
4978 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4979 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4982 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4983 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4986 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4987 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4991 if (cts->protocol == PROTO_ATA) {
4992 struct ccb_trans_settings_ata *ata=
4993 &cts->proto_specific.ata;
4995 if (ata->valid & CTS_ATA_VALID_TQ) {
4996 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4997 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4998 "enabled" : "disabled");
5001 if (cts->protocol == PROTO_SCSI) {
5002 struct ccb_trans_settings_scsi *scsi=
5003 &cts->proto_specific.scsi;
5005 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5006 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5007 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5008 "enabled" : "disabled");
5015 * Get a path inquiry CCB for the specified device.
5018 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5023 ccb = cam_getccb(device);
5025 warnx("get_cpi: couldn't allocate CCB");
5028 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5029 ccb->ccb_h.func_code = XPT_PATH_INQ;
5030 if (cam_send_ccb(device, ccb) < 0) {
5031 warn("get_cpi: error sending Path Inquiry CCB");
5032 if (arglist & CAM_ARG_VERBOSE)
5033 cam_error_print(device, ccb, CAM_ESF_ALL,
5034 CAM_EPF_ALL, stderr);
5036 goto get_cpi_bailout;
5038 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5039 if (arglist & CAM_ARG_VERBOSE)
5040 cam_error_print(device, ccb, CAM_ESF_ALL,
5041 CAM_EPF_ALL, stderr);
5043 goto get_cpi_bailout;
5045 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5053 * Get a get device CCB for the specified device.
5056 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5061 ccb = cam_getccb(device);
5063 warnx("get_cgd: couldn't allocate CCB");
5066 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5067 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5068 if (cam_send_ccb(device, ccb) < 0) {
5069 warn("get_cgd: error sending Path Inquiry CCB");
5070 if (arglist & CAM_ARG_VERBOSE)
5071 cam_error_print(device, ccb, CAM_ESF_ALL,
5072 CAM_EPF_ALL, stderr);
5074 goto get_cgd_bailout;
5076 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5077 if (arglist & CAM_ARG_VERBOSE)
5078 cam_error_print(device, ccb, CAM_ESF_ALL,
5079 CAM_EPF_ALL, stderr);
5081 goto get_cgd_bailout;
5083 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5091 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5095 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5096 int timeout, int verbosemode)
5098 union ccb *ccb = NULL;
5099 struct scsi_vpd_supported_page_list sup_pages;
5103 ccb = cam_getccb(dev);
5105 warn("Unable to allocate CCB");
5110 /* cam_getccb cleans up the header, caller has to zero the payload */
5111 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5113 bzero(&sup_pages, sizeof(sup_pages));
5115 scsi_inquiry(&ccb->csio,
5116 /*retries*/ retry_count,
5118 /* tag_action */ MSG_SIMPLE_Q_TAG,
5119 /* inq_buf */ (u_int8_t *)&sup_pages,
5120 /* inq_len */ sizeof(sup_pages),
5122 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5123 /* sense_len */ SSD_FULL_SIZE,
5124 /* timeout */ timeout ? timeout : 5000);
5126 /* Disable freezing the device queue */
5127 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5129 if (retry_count != 0)
5130 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5132 if (cam_send_ccb(dev, ccb) < 0) {
5139 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5140 if (verbosemode != 0)
5141 cam_error_print(dev, ccb, CAM_ESF_ALL,
5142 CAM_EPF_ALL, stderr);
5147 for (i = 0; i < sup_pages.length; i++) {
5148 if (sup_pages.list[i] == page_id) {
5161 * devtype is filled in with the type of device.
5162 * Returns 0 for success, non-zero for failure.
5165 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5166 int verbosemode, camcontrol_devtype *devtype)
5168 struct ccb_getdev cgd;
5171 retval = get_cgd(dev, &cgd);
5175 switch (cgd.protocol) {
5181 *devtype = CC_DT_ATA;
5183 break; /*NOTREACHED*/
5185 *devtype = CC_DT_UNKNOWN;
5187 break; /*NOTREACHED*/
5191 * Check for the ATA Information VPD page (0x89). If this is an
5192 * ATA device behind a SCSI to ATA translation layer, this VPD page
5193 * should be present.
5195 * If that VPD page isn't present, or we get an error back from the
5196 * INQUIRY command, we'll just treat it as a normal SCSI device.
5198 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5199 timeout, verbosemode);
5201 *devtype = CC_DT_ATA_BEHIND_SCSI;
5203 *devtype = CC_DT_SCSI;
5212 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5213 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5214 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5215 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5216 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5217 int is48bit, camcontrol_devtype devtype)
5221 if (devtype == CC_DT_ATA) {
5222 cam_fill_ataio(&ccb->ataio,
5223 /*retries*/ retry_count,
5226 /*tag_action*/ tag_action,
5227 /*data_ptr*/ data_ptr,
5228 /*dxfer_len*/ dxfer_len,
5229 /*timeout*/ timeout);
5230 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5231 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5234 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5237 if (auxiliary != 0) {
5238 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5239 ccb->ataio.aux = auxiliary;
5242 if (ata_flags & AP_FLAG_CHK_COND)
5243 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5245 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5246 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5247 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5248 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5250 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5251 protocol |= AP_EXTEND;
5253 retval = scsi_ata_pass(&ccb->csio,
5254 /*retries*/ retry_count,
5257 /*tag_action*/ tag_action,
5258 /*protocol*/ protocol,
5259 /*ata_flags*/ ata_flags,
5260 /*features*/ features,
5261 /*sector_count*/ sector_count,
5263 /*command*/ command,
5266 /*auxiliary*/ auxiliary,
5268 /*data_ptr*/ data_ptr,
5269 /*dxfer_len*/ dxfer_len,
5270 /*cdb_storage*/ cdb_storage,
5271 /*cdb_storage_len*/ cdb_storage_len,
5272 /*minimum_cmd_size*/ 0,
5273 /*sense_len*/ sense_len,
5274 /*timeout*/ timeout);
5281 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5282 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5286 switch (ccb->ccb_h.func_code) {
5289 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5292 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5293 * or 16 byte, and need to see what
5295 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5296 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5298 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5299 if ((opcode != ATA_PASS_12)
5300 && (opcode != ATA_PASS_16)) {
5302 warnx("%s: unsupported opcode %02x", __func__, opcode);
5306 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5308 /* Note: the _ccb() variant returns 0 for an error */
5315 switch (error_code) {
5316 case SSD_DESC_CURRENT_ERROR:
5317 case SSD_DESC_DEFERRED_ERROR: {
5318 struct scsi_sense_data_desc *sense;
5319 struct scsi_sense_ata_ret_desc *desc;
5322 sense = (struct scsi_sense_data_desc *)
5323 &ccb->csio.sense_data;
5325 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5326 ccb->csio.sense_resid, SSD_DESC_ATA);
5327 if (desc_ptr == NULL) {
5328 cam_error_print(dev, ccb, CAM_ESF_ALL,
5329 CAM_EPF_ALL, stderr);
5333 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5335 *error = desc->error;
5336 *count = (desc->count_15_8 << 8) |
5338 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5339 ((uint64_t)desc->lba_39_32 << 32) |
5340 ((uint64_t)desc->lba_31_24 << 24) |
5341 (desc->lba_23_16 << 16) |
5342 (desc->lba_15_8 << 8) |
5344 *device = desc->device;
5345 *status = desc->status;
5348 * If the extend bit isn't set, the result is for a
5349 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5350 * command without the extend bit set. This means
5351 * that the device is supposed to return 28-bit
5352 * status. The count field is only 8 bits, and the
5353 * LBA field is only 8 bits.
5355 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5361 case SSD_CURRENT_ERROR:
5362 case SSD_DEFERRED_ERROR: {
5364 struct scsi_sense_data_fixed *sense;
5367 * XXX KDM need to support fixed sense data.
5369 warnx("%s: Fixed sense data not supported yet",
5373 break; /*NOTREACHED*/
5384 struct ata_res *res;
5387 * In this case, we have an ATA command, and we need to
5388 * fill in the requested values from the result register
5391 res = &ccb->ataio.res;
5392 *error = res->error;
5393 *status = res->status;
5394 *device = res->device;
5395 *count = res->sector_count;
5396 *lba = (res->lba_high << 16) |
5397 (res->lba_mid << 8) |
5399 if (res->flags & CAM_ATAIO_48BIT) {
5400 *count |= (res->sector_count_exp << 8);
5401 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5402 ((uint64_t)res->lba_mid_exp << 32) |
5403 ((uint64_t)res->lba_high_exp << 40);
5405 *lba |= (res->device & 0xf) << 24;
5418 cpi_print(struct ccb_pathinq *cpi)
5420 char adapter_str[1024];
5423 snprintf(adapter_str, sizeof(adapter_str),
5424 "%s%d:", cpi->dev_name, cpi->unit_number);
5426 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5429 for (i = 1; i < UINT8_MAX; i = i << 1) {
5432 if ((i & cpi->hba_inquiry) == 0)
5435 fprintf(stdout, "%s supports ", adapter_str);
5439 str = "MDP message";
5442 str = "32 bit wide SCSI";
5445 str = "16 bit wide SCSI";
5448 str = "SDTR message";
5451 str = "linked CDBs";
5454 str = "tag queue messages";
5457 str = "soft reset alternative";
5460 str = "SATA Port Multiplier";
5463 str = "unknown PI bit set";
5466 fprintf(stdout, "%s\n", str);
5469 for (i = 1; i < UINT32_MAX; i = i << 1) {
5472 if ((i & cpi->hba_misc) == 0)
5475 fprintf(stdout, "%s ", adapter_str);
5479 str = "can understand ata_ext requests";
5482 str = "64bit extended LUNs supported";
5485 str = "bus scans from high ID to low ID";
5488 str = "removable devices not included in scan";
5490 case PIM_NOINITIATOR:
5491 str = "initiator role not supported";
5493 case PIM_NOBUSRESET:
5494 str = "user has disabled initial BUS RESET or"
5495 " controller is in target/mixed mode";
5498 str = "do not send 6-byte commands";
5501 str = "scan bus sequentially";
5504 str = "unmapped I/O supported";
5507 str = "does its own scanning";
5510 str = "unknown PIM bit set";
5513 fprintf(stdout, "%s\n", str);
5516 for (i = 1; i < UINT16_MAX; i = i << 1) {
5519 if ((i & cpi->target_sprt) == 0)
5522 fprintf(stdout, "%s supports ", adapter_str);
5525 str = "target mode processor mode";
5528 str = "target mode phase cog. mode";
5530 case PIT_DISCONNECT:
5531 str = "disconnects in target mode";
5534 str = "terminate I/O message in target mode";
5537 str = "group 6 commands in target mode";
5540 str = "group 7 commands in target mode";
5543 str = "unknown PIT bit set";
5547 fprintf(stdout, "%s\n", str);
5549 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5551 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5553 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5555 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5556 adapter_str, cpi->hpath_id);
5557 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5559 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5560 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5561 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5562 adapter_str, cpi->hba_vendor);
5563 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5564 adapter_str, cpi->hba_device);
5565 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5566 adapter_str, cpi->hba_subvendor);
5567 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5568 adapter_str, cpi->hba_subdevice);
5569 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5570 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5571 if (cpi->base_transfer_speed > 1000)
5572 fprintf(stdout, "%d.%03dMB/sec\n",
5573 cpi->base_transfer_speed / 1000,
5574 cpi->base_transfer_speed % 1000);
5576 fprintf(stdout, "%dKB/sec\n",
5577 (cpi->base_transfer_speed % 1000) * 1000);
5578 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5579 adapter_str, cpi->maxio);
5583 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5584 struct ccb_trans_settings *cts)
5590 ccb = cam_getccb(device);
5593 warnx("get_print_cts: error allocating ccb");
5597 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5599 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5601 if (user_settings == 0)
5602 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5604 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5606 if (cam_send_ccb(device, ccb) < 0) {
5607 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5608 if (arglist & CAM_ARG_VERBOSE)
5609 cam_error_print(device, ccb, CAM_ESF_ALL,
5610 CAM_EPF_ALL, stderr);
5612 goto get_print_cts_bailout;
5615 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5616 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5617 if (arglist & CAM_ARG_VERBOSE)
5618 cam_error_print(device, ccb, CAM_ESF_ALL,
5619 CAM_EPF_ALL, stderr);
5621 goto get_print_cts_bailout;
5625 cts_print(device, &ccb->cts);
5628 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5630 get_print_cts_bailout:
5638 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5639 int timeout, int argc, char **argv, char *combinedopt)
5643 int user_settings = 0;
5645 int disc_enable = -1, tag_enable = -1;
5648 double syncrate = -1;
5651 int change_settings = 0, send_tur = 0;
5652 struct ccb_pathinq cpi;
5654 ccb = cam_getccb(device);
5656 warnx("ratecontrol: error allocating ccb");
5659 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5668 if (strncasecmp(optarg, "enable", 6) == 0)
5670 else if (strncasecmp(optarg, "disable", 7) == 0)
5673 warnx("-D argument \"%s\" is unknown", optarg);
5675 goto ratecontrol_bailout;
5677 change_settings = 1;
5680 mode = ata_string2mode(optarg);
5682 warnx("unknown mode '%s'", optarg);
5684 goto ratecontrol_bailout;
5686 change_settings = 1;
5689 offset = strtol(optarg, NULL, 0);
5691 warnx("offset value %d is < 0", offset);
5693 goto ratecontrol_bailout;
5695 change_settings = 1;
5701 syncrate = atof(optarg);
5703 warnx("sync rate %f is < 0", syncrate);
5705 goto ratecontrol_bailout;
5707 change_settings = 1;
5710 if (strncasecmp(optarg, "enable", 6) == 0)
5712 else if (strncasecmp(optarg, "disable", 7) == 0)
5715 warnx("-T argument \"%s\" is unknown", optarg);
5717 goto ratecontrol_bailout;
5719 change_settings = 1;
5725 bus_width = strtol(optarg, NULL, 0);
5726 if (bus_width < 0) {
5727 warnx("bus width %d is < 0", bus_width);
5729 goto ratecontrol_bailout;
5731 change_settings = 1;
5737 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5739 * Grab path inquiry information, so we can determine whether
5740 * or not the initiator is capable of the things that the user
5743 ccb->ccb_h.func_code = XPT_PATH_INQ;
5744 if (cam_send_ccb(device, ccb) < 0) {
5745 perror("error sending XPT_PATH_INQ CCB");
5746 if (arglist & CAM_ARG_VERBOSE) {
5747 cam_error_print(device, ccb, CAM_ESF_ALL,
5748 CAM_EPF_ALL, stderr);
5751 goto ratecontrol_bailout;
5753 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5754 warnx("XPT_PATH_INQ CCB failed");
5755 if (arglist & CAM_ARG_VERBOSE) {
5756 cam_error_print(device, ccb, CAM_ESF_ALL,
5757 CAM_EPF_ALL, stderr);
5760 goto ratecontrol_bailout;
5762 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5763 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5765 fprintf(stdout, "%s parameters:\n",
5766 user_settings ? "User" : "Current");
5768 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5770 goto ratecontrol_bailout;
5772 if (arglist & CAM_ARG_VERBOSE)
5775 if (change_settings) {
5776 int didsettings = 0;
5777 struct ccb_trans_settings_spi *spi = NULL;
5778 struct ccb_trans_settings_pata *pata = NULL;
5779 struct ccb_trans_settings_sata *sata = NULL;
5780 struct ccb_trans_settings_ata *ata = NULL;
5781 struct ccb_trans_settings_scsi *scsi = NULL;
5783 if (ccb->cts.transport == XPORT_SPI)
5784 spi = &ccb->cts.xport_specific.spi;
5785 if (ccb->cts.transport == XPORT_ATA)
5786 pata = &ccb->cts.xport_specific.ata;
5787 if (ccb->cts.transport == XPORT_SATA)
5788 sata = &ccb->cts.xport_specific.sata;
5789 if (ccb->cts.protocol == PROTO_ATA)
5790 ata = &ccb->cts.proto_specific.ata;
5791 if (ccb->cts.protocol == PROTO_SCSI)
5792 scsi = &ccb->cts.proto_specific.scsi;
5793 ccb->cts.xport_specific.valid = 0;
5794 ccb->cts.proto_specific.valid = 0;
5795 if (spi && disc_enable != -1) {
5796 spi->valid |= CTS_SPI_VALID_DISC;
5797 if (disc_enable == 0)
5798 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5800 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5803 if (tag_enable != -1) {
5804 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5805 warnx("HBA does not support tagged queueing, "
5806 "so you cannot modify tag settings");
5808 goto ratecontrol_bailout;
5811 ata->valid |= CTS_SCSI_VALID_TQ;
5812 if (tag_enable == 0)
5813 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5815 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5818 scsi->valid |= CTS_SCSI_VALID_TQ;
5819 if (tag_enable == 0)
5820 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5822 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5826 if (spi && offset != -1) {
5827 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5828 warnx("HBA is not capable of changing offset");
5830 goto ratecontrol_bailout;
5832 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5833 spi->sync_offset = offset;
5836 if (spi && syncrate != -1) {
5837 int prelim_sync_period;
5839 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5840 warnx("HBA is not capable of changing "
5843 goto ratecontrol_bailout;
5845 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5847 * The sync rate the user gives us is in MHz.
5848 * We need to translate it into KHz for this
5853 * Next, we calculate a "preliminary" sync period
5854 * in tenths of a nanosecond.
5857 prelim_sync_period = 0;
5859 prelim_sync_period = 10000000 / syncrate;
5861 scsi_calc_syncparam(prelim_sync_period);
5864 if (sata && syncrate != -1) {
5865 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5866 warnx("HBA is not capable of changing "
5869 goto ratecontrol_bailout;
5871 if (!user_settings) {
5872 warnx("You can modify only user rate "
5873 "settings for SATA");
5875 goto ratecontrol_bailout;
5877 sata->revision = ata_speed2revision(syncrate * 100);
5878 if (sata->revision < 0) {
5879 warnx("Invalid rate %f", syncrate);
5881 goto ratecontrol_bailout;
5883 sata->valid |= CTS_SATA_VALID_REVISION;
5886 if ((pata || sata) && mode != -1) {
5887 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5888 warnx("HBA is not capable of changing "
5891 goto ratecontrol_bailout;
5893 if (!user_settings) {
5894 warnx("You can modify only user mode "
5895 "settings for ATA/SATA");
5897 goto ratecontrol_bailout;
5901 pata->valid |= CTS_ATA_VALID_MODE;
5904 sata->valid |= CTS_SATA_VALID_MODE;
5909 * The bus_width argument goes like this:
5913 * Therefore, if you shift the number of bits given on the
5914 * command line right by 4, you should get the correct
5917 if (spi && bus_width != -1) {
5919 * We might as well validate things here with a
5920 * decipherable error message, rather than what
5921 * will probably be an indecipherable error message
5922 * by the time it gets back to us.
5924 if ((bus_width == 16)
5925 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5926 warnx("HBA does not support 16 bit bus width");
5928 goto ratecontrol_bailout;
5929 } else if ((bus_width == 32)
5930 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5931 warnx("HBA does not support 32 bit bus width");
5933 goto ratecontrol_bailout;
5934 } else if ((bus_width != 8)
5935 && (bus_width != 16)
5936 && (bus_width != 32)) {
5937 warnx("Invalid bus width %d", bus_width);
5939 goto ratecontrol_bailout;
5941 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5942 spi->bus_width = bus_width >> 4;
5945 if (didsettings == 0) {
5946 goto ratecontrol_bailout;
5948 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5949 if (cam_send_ccb(device, ccb) < 0) {
5950 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5951 if (arglist & CAM_ARG_VERBOSE) {
5952 cam_error_print(device, ccb, CAM_ESF_ALL,
5953 CAM_EPF_ALL, stderr);
5956 goto ratecontrol_bailout;
5958 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5959 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5960 if (arglist & CAM_ARG_VERBOSE) {
5961 cam_error_print(device, ccb, CAM_ESF_ALL,
5962 CAM_EPF_ALL, stderr);
5965 goto ratecontrol_bailout;
5969 retval = testunitready(device, task_attr, retry_count, timeout,
5970 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5972 * If the TUR didn't succeed, just bail.
5976 fprintf(stderr, "Test Unit Ready failed\n");
5977 goto ratecontrol_bailout;
5980 if ((change_settings || send_tur) && !quiet &&
5981 (ccb->cts.transport == XPORT_ATA ||
5982 ccb->cts.transport == XPORT_SATA || send_tur)) {
5983 fprintf(stdout, "New parameters:\n");
5984 retval = get_print_cts(device, user_settings, 0, NULL);
5987 ratecontrol_bailout:
5993 scsiformat(struct cam_device *device, int argc, char **argv,
5994 char *combinedopt, int task_attr, int retry_count, int timeout)
5998 int ycount = 0, quiet = 0;
5999 int error = 0, retval = 0;
6000 int use_timeout = 10800 * 1000;
6002 struct format_defect_list_header fh;
6003 u_int8_t *data_ptr = NULL;
6004 u_int32_t dxfer_len = 0;
6006 int num_warnings = 0;
6009 ccb = cam_getccb(device);
6012 warnx("scsiformat: error allocating ccb");
6016 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6018 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6039 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6040 "following device:\n");
6042 error = scsidoinquiry(device, argc, argv, combinedopt,
6043 task_attr, retry_count, timeout);
6046 warnx("scsiformat: error sending inquiry");
6047 goto scsiformat_bailout;
6052 if (!get_confirmation()) {
6054 goto scsiformat_bailout;
6059 use_timeout = timeout;
6062 fprintf(stdout, "Current format timeout is %d seconds\n",
6063 use_timeout / 1000);
6067 * If the user hasn't disabled questions and didn't specify a
6068 * timeout on the command line, ask them if they want the current
6072 && (timeout == 0)) {
6074 int new_timeout = 0;
6076 fprintf(stdout, "Enter new timeout in seconds or press\n"
6077 "return to keep the current timeout [%d] ",
6078 use_timeout / 1000);
6080 if (fgets(str, sizeof(str), stdin) != NULL) {
6082 new_timeout = atoi(str);
6085 if (new_timeout != 0) {
6086 use_timeout = new_timeout * 1000;
6087 fprintf(stdout, "Using new timeout value %d\n",
6088 use_timeout / 1000);
6093 * Keep this outside the if block below to silence any unused
6094 * variable warnings.
6096 bzero(&fh, sizeof(fh));
6099 * If we're in immediate mode, we've got to include the format
6102 if (immediate != 0) {
6103 fh.byte2 = FU_DLH_IMMED;
6104 data_ptr = (u_int8_t *)&fh;
6105 dxfer_len = sizeof(fh);
6106 byte2 = FU_FMT_DATA;
6107 } else if (quiet == 0) {
6108 fprintf(stdout, "Formatting...");
6112 scsi_format_unit(&ccb->csio,
6113 /* retries */ retry_count,
6115 /* tag_action */ task_attr,
6118 /* data_ptr */ data_ptr,
6119 /* dxfer_len */ dxfer_len,
6120 /* sense_len */ SSD_FULL_SIZE,
6121 /* timeout */ use_timeout);
6123 /* Disable freezing the device queue */
6124 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6126 if (arglist & CAM_ARG_ERR_RECOVER)
6127 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6129 if (((retval = cam_send_ccb(device, ccb)) < 0)
6130 || ((immediate == 0)
6131 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6132 const char errstr[] = "error sending format command";
6139 if (arglist & CAM_ARG_VERBOSE) {
6140 cam_error_print(device, ccb, CAM_ESF_ALL,
6141 CAM_EPF_ALL, stderr);
6144 goto scsiformat_bailout;
6148 * If we ran in non-immediate mode, we already checked for errors
6149 * above and printed out any necessary information. If we're in
6150 * immediate mode, we need to loop through and get status
6151 * information periodically.
6153 if (immediate == 0) {
6155 fprintf(stdout, "Format Complete\n");
6157 goto scsiformat_bailout;
6164 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6167 * There's really no need to do error recovery or
6168 * retries here, since we're just going to sit in a
6169 * loop and wait for the device to finish formatting.
6171 scsi_test_unit_ready(&ccb->csio,
6174 /* tag_action */ task_attr,
6175 /* sense_len */ SSD_FULL_SIZE,
6176 /* timeout */ 5000);
6178 /* Disable freezing the device queue */
6179 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6181 retval = cam_send_ccb(device, ccb);
6184 * If we get an error from the ioctl, bail out. SCSI
6185 * errors are expected.
6188 warn("error sending CAMIOCOMMAND ioctl");
6189 if (arglist & CAM_ARG_VERBOSE) {
6190 cam_error_print(device, ccb, CAM_ESF_ALL,
6191 CAM_EPF_ALL, stderr);
6194 goto scsiformat_bailout;
6197 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6199 if ((status != CAM_REQ_CMP)
6200 && (status == CAM_SCSI_STATUS_ERROR)
6201 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6202 struct scsi_sense_data *sense;
6203 int error_code, sense_key, asc, ascq;
6205 sense = &ccb->csio.sense_data;
6206 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6207 ccb->csio.sense_resid, &error_code, &sense_key,
6208 &asc, &ascq, /*show_errors*/ 1);
6211 * According to the SCSI-2 and SCSI-3 specs, a
6212 * drive that is in the middle of a format should
6213 * return NOT READY with an ASC of "logical unit
6214 * not ready, format in progress". The sense key
6215 * specific bytes will then be a progress indicator.
6217 if ((sense_key == SSD_KEY_NOT_READY)
6218 && (asc == 0x04) && (ascq == 0x04)) {
6221 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6222 ccb->csio.sense_resid, sks) == 0)
6225 u_int64_t percentage;
6227 val = scsi_2btoul(&sks[1]);
6228 percentage = 10000 * val;
6231 "\rFormatting: %ju.%02u %% "
6233 (uintmax_t)(percentage /
6235 (unsigned)((percentage /
6239 } else if ((quiet == 0)
6240 && (++num_warnings <= 1)) {
6241 warnx("Unexpected SCSI Sense Key "
6242 "Specific value returned "
6244 scsi_sense_print(device, &ccb->csio,
6246 warnx("Unable to print status "
6247 "information, but format will "
6249 warnx("will exit when format is "
6254 warnx("Unexpected SCSI error during format");
6255 cam_error_print(device, ccb, CAM_ESF_ALL,
6256 CAM_EPF_ALL, stderr);
6258 goto scsiformat_bailout;
6261 } else if (status != CAM_REQ_CMP) {
6262 warnx("Unexpected CAM status %#x", status);
6263 if (arglist & CAM_ARG_VERBOSE)
6264 cam_error_print(device, ccb, CAM_ESF_ALL,
6265 CAM_EPF_ALL, stderr);
6267 goto scsiformat_bailout;
6270 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6273 fprintf(stdout, "\nFormat Complete\n");
6283 scsisanitize(struct cam_device *device, int argc, char **argv,
6284 char *combinedopt, int task_attr, int retry_count, int timeout)
6287 u_int8_t action = 0;
6289 int ycount = 0, quiet = 0;
6290 int error = 0, retval = 0;
6291 int use_timeout = 10800 * 1000;
6297 const char *pattern = NULL;
6298 u_int8_t *data_ptr = NULL;
6299 u_int32_t dxfer_len = 0;
6301 int num_warnings = 0;
6304 ccb = cam_getccb(device);
6307 warnx("scsisanitize: error allocating ccb");
6311 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6313 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6316 if (strcasecmp(optarg, "overwrite") == 0)
6317 action = SSZ_SERVICE_ACTION_OVERWRITE;
6318 else if (strcasecmp(optarg, "block") == 0)
6319 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6320 else if (strcasecmp(optarg, "crypto") == 0)
6321 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6322 else if (strcasecmp(optarg, "exitfailure") == 0)
6323 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6325 warnx("invalid service operation \"%s\"",
6328 goto scsisanitize_bailout;
6332 passes = strtol(optarg, NULL, 0);
6333 if (passes < 1 || passes > 31) {
6334 warnx("invalid passes value %d", passes);
6336 goto scsisanitize_bailout;
6367 warnx("an action is required");
6369 goto scsisanitize_bailout;
6370 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6371 struct scsi_sanitize_parameter_list *pl;
6375 if (pattern == NULL) {
6376 warnx("overwrite action requires -P argument");
6378 goto scsisanitize_bailout;
6380 fd = open(pattern, O_RDONLY);
6382 warn("cannot open pattern file %s", pattern);
6384 goto scsisanitize_bailout;
6386 if (fstat(fd, &sb) < 0) {
6387 warn("cannot stat pattern file %s", pattern);
6389 goto scsisanitize_bailout;
6392 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6393 warnx("pattern file size exceeds maximum value %d",
6394 SSZPL_MAX_PATTERN_LENGTH);
6396 goto scsisanitize_bailout;
6398 dxfer_len = sizeof(*pl) + sz;
6399 data_ptr = calloc(1, dxfer_len);
6400 if (data_ptr == NULL) {
6401 warnx("cannot allocate parameter list buffer");
6403 goto scsisanitize_bailout;
6406 amt = read(fd, data_ptr + sizeof(*pl), sz);
6408 warn("cannot read pattern file");
6410 goto scsisanitize_bailout;
6411 } else if (amt != sz) {
6412 warnx("short pattern file read");
6414 goto scsisanitize_bailout;
6417 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6423 pl->byte1 |= SSZPL_INVERT;
6424 scsi_ulto2b(sz, pl->length);
6430 else if (invert != 0)
6432 else if (pattern != NULL)
6437 warnx("%s argument only valid with overwrite "
6440 goto scsisanitize_bailout;
6445 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6446 "following device:\n");
6448 error = scsidoinquiry(device, argc, argv, combinedopt,
6449 task_attr, retry_count, timeout);
6452 warnx("scsisanitize: error sending inquiry");
6453 goto scsisanitize_bailout;
6458 if (!get_confirmation()) {
6460 goto scsisanitize_bailout;
6465 use_timeout = timeout;
6468 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6469 use_timeout / 1000);
6473 * If the user hasn't disabled questions and didn't specify a
6474 * timeout on the command line, ask them if they want the current
6478 && (timeout == 0)) {
6480 int new_timeout = 0;
6482 fprintf(stdout, "Enter new timeout in seconds or press\n"
6483 "return to keep the current timeout [%d] ",
6484 use_timeout / 1000);
6486 if (fgets(str, sizeof(str), stdin) != NULL) {
6488 new_timeout = atoi(str);
6491 if (new_timeout != 0) {
6492 use_timeout = new_timeout * 1000;
6493 fprintf(stdout, "Using new timeout value %d\n",
6494 use_timeout / 1000);
6500 byte2 |= SSZ_UNRESTRICTED_EXIT;
6504 scsi_sanitize(&ccb->csio,
6505 /* retries */ retry_count,
6507 /* tag_action */ task_attr,
6510 /* data_ptr */ data_ptr,
6511 /* dxfer_len */ dxfer_len,
6512 /* sense_len */ SSD_FULL_SIZE,
6513 /* timeout */ use_timeout);
6515 /* Disable freezing the device queue */
6516 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6518 if (arglist & CAM_ARG_ERR_RECOVER)
6519 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6521 if (cam_send_ccb(device, ccb) < 0) {
6522 warn("error sending sanitize command");
6524 goto scsisanitize_bailout;
6527 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6528 struct scsi_sense_data *sense;
6529 int error_code, sense_key, asc, ascq;
6531 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6532 CAM_SCSI_STATUS_ERROR) {
6533 sense = &ccb->csio.sense_data;
6534 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6535 ccb->csio.sense_resid, &error_code, &sense_key,
6536 &asc, &ascq, /*show_errors*/ 1);
6538 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6539 asc == 0x20 && ascq == 0x00)
6540 warnx("sanitize is not supported by "
6543 warnx("error sanitizing this device");
6545 warnx("error sanitizing this device");
6547 if (arglist & CAM_ARG_VERBOSE) {
6548 cam_error_print(device, ccb, CAM_ESF_ALL,
6549 CAM_EPF_ALL, stderr);
6552 goto scsisanitize_bailout;
6556 * If we ran in non-immediate mode, we already checked for errors
6557 * above and printed out any necessary information. If we're in
6558 * immediate mode, we need to loop through and get status
6559 * information periodically.
6561 if (immediate == 0) {
6563 fprintf(stdout, "Sanitize Complete\n");
6565 goto scsisanitize_bailout;
6572 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6575 * There's really no need to do error recovery or
6576 * retries here, since we're just going to sit in a
6577 * loop and wait for the device to finish sanitizing.
6579 scsi_test_unit_ready(&ccb->csio,
6582 /* tag_action */ task_attr,
6583 /* sense_len */ SSD_FULL_SIZE,
6584 /* timeout */ 5000);
6586 /* Disable freezing the device queue */
6587 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6589 retval = cam_send_ccb(device, ccb);
6592 * If we get an error from the ioctl, bail out. SCSI
6593 * errors are expected.
6596 warn("error sending CAMIOCOMMAND ioctl");
6597 if (arglist & CAM_ARG_VERBOSE) {
6598 cam_error_print(device, ccb, CAM_ESF_ALL,
6599 CAM_EPF_ALL, stderr);
6602 goto scsisanitize_bailout;
6605 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6607 if ((status != CAM_REQ_CMP)
6608 && (status == CAM_SCSI_STATUS_ERROR)
6609 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6610 struct scsi_sense_data *sense;
6611 int error_code, sense_key, asc, ascq;
6613 sense = &ccb->csio.sense_data;
6614 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6615 ccb->csio.sense_resid, &error_code, &sense_key,
6616 &asc, &ascq, /*show_errors*/ 1);
6619 * According to the SCSI-3 spec, a drive that is in the
6620 * middle of a sanitize should return NOT READY with an
6621 * ASC of "logical unit not ready, sanitize in
6622 * progress". The sense key specific bytes will then
6623 * be a progress indicator.
6625 if ((sense_key == SSD_KEY_NOT_READY)
6626 && (asc == 0x04) && (ascq == 0x1b)) {
6629 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6630 ccb->csio.sense_resid, sks) == 0)
6633 u_int64_t percentage;
6635 val = scsi_2btoul(&sks[1]);
6636 percentage = 10000 * val;
6639 "\rSanitizing: %ju.%02u %% "
6641 (uintmax_t)(percentage /
6643 (unsigned)((percentage /
6647 } else if ((quiet == 0)
6648 && (++num_warnings <= 1)) {
6649 warnx("Unexpected SCSI Sense Key "
6650 "Specific value returned "
6651 "during sanitize:");
6652 scsi_sense_print(device, &ccb->csio,
6654 warnx("Unable to print status "
6655 "information, but sanitze will "
6657 warnx("will exit when sanitize is "
6662 warnx("Unexpected SCSI error during sanitize");
6663 cam_error_print(device, ccb, CAM_ESF_ALL,
6664 CAM_EPF_ALL, stderr);
6666 goto scsisanitize_bailout;
6669 } else if (status != CAM_REQ_CMP) {
6670 warnx("Unexpected CAM status %#x", status);
6671 if (arglist & CAM_ARG_VERBOSE)
6672 cam_error_print(device, ccb, CAM_ESF_ALL,
6673 CAM_EPF_ALL, stderr);
6675 goto scsisanitize_bailout;
6677 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6680 fprintf(stdout, "\nSanitize Complete\n");
6682 scsisanitize_bailout:
6685 if (data_ptr != NULL)
6693 scsireportluns(struct cam_device *device, int argc, char **argv,
6694 char *combinedopt, int task_attr, int retry_count, int timeout)
6697 int c, countonly, lunsonly;
6698 struct scsi_report_luns_data *lundata;
6700 uint8_t report_type;
6701 uint32_t list_len, i, j;
6706 report_type = RPL_REPORT_DEFAULT;
6707 ccb = cam_getccb(device);
6710 warnx("%s: error allocating ccb", __func__);
6714 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6719 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6728 if (strcasecmp(optarg, "default") == 0)
6729 report_type = RPL_REPORT_DEFAULT;
6730 else if (strcasecmp(optarg, "wellknown") == 0)
6731 report_type = RPL_REPORT_WELLKNOWN;
6732 else if (strcasecmp(optarg, "all") == 0)
6733 report_type = RPL_REPORT_ALL;
6735 warnx("%s: invalid report type \"%s\"",
6746 if ((countonly != 0)
6747 && (lunsonly != 0)) {
6748 warnx("%s: you can only specify one of -c or -l", __func__);
6753 * According to SPC-4, the allocation length must be at least 16
6754 * bytes -- enough for the header and one LUN.
6756 alloc_len = sizeof(*lundata) + 8;
6760 lundata = malloc(alloc_len);
6762 if (lundata == NULL) {
6763 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6768 scsi_report_luns(&ccb->csio,
6769 /*retries*/ retry_count,
6771 /*tag_action*/ task_attr,
6772 /*select_report*/ report_type,
6773 /*rpl_buf*/ lundata,
6774 /*alloc_len*/ alloc_len,
6775 /*sense_len*/ SSD_FULL_SIZE,
6776 /*timeout*/ timeout ? timeout : 5000);
6778 /* Disable freezing the device queue */
6779 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6781 if (arglist & CAM_ARG_ERR_RECOVER)
6782 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6784 if (cam_send_ccb(device, ccb) < 0) {
6785 warn("error sending REPORT LUNS command");
6787 if (arglist & CAM_ARG_VERBOSE)
6788 cam_error_print(device, ccb, CAM_ESF_ALL,
6789 CAM_EPF_ALL, stderr);
6795 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6796 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6802 list_len = scsi_4btoul(lundata->length);
6805 * If we need to list the LUNs, and our allocation
6806 * length was too short, reallocate and retry.
6808 if ((countonly == 0)
6809 && (list_len > (alloc_len - sizeof(*lundata)))) {
6810 alloc_len = list_len + sizeof(*lundata);
6816 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6817 ((list_len / 8) > 1) ? "s" : "");
6822 for (i = 0; i < (list_len / 8); i++) {
6826 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6828 fprintf(stdout, ",");
6829 switch (lundata->luns[i].lundata[j] &
6830 RPL_LUNDATA_ATYP_MASK) {
6831 case RPL_LUNDATA_ATYP_PERIPH:
6832 if ((lundata->luns[i].lundata[j] &
6833 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6834 fprintf(stdout, "%d:",
6835 lundata->luns[i].lundata[j] &
6836 RPL_LUNDATA_PERIPH_BUS_MASK);
6838 && ((lundata->luns[i].lundata[j+2] &
6839 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6842 fprintf(stdout, "%d",
6843 lundata->luns[i].lundata[j+1]);
6845 case RPL_LUNDATA_ATYP_FLAT: {
6847 tmplun[0] = lundata->luns[i].lundata[j] &
6848 RPL_LUNDATA_FLAT_LUN_MASK;
6849 tmplun[1] = lundata->luns[i].lundata[j+1];
6851 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6855 case RPL_LUNDATA_ATYP_LUN:
6856 fprintf(stdout, "%d:%d:%d",
6857 (lundata->luns[i].lundata[j+1] &
6858 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6859 lundata->luns[i].lundata[j] &
6860 RPL_LUNDATA_LUN_TARG_MASK,
6861 lundata->luns[i].lundata[j+1] &
6862 RPL_LUNDATA_LUN_LUN_MASK);
6864 case RPL_LUNDATA_ATYP_EXTLUN: {
6865 int field_len_code, eam_code;
6867 eam_code = lundata->luns[i].lundata[j] &
6868 RPL_LUNDATA_EXT_EAM_MASK;
6869 field_len_code = (lundata->luns[i].lundata[j] &
6870 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6872 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6873 && (field_len_code == 0x00)) {
6874 fprintf(stdout, "%d",
6875 lundata->luns[i].lundata[j+1]);
6876 } else if ((eam_code ==
6877 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6878 && (field_len_code == 0x03)) {
6882 * This format takes up all 8 bytes.
6883 * If we aren't starting at offset 0,
6887 fprintf(stdout, "Invalid "
6890 "specified format", j);
6894 bzero(tmp_lun, sizeof(tmp_lun));
6895 bcopy(&lundata->luns[i].lundata[j+1],
6896 &tmp_lun[1], sizeof(tmp_lun) - 1);
6897 fprintf(stdout, "%#jx",
6898 (intmax_t)scsi_8btou64(tmp_lun));
6901 fprintf(stderr, "Unknown Extended LUN"
6902 "Address method %#x, length "
6903 "code %#x", eam_code,
6910 fprintf(stderr, "Unknown LUN address method "
6911 "%#x\n", lundata->luns[i].lundata[0] &
6912 RPL_LUNDATA_ATYP_MASK);
6916 * For the flat addressing method, there are no
6917 * other levels after it.
6922 fprintf(stdout, "\n");
6935 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6936 char *combinedopt, int task_attr, int retry_count, int timeout)
6939 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6940 struct scsi_read_capacity_data rcap;
6941 struct scsi_read_capacity_data_long rcaplong;
6955 ccb = cam_getccb(device);
6958 warnx("%s: error allocating ccb", __func__);
6962 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6964 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6991 if ((blocksizeonly != 0)
6992 && (numblocks != 0)) {
6993 warnx("%s: you can only specify one of -b or -N", __func__);
6998 if ((blocksizeonly != 0)
6999 && (sizeonly != 0)) {
7000 warnx("%s: you can only specify one of -b or -s", __func__);
7007 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7013 && (blocksizeonly != 0)) {
7014 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7019 scsi_read_capacity(&ccb->csio,
7020 /*retries*/ retry_count,
7022 /*tag_action*/ task_attr,
7025 /*timeout*/ timeout ? timeout : 5000);
7027 /* Disable freezing the device queue */
7028 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7030 if (arglist & CAM_ARG_ERR_RECOVER)
7031 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7033 if (cam_send_ccb(device, ccb) < 0) {
7034 warn("error sending READ CAPACITY command");
7036 if (arglist & CAM_ARG_VERBOSE)
7037 cam_error_print(device, ccb, CAM_ESF_ALL,
7038 CAM_EPF_ALL, stderr);
7044 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7045 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7050 maxsector = scsi_4btoul(rcap.addr);
7051 block_len = scsi_4btoul(rcap.length);
7054 * A last block of 2^32-1 means that the true capacity is over 2TB,
7055 * and we need to issue the long READ CAPACITY to get the real
7056 * capacity. Otherwise, we're all set.
7058 if (maxsector != 0xffffffff)
7061 scsi_read_capacity_16(&ccb->csio,
7062 /*retries*/ retry_count,
7064 /*tag_action*/ task_attr,
7068 /*rcap_buf*/ (uint8_t *)&rcaplong,
7069 /*rcap_buf_len*/ sizeof(rcaplong),
7070 /*sense_len*/ SSD_FULL_SIZE,
7071 /*timeout*/ timeout ? timeout : 5000);
7073 /* Disable freezing the device queue */
7074 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7076 if (arglist & CAM_ARG_ERR_RECOVER)
7077 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7079 if (cam_send_ccb(device, ccb) < 0) {
7080 warn("error sending READ CAPACITY (16) command");
7082 if (arglist & CAM_ARG_VERBOSE)
7083 cam_error_print(device, ccb, CAM_ESF_ALL,
7084 CAM_EPF_ALL, stderr);
7090 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7091 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7096 maxsector = scsi_8btou64(rcaplong.addr);
7097 block_len = scsi_4btoul(rcaplong.length);
7100 if (blocksizeonly == 0) {
7102 * Humanize implies !quiet, and also implies numblocks.
7104 if (humanize != 0) {
7109 tmpbytes = (maxsector + 1) * block_len;
7110 ret = humanize_number(tmpstr, sizeof(tmpstr),
7111 tmpbytes, "", HN_AUTOSCALE,
7114 HN_DIVISOR_1000 : 0));
7116 warnx("%s: humanize_number failed!", __func__);
7120 fprintf(stdout, "Device Size: %s%s", tmpstr,
7121 (sizeonly == 0) ? ", " : "\n");
7122 } else if (numblocks != 0) {
7123 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7124 "Blocks: " : "", (uintmax_t)maxsector + 1,
7125 (sizeonly == 0) ? ", " : "\n");
7127 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7128 "Last Block: " : "", (uintmax_t)maxsector,
7129 (sizeonly == 0) ? ", " : "\n");
7133 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7134 "Block Length: " : "", block_len, (quiet == 0) ?
7143 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7144 int retry_count, int timeout)
7148 uint8_t *smp_request = NULL, *smp_response = NULL;
7149 int request_size = 0, response_size = 0;
7150 int fd_request = 0, fd_response = 0;
7151 char *datastr = NULL;
7152 struct get_hook hook;
7157 * Note that at the moment we don't support sending SMP CCBs to
7158 * devices that aren't probed by CAM.
7160 ccb = cam_getccb(device);
7162 warnx("%s: error allocating CCB", __func__);
7166 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7168 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7171 arglist |= CAM_ARG_CMD_IN;
7172 response_size = strtol(optarg, NULL, 0);
7173 if (response_size <= 0) {
7174 warnx("invalid number of response bytes %d",
7177 goto smpcmd_bailout;
7179 hook.argc = argc - optind;
7180 hook.argv = argv + optind;
7183 datastr = cget(&hook, NULL);
7185 * If the user supplied "-" instead of a format, he
7186 * wants the data to be written to stdout.
7188 if ((datastr != NULL)
7189 && (datastr[0] == '-'))
7192 smp_response = (u_int8_t *)malloc(response_size);
7193 if (smp_response == NULL) {
7194 warn("can't malloc memory for SMP response");
7196 goto smpcmd_bailout;
7200 arglist |= CAM_ARG_CMD_OUT;
7201 request_size = strtol(optarg, NULL, 0);
7202 if (request_size <= 0) {
7203 warnx("invalid number of request bytes %d",
7206 goto smpcmd_bailout;
7208 hook.argc = argc - optind;
7209 hook.argv = argv + optind;
7211 datastr = cget(&hook, NULL);
7212 smp_request = (u_int8_t *)malloc(request_size);
7213 if (smp_request == NULL) {
7214 warn("can't malloc memory for SMP request");
7216 goto smpcmd_bailout;
7218 bzero(smp_request, request_size);
7220 * If the user supplied "-" instead of a format, he
7221 * wants the data to be read from stdin.
7223 if ((datastr != NULL)
7224 && (datastr[0] == '-'))
7227 buff_encode_visit(smp_request, request_size,
7238 * If fd_data is set, and we're writing to the device, we need to
7239 * read the data the user wants written from stdin.
7241 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7243 int amt_to_read = request_size;
7244 u_int8_t *buf_ptr = smp_request;
7246 for (amt_read = 0; amt_to_read > 0;
7247 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7248 if (amt_read == -1) {
7249 warn("error reading data from stdin");
7251 goto smpcmd_bailout;
7253 amt_to_read -= amt_read;
7254 buf_ptr += amt_read;
7258 if (((arglist & CAM_ARG_CMD_IN) == 0)
7259 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7260 warnx("%s: need both the request (-r) and response (-R) "
7261 "arguments", __func__);
7263 goto smpcmd_bailout;
7266 flags |= CAM_DEV_QFRZDIS;
7268 cam_fill_smpio(&ccb->smpio,
7269 /*retries*/ retry_count,
7272 /*smp_request*/ smp_request,
7273 /*smp_request_len*/ request_size,
7274 /*smp_response*/ smp_response,
7275 /*smp_response_len*/ response_size,
7276 /*timeout*/ timeout ? timeout : 5000);
7278 ccb->smpio.flags = SMP_FLAG_NONE;
7280 if (((retval = cam_send_ccb(device, ccb)) < 0)
7281 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7282 const char warnstr[] = "error sending command";
7289 if (arglist & CAM_ARG_VERBOSE) {
7290 cam_error_print(device, ccb, CAM_ESF_ALL,
7291 CAM_EPF_ALL, stderr);
7295 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7296 && (response_size > 0)) {
7297 if (fd_response == 0) {
7298 buff_decode_visit(smp_response, response_size,
7299 datastr, arg_put, NULL);
7300 fprintf(stdout, "\n");
7302 ssize_t amt_written;
7303 int amt_to_write = response_size;
7304 u_int8_t *buf_ptr = smp_response;
7306 for (amt_written = 0; (amt_to_write > 0) &&
7307 (amt_written = write(STDOUT_FILENO, buf_ptr,
7308 amt_to_write)) > 0;){
7309 amt_to_write -= amt_written;
7310 buf_ptr += amt_written;
7312 if (amt_written == -1) {
7313 warn("error writing data to stdout");
7315 goto smpcmd_bailout;
7316 } else if ((amt_written == 0)
7317 && (amt_to_write > 0)) {
7318 warnx("only wrote %u bytes out of %u",
7319 response_size - amt_to_write,
7328 if (smp_request != NULL)
7331 if (smp_response != NULL)
7338 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7339 char *combinedopt, int retry_count, int timeout)
7342 struct smp_report_general_request *request = NULL;
7343 struct smp_report_general_response *response = NULL;
7344 struct sbuf *sb = NULL;
7346 int c, long_response = 0;
7350 * Note that at the moment we don't support sending SMP CCBs to
7351 * devices that aren't probed by CAM.
7353 ccb = cam_getccb(device);
7355 warnx("%s: error allocating CCB", __func__);
7359 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7361 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7370 request = malloc(sizeof(*request));
7371 if (request == NULL) {
7372 warn("%s: unable to allocate %zd bytes", __func__,
7378 response = malloc(sizeof(*response));
7379 if (response == NULL) {
7380 warn("%s: unable to allocate %zd bytes", __func__,
7387 smp_report_general(&ccb->smpio,
7391 /*request_len*/ sizeof(*request),
7392 (uint8_t *)response,
7393 /*response_len*/ sizeof(*response),
7394 /*long_response*/ long_response,
7397 if (((retval = cam_send_ccb(device, ccb)) < 0)
7398 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7399 const char warnstr[] = "error sending command";
7406 if (arglist & CAM_ARG_VERBOSE) {
7407 cam_error_print(device, ccb, CAM_ESF_ALL,
7408 CAM_EPF_ALL, stderr);
7415 * If the device supports the long response bit, try again and see
7416 * if we can get all of the data.
7418 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7419 && (long_response == 0)) {
7420 ccb->ccb_h.status = CAM_REQ_INPROG;
7421 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7427 * XXX KDM detect and decode SMP errors here.
7429 sb = sbuf_new_auto();
7431 warnx("%s: error allocating sbuf", __func__);
7435 smp_report_general_sbuf(response, sizeof(*response), sb);
7437 if (sbuf_finish(sb) != 0) {
7438 warnx("%s: sbuf_finish", __func__);
7442 printf("%s", sbuf_data(sb));
7448 if (request != NULL)
7451 if (response != NULL)
7460 static struct camcontrol_opts phy_ops[] = {
7461 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7462 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7463 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7464 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7465 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7466 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7467 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7468 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7469 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7474 smpphycontrol(struct cam_device *device, int argc, char **argv,
7475 char *combinedopt, int retry_count, int timeout)
7478 struct smp_phy_control_request *request = NULL;
7479 struct smp_phy_control_response *response = NULL;
7480 int long_response = 0;
7483 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7485 uint64_t attached_dev_name = 0;
7486 int dev_name_set = 0;
7487 uint32_t min_plr = 0, max_plr = 0;
7488 uint32_t pp_timeout_val = 0;
7489 int slumber_partial = 0;
7490 int set_pp_timeout_val = 0;
7494 * Note that at the moment we don't support sending SMP CCBs to
7495 * devices that aren't probed by CAM.
7497 ccb = cam_getccb(device);
7499 warnx("%s: error allocating CCB", __func__);
7503 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7505 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7513 if (strcasecmp(optarg, "enable") == 0)
7515 else if (strcasecmp(optarg, "disable") == 0)
7518 warnx("%s: Invalid argument %s", __func__,
7525 slumber_partial |= enable <<
7526 SMP_PC_SAS_SLUMBER_SHIFT;
7529 slumber_partial |= enable <<
7530 SMP_PC_SAS_PARTIAL_SHIFT;
7533 slumber_partial |= enable <<
7534 SMP_PC_SATA_SLUMBER_SHIFT;
7537 slumber_partial |= enable <<
7538 SMP_PC_SATA_PARTIAL_SHIFT;
7541 warnx("%s: programmer error", __func__);
7544 break; /*NOTREACHED*/
7549 attached_dev_name = (uintmax_t)strtoumax(optarg,
7558 * We don't do extensive checking here, so this
7559 * will continue to work when new speeds come out.
7561 min_plr = strtoul(optarg, NULL, 0);
7563 || (min_plr > 0xf)) {
7564 warnx("%s: invalid link rate %x",
7572 * We don't do extensive checking here, so this
7573 * will continue to work when new speeds come out.
7575 max_plr = strtoul(optarg, NULL, 0);
7577 || (max_plr > 0xf)) {
7578 warnx("%s: invalid link rate %x",
7585 camcontrol_optret optreturn;
7586 cam_argmask argnums;
7589 if (phy_op_set != 0) {
7590 warnx("%s: only one phy operation argument "
7591 "(-o) allowed", __func__);
7599 * Allow the user to specify the phy operation
7600 * numerically, as well as with a name. This will
7601 * future-proof it a bit, so options that are added
7602 * in future specs can be used.
7604 if (isdigit(optarg[0])) {
7605 phy_operation = strtoul(optarg, NULL, 0);
7606 if ((phy_operation == 0)
7607 || (phy_operation > 0xff)) {
7608 warnx("%s: invalid phy operation %#x",
7609 __func__, phy_operation);
7615 optreturn = getoption(phy_ops, optarg, &phy_operation,
7618 if (optreturn == CC_OR_AMBIGUOUS) {
7619 warnx("%s: ambiguous option %s", __func__,
7624 } else if (optreturn == CC_OR_NOT_FOUND) {
7625 warnx("%s: option %s not found", __func__,
7637 pp_timeout_val = strtoul(optarg, NULL, 0);
7638 if (pp_timeout_val > 15) {
7639 warnx("%s: invalid partial pathway timeout "
7640 "value %u, need a value less than 16",
7641 __func__, pp_timeout_val);
7645 set_pp_timeout_val = 1;
7653 warnx("%s: a PHY (-p phy) argument is required",__func__);
7658 if (((dev_name_set != 0)
7659 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7660 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7661 && (dev_name_set == 0))) {
7662 warnx("%s: -d name and -o setdevname arguments both "
7663 "required to set device name", __func__);
7668 request = malloc(sizeof(*request));
7669 if (request == NULL) {
7670 warn("%s: unable to allocate %zd bytes", __func__,
7676 response = malloc(sizeof(*response));
7677 if (response == NULL) {
7678 warn("%s: unable to allocate %zd bytes", __func__,
7684 smp_phy_control(&ccb->smpio,
7689 (uint8_t *)response,
7692 /*expected_exp_change_count*/ 0,
7695 (set_pp_timeout_val != 0) ? 1 : 0,
7703 if (((retval = cam_send_ccb(device, ccb)) < 0)
7704 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7705 const char warnstr[] = "error sending command";
7712 if (arglist & CAM_ARG_VERBOSE) {
7714 * Use CAM_EPF_NORMAL so we only get one line of
7715 * SMP command decoding.
7717 cam_error_print(device, ccb, CAM_ESF_ALL,
7718 CAM_EPF_NORMAL, stderr);
7724 /* XXX KDM print out something here for success? */
7729 if (request != NULL)
7732 if (response != NULL)
7739 smpmaninfo(struct cam_device *device, int argc, char **argv,
7740 char *combinedopt, int retry_count, int timeout)
7743 struct smp_report_manuf_info_request request;
7744 struct smp_report_manuf_info_response response;
7745 struct sbuf *sb = NULL;
7746 int long_response = 0;
7751 * Note that at the moment we don't support sending SMP CCBs to
7752 * devices that aren't probed by CAM.
7754 ccb = cam_getccb(device);
7756 warnx("%s: error allocating CCB", __func__);
7760 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7762 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7771 bzero(&request, sizeof(request));
7772 bzero(&response, sizeof(response));
7774 smp_report_manuf_info(&ccb->smpio,
7779 (uint8_t *)&response,
7784 if (((retval = cam_send_ccb(device, ccb)) < 0)
7785 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7786 const char warnstr[] = "error sending command";
7793 if (arglist & CAM_ARG_VERBOSE) {
7794 cam_error_print(device, ccb, CAM_ESF_ALL,
7795 CAM_EPF_ALL, stderr);
7801 sb = sbuf_new_auto();
7803 warnx("%s: error allocating sbuf", __func__);
7807 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7809 if (sbuf_finish(sb) != 0) {
7810 warnx("%s: sbuf_finish", __func__);
7814 printf("%s", sbuf_data(sb));
7828 getdevid(struct cam_devitem *item)
7831 union ccb *ccb = NULL;
7833 struct cam_device *dev;
7835 dev = cam_open_btl(item->dev_match.path_id,
7836 item->dev_match.target_id,
7837 item->dev_match.target_lun, O_RDWR, NULL);
7840 warnx("%s", cam_errbuf);
7845 item->device_id_len = 0;
7847 ccb = cam_getccb(dev);
7849 warnx("%s: error allocating CCB", __func__);
7854 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7857 * On the first try, we just probe for the size of the data, and
7858 * then allocate that much memory and try again.
7861 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7862 ccb->ccb_h.flags = CAM_DIR_IN;
7863 ccb->cdai.flags = CDAI_FLAG_NONE;
7864 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7865 ccb->cdai.bufsiz = item->device_id_len;
7866 if (item->device_id_len != 0)
7867 ccb->cdai.buf = (uint8_t *)item->device_id;
7869 if (cam_send_ccb(dev, ccb) < 0) {
7870 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7875 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7876 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7881 if (item->device_id_len == 0) {
7883 * This is our first time through. Allocate the buffer,
7884 * and then go back to get the data.
7886 if (ccb->cdai.provsiz == 0) {
7887 warnx("%s: invalid .provsiz field returned with "
7888 "XPT_GDEV_ADVINFO CCB", __func__);
7892 item->device_id_len = ccb->cdai.provsiz;
7893 item->device_id = malloc(item->device_id_len);
7894 if (item->device_id == NULL) {
7895 warn("%s: unable to allocate %d bytes", __func__,
7896 item->device_id_len);
7900 ccb->ccb_h.status = CAM_REQ_INPROG;
7906 cam_close_device(dev);
7915 * XXX KDM merge this code with getdevtree()?
7918 buildbusdevlist(struct cam_devlist *devlist)
7921 int bufsize, fd = -1;
7922 struct dev_match_pattern *patterns;
7923 struct cam_devitem *item = NULL;
7924 int skip_device = 0;
7927 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7928 warn("couldn't open %s", XPT_DEVICE);
7932 bzero(&ccb, sizeof(union ccb));
7934 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7935 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7936 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7938 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7939 bufsize = sizeof(struct dev_match_result) * 100;
7940 ccb.cdm.match_buf_len = bufsize;
7941 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7942 if (ccb.cdm.matches == NULL) {
7943 warnx("can't malloc memory for matches");
7947 ccb.cdm.num_matches = 0;
7948 ccb.cdm.num_patterns = 2;
7949 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7950 ccb.cdm.num_patterns;
7952 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7953 if (patterns == NULL) {
7954 warnx("can't malloc memory for patterns");
7959 ccb.cdm.patterns = patterns;
7960 bzero(patterns, ccb.cdm.pattern_buf_len);
7962 patterns[0].type = DEV_MATCH_DEVICE;
7963 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7964 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7965 patterns[1].type = DEV_MATCH_PERIPH;
7966 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7967 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7970 * We do the ioctl multiple times if necessary, in case there are
7971 * more than 100 nodes in the EDT.
7976 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7977 warn("error sending CAMIOCOMMAND ioctl");
7982 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7983 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7984 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7985 warnx("got CAM error %#x, CDM error %d\n",
7986 ccb.ccb_h.status, ccb.cdm.status);
7991 for (i = 0; i < ccb.cdm.num_matches; i++) {
7992 switch (ccb.cdm.matches[i].type) {
7993 case DEV_MATCH_DEVICE: {
7994 struct device_match_result *dev_result;
7997 &ccb.cdm.matches[i].result.device_result;
7999 if (dev_result->flags &
8000 DEV_RESULT_UNCONFIGURED) {
8006 item = malloc(sizeof(*item));
8008 warn("%s: unable to allocate %zd bytes",
8009 __func__, sizeof(*item));
8013 bzero(item, sizeof(*item));
8014 bcopy(dev_result, &item->dev_match,
8015 sizeof(*dev_result));
8016 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8019 if (getdevid(item) != 0) {
8025 case DEV_MATCH_PERIPH: {
8026 struct periph_match_result *periph_result;
8029 &ccb.cdm.matches[i].result.periph_result;
8031 if (skip_device != 0)
8033 item->num_periphs++;
8034 item->periph_matches = realloc(
8035 item->periph_matches,
8037 sizeof(struct periph_match_result));
8038 if (item->periph_matches == NULL) {
8039 warn("%s: error allocating periph "
8044 bcopy(periph_result, &item->periph_matches[
8045 item->num_periphs - 1],
8046 sizeof(*periph_result));
8050 fprintf(stderr, "%s: unexpected match "
8051 "type %d\n", __func__,
8052 ccb.cdm.matches[i].type);
8055 break; /*NOTREACHED*/
8058 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8059 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8067 free(ccb.cdm.matches);
8070 freebusdevlist(devlist);
8076 freebusdevlist(struct cam_devlist *devlist)
8078 struct cam_devitem *item, *item2;
8080 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8081 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8083 free(item->device_id);
8084 free(item->periph_matches);
8089 static struct cam_devitem *
8090 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8092 struct cam_devitem *item;
8094 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8095 struct scsi_vpd_id_descriptor *idd;
8098 * XXX KDM look for LUN IDs as well?
8100 idd = scsi_get_devid(item->device_id,
8101 item->device_id_len,
8102 scsi_devid_is_sas_target);
8106 if (scsi_8btou64(idd->identifier) == sasaddr)
8114 smpphylist(struct cam_device *device, int argc, char **argv,
8115 char *combinedopt, int retry_count, int timeout)
8117 struct smp_report_general_request *rgrequest = NULL;
8118 struct smp_report_general_response *rgresponse = NULL;
8119 struct smp_discover_request *disrequest = NULL;
8120 struct smp_discover_response *disresponse = NULL;
8121 struct cam_devlist devlist;
8123 int long_response = 0;
8130 * Note that at the moment we don't support sending SMP CCBs to
8131 * devices that aren't probed by CAM.
8133 ccb = cam_getccb(device);
8135 warnx("%s: error allocating CCB", __func__);
8139 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8140 STAILQ_INIT(&devlist.dev_queue);
8142 rgrequest = malloc(sizeof(*rgrequest));
8143 if (rgrequest == NULL) {
8144 warn("%s: unable to allocate %zd bytes", __func__,
8145 sizeof(*rgrequest));
8150 rgresponse = malloc(sizeof(*rgresponse));
8151 if (rgresponse == NULL) {
8152 warn("%s: unable to allocate %zd bytes", __func__,
8153 sizeof(*rgresponse));
8158 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8171 smp_report_general(&ccb->smpio,
8175 /*request_len*/ sizeof(*rgrequest),
8176 (uint8_t *)rgresponse,
8177 /*response_len*/ sizeof(*rgresponse),
8178 /*long_response*/ long_response,
8181 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8183 if (((retval = cam_send_ccb(device, ccb)) < 0)
8184 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8185 const char warnstr[] = "error sending command";
8192 if (arglist & CAM_ARG_VERBOSE) {
8193 cam_error_print(device, ccb, CAM_ESF_ALL,
8194 CAM_EPF_ALL, stderr);
8200 num_phys = rgresponse->num_phys;
8202 if (num_phys == 0) {
8204 fprintf(stdout, "%s: No Phys reported\n", __func__);
8209 devlist.path_id = device->path_id;
8211 retval = buildbusdevlist(&devlist);
8216 fprintf(stdout, "%d PHYs:\n", num_phys);
8217 fprintf(stdout, "PHY Attached SAS Address\n");
8220 disrequest = malloc(sizeof(*disrequest));
8221 if (disrequest == NULL) {
8222 warn("%s: unable to allocate %zd bytes", __func__,
8223 sizeof(*disrequest));
8228 disresponse = malloc(sizeof(*disresponse));
8229 if (disresponse == NULL) {
8230 warn("%s: unable to allocate %zd bytes", __func__,
8231 sizeof(*disresponse));
8236 for (i = 0; i < num_phys; i++) {
8237 struct cam_devitem *item;
8238 struct device_match_result *dev_match;
8239 char vendor[16], product[48], revision[16];
8243 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8245 ccb->ccb_h.status = CAM_REQ_INPROG;
8246 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8248 smp_discover(&ccb->smpio,
8252 sizeof(*disrequest),
8253 (uint8_t *)disresponse,
8254 sizeof(*disresponse),
8256 /*ignore_zone_group*/ 0,
8260 if (((retval = cam_send_ccb(device, ccb)) < 0)
8261 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8262 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8263 const char warnstr[] = "error sending command";
8270 if (arglist & CAM_ARG_VERBOSE) {
8271 cam_error_print(device, ccb, CAM_ESF_ALL,
8272 CAM_EPF_ALL, stderr);
8278 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8280 fprintf(stdout, "%3d <vacant>\n", i);
8284 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8287 item = findsasdevice(&devlist,
8288 scsi_8btou64(disresponse->attached_sas_address));
8292 || (item != NULL)) {
8293 fprintf(stdout, "%3d 0x%016jx", i,
8294 (uintmax_t)scsi_8btou64(
8295 disresponse->attached_sas_address));
8297 fprintf(stdout, "\n");
8300 } else if (quiet != 0)
8303 dev_match = &item->dev_match;
8305 if (dev_match->protocol == PROTO_SCSI) {
8306 cam_strvis(vendor, dev_match->inq_data.vendor,
8307 sizeof(dev_match->inq_data.vendor),
8309 cam_strvis(product, dev_match->inq_data.product,
8310 sizeof(dev_match->inq_data.product),
8312 cam_strvis(revision, dev_match->inq_data.revision,
8313 sizeof(dev_match->inq_data.revision),
8315 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8317 } else if ((dev_match->protocol == PROTO_ATA)
8318 || (dev_match->protocol == PROTO_SATAPM)) {
8319 cam_strvis(product, dev_match->ident_data.model,
8320 sizeof(dev_match->ident_data.model),
8322 cam_strvis(revision, dev_match->ident_data.revision,
8323 sizeof(dev_match->ident_data.revision),
8325 sprintf(tmpstr, "<%s %s>", product, revision);
8327 sprintf(tmpstr, "<>");
8329 fprintf(stdout, " %-33s ", tmpstr);
8332 * If we have 0 periphs, that's a bug...
8334 if (item->num_periphs == 0) {
8335 fprintf(stdout, "\n");
8339 fprintf(stdout, "(");
8340 for (j = 0; j < item->num_periphs; j++) {
8342 fprintf(stdout, ",");
8344 fprintf(stdout, "%s%d",
8345 item->periph_matches[j].periph_name,
8346 item->periph_matches[j].unit_number);
8349 fprintf(stdout, ")\n");
8363 freebusdevlist(&devlist);
8369 atapm(struct cam_device *device, int argc, char **argv,
8370 char *combinedopt, int retry_count, int timeout)
8378 ccb = cam_getccb(device);
8381 warnx("%s: error allocating ccb", __func__);
8385 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8394 if (strcmp(argv[1], "idle") == 0) {
8396 cmd = ATA_IDLE_IMMEDIATE;
8399 } else if (strcmp(argv[1], "standby") == 0) {
8401 cmd = ATA_STANDBY_IMMEDIATE;
8403 cmd = ATA_STANDBY_CMD;
8411 else if (t <= (240 * 5))
8413 else if (t <= (252 * 5))
8414 /* special encoding for 21 minutes */
8416 else if (t <= (11 * 30 * 60))
8417 sc = (t - 1) / (30 * 60) + 241;
8421 retval = ata_do_28bit_cmd(device,
8423 /*retries*/retry_count,
8424 /*flags*/CAM_DIR_NONE,
8425 /*protocol*/AP_PROTO_NON_DATA,
8426 /*tag_action*/MSG_SIMPLE_Q_TAG,
8433 /*timeout*/timeout ? timeout : 30 * 1000,
8441 ataaxm(struct cam_device *device, int argc, char **argv,
8442 char *combinedopt, int retry_count, int timeout)
8450 ccb = cam_getccb(device);
8453 warnx("%s: error allocating ccb", __func__);
8457 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8467 if (strcmp(argv[1], "apm") == 0) {
8483 retval = ata_do_28bit_cmd(device,
8485 /*retries*/retry_count,
8486 /*flags*/CAM_DIR_NONE,
8487 /*protocol*/AP_PROTO_NON_DATA,
8488 /*tag_action*/MSG_SIMPLE_Q_TAG,
8489 /*command*/ATA_SETFEATURES,
8495 /*timeout*/timeout ? timeout : 30 * 1000,
8503 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8504 int show_sa_errors, int sa_set, int service_action,
8505 int timeout_desc, int task_attr, int retry_count, int timeout,
8506 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
8508 union ccb *ccb = NULL;
8509 uint8_t *buf = NULL;
8510 uint32_t alloc_len = 0, num_opcodes;
8511 uint32_t valid_len = 0;
8512 uint32_t avail_len = 0;
8513 struct scsi_report_supported_opcodes_all *all_hdr;
8514 struct scsi_report_supported_opcodes_one *one;
8519 * Make it clear that we haven't yet allocated or filled anything.
8524 ccb = cam_getccb(device);
8526 warnx("couldn't allocate CCB");
8531 /* cam_getccb cleans up the header, caller has to zero the payload */
8532 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8534 if (opcode_set != 0) {
8535 options |= RSO_OPTIONS_OC;
8537 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8540 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8541 sizeof(struct scsi_report_supported_opcodes_descr));
8544 if (timeout_desc != 0) {
8545 options |= RSO_RCTD;
8546 alloc_len += num_opcodes *
8547 sizeof(struct scsi_report_supported_opcodes_timeout);
8551 options |= RSO_OPTIONS_OC_SA;
8552 if (show_sa_errors != 0)
8553 options &= ~RSO_OPTIONS_OC;
8562 buf = malloc(alloc_len);
8564 warn("Unable to allocate %u bytes", alloc_len);
8568 bzero(buf, alloc_len);
8570 scsi_report_supported_opcodes(&ccb->csio,
8571 /*retries*/ retry_count,
8573 /*tag_action*/ task_attr,
8574 /*options*/ options,
8575 /*req_opcode*/ opcode,
8576 /*req_service_action*/ service_action,
8578 /*dxfer_len*/ alloc_len,
8579 /*sense_len*/ SSD_FULL_SIZE,
8580 /*timeout*/ timeout ? timeout : 10000);
8582 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8584 if (retry_count != 0)
8585 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8587 if (cam_send_ccb(device, ccb) < 0) {
8588 perror("error sending REPORT SUPPORTED OPERATION CODES");
8593 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8594 if (verbosemode != 0)
8595 cam_error_print(device, ccb, CAM_ESF_ALL,
8596 CAM_EPF_ALL, stderr);
8602 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8604 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8605 && (valid_len >= sizeof(*all_hdr))) {
8606 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8607 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8608 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8609 && (valid_len >= sizeof(*one))) {
8610 uint32_t cdb_length;
8612 one = (struct scsi_report_supported_opcodes_one *)buf;
8613 cdb_length = scsi_2btoul(one->cdb_length);
8614 avail_len = sizeof(*one) + cdb_length;
8615 if (one->support & RSO_ONE_CTDP) {
8616 struct scsi_report_supported_opcodes_timeout *td;
8618 td = (struct scsi_report_supported_opcodes_timeout *)
8620 if (valid_len >= (avail_len + sizeof(td->length))) {
8621 avail_len += scsi_2btoul(td->length) +
8624 avail_len += sizeof(*td);
8630 * avail_len could be zero if we didn't get enough data back from
8631 * thet target to determine
8633 if ((avail_len != 0)
8634 && (avail_len > valid_len)) {
8635 alloc_len = avail_len;
8639 *fill_len = valid_len;
8651 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8652 int req_sa, uint8_t *buf, uint32_t valid_len)
8654 struct scsi_report_supported_opcodes_one *one;
8655 struct scsi_report_supported_opcodes_timeout *td;
8656 uint32_t cdb_len = 0, td_len = 0;
8657 const char *op_desc = NULL;
8661 one = (struct scsi_report_supported_opcodes_one *)buf;
8664 * If we don't have the full single opcode descriptor, no point in
8667 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8669 warnx("Only %u bytes returned, not enough to verify support",
8675 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8677 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8680 printf(", SA 0x%x", req_sa);
8683 switch (one->support & RSO_ONE_SUP_MASK) {
8684 case RSO_ONE_SUP_UNAVAIL:
8685 printf("No command support information currently available\n");
8687 case RSO_ONE_SUP_NOT_SUP:
8688 printf("Command not supported\n");
8691 break; /*NOTREACHED*/
8692 case RSO_ONE_SUP_AVAIL:
8693 printf("Command is supported, complies with a SCSI standard\n");
8695 case RSO_ONE_SUP_VENDOR:
8696 printf("Command is supported, vendor-specific "
8697 "implementation\n");
8700 printf("Unknown command support flags 0x%#x\n",
8701 one->support & RSO_ONE_SUP_MASK);
8706 * If we don't have the CDB length, it isn't exactly an error, the
8707 * command probably isn't supported.
8709 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8713 cdb_len = scsi_2btoul(one->cdb_length);
8716 * If our valid data doesn't include the full reported length,
8717 * return. The caller should have detected this and adjusted his
8718 * allocation length to get all of the available data.
8720 if (valid_len < sizeof(*one) + cdb_len) {
8726 * If all we have is the opcode, there is no point in printing out
8734 printf("CDB usage bitmap:");
8735 for (i = 0; i < cdb_len; i++) {
8736 printf(" %02x", one->cdb_usage[i]);
8741 * If we don't have a timeout descriptor, we're done.
8743 if ((one->support & RSO_ONE_CTDP) == 0)
8747 * If we don't have enough valid length to include the timeout
8748 * descriptor length, we're done.
8750 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8753 td = (struct scsi_report_supported_opcodes_timeout *)
8754 &buf[sizeof(*one) + cdb_len];
8755 td_len = scsi_2btoul(td->length);
8756 td_len += sizeof(td->length);
8759 * If we don't have the full timeout descriptor, we're done.
8761 if (td_len < sizeof(*td))
8765 * If we don't have enough valid length to contain the full timeout
8766 * descriptor, we're done.
8768 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8771 printf("Timeout information:\n");
8772 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8773 printf("Nominal timeout: %u seconds\n",
8774 scsi_4btoul(td->nominal_time));
8775 printf("Recommended timeout: %u seconds\n",
8776 scsi_4btoul(td->recommended_time));
8783 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8786 struct scsi_report_supported_opcodes_all *hdr;
8787 struct scsi_report_supported_opcodes_descr *desc;
8788 uint32_t avail_len = 0, used_len = 0;
8792 if (valid_len < sizeof(*hdr)) {
8793 warnx("%s: not enough returned data (%u bytes) opcode list",
8794 __func__, valid_len);
8798 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8799 avail_len = scsi_4btoul(hdr->length);
8800 avail_len += sizeof(hdr->length);
8802 * Take the lesser of the amount of data the drive claims is
8803 * available, and the amount of data the HBA says was returned.
8805 avail_len = MIN(avail_len, valid_len);
8807 used_len = sizeof(hdr->length);
8809 printf("%-6s %4s %8s ",
8810 "Opcode", "SA", "CDB len" );
8813 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8814 printf(" Description\n");
8816 while ((avail_len - used_len) > sizeof(*desc)) {
8817 struct scsi_report_supported_opcodes_timeout *td;
8819 const char *op_desc = NULL;
8821 cur_ptr = &buf[used_len];
8822 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8824 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8825 if (op_desc == NULL)
8826 op_desc = "UNKNOWN";
8828 printf("0x%02x %#4x %8u ", desc->opcode,
8829 scsi_2btoul(desc->service_action),
8830 scsi_2btoul(desc->cdb_length));
8832 used_len += sizeof(*desc);
8834 if ((desc->flags & RSO_CTDP) == 0) {
8835 printf(" %s\n", op_desc);
8840 * If we don't have enough space to fit a timeout
8841 * descriptor, then we're done.
8843 if (avail_len - used_len < sizeof(*td)) {
8844 used_len = avail_len;
8845 printf(" %s\n", op_desc);
8848 cur_ptr = &buf[used_len];
8849 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8850 td_len = scsi_2btoul(td->length);
8851 td_len += sizeof(td->length);
8855 * If the given timeout descriptor length is less than what
8856 * we understand, skip it.
8858 if (td_len < sizeof(*td)) {
8859 printf(" %s\n", op_desc);
8863 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8864 scsi_4btoul(td->nominal_time),
8865 scsi_4btoul(td->recommended_time), op_desc);
8872 scsiopcodes(struct cam_device *device, int argc, char **argv,
8873 char *combinedopt, int task_attr, int retry_count, int timeout,
8877 uint32_t opcode = 0, service_action = 0;
8878 int td_set = 0, opcode_set = 0, sa_set = 0;
8879 int show_sa_errors = 1;
8880 uint32_t valid_len = 0;
8881 uint8_t *buf = NULL;
8885 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8891 opcode = strtoul(optarg, &endptr, 0);
8892 if (*endptr != '\0') {
8893 warnx("Invalid opcode \"%s\", must be a number",
8898 if (opcode > 0xff) {
8899 warnx("Invalid opcode 0x%#x, must be between"
8900 "0 and 0xff inclusive", opcode);
8907 service_action = strtoul(optarg, &endptr, 0);
8908 if (*endptr != '\0') {
8909 warnx("Invalid service action \"%s\", must "
8910 "be a number", optarg);
8914 if (service_action > 0xffff) {
8915 warnx("Invalid service action 0x%#x, must "
8916 "be between 0 and 0xffff inclusive",
8931 && (opcode_set == 0)) {
8932 warnx("You must specify an opcode with -o if a service "
8937 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8938 sa_set, service_action, td_set, task_attr,
8939 retry_count, timeout, verbosemode, &valid_len,
8944 if ((opcode_set != 0)
8946 retval = scsiprintoneopcode(device, opcode, sa_set,
8947 service_action, buf, valid_len);
8949 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8958 #endif /* MINIMALISTIC */
8961 scsireprobe(struct cam_device *device)
8966 ccb = cam_getccb(device);
8969 warnx("%s: error allocating ccb", __func__);
8973 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8975 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8977 if (cam_send_ccb(device, ccb) < 0) {
8978 warn("error sending XPT_REPROBE_LUN CCB");
8983 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8984 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8996 usage(int printlong)
8999 fprintf(printlong ? stdout : stderr,
9000 "usage: camcontrol <command> [device id][generic args][command args]\n"
9001 " camcontrol devlist [-b] [-v]\n"
9002 #ifndef MINIMALISTIC
9003 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9004 " camcontrol tur [dev_id][generic args]\n"
9005 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9006 " camcontrol identify [dev_id][generic args] [-v]\n"
9007 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9008 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9010 " camcontrol start [dev_id][generic args]\n"
9011 " camcontrol stop [dev_id][generic args]\n"
9012 " camcontrol load [dev_id][generic args]\n"
9013 " camcontrol eject [dev_id][generic args]\n"
9014 " camcontrol reprobe [dev_id][generic args]\n"
9015 #endif /* MINIMALISTIC */
9016 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9017 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9018 #ifndef MINIMALISTIC
9019 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9020 " [-q][-s][-S offset][-X]\n"
9021 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9022 " [-P pagectl][-e | -b][-d]\n"
9023 " camcontrol cmd [dev_id][generic args]\n"
9024 " <-a cmd [args] | -c cmd [args]>\n"
9025 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9026 " camcontrol smpcmd [dev_id][generic args]\n"
9027 " <-r len fmt [args]> <-R len fmt [args]>\n"
9028 " camcontrol smprg [dev_id][generic args][-l]\n"
9029 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9030 " [-o operation][-d name][-m rate][-M rate]\n"
9031 " [-T pp_timeout][-a enable|disable]\n"
9032 " [-A enable|disable][-s enable|disable]\n"
9033 " [-S enable|disable]\n"
9034 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9035 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9036 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9037 " <all|bus[:target[:lun]]|off>\n"
9038 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9039 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9040 " [-D <enable|disable>][-M mode][-O offset]\n"
9041 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9042 " [-U][-W bus_width]\n"
9043 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9044 " camcontrol sanitize [dev_id][generic args]\n"
9045 " [-a overwrite|block|crypto|exitfailure]\n"
9046 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9048 " camcontrol idle [dev_id][generic args][-t time]\n"
9049 " camcontrol standby [dev_id][generic args][-t time]\n"
9050 " camcontrol sleep [dev_id][generic args]\n"
9051 " camcontrol apm [dev_id][generic args][-l level]\n"
9052 " camcontrol aam [dev_id][generic args][-l level]\n"
9053 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9055 " camcontrol security [dev_id][generic args]\n"
9056 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9057 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9058 " [-U <user|master>] [-y]\n"
9059 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9060 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9061 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9062 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9063 " [-s scope][-S][-T type][-U]\n"
9064 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9065 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9066 " [-p part][-s start][-T type][-V vol]\n"
9067 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9069 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9070 " [-o rep_opts] [-P print_opts]\n"
9071 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9072 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9073 " [-S power_src] [-T timer]\n"
9074 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9075 " <-s <-f format -T time | -U >>\n"
9077 #endif /* MINIMALISTIC */
9078 " camcontrol help\n");
9081 #ifndef MINIMALISTIC
9083 "Specify one of the following options:\n"
9084 "devlist list all CAM devices\n"
9085 "periphlist list all CAM peripheral drivers attached to a device\n"
9086 "tur send a test unit ready to the named device\n"
9087 "inquiry send a SCSI inquiry command to the named device\n"
9088 "identify send a ATA identify command to the named device\n"
9089 "reportluns send a SCSI report luns command to the device\n"
9090 "readcap send a SCSI read capacity command to the device\n"
9091 "start send a Start Unit command to the device\n"
9092 "stop send a Stop Unit command to the device\n"
9093 "load send a Start Unit command to the device with the load bit set\n"
9094 "eject send a Stop Unit command to the device with the eject bit set\n"
9095 "reprobe update capacity information of the given device\n"
9096 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9097 "reset reset all buses, the given bus, bus:target:lun or device\n"
9098 "defects read the defect list of the specified device\n"
9099 "modepage display or edit (-e) the given mode page\n"
9100 "cmd send the given SCSI command, may need -i or -o as well\n"
9101 "smpcmd send the given SMP command, requires -o and -i\n"
9102 "smprg send the SMP Report General command\n"
9103 "smppc send the SMP PHY Control command, requires -p\n"
9104 "smpphylist display phys attached to a SAS expander\n"
9105 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9106 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9107 "tags report or set the number of transaction slots for a device\n"
9108 "negotiate report or set device negotiation parameters\n"
9109 "format send the SCSI FORMAT UNIT command to the named device\n"
9110 "sanitize send the SCSI SANITIZE command to the named device\n"
9111 "idle send the ATA IDLE command to the named device\n"
9112 "standby send the ATA STANDBY command to the named device\n"
9113 "sleep send the ATA SLEEP command to the named device\n"
9114 "fwdownload program firmware of the named device with the given image\n"
9115 "security report or send ATA security commands to the named device\n"
9116 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9117 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9118 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9119 "zone manage Zoned Block (Shingled) devices\n"
9120 "epc send ATA Extended Power Conditions commands\n"
9121 "timestamp report or set the device's timestamp\n"
9122 "help this message\n"
9123 "Device Identifiers:\n"
9124 "bus:target specify the bus and target, lun defaults to 0\n"
9125 "bus:target:lun specify the bus, target and lun\n"
9126 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9127 "Generic arguments:\n"
9128 "-v be verbose, print out sense information\n"
9129 "-t timeout command timeout in seconds, overrides default timeout\n"
9130 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9131 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9132 "-E have the kernel attempt to perform SCSI error recovery\n"
9133 "-C count specify the SCSI command retry count (needs -E to work)\n"
9134 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9135 "modepage arguments:\n"
9136 "-l list all available mode pages\n"
9137 "-m page specify the mode page to view or edit\n"
9138 "-e edit the specified mode page\n"
9139 "-b force view to binary mode\n"
9140 "-d disable block descriptors for mode sense\n"
9141 "-P pgctl page control field 0-3\n"
9142 "defects arguments:\n"
9143 "-f format specify defect list format (block, bfi or phys)\n"
9144 "-G get the grown defect list\n"
9145 "-P get the permanent defect list\n"
9146 "inquiry arguments:\n"
9147 "-D get the standard inquiry data\n"
9148 "-S get the serial number\n"
9149 "-R get the transfer rate, etc.\n"
9150 "reportluns arguments:\n"
9151 "-c only report a count of available LUNs\n"
9152 "-l only print out luns, and not a count\n"
9153 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9154 "readcap arguments\n"
9155 "-b only report the blocksize\n"
9156 "-h human readable device size, base 2\n"
9157 "-H human readable device size, base 10\n"
9158 "-N print the number of blocks instead of last block\n"
9159 "-q quiet, print numbers only\n"
9160 "-s only report the last block/device size\n"
9162 "-c cdb [args] specify the SCSI CDB\n"
9163 "-i len fmt specify input data and input data format\n"
9164 "-o len fmt [args] specify output data and output data fmt\n"
9165 "smpcmd arguments:\n"
9166 "-r len fmt [args] specify the SMP command to be sent\n"
9167 "-R len fmt [args] specify SMP response format\n"
9168 "smprg arguments:\n"
9169 "-l specify the long response format\n"
9170 "smppc arguments:\n"
9171 "-p phy specify the PHY to operate on\n"
9172 "-l specify the long request/response format\n"
9173 "-o operation specify the phy control operation\n"
9174 "-d name set the attached device name\n"
9175 "-m rate set the minimum physical link rate\n"
9176 "-M rate set the maximum physical link rate\n"
9177 "-T pp_timeout set the partial pathway timeout value\n"
9178 "-a enable|disable enable or disable SATA slumber\n"
9179 "-A enable|disable enable or disable SATA partial phy power\n"
9180 "-s enable|disable enable or disable SAS slumber\n"
9181 "-S enable|disable enable or disable SAS partial phy power\n"
9182 "smpphylist arguments:\n"
9183 "-l specify the long response format\n"
9184 "-q only print phys with attached devices\n"
9185 "smpmaninfo arguments:\n"
9186 "-l specify the long response format\n"
9187 "debug arguments:\n"
9188 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9189 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9190 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9191 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9193 "-N tags specify the number of tags to use for this device\n"
9194 "-q be quiet, don't report the number of tags\n"
9195 "-v report a number of tag-related parameters\n"
9196 "negotiate arguments:\n"
9197 "-a send a test unit ready after negotiation\n"
9198 "-c report/set current negotiation settings\n"
9199 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9200 "-M mode set ATA mode\n"
9201 "-O offset set command delay offset\n"
9202 "-q be quiet, don't report anything\n"
9203 "-R syncrate synchronization rate in MHz\n"
9204 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9205 "-U report/set user negotiation settings\n"
9206 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9207 "-v also print a Path Inquiry CCB for the controller\n"
9208 "format arguments:\n"
9209 "-q be quiet, don't print status messages\n"
9210 "-r run in report only mode\n"
9211 "-w don't send immediate format command\n"
9212 "-y don't ask any questions\n"
9213 "sanitize arguments:\n"
9214 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9215 "-c passes overwrite passes to perform (1 to 31)\n"
9216 "-I invert overwrite pattern after each pass\n"
9217 "-P pattern path to overwrite pattern file\n"
9218 "-q be quiet, don't print status messages\n"
9219 "-r run in report only mode\n"
9220 "-U run operation in unrestricted completion exit mode\n"
9221 "-w don't send immediate sanitize command\n"
9222 "-y don't ask any questions\n"
9223 "idle/standby arguments:\n"
9224 "-t <arg> number of seconds before respective state.\n"
9225 "fwdownload arguments:\n"
9226 "-f fw_image path to firmware image file\n"
9227 "-q don't print informational messages, only errors\n"
9228 "-s run in simulation mode\n"
9229 "-v print info for every firmware segment sent to device\n"
9230 "-y don't ask any questions\n"
9231 "security arguments:\n"
9232 "-d pwd disable security using the given password for the selected\n"
9234 "-e pwd erase the device using the given pwd for the selected user\n"
9235 "-f freeze the security configuration of the specified device\n"
9236 "-h pwd enhanced erase the device using the given pwd for the\n"
9238 "-k pwd unlock the device using the given pwd for the selected\n"
9240 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9241 "-q be quiet, do not print any status messages\n"
9242 "-s pwd password the device (enable security) using the given\n"
9243 " pwd for the selected user\n"
9244 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9245 "-U <user|master> specifies which user to set: user or master\n"
9246 "-y don't ask any questions\n"
9248 "-f freeze the HPA configuration of the device\n"
9249 "-l lock the HPA configuration of the device\n"
9250 "-P make the HPA max sectors persist\n"
9251 "-p pwd Set the HPA configuration password required for unlock\n"
9253 "-q be quiet, do not print any status messages\n"
9254 "-s sectors configures the maximum user accessible sectors of the\n"
9256 "-U pwd unlock the HPA configuration of the device\n"
9257 "-y don't ask any questions\n"
9258 "persist arguments:\n"
9259 "-i action specify read_keys, read_reservation, report_cap, or\n"
9260 " read_full_status\n"
9261 "-o action specify register, register_ignore, reserve, release,\n"
9262 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9263 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9264 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9265 "-k key specify the Reservation Key\n"
9266 "-K sa_key specify the Service Action Reservation Key\n"
9267 "-p set the Activate Persist Through Power Loss bit\n"
9268 "-R rtp specify the Relative Target Port\n"
9269 "-s scope specify the scope: lun, extent, element or a number\n"
9270 "-S specify Transport ID for register, requires -I\n"
9271 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9272 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9273 "-U unregister the current initiator for register_move\n"
9274 "attrib arguments:\n"
9275 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9277 "-w attr specify an attribute to write, one -w argument per attr\n"
9278 "-a attr_num only display this attribute number\n"
9279 "-c get cached attributes\n"
9280 "-e elem_addr request attributes for the given element in a changer\n"
9281 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9282 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9283 " field_none, field_desc, field_num, field_size, field_rw\n"
9284 "-p partition request attributes for the given partition\n"
9285 "-s start_attr request attributes starting at the given number\n"
9286 "-T elem_type specify the element type (used with -e)\n"
9287 "-V logical_vol specify the logical volume ID\n"
9288 "opcodes arguments:\n"
9289 "-o opcode specify the individual opcode to list\n"
9290 "-s service_action specify the service action for the opcode\n"
9291 "-N do not return SCSI error for unsupported SA\n"
9292 "-T request nominal and recommended timeout values\n"
9294 "-c cmd required: rz, open, close, finish, or rwp\n"
9295 "-a apply the action to all zones\n"
9296 "-l LBA specify the zone starting LBA\n"
9297 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9298 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9299 "-P print_opt report zones printing: normal, summary, script\n"
9301 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9302 " source, status, list\n"
9303 "-d disable power mode (timer, state)\n"
9304 "-D delayed entry (goto)\n"
9305 "-e enable power mode (timer, state)\n"
9306 "-H hold power mode (goto)\n"
9307 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9309 "-P only display power mode (status)\n"
9310 "-r rst_src restore settings from: default, saved (restore)\n"
9311 "-s save mode (timer, state, restore)\n"
9312 "-S power_src set power source: battery, nonbattery (source)\n"
9313 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9314 "timestamp arguments:\n"
9315 "-r report the timestamp of the device\n"
9316 "-f format report the timestamp of the device with the given\n"
9317 " strftime(3) format string\n"
9318 "-m report the timestamp of the device as milliseconds since\n"
9319 " January 1st, 1970\n"
9320 "-U report the time with UTC instead of the local time zone\n"
9321 "-s set the timestamp of the device\n"
9322 "-f format the format of the time string passed into strptime(3)\n"
9323 "-T time the time value passed into strptime(3)\n"
9324 "-U set the timestamp of the device to UTC time\n"
9326 #endif /* MINIMALISTIC */
9330 main(int argc, char **argv)
9333 char *device = NULL;
9335 struct cam_device *cam_dev = NULL;
9336 int timeout = 0, retry_count = 1;
9337 camcontrol_optret optreturn;
9339 const char *mainopt = "C:En:Q:t:u:v";
9340 const char *subopt = NULL;
9341 char combinedopt[256];
9342 int error = 0, optstart = 2;
9343 int task_attr = MSG_SIMPLE_Q_TAG;
9345 #ifndef MINIMALISTIC
9349 #endif /* MINIMALISTIC */
9351 cmdlist = CAM_CMD_NONE;
9352 arglist = CAM_ARG_NONE;
9360 * Get the base option.
9362 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9364 if (optreturn == CC_OR_AMBIGUOUS) {
9365 warnx("ambiguous option %s", argv[1]);
9368 } else if (optreturn == CC_OR_NOT_FOUND) {
9369 warnx("option %s not found", argv[1]);
9375 * Ahh, getopt(3) is a pain.
9377 * This is a gross hack. There really aren't many other good
9378 * options (excuse the pun) for parsing options in a situation like
9379 * this. getopt is kinda braindead, so you end up having to run
9380 * through the options twice, and give each invocation of getopt
9381 * the option string for the other invocation.
9383 * You would think that you could just have two groups of options.
9384 * The first group would get parsed by the first invocation of
9385 * getopt, and the second group would get parsed by the second
9386 * invocation of getopt. It doesn't quite work out that way. When
9387 * the first invocation of getopt finishes, it leaves optind pointing
9388 * to the argument _after_ the first argument in the second group.
9389 * So when the second invocation of getopt comes around, it doesn't
9390 * recognize the first argument it gets and then bails out.
9392 * A nice alternative would be to have a flag for getopt that says
9393 * "just keep parsing arguments even when you encounter an unknown
9394 * argument", but there isn't one. So there's no real clean way to
9395 * easily parse two sets of arguments without having one invocation
9396 * of getopt know about the other.
9398 * Without this hack, the first invocation of getopt would work as
9399 * long as the generic arguments are first, but the second invocation
9400 * (in the subfunction) would fail in one of two ways. In the case
9401 * where you don't set optreset, it would fail because optind may be
9402 * pointing to the argument after the one it should be pointing at.
9403 * In the case where you do set optreset, and reset optind, it would
9404 * fail because getopt would run into the first set of options, which
9405 * it doesn't understand.
9407 * All of this would "sort of" work if you could somehow figure out
9408 * whether optind had been incremented one option too far. The
9409 * mechanics of that, however, are more daunting than just giving
9410 * both invocations all of the expect options for either invocation.
9412 * Needless to say, I wouldn't mind if someone invented a better
9413 * (non-GPL!) command line parsing interface than getopt. I
9414 * wouldn't mind if someone added more knobs to getopt to make it
9415 * work better. Who knows, I may talk myself into doing it someday,
9416 * if the standards weenies let me. As it is, it just leads to
9417 * hackery like this and causes people to avoid it in some cases.
9419 * KDM, September 8th, 1998
9422 sprintf(combinedopt, "%s%s", mainopt, subopt);
9424 sprintf(combinedopt, "%s", mainopt);
9427 * For these options we do not parse optional device arguments and
9428 * we do not open a passthrough device.
9430 if ((cmdlist == CAM_CMD_RESCAN)
9431 || (cmdlist == CAM_CMD_RESET)
9432 || (cmdlist == CAM_CMD_DEVTREE)
9433 || (cmdlist == CAM_CMD_USAGE)
9434 || (cmdlist == CAM_CMD_DEBUG))
9437 #ifndef MINIMALISTIC
9439 && (argc > 2 && argv[2][0] != '-')) {
9443 if (isdigit(argv[2][0])) {
9444 /* device specified as bus:target[:lun] */
9445 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9447 errx(1, "numeric device specification must "
9448 "be either bus:target, or "
9450 /* default to 0 if lun was not specified */
9451 if ((arglist & CAM_ARG_LUN) == 0) {
9453 arglist |= CAM_ARG_LUN;
9457 if (cam_get_device(argv[2], name, sizeof name, &unit)
9459 errx(1, "%s", cam_errbuf);
9460 device = strdup(name);
9461 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9465 #endif /* MINIMALISTIC */
9467 * Start getopt processing at argv[2/3], since we've already
9468 * accepted argv[1..2] as the command name, and as a possible
9474 * Now we run through the argument list looking for generic
9475 * options, and ignoring options that possibly belong to
9478 while ((c = getopt(argc, argv, combinedopt))!= -1){
9481 retry_count = strtol(optarg, NULL, 0);
9482 if (retry_count < 0)
9483 errx(1, "retry count %d is < 0",
9485 arglist |= CAM_ARG_RETRIES;
9488 arglist |= CAM_ARG_ERR_RECOVER;
9491 arglist |= CAM_ARG_DEVICE;
9493 while (isspace(*tstr) && (*tstr != '\0'))
9495 device = (char *)strdup(tstr);
9499 int table_entry = 0;
9502 while (isspace(*tstr) && (*tstr != '\0'))
9504 if (isdigit(*tstr)) {
9505 task_attr = strtol(tstr, &endptr, 0);
9506 if (*endptr != '\0') {
9507 errx(1, "Invalid queue option "
9512 scsi_nv_status status;
9514 table_size = sizeof(task_attrs) /
9515 sizeof(task_attrs[0]);
9516 status = scsi_get_nv(task_attrs,
9517 table_size, tstr, &table_entry,
9518 SCSI_NV_FLAG_IG_CASE);
9519 if (status == SCSI_NV_FOUND)
9520 task_attr = task_attrs[
9523 errx(1, "%s option %s",
9524 (status == SCSI_NV_AMBIGUOUS)?
9525 "ambiguous" : "invalid",
9532 timeout = strtol(optarg, NULL, 0);
9534 errx(1, "invalid timeout %d", timeout);
9535 /* Convert the timeout from seconds to ms */
9537 arglist |= CAM_ARG_TIMEOUT;
9540 arglist |= CAM_ARG_UNIT;
9541 unit = strtol(optarg, NULL, 0);
9544 arglist |= CAM_ARG_VERBOSE;
9551 #ifndef MINIMALISTIC
9553 * For most commands we'll want to open the passthrough device
9554 * associated with the specified device. In the case of the rescan
9555 * commands, we don't use a passthrough device at all, just the
9556 * transport layer device.
9559 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9560 && (((arglist & CAM_ARG_DEVICE) == 0)
9561 || ((arglist & CAM_ARG_UNIT) == 0))) {
9562 errx(1, "subcommand \"%s\" requires a valid device "
9563 "identifier", argv[1]);
9566 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9567 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9568 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9570 errx(1,"%s", cam_errbuf);
9572 #endif /* MINIMALISTIC */
9575 * Reset optind to 2, and reset getopt, so these routines can parse
9576 * the arguments again.
9582 #ifndef MINIMALISTIC
9583 case CAM_CMD_DEVLIST:
9584 error = getdevlist(cam_dev);
9587 error = atahpa(cam_dev, retry_count, timeout,
9588 argc, argv, combinedopt);
9590 #endif /* MINIMALISTIC */
9591 case CAM_CMD_DEVTREE:
9592 error = getdevtree(argc, argv, combinedopt);
9594 #ifndef MINIMALISTIC
9596 error = testunitready(cam_dev, task_attr, retry_count,
9599 case CAM_CMD_INQUIRY:
9600 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9601 task_attr, retry_count, timeout);
9603 case CAM_CMD_IDENTIFY:
9604 error = ataidentify(cam_dev, retry_count, timeout);
9606 case CAM_CMD_STARTSTOP:
9607 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9608 arglist & CAM_ARG_EJECT, task_attr,
9609 retry_count, timeout);
9611 #endif /* MINIMALISTIC */
9612 case CAM_CMD_RESCAN:
9613 error = dorescan_or_reset(argc, argv, 1);
9616 error = dorescan_or_reset(argc, argv, 0);
9618 #ifndef MINIMALISTIC
9619 case CAM_CMD_READ_DEFECTS:
9620 error = readdefects(cam_dev, argc, argv, combinedopt,
9621 task_attr, retry_count, timeout);
9623 case CAM_CMD_MODE_PAGE:
9624 modepage(cam_dev, argc, argv, combinedopt,
9625 task_attr, retry_count, timeout);
9627 case CAM_CMD_SCSI_CMD:
9628 error = scsicmd(cam_dev, argc, argv, combinedopt,
9629 task_attr, retry_count, timeout);
9631 case CAM_CMD_SMP_CMD:
9632 error = smpcmd(cam_dev, argc, argv, combinedopt,
9633 retry_count, timeout);
9635 case CAM_CMD_SMP_RG:
9636 error = smpreportgeneral(cam_dev, argc, argv,
9637 combinedopt, retry_count,
9640 case CAM_CMD_SMP_PC:
9641 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9642 retry_count, timeout);
9644 case CAM_CMD_SMP_PHYLIST:
9645 error = smpphylist(cam_dev, argc, argv, combinedopt,
9646 retry_count, timeout);
9648 case CAM_CMD_SMP_MANINFO:
9649 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9650 retry_count, timeout);
9653 error = camdebug(argc, argv, combinedopt);
9656 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9659 error = ratecontrol(cam_dev, task_attr, retry_count,
9660 timeout, argc, argv, combinedopt);
9662 case CAM_CMD_FORMAT:
9663 error = scsiformat(cam_dev, argc, argv,
9664 combinedopt, task_attr, retry_count,
9667 case CAM_CMD_REPORTLUNS:
9668 error = scsireportluns(cam_dev, argc, argv,
9669 combinedopt, task_attr,
9670 retry_count, timeout);
9672 case CAM_CMD_READCAP:
9673 error = scsireadcapacity(cam_dev, argc, argv,
9674 combinedopt, task_attr,
9675 retry_count, timeout);
9678 case CAM_CMD_STANDBY:
9680 error = atapm(cam_dev, argc, argv,
9681 combinedopt, retry_count, timeout);
9685 error = ataaxm(cam_dev, argc, argv,
9686 combinedopt, retry_count, timeout);
9688 case CAM_CMD_SECURITY:
9689 error = atasecurity(cam_dev, retry_count, timeout,
9690 argc, argv, combinedopt);
9692 case CAM_CMD_DOWNLOAD_FW:
9693 error = fwdownload(cam_dev, argc, argv, combinedopt,
9694 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
9697 case CAM_CMD_SANITIZE:
9698 error = scsisanitize(cam_dev, argc, argv,
9699 combinedopt, task_attr,
9700 retry_count, timeout);
9702 case CAM_CMD_PERSIST:
9703 error = scsipersist(cam_dev, argc, argv, combinedopt,
9704 task_attr, retry_count, timeout,
9705 arglist & CAM_ARG_VERBOSE,
9706 arglist & CAM_ARG_ERR_RECOVER);
9708 case CAM_CMD_ATTRIB:
9709 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9710 task_attr, retry_count, timeout,
9711 arglist & CAM_ARG_VERBOSE,
9712 arglist & CAM_ARG_ERR_RECOVER);
9714 case CAM_CMD_OPCODES:
9715 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9716 task_attr, retry_count, timeout,
9717 arglist & CAM_ARG_VERBOSE);
9719 case CAM_CMD_REPROBE:
9720 error = scsireprobe(cam_dev);
9723 error = zone(cam_dev, argc, argv, combinedopt,
9724 task_attr, retry_count, timeout,
9725 arglist & CAM_ARG_VERBOSE);
9728 error = epc(cam_dev, argc, argv, combinedopt,
9729 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9731 case CAM_CMD_TIMESTAMP:
9732 error = timestamp(cam_dev, argc, argv, combinedopt,
9733 task_attr, retry_count, timeout,
9734 arglist & CAM_ARG_VERBOSE);
9736 #endif /* MINIMALISTIC */
9746 if (cam_dev != NULL)
9747 cam_close_device(cam_dev);