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
108 CAM_ARG_NONE = 0x00000000,
109 CAM_ARG_VERBOSE = 0x00000001,
110 CAM_ARG_DEVICE = 0x00000002,
111 CAM_ARG_BUS = 0x00000004,
112 CAM_ARG_TARGET = 0x00000008,
113 CAM_ARG_LUN = 0x00000010,
114 CAM_ARG_EJECT = 0x00000020,
115 CAM_ARG_UNIT = 0x00000040,
116 CAM_ARG_FORMAT_BLOCK = 0x00000080,
117 CAM_ARG_FORMAT_BFI = 0x00000100,
118 CAM_ARG_FORMAT_PHYS = 0x00000200,
119 CAM_ARG_PLIST = 0x00000400,
120 CAM_ARG_GLIST = 0x00000800,
121 CAM_ARG_GET_SERIAL = 0x00001000,
122 CAM_ARG_GET_STDINQ = 0x00002000,
123 CAM_ARG_GET_XFERRATE = 0x00004000,
124 CAM_ARG_INQ_MASK = 0x00007000,
125 CAM_ARG_TIMEOUT = 0x00020000,
126 CAM_ARG_CMD_IN = 0x00040000,
127 CAM_ARG_CMD_OUT = 0x00080000,
128 CAM_ARG_ERR_RECOVER = 0x00200000,
129 CAM_ARG_RETRIES = 0x00400000,
130 CAM_ARG_START_UNIT = 0x00800000,
131 CAM_ARG_DEBUG_INFO = 0x01000000,
132 CAM_ARG_DEBUG_TRACE = 0x02000000,
133 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
134 CAM_ARG_DEBUG_CDB = 0x08000000,
135 CAM_ARG_DEBUG_XPT = 0x10000000,
136 CAM_ARG_DEBUG_PERIPH = 0x20000000,
137 CAM_ARG_DEBUG_PROBE = 0x40000000,
140 struct camcontrol_opts {
148 struct ata_res_pass16 {
149 u_int16_t reserved[5];
152 u_int8_t sector_count_exp;
153 u_int8_t sector_count;
154 u_int8_t lba_low_exp;
156 u_int8_t lba_mid_exp;
158 u_int8_t lba_high_exp;
164 struct ata_set_max_pwd
167 u_int8_t password[32];
168 u_int16_t reserved2[239];
171 static struct scsi_nv task_attrs[] = {
172 { "simple", MSG_SIMPLE_Q_TAG },
173 { "head", MSG_HEAD_OF_Q_TAG },
174 { "ordered", MSG_ORDERED_Q_TAG },
175 { "iwr", MSG_IGN_WIDE_RESIDUE },
176 { "aca", MSG_ACA_TASK }
179 static const char scsicmd_opts[] = "a:c:dfi:o:r";
180 static const char readdefect_opts[] = "f:GPqsS:X";
181 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
182 static const char smprg_opts[] = "l";
183 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
184 static const char smpphylist_opts[] = "lq";
188 static struct camcontrol_opts option_table[] = {
190 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
191 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
192 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
193 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
194 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
195 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
196 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
197 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
198 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
199 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
200 #endif /* MINIMALISTIC */
201 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
202 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
204 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
205 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
206 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
207 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
208 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
209 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
210 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
211 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
212 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
213 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
214 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
215 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
216 #endif /* MINIMALISTIC */
217 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
219 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
220 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
221 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
222 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
223 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
224 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
225 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
226 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
227 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
228 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
229 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
230 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
231 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
232 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
233 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
234 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
235 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
236 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
237 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
238 #endif /* MINIMALISTIC */
239 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
240 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
241 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
246 struct device_match_result dev_match;
248 struct periph_match_result *periph_matches;
249 struct scsi_vpd_device_id *device_id;
251 STAILQ_ENTRY(cam_devitem) links;
255 STAILQ_HEAD(, cam_devitem) dev_queue;
259 static cam_cmdmask cmdlist;
260 static cam_argmask arglist;
262 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
263 uint32_t *cmdnum, cam_argmask *argnum,
264 const char **subopt);
266 static int getdevlist(struct cam_device *device);
267 #endif /* MINIMALISTIC */
268 static int getdevtree(int argc, char **argv, char *combinedopt);
270 static int testunitready(struct cam_device *device, int task_attr,
271 int retry_count, int timeout, int quiet);
272 static int scsistart(struct cam_device *device, int startstop, int loadeject,
273 int task_attr, int retry_count, int timeout);
274 static int scsiinquiry(struct cam_device *device, int task_attr,
275 int retry_count, int timeout);
276 static int scsiserial(struct cam_device *device, int task_attr,
277 int retry_count, int timeout);
278 #endif /* MINIMALISTIC */
279 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
280 lun_id_t *lun, cam_argmask *arglst);
281 static int dorescan_or_reset(int argc, char **argv, int rescan);
282 static int rescan_or_reset_bus(path_id_t bus, int rescan);
283 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
284 lun_id_t lun, int scan);
286 static int readdefects(struct cam_device *device, int argc, char **argv,
287 char *combinedopt, int task_attr, int retry_count,
289 static void modepage(struct cam_device *device, int argc, char **argv,
290 char *combinedopt, int task_attr, int retry_count,
292 static int scsicmd(struct cam_device *device, int argc, char **argv,
293 char *combinedopt, int task_attr, int retry_count,
295 static int smpcmd(struct cam_device *device, int argc, char **argv,
296 char *combinedopt, int retry_count, int timeout);
297 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
298 char *combinedopt, int retry_count, int timeout);
299 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
300 char *combinedopt, int retry_count, int timeout);
301 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
302 char *combinedopt, int retry_count, int timeout);
303 static int getdevid(struct cam_devitem *item);
304 static int buildbusdevlist(struct cam_devlist *devlist);
305 static void freebusdevlist(struct cam_devlist *devlist);
306 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
308 static int smpphylist(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int retry_count, int timeout);
310 static int tagcontrol(struct cam_device *device, int argc, char **argv,
312 static void cts_print(struct cam_device *device,
313 struct ccb_trans_settings *cts);
314 static void cpi_print(struct ccb_pathinq *cpi);
315 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
316 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
317 static int get_print_cts(struct cam_device *device, int user_settings,
318 int quiet, struct ccb_trans_settings *cts);
319 static int ratecontrol(struct cam_device *device, int task_attr,
320 int retry_count, int timeout, int argc, char **argv,
322 static int scsiformat(struct cam_device *device, int argc, char **argv,
323 char *combinedopt, int task_attr, int retry_count,
325 static int scsisanitize(struct cam_device *device, int argc, char **argv,
326 char *combinedopt, int task_attr, int retry_count,
328 static int scsireportluns(struct cam_device *device, int argc, char **argv,
329 char *combinedopt, int task_attr, int retry_count,
331 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
332 char *combinedopt, int task_attr, int retry_count,
334 static int atapm(struct cam_device *device, int argc, char **argv,
335 char *combinedopt, int retry_count, int timeout);
336 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
337 int argc, char **argv, char *combinedopt);
338 static int atahpa(struct cam_device *device, int retry_count, int timeout,
339 int argc, char **argv, char *combinedopt);
340 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
341 int sa_set, int req_sa, uint8_t *buf,
343 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
345 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
346 char *combinedopt, int task_attr, int retry_count,
347 int timeout, int verbose);
348 static int scsireprobe(struct cam_device *device);
350 #endif /* MINIMALISTIC */
352 #define min(a,b) (((a)<(b))?(a):(b))
355 #define max(a,b) (((a)>(b))?(a):(b))
359 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
360 cam_argmask *argnum, const char **subopt)
362 struct camcontrol_opts *opts;
365 for (opts = table; (opts != NULL) && (opts->optname != NULL);
367 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
368 *cmdnum = opts->cmdnum;
369 *argnum = opts->argnum;
370 *subopt = opts->subopt;
371 if (++num_matches > 1)
372 return(CC_OR_AMBIGUOUS);
379 return(CC_OR_NOT_FOUND);
384 getdevlist(struct cam_device *device)
390 ccb = cam_getccb(device);
392 ccb->ccb_h.func_code = XPT_GDEVLIST;
393 ccb->ccb_h.flags = CAM_DIR_NONE;
394 ccb->ccb_h.retry_count = 1;
396 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
397 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
398 if (cam_send_ccb(device, ccb) < 0) {
399 perror("error getting device list");
406 switch (ccb->cgdl.status) {
407 case CAM_GDEVLIST_MORE_DEVS:
408 strcpy(status, "MORE");
410 case CAM_GDEVLIST_LAST_DEVICE:
411 strcpy(status, "LAST");
413 case CAM_GDEVLIST_LIST_CHANGED:
414 strcpy(status, "CHANGED");
416 case CAM_GDEVLIST_ERROR:
417 strcpy(status, "ERROR");
422 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
423 ccb->cgdl.periph_name,
424 ccb->cgdl.unit_number,
425 ccb->cgdl.generation,
430 * If the list has changed, we need to start over from the
433 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
441 #endif /* MINIMALISTIC */
444 getdevtree(int argc, char **argv, char *combinedopt)
455 while ((c = getopt(argc, argv, combinedopt)) != -1) {
458 if ((arglist & CAM_ARG_VERBOSE) == 0)
466 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
467 warn("couldn't open %s", XPT_DEVICE);
471 bzero(&ccb, sizeof(union ccb));
473 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
474 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
475 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
477 ccb.ccb_h.func_code = XPT_DEV_MATCH;
478 bufsize = sizeof(struct dev_match_result) * 100;
479 ccb.cdm.match_buf_len = bufsize;
480 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
481 if (ccb.cdm.matches == NULL) {
482 warnx("can't malloc memory for matches");
486 ccb.cdm.num_matches = 0;
489 * We fetch all nodes, since we display most of them in the default
490 * case, and all in the verbose case.
492 ccb.cdm.num_patterns = 0;
493 ccb.cdm.pattern_buf_len = 0;
496 * We do the ioctl multiple times if necessary, in case there are
497 * more than 100 nodes in the EDT.
500 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
501 warn("error sending CAMIOCOMMAND ioctl");
506 if ((ccb.ccb_h.status != CAM_REQ_CMP)
507 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
508 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
509 warnx("got CAM error %#x, CDM error %d\n",
510 ccb.ccb_h.status, ccb.cdm.status);
515 for (i = 0; i < ccb.cdm.num_matches; i++) {
516 switch (ccb.cdm.matches[i].type) {
517 case DEV_MATCH_BUS: {
518 struct bus_match_result *bus_result;
521 * Only print the bus information if the
522 * user turns on the verbose flag.
524 if ((busonly == 0) &&
525 (arglist & CAM_ARG_VERBOSE) == 0)
529 &ccb.cdm.matches[i].result.bus_result;
532 fprintf(stdout, ")\n");
536 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
538 bus_result->dev_name,
539 bus_result->unit_number,
541 (busonly ? "" : ":"));
544 case DEV_MATCH_DEVICE: {
545 struct device_match_result *dev_result;
546 char vendor[16], product[48], revision[16];
547 char fw[5], tmpstr[256];
553 &ccb.cdm.matches[i].result.device_result;
555 if ((dev_result->flags
556 & DEV_RESULT_UNCONFIGURED)
557 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
563 if (dev_result->protocol == PROTO_SCSI) {
564 cam_strvis(vendor, dev_result->inq_data.vendor,
565 sizeof(dev_result->inq_data.vendor),
568 dev_result->inq_data.product,
569 sizeof(dev_result->inq_data.product),
572 dev_result->inq_data.revision,
573 sizeof(dev_result->inq_data.revision),
575 sprintf(tmpstr, "<%s %s %s>", vendor, product,
577 } else if (dev_result->protocol == PROTO_ATA ||
578 dev_result->protocol == PROTO_SATAPM) {
580 dev_result->ident_data.model,
581 sizeof(dev_result->ident_data.model),
584 dev_result->ident_data.revision,
585 sizeof(dev_result->ident_data.revision),
587 sprintf(tmpstr, "<%s %s>", product,
589 } else if (dev_result->protocol == PROTO_SEMB) {
590 struct sep_identify_data *sid;
592 sid = (struct sep_identify_data *)
593 &dev_result->ident_data;
594 cam_strvis(vendor, sid->vendor_id,
595 sizeof(sid->vendor_id),
597 cam_strvis(product, sid->product_id,
598 sizeof(sid->product_id),
600 cam_strvis(revision, sid->product_rev,
601 sizeof(sid->product_rev),
603 cam_strvis(fw, sid->firmware_rev,
604 sizeof(sid->firmware_rev),
606 sprintf(tmpstr, "<%s %s %s %s>",
607 vendor, product, revision, fw);
609 sprintf(tmpstr, "<>");
612 fprintf(stdout, ")\n");
616 fprintf(stdout, "%-33s at scbus%d "
617 "target %d lun %jx (",
620 dev_result->target_id,
621 (uintmax_t)dev_result->target_lun);
627 case DEV_MATCH_PERIPH: {
628 struct periph_match_result *periph_result;
631 &ccb.cdm.matches[i].result.periph_result;
633 if (busonly || skip_device != 0)
637 fprintf(stdout, ",");
639 fprintf(stdout, "%s%d",
640 periph_result->periph_name,
641 periph_result->unit_number);
647 fprintf(stdout, "unknown match type\n");
652 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
653 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
656 fprintf(stdout, ")\n");
665 testunitready(struct cam_device *device, int task_attr, int retry_count,
666 int timeout, int quiet)
671 ccb = cam_getccb(device);
673 scsi_test_unit_ready(&ccb->csio,
674 /* retries */ retry_count,
676 /* tag_action */ task_attr,
677 /* sense_len */ SSD_FULL_SIZE,
678 /* timeout */ timeout ? timeout : 5000);
680 /* Disable freezing the device queue */
681 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
683 if (arglist & CAM_ARG_ERR_RECOVER)
684 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
686 if (cam_send_ccb(device, ccb) < 0) {
688 perror("error sending test unit ready");
690 if (arglist & CAM_ARG_VERBOSE) {
691 cam_error_print(device, ccb, CAM_ESF_ALL,
692 CAM_EPF_ALL, stderr);
699 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
701 fprintf(stdout, "Unit is ready\n");
704 fprintf(stdout, "Unit is not ready\n");
707 if (arglist & CAM_ARG_VERBOSE) {
708 cam_error_print(device, ccb, CAM_ESF_ALL,
709 CAM_EPF_ALL, stderr);
719 scsistart(struct cam_device *device, int startstop, int loadeject,
720 int task_attr, int retry_count, int timeout)
725 ccb = cam_getccb(device);
728 * If we're stopping, send an ordered tag so the drive in question
729 * will finish any previously queued writes before stopping. If
730 * the device isn't capable of tagged queueing, or if tagged
731 * queueing is turned off, the tag action is a no-op. We override
732 * the default simple tag, although this also has the effect of
733 * overriding the user's wishes if he wanted to specify a simple
737 && (task_attr == MSG_SIMPLE_Q_TAG))
738 task_attr = MSG_ORDERED_Q_TAG;
740 scsi_start_stop(&ccb->csio,
741 /* retries */ retry_count,
743 /* tag_action */ task_attr,
744 /* start/stop */ startstop,
745 /* load_eject */ loadeject,
747 /* sense_len */ SSD_FULL_SIZE,
748 /* timeout */ timeout ? timeout : 120000);
750 /* Disable freezing the device queue */
751 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
753 if (arglist & CAM_ARG_ERR_RECOVER)
754 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
756 if (cam_send_ccb(device, ccb) < 0) {
757 perror("error sending start unit");
759 if (arglist & CAM_ARG_VERBOSE) {
760 cam_error_print(device, ccb, CAM_ESF_ALL,
761 CAM_EPF_ALL, stderr);
768 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
770 fprintf(stdout, "Unit started successfully");
772 fprintf(stdout,", Media loaded\n");
774 fprintf(stdout,"\n");
776 fprintf(stdout, "Unit stopped successfully");
778 fprintf(stdout, ", Media ejected\n");
780 fprintf(stdout, "\n");
786 "Error received from start unit command\n");
789 "Error received from stop unit command\n");
791 if (arglist & CAM_ARG_VERBOSE) {
792 cam_error_print(device, ccb, CAM_ESF_ALL,
793 CAM_EPF_ALL, stderr);
803 scsidoinquiry(struct cam_device *device, int argc, char **argv,
804 char *combinedopt, int task_attr, int retry_count, int timeout)
809 while ((c = getopt(argc, argv, combinedopt)) != -1) {
812 arglist |= CAM_ARG_GET_STDINQ;
815 arglist |= CAM_ARG_GET_XFERRATE;
818 arglist |= CAM_ARG_GET_SERIAL;
826 * If the user didn't specify any inquiry options, he wants all of
829 if ((arglist & CAM_ARG_INQ_MASK) == 0)
830 arglist |= CAM_ARG_INQ_MASK;
832 if (arglist & CAM_ARG_GET_STDINQ)
833 error = scsiinquiry(device, task_attr, retry_count, timeout);
838 if (arglist & CAM_ARG_GET_SERIAL)
839 scsiserial(device, task_attr, retry_count, timeout);
841 if (arglist & CAM_ARG_GET_XFERRATE)
842 error = camxferrate(device);
848 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
852 struct scsi_inquiry_data *inq_buf;
855 ccb = cam_getccb(device);
858 warnx("couldn't allocate CCB");
862 /* cam_getccb cleans up the header, caller has to zero the payload */
863 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
865 inq_buf = (struct scsi_inquiry_data *)malloc(
866 sizeof(struct scsi_inquiry_data));
868 if (inq_buf == NULL) {
870 warnx("can't malloc memory for inquiry\n");
873 bzero(inq_buf, sizeof(*inq_buf));
876 * Note that although the size of the inquiry buffer is the full
877 * 256 bytes specified in the SCSI spec, we only tell the device
878 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
879 * two reasons for this:
881 * - The SCSI spec says that when a length field is only 1 byte,
882 * a value of 0 will be interpreted as 256. Therefore
883 * scsi_inquiry() will convert an inq_len (which is passed in as
884 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
885 * to 0. Evidently, very few devices meet the spec in that
886 * regard. Some devices, like many Seagate disks, take the 0 as
887 * 0, and don't return any data. One Pioneer DVD-R drive
888 * returns more data than the command asked for.
890 * So, since there are numerous devices that just don't work
891 * right with the full inquiry size, we don't send the full size.
893 * - The second reason not to use the full inquiry data length is
894 * that we don't need it here. The only reason we issue a
895 * standard inquiry is to get the vendor name, device name,
896 * and revision so scsi_print_inquiry() can print them.
898 * If, at some point in the future, more inquiry data is needed for
899 * some reason, this code should use a procedure similar to the
900 * probe code. i.e., issue a short inquiry, and determine from
901 * the additional length passed back from the device how much
902 * inquiry data the device supports. Once the amount the device
903 * supports is determined, issue an inquiry for that amount and no
908 scsi_inquiry(&ccb->csio,
909 /* retries */ retry_count,
911 /* tag_action */ task_attr,
912 /* inq_buf */ (u_int8_t *)inq_buf,
913 /* inq_len */ SHORT_INQUIRY_LENGTH,
916 /* sense_len */ SSD_FULL_SIZE,
917 /* timeout */ timeout ? timeout : 5000);
919 /* Disable freezing the device queue */
920 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
922 if (arglist & CAM_ARG_ERR_RECOVER)
923 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
925 if (cam_send_ccb(device, ccb) < 0) {
926 perror("error sending SCSI inquiry");
928 if (arglist & CAM_ARG_VERBOSE) {
929 cam_error_print(device, ccb, CAM_ESF_ALL,
930 CAM_EPF_ALL, stderr);
937 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
940 if (arglist & CAM_ARG_VERBOSE) {
941 cam_error_print(device, ccb, CAM_ESF_ALL,
942 CAM_EPF_ALL, stderr);
953 fprintf(stdout, "%s%d: ", device->device_name,
954 device->dev_unit_num);
955 scsi_print_inquiry(inq_buf);
963 scsiserial(struct cam_device *device, int task_attr, int retry_count,
967 struct scsi_vpd_unit_serial_number *serial_buf;
968 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
971 ccb = cam_getccb(device);
974 warnx("couldn't allocate CCB");
978 /* cam_getccb cleans up the header, caller has to zero the payload */
979 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
981 serial_buf = (struct scsi_vpd_unit_serial_number *)
982 malloc(sizeof(*serial_buf));
984 if (serial_buf == NULL) {
986 warnx("can't malloc memory for serial number");
990 scsi_inquiry(&ccb->csio,
991 /*retries*/ retry_count,
993 /* tag_action */ task_attr,
994 /* inq_buf */ (u_int8_t *)serial_buf,
995 /* inq_len */ sizeof(*serial_buf),
997 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
998 /* sense_len */ SSD_FULL_SIZE,
999 /* timeout */ timeout ? timeout : 5000);
1001 /* Disable freezing the device queue */
1002 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1004 if (arglist & CAM_ARG_ERR_RECOVER)
1005 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1007 if (cam_send_ccb(device, ccb) < 0) {
1008 warn("error getting serial number");
1010 if (arglist & CAM_ARG_VERBOSE) {
1011 cam_error_print(device, ccb, CAM_ESF_ALL,
1012 CAM_EPF_ALL, stderr);
1020 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1023 if (arglist & CAM_ARG_VERBOSE) {
1024 cam_error_print(device, ccb, CAM_ESF_ALL,
1025 CAM_EPF_ALL, stderr);
1036 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1037 serial_num[serial_buf->length] = '\0';
1039 if ((arglist & CAM_ARG_GET_STDINQ)
1040 || (arglist & CAM_ARG_GET_XFERRATE))
1041 fprintf(stdout, "%s%d: Serial Number ",
1042 device->device_name, device->dev_unit_num);
1044 fprintf(stdout, "%.60s\n", serial_num);
1052 camxferrate(struct cam_device *device)
1054 struct ccb_pathinq cpi;
1056 u_int32_t speed = 0;
1061 if ((retval = get_cpi(device, &cpi)) != 0)
1064 ccb = cam_getccb(device);
1067 warnx("couldn't allocate CCB");
1071 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1073 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1074 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1076 if (((retval = cam_send_ccb(device, ccb)) < 0)
1077 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1078 const char error_string[] = "error getting transfer settings";
1083 warnx(error_string);
1085 if (arglist & CAM_ARG_VERBOSE)
1086 cam_error_print(device, ccb, CAM_ESF_ALL,
1087 CAM_EPF_ALL, stderr);
1091 goto xferrate_bailout;
1095 speed = cpi.base_transfer_speed;
1097 if (ccb->cts.transport == XPORT_SPI) {
1098 struct ccb_trans_settings_spi *spi =
1099 &ccb->cts.xport_specific.spi;
1101 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1102 freq = scsi_calc_syncsrate(spi->sync_period);
1105 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1106 speed *= (0x01 << spi->bus_width);
1108 } else if (ccb->cts.transport == XPORT_FC) {
1109 struct ccb_trans_settings_fc *fc =
1110 &ccb->cts.xport_specific.fc;
1112 if (fc->valid & CTS_FC_VALID_SPEED)
1113 speed = fc->bitrate;
1114 } else if (ccb->cts.transport == XPORT_SAS) {
1115 struct ccb_trans_settings_sas *sas =
1116 &ccb->cts.xport_specific.sas;
1118 if (sas->valid & CTS_SAS_VALID_SPEED)
1119 speed = sas->bitrate;
1120 } else if (ccb->cts.transport == XPORT_ATA) {
1121 struct ccb_trans_settings_pata *pata =
1122 &ccb->cts.xport_specific.ata;
1124 if (pata->valid & CTS_ATA_VALID_MODE)
1125 speed = ata_mode2speed(pata->mode);
1126 } else if (ccb->cts.transport == XPORT_SATA) {
1127 struct ccb_trans_settings_sata *sata =
1128 &ccb->cts.xport_specific.sata;
1130 if (sata->valid & CTS_SATA_VALID_REVISION)
1131 speed = ata_revision2speed(sata->revision);
1136 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1137 device->device_name, device->dev_unit_num,
1140 fprintf(stdout, "%s%d: %dKB/s transfers",
1141 device->device_name, device->dev_unit_num,
1145 if (ccb->cts.transport == XPORT_SPI) {
1146 struct ccb_trans_settings_spi *spi =
1147 &ccb->cts.xport_specific.spi;
1149 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1150 && (spi->sync_offset != 0))
1151 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1152 freq % 1000, spi->sync_offset);
1154 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1155 && (spi->bus_width > 0)) {
1156 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1157 && (spi->sync_offset != 0)) {
1158 fprintf(stdout, ", ");
1160 fprintf(stdout, " (");
1162 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1163 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1164 && (spi->sync_offset != 0)) {
1165 fprintf(stdout, ")");
1167 } else if (ccb->cts.transport == XPORT_ATA) {
1168 struct ccb_trans_settings_pata *pata =
1169 &ccb->cts.xport_specific.ata;
1172 if (pata->valid & CTS_ATA_VALID_MODE)
1173 printf("%s, ", ata_mode2string(pata->mode));
1174 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1175 printf("ATAPI %dbytes, ", pata->atapi);
1176 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1177 printf("PIO %dbytes", pata->bytecount);
1179 } else if (ccb->cts.transport == XPORT_SATA) {
1180 struct ccb_trans_settings_sata *sata =
1181 &ccb->cts.xport_specific.sata;
1184 if (sata->valid & CTS_SATA_VALID_REVISION)
1185 printf("SATA %d.x, ", sata->revision);
1188 if (sata->valid & CTS_SATA_VALID_MODE)
1189 printf("%s, ", ata_mode2string(sata->mode));
1190 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1191 printf("ATAPI %dbytes, ", sata->atapi);
1192 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1193 printf("PIO %dbytes", sata->bytecount);
1197 if (ccb->cts.protocol == PROTO_SCSI) {
1198 struct ccb_trans_settings_scsi *scsi =
1199 &ccb->cts.proto_specific.scsi;
1200 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1201 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1202 fprintf(stdout, ", Command Queueing Enabled");
1207 fprintf(stdout, "\n");
1217 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1219 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1220 ((u_int32_t)parm->lba_size_2 << 16);
1222 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1223 ((u_int64_t)parm->lba_size48_2 << 16) |
1224 ((u_int64_t)parm->lba_size48_3 << 32) |
1225 ((u_int64_t)parm->lba_size48_4 << 48);
1229 "Support Enabled Value\n");
1232 printf("Host Protected Area (HPA) ");
1233 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1234 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1235 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1238 printf("HPA - Security ");
1239 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1249 atasata(struct ata_params *parm)
1253 if (parm->satacapabilities != 0xffff &&
1254 parm->satacapabilities != 0x0000)
1261 atacapprint(struct ata_params *parm)
1263 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1264 ((u_int32_t)parm->lba_size_2 << 16);
1266 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1267 ((u_int64_t)parm->lba_size48_2 << 16) |
1268 ((u_int64_t)parm->lba_size48_3 << 32) |
1269 ((u_int64_t)parm->lba_size48_4 << 48);
1272 printf("protocol ");
1273 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1274 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1275 if (parm->satacapabilities & ATA_SATA_GEN3)
1276 printf(" SATA 3.x\n");
1277 else if (parm->satacapabilities & ATA_SATA_GEN2)
1278 printf(" SATA 2.x\n");
1279 else if (parm->satacapabilities & ATA_SATA_GEN1)
1280 printf(" SATA 1.x\n");
1286 printf("device model %.40s\n", parm->model);
1287 printf("firmware revision %.8s\n", parm->revision);
1288 printf("serial number %.20s\n", parm->serial);
1289 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1290 printf("WWN %04x%04x%04x%04x\n",
1291 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1293 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1294 printf("media serial number %.30s\n",
1295 parm->media_serial);
1298 printf("cylinders %d\n", parm->cylinders);
1299 printf("heads %d\n", parm->heads);
1300 printf("sectors/track %d\n", parm->sectors);
1301 printf("sector size logical %u, physical %lu, offset %lu\n",
1302 ata_logical_sector_size(parm),
1303 (unsigned long)ata_physical_sector_size(parm),
1304 (unsigned long)ata_logical_sector_offset(parm));
1306 if (parm->config == ATA_PROTO_CFA ||
1307 (parm->support.command2 & ATA_SUPPORT_CFA))
1308 printf("CFA supported\n");
1310 printf("LBA%ssupported ",
1311 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1313 printf("%d sectors\n", lbasize);
1317 printf("LBA48%ssupported ",
1318 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1320 printf("%ju sectors\n", (uintmax_t)lbasize48);
1324 printf("PIO supported PIO");
1325 switch (ata_max_pmode(parm)) {
1341 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1342 printf(" w/o IORDY");
1345 printf("DMA%ssupported ",
1346 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1347 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1348 if (parm->mwdmamodes & 0xff) {
1350 if (parm->mwdmamodes & 0x04)
1352 else if (parm->mwdmamodes & 0x02)
1354 else if (parm->mwdmamodes & 0x01)
1358 if ((parm->atavalid & ATA_FLAG_88) &&
1359 (parm->udmamodes & 0xff)) {
1361 if (parm->udmamodes & 0x40)
1363 else if (parm->udmamodes & 0x20)
1365 else if (parm->udmamodes & 0x10)
1367 else if (parm->udmamodes & 0x08)
1369 else if (parm->udmamodes & 0x04)
1371 else if (parm->udmamodes & 0x02)
1373 else if (parm->udmamodes & 0x01)
1380 if (parm->media_rotation_rate == 1) {
1381 printf("media RPM non-rotating\n");
1382 } else if (parm->media_rotation_rate >= 0x0401 &&
1383 parm->media_rotation_rate <= 0xFFFE) {
1384 printf("media RPM %d\n",
1385 parm->media_rotation_rate);
1389 "Support Enabled Value Vendor\n");
1390 printf("read ahead %s %s\n",
1391 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1392 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1393 printf("write cache %s %s\n",
1394 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1395 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1396 printf("flush cache %s %s\n",
1397 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1398 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1399 printf("overlap %s\n",
1400 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1401 printf("Tagged Command Queuing (TCQ) %s %s",
1402 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1403 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1404 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1405 printf(" %d tags\n",
1406 ATA_QUEUE_LEN(parm->queue) + 1);
1409 printf("Native Command Queuing (NCQ) ");
1410 if (parm->satacapabilities != 0xffff &&
1411 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1412 printf("yes %d tags\n",
1413 ATA_QUEUE_LEN(parm->queue) + 1);
1417 printf("NCQ Queue Management %s\n", atasata(parm) &&
1418 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1420 printf("NCQ Streaming %s\n", atasata(parm) &&
1421 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1423 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1424 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1427 printf("SMART %s %s\n",
1428 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1429 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1430 printf("microcode download %s %s\n",
1431 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1432 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1433 printf("security %s %s\n",
1434 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1435 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1436 printf("power management %s %s\n",
1437 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1438 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1439 printf("advanced power management %s %s",
1440 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1441 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1442 if (parm->support.command2 & ATA_SUPPORT_APM) {
1443 printf(" %d/0x%02X\n",
1444 parm->apm_value & 0xff, parm->apm_value & 0xff);
1447 printf("automatic acoustic management %s %s",
1448 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1449 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1450 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1451 printf(" %d/0x%02X %d/0x%02X\n",
1452 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1453 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1454 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1455 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1458 printf("media status notification %s %s\n",
1459 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1460 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1461 printf("power-up in Standby %s %s\n",
1462 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1463 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1464 printf("write-read-verify %s %s",
1465 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1466 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1467 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1468 printf(" %d/0x%x\n",
1469 parm->wrv_mode, parm->wrv_mode);
1472 printf("unload %s %s\n",
1473 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1474 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1475 printf("general purpose logging %s %s\n",
1476 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1477 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1478 printf("free-fall %s %s\n",
1479 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1480 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1481 printf("Data Set Management (DSM/TRIM) ");
1482 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1484 printf("DSM - max 512byte blocks ");
1485 if (parm->max_dsm_blocks == 0x00)
1486 printf("yes not specified\n");
1489 parm->max_dsm_blocks);
1491 printf("DSM - deterministic read ");
1492 if (parm->support3 & ATA_SUPPORT_DRAT) {
1493 if (parm->support3 & ATA_SUPPORT_RZAT)
1494 printf("yes zeroed\n");
1496 printf("yes any value\n");
1506 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1508 struct ata_pass_16 *ata_pass_16;
1509 struct ata_cmd ata_cmd;
1511 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1512 ata_cmd.command = ata_pass_16->command;
1513 ata_cmd.control = ata_pass_16->control;
1514 ata_cmd.features = ata_pass_16->features;
1516 if (arglist & CAM_ARG_VERBOSE) {
1517 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1518 ata_op_string(&ata_cmd),
1519 ccb->csio.ccb_h.timeout);
1522 /* Disable freezing the device queue */
1523 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1525 if (arglist & CAM_ARG_ERR_RECOVER)
1526 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1528 if (cam_send_ccb(device, ccb) < 0) {
1529 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1530 warn("error sending ATA %s via pass_16",
1531 ata_op_string(&ata_cmd));
1534 if (arglist & CAM_ARG_VERBOSE) {
1535 cam_error_print(device, ccb, CAM_ESF_ALL,
1536 CAM_EPF_ALL, stderr);
1542 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1543 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1544 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1545 warnx("ATA %s via pass_16 failed",
1546 ata_op_string(&ata_cmd));
1548 if (arglist & CAM_ARG_VERBOSE) {
1549 cam_error_print(device, ccb, CAM_ESF_ALL,
1550 CAM_EPF_ALL, stderr);
1561 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1563 if (arglist & CAM_ARG_VERBOSE) {
1564 warnx("sending ATA %s with timeout of %u msecs",
1565 ata_op_string(&(ccb->ataio.cmd)),
1566 ccb->ataio.ccb_h.timeout);
1569 /* Disable freezing the device queue */
1570 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1572 if (arglist & CAM_ARG_ERR_RECOVER)
1573 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1575 if (cam_send_ccb(device, ccb) < 0) {
1576 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1577 warn("error sending ATA %s",
1578 ata_op_string(&(ccb->ataio.cmd)));
1581 if (arglist & CAM_ARG_VERBOSE) {
1582 cam_error_print(device, ccb, CAM_ESF_ALL,
1583 CAM_EPF_ALL, stderr);
1589 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1590 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1591 warnx("ATA %s failed: %d",
1592 ata_op_string(&(ccb->ataio.cmd)), quiet);
1595 if (arglist & CAM_ARG_VERBOSE) {
1596 cam_error_print(device, ccb, CAM_ESF_ALL,
1597 CAM_EPF_ALL, stderr);
1607 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1608 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1609 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1610 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1611 u_int16_t dxfer_len, int timeout, int quiet)
1613 if (data_ptr != NULL) {
1614 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1615 AP_FLAG_TLEN_SECT_CNT;
1616 if (flags & CAM_DIR_OUT)
1617 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1619 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1621 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1624 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1626 scsi_ata_pass_16(&ccb->csio,
1640 /*sense_len*/SSD_FULL_SIZE,
1643 return scsi_cam_pass_16_send(device, ccb, quiet);
1647 ata_try_pass_16(struct cam_device *device)
1649 struct ccb_pathinq cpi;
1651 if (get_cpi(device, &cpi) != 0) {
1652 warnx("couldn't get CPI");
1656 if (cpi.protocol == PROTO_SCSI) {
1657 /* possibly compatible with pass_16 */
1661 /* likely not compatible with pass_16 */
1666 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1667 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1668 u_int8_t command, u_int8_t features, u_int32_t lba,
1669 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1670 int timeout, int quiet)
1674 switch (ata_try_pass_16(device)) {
1678 /* Try using SCSI Passthrough */
1679 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1680 0, tag_action, command, features, lba,
1681 sector_count, data_ptr, dxfer_len,
1685 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1686 cam_fill_ataio(&ccb->ataio,
1695 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1696 return ata_cam_send(device, ccb, quiet);
1700 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1701 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1702 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1703 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1704 u_int16_t dxfer_len, int timeout, int force48bit)
1708 retval = ata_try_pass_16(device);
1715 /* Try using SCSI Passthrough */
1716 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1717 ata_flags, tag_action, command, features,
1718 lba, sector_count, data_ptr, dxfer_len,
1721 if (ata_flags & AP_FLAG_CHK_COND) {
1722 /* Decode ata_res from sense data */
1723 struct ata_res_pass16 *res_pass16;
1724 struct ata_res *res;
1728 /* sense_data is 4 byte aligned */
1729 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1730 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1731 ptr[i] = le16toh(ptr[i]);
1733 /* sense_data is 4 byte aligned */
1734 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1735 &ccb->csio.sense_data;
1736 res = &ccb->ataio.res;
1737 res->flags = res_pass16->flags;
1738 res->status = res_pass16->status;
1739 res->error = res_pass16->error;
1740 res->lba_low = res_pass16->lba_low;
1741 res->lba_mid = res_pass16->lba_mid;
1742 res->lba_high = res_pass16->lba_high;
1743 res->device = res_pass16->device;
1744 res->lba_low_exp = res_pass16->lba_low_exp;
1745 res->lba_mid_exp = res_pass16->lba_mid_exp;
1746 res->lba_high_exp = res_pass16->lba_high_exp;
1747 res->sector_count = res_pass16->sector_count;
1748 res->sector_count_exp = res_pass16->sector_count_exp;
1754 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1755 cam_fill_ataio(&ccb->ataio,
1764 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1765 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1767 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1769 if (ata_flags & AP_FLAG_CHK_COND)
1770 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1772 return ata_cam_send(device, ccb, 0);
1776 dump_data(uint16_t *ptr, uint32_t len)
1780 for (i = 0; i < len / 2; i++) {
1782 printf(" %3d: ", i);
1783 printf("%04hx ", ptr[i]);
1792 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1793 int is48bit, u_int64_t *hpasize)
1795 struct ata_res *res;
1797 res = &ccb->ataio.res;
1798 if (res->status & ATA_STATUS_ERROR) {
1799 if (arglist & CAM_ARG_VERBOSE) {
1800 cam_error_print(device, ccb, CAM_ESF_ALL,
1801 CAM_EPF_ALL, stderr);
1802 printf("error = 0x%02x, sector_count = 0x%04x, "
1803 "device = 0x%02x, status = 0x%02x\n",
1804 res->error, res->sector_count,
1805 res->device, res->status);
1808 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1809 warnx("Max address has already been set since "
1810 "last power-on or hardware reset");
1816 if (arglist & CAM_ARG_VERBOSE) {
1817 fprintf(stdout, "%s%d: Raw native max data:\n",
1818 device->device_name, device->dev_unit_num);
1819 /* res is 4 byte aligned */
1820 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1822 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1823 "status = 0x%02x\n", res->error, res->sector_count,
1824 res->device, res->status);
1827 if (hpasize != NULL) {
1829 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1830 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1831 ((res->lba_high << 16) | (res->lba_mid << 8) |
1834 *hpasize = (((res->device & 0x0f) << 24) |
1835 (res->lba_high << 16) | (res->lba_mid << 8) |
1844 ata_read_native_max(struct cam_device *device, int retry_count,
1845 u_int32_t timeout, union ccb *ccb,
1846 struct ata_params *parm, u_int64_t *hpasize)
1852 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1853 protocol = AP_PROTO_NON_DATA;
1856 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1857 protocol |= AP_EXTEND;
1859 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1862 error = ata_do_cmd(device,
1865 /*flags*/CAM_DIR_NONE,
1866 /*protocol*/protocol,
1867 /*ata_flags*/AP_FLAG_CHK_COND,
1868 /*tag_action*/MSG_SIMPLE_Q_TAG,
1875 timeout ? timeout : 1000,
1881 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1885 atahpa_set_max(struct cam_device *device, int retry_count,
1886 u_int32_t timeout, union ccb *ccb,
1887 int is48bit, u_int64_t maxsize, int persist)
1893 protocol = AP_PROTO_NON_DATA;
1896 cmd = ATA_SET_MAX_ADDRESS48;
1897 protocol |= AP_EXTEND;
1899 cmd = ATA_SET_MAX_ADDRESS;
1902 /* lba's are zero indexed so the max lba is requested max - 1 */
1906 error = ata_do_cmd(device,
1909 /*flags*/CAM_DIR_NONE,
1910 /*protocol*/protocol,
1911 /*ata_flags*/AP_FLAG_CHK_COND,
1912 /*tag_action*/MSG_SIMPLE_Q_TAG,
1914 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1916 /*sector_count*/persist,
1919 timeout ? timeout : 1000,
1925 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1929 atahpa_password(struct cam_device *device, int retry_count,
1930 u_int32_t timeout, union ccb *ccb,
1931 int is48bit, struct ata_set_max_pwd *pwd)
1937 protocol = AP_PROTO_PIO_OUT;
1938 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1940 error = ata_do_cmd(device,
1943 /*flags*/CAM_DIR_OUT,
1944 /*protocol*/protocol,
1945 /*ata_flags*/AP_FLAG_CHK_COND,
1946 /*tag_action*/MSG_SIMPLE_Q_TAG,
1948 /*features*/ATA_HPA_FEAT_SET_PWD,
1951 /*data_ptr*/(u_int8_t*)pwd,
1952 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1953 timeout ? timeout : 1000,
1959 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1963 atahpa_lock(struct cam_device *device, int retry_count,
1964 u_int32_t timeout, union ccb *ccb, int is48bit)
1970 protocol = AP_PROTO_NON_DATA;
1971 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1973 error = ata_do_cmd(device,
1976 /*flags*/CAM_DIR_NONE,
1977 /*protocol*/protocol,
1978 /*ata_flags*/AP_FLAG_CHK_COND,
1979 /*tag_action*/MSG_SIMPLE_Q_TAG,
1981 /*features*/ATA_HPA_FEAT_LOCK,
1986 timeout ? timeout : 1000,
1992 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1996 atahpa_unlock(struct cam_device *device, int retry_count,
1997 u_int32_t timeout, union ccb *ccb,
1998 int is48bit, struct ata_set_max_pwd *pwd)
2004 protocol = AP_PROTO_PIO_OUT;
2005 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2007 error = ata_do_cmd(device,
2010 /*flags*/CAM_DIR_OUT,
2011 /*protocol*/protocol,
2012 /*ata_flags*/AP_FLAG_CHK_COND,
2013 /*tag_action*/MSG_SIMPLE_Q_TAG,
2015 /*features*/ATA_HPA_FEAT_UNLOCK,
2018 /*data_ptr*/(u_int8_t*)pwd,
2019 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2020 timeout ? timeout : 1000,
2026 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2030 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2031 u_int32_t timeout, union ccb *ccb, int is48bit)
2037 protocol = AP_PROTO_NON_DATA;
2038 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2040 error = ata_do_cmd(device,
2043 /*flags*/CAM_DIR_NONE,
2044 /*protocol*/protocol,
2045 /*ata_flags*/AP_FLAG_CHK_COND,
2046 /*tag_action*/MSG_SIMPLE_Q_TAG,
2048 /*features*/ATA_HPA_FEAT_FREEZE,
2053 timeout ? timeout : 1000,
2059 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2064 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2065 union ccb *ccb, struct ata_params** ident_bufp)
2067 struct ata_params *ident_buf;
2068 struct ccb_pathinq cpi;
2069 struct ccb_getdev cgd;
2072 u_int8_t command, retry_command;
2074 if (get_cpi(device, &cpi) != 0) {
2075 warnx("couldn't get CPI");
2079 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2080 if (cpi.protocol == PROTO_ATA) {
2081 if (get_cgd(device, &cgd) != 0) {
2082 warnx("couldn't get CGD");
2086 command = (cgd.protocol == PROTO_ATA) ?
2087 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2090 /* We don't know which for sure so try both */
2091 command = ATA_ATA_IDENTIFY;
2092 retry_command = ATA_ATAPI_IDENTIFY;
2095 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2097 warnx("can't calloc memory for identify\n");
2101 error = ata_do_28bit_cmd(device,
2103 /*retries*/retry_count,
2104 /*flags*/CAM_DIR_IN,
2105 /*protocol*/AP_PROTO_PIO_IN,
2106 /*tag_action*/MSG_SIMPLE_Q_TAG,
2110 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2111 /*data_ptr*/(u_int8_t *)ptr,
2112 /*dxfer_len*/sizeof(struct ata_params),
2113 /*timeout*/timeout ? timeout : 30 * 1000,
2117 if (retry_command == 0) {
2121 error = ata_do_28bit_cmd(device,
2123 /*retries*/retry_count,
2124 /*flags*/CAM_DIR_IN,
2125 /*protocol*/AP_PROTO_PIO_IN,
2126 /*tag_action*/MSG_SIMPLE_Q_TAG,
2127 /*command*/retry_command,
2130 /*sector_count*/(u_int8_t)
2131 sizeof(struct ata_params),
2132 /*data_ptr*/(u_int8_t *)ptr,
2133 /*dxfer_len*/sizeof(struct ata_params),
2134 /*timeout*/timeout ? timeout : 30 * 1000,
2144 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2145 ptr[i] = le16toh(ptr[i]);
2150 if (arglist & CAM_ARG_VERBOSE) {
2151 fprintf(stdout, "%s%d: Raw identify data:\n",
2152 device->device_name, device->dev_unit_num);
2153 dump_data(ptr, sizeof(struct ata_params));
2156 /* check for invalid (all zero) response */
2158 warnx("Invalid identify response detected");
2163 ident_buf = (struct ata_params *)ptr;
2164 if (strncmp(ident_buf->model, "FX", 2) &&
2165 strncmp(ident_buf->model, "NEC", 3) &&
2166 strncmp(ident_buf->model, "Pioneer", 7) &&
2167 strncmp(ident_buf->model, "SHARP", 5)) {
2168 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2169 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2170 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2171 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2173 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2174 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2175 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2176 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2177 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2178 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2179 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2180 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2181 sizeof(ident_buf->media_serial));
2183 *ident_bufp = ident_buf;
2190 ataidentify(struct cam_device *device, int retry_count, int timeout)
2193 struct ata_params *ident_buf;
2196 if ((ccb = cam_getccb(device)) == NULL) {
2197 warnx("couldn't allocate CCB");
2201 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2206 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2207 if (ata_read_native_max(device, retry_count, timeout, ccb,
2208 ident_buf, &hpasize) != 0) {
2216 printf("%s%d: ", device->device_name, device->dev_unit_num);
2217 ata_print_ident(ident_buf);
2218 camxferrate(device);
2219 atacapprint(ident_buf);
2220 atahpa_print(ident_buf, hpasize, 0);
2227 #endif /* MINIMALISTIC */
2230 #ifndef MINIMALISTIC
2232 ATA_SECURITY_ACTION_PRINT,
2233 ATA_SECURITY_ACTION_FREEZE,
2234 ATA_SECURITY_ACTION_UNLOCK,
2235 ATA_SECURITY_ACTION_DISABLE,
2236 ATA_SECURITY_ACTION_ERASE,
2237 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2238 ATA_SECURITY_ACTION_SET_PASSWORD
2242 atasecurity_print_time(u_int16_t tw)
2246 printf("unspecified");
2248 printf("> 508 min");
2250 printf("%i min", 2 * tw);
2254 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2258 return 2 * 3600 * 1000; /* default: two hours */
2259 else if (timeout > 255)
2260 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2262 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2267 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2271 bzero(&cmd, sizeof(cmd));
2272 cmd.command = command;
2273 printf("Issuing %s", ata_op_string(&cmd));
2276 char pass[sizeof(pwd->password)+1];
2278 /* pwd->password may not be null terminated */
2279 pass[sizeof(pwd->password)] = '\0';
2280 strncpy(pass, pwd->password, sizeof(pwd->password));
2281 printf(" password='%s', user='%s'",
2283 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2286 if (command == ATA_SECURITY_SET_PASSWORD) {
2287 printf(", mode='%s'",
2288 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2289 "maximum" : "high");
2297 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2298 int retry_count, u_int32_t timeout, int quiet)
2302 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2304 return ata_do_28bit_cmd(device,
2307 /*flags*/CAM_DIR_NONE,
2308 /*protocol*/AP_PROTO_NON_DATA,
2309 /*tag_action*/MSG_SIMPLE_Q_TAG,
2310 /*command*/ATA_SECURITY_FREEZE_LOCK,
2321 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2322 int retry_count, u_int32_t timeout,
2323 struct ata_security_password *pwd, int quiet)
2327 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2329 return ata_do_28bit_cmd(device,
2332 /*flags*/CAM_DIR_OUT,
2333 /*protocol*/AP_PROTO_PIO_OUT,
2334 /*tag_action*/MSG_SIMPLE_Q_TAG,
2335 /*command*/ATA_SECURITY_UNLOCK,
2339 /*data_ptr*/(u_int8_t *)pwd,
2340 /*dxfer_len*/sizeof(*pwd),
2346 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2347 int retry_count, u_int32_t timeout,
2348 struct ata_security_password *pwd, int quiet)
2352 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2353 return ata_do_28bit_cmd(device,
2356 /*flags*/CAM_DIR_OUT,
2357 /*protocol*/AP_PROTO_PIO_OUT,
2358 /*tag_action*/MSG_SIMPLE_Q_TAG,
2359 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2363 /*data_ptr*/(u_int8_t *)pwd,
2364 /*dxfer_len*/sizeof(*pwd),
2371 atasecurity_erase_confirm(struct cam_device *device,
2372 struct ata_params* ident_buf)
2375 printf("\nYou are about to ERASE ALL DATA from the following"
2376 " device:\n%s%d,%s%d: ", device->device_name,
2377 device->dev_unit_num, device->given_dev_name,
2378 device->given_unit_number);
2379 ata_print_ident(ident_buf);
2383 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2385 if (fgets(str, sizeof(str), stdin) != NULL) {
2386 if (strncasecmp(str, "yes", 3) == 0) {
2388 } else if (strncasecmp(str, "no", 2) == 0) {
2391 printf("Please answer \"yes\" or "
2402 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2403 int retry_count, u_int32_t timeout,
2404 u_int32_t erase_timeout,
2405 struct ata_security_password *pwd, int quiet)
2410 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2412 error = ata_do_28bit_cmd(device,
2415 /*flags*/CAM_DIR_NONE,
2416 /*protocol*/AP_PROTO_NON_DATA,
2417 /*tag_action*/MSG_SIMPLE_Q_TAG,
2418 /*command*/ATA_SECURITY_ERASE_PREPARE,
2431 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2433 error = ata_do_28bit_cmd(device,
2436 /*flags*/CAM_DIR_OUT,
2437 /*protocol*/AP_PROTO_PIO_OUT,
2438 /*tag_action*/MSG_SIMPLE_Q_TAG,
2439 /*command*/ATA_SECURITY_ERASE_UNIT,
2443 /*data_ptr*/(u_int8_t *)pwd,
2444 /*dxfer_len*/sizeof(*pwd),
2445 /*timeout*/erase_timeout,
2448 if (error == 0 && quiet == 0)
2449 printf("\nErase Complete\n");
2455 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2456 int retry_count, u_int32_t timeout,
2457 struct ata_security_password *pwd, int quiet)
2461 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2463 return ata_do_28bit_cmd(device,
2466 /*flags*/CAM_DIR_OUT,
2467 /*protocol*/AP_PROTO_PIO_OUT,
2468 /*tag_action*/MSG_SIMPLE_Q_TAG,
2469 /*command*/ATA_SECURITY_SET_PASSWORD,
2473 /*data_ptr*/(u_int8_t *)pwd,
2474 /*dxfer_len*/sizeof(*pwd),
2480 atasecurity_print(struct ata_params *parm)
2483 printf("\nSecurity Option Value\n");
2484 if (arglist & CAM_ARG_VERBOSE) {
2485 printf("status %04x\n",
2486 parm->security_status);
2488 printf("supported %s\n",
2489 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2490 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2492 printf("enabled %s\n",
2493 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2494 printf("drive locked %s\n",
2495 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2496 printf("security config frozen %s\n",
2497 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2498 printf("count expired %s\n",
2499 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2500 printf("security level %s\n",
2501 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2502 printf("enhanced erase supported %s\n",
2503 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2504 printf("erase time ");
2505 atasecurity_print_time(parm->erase_time);
2507 printf("enhanced erase time ");
2508 atasecurity_print_time(parm->enhanced_erase_time);
2510 printf("master password rev %04x%s\n",
2511 parm->master_passwd_revision,
2512 parm->master_passwd_revision == 0x0000 ||
2513 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2517 * Validates and copies the password in optarg to the passed buffer.
2518 * If the password in optarg is the same length as the buffer then
2519 * the data will still be copied but no null termination will occur.
2522 ata_getpwd(u_int8_t *passwd, int max, char opt)
2526 len = strlen(optarg);
2528 warnx("-%c password is too long", opt);
2530 } else if (len == 0) {
2531 warnx("-%c password is missing", opt);
2533 } else if (optarg[0] == '-'){
2534 warnx("-%c password starts with '-' (generic arg?)", opt);
2536 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2537 warnx("-%c password conflicts with existing password from -%c",
2542 /* Callers pass in a buffer which does NOT need to be terminated */
2543 strncpy(passwd, optarg, max);
2550 ATA_HPA_ACTION_PRINT,
2551 ATA_HPA_ACTION_SET_MAX,
2552 ATA_HPA_ACTION_SET_PWD,
2553 ATA_HPA_ACTION_LOCK,
2554 ATA_HPA_ACTION_UNLOCK,
2555 ATA_HPA_ACTION_FREEZE_LOCK
2559 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2560 u_int64_t maxsize, int persist)
2562 printf("\nYou are about to configure HPA to limit the user accessible\n"
2563 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2564 persist ? "persistently" : "temporarily",
2565 device->device_name, device->dev_unit_num,
2566 device->given_dev_name, device->given_unit_number);
2567 ata_print_ident(ident_buf);
2571 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2573 if (NULL != fgets(str, sizeof(str), stdin)) {
2574 if (0 == strncasecmp(str, "yes", 3)) {
2576 } else if (0 == strncasecmp(str, "no", 2)) {
2579 printf("Please answer \"yes\" or "
2590 atahpa(struct cam_device *device, int retry_count, int timeout,
2591 int argc, char **argv, char *combinedopt)
2594 struct ata_params *ident_buf;
2595 struct ccb_getdev cgd;
2596 struct ata_set_max_pwd pwd;
2597 int error, confirm, quiet, c, action, actions, setpwd, persist;
2598 int security, is48bit, pwdsize;
2599 u_int64_t hpasize, maxsize;
2609 memset(&pwd, 0, sizeof(pwd));
2611 /* default action is to print hpa information */
2612 action = ATA_HPA_ACTION_PRINT;
2613 pwdsize = sizeof(pwd.password);
2615 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2618 action = ATA_HPA_ACTION_SET_MAX;
2619 maxsize = strtoumax(optarg, NULL, 0);
2624 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2626 action = ATA_HPA_ACTION_SET_PWD;
2632 action = ATA_HPA_ACTION_LOCK;
2638 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2640 action = ATA_HPA_ACTION_UNLOCK;
2646 action = ATA_HPA_ACTION_FREEZE_LOCK;
2666 warnx("too many hpa actions specified");
2670 if (get_cgd(device, &cgd) != 0) {
2671 warnx("couldn't get CGD");
2675 ccb = cam_getccb(device);
2677 warnx("couldn't allocate CCB");
2681 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2688 printf("%s%d: ", device->device_name, device->dev_unit_num);
2689 ata_print_ident(ident_buf);
2690 camxferrate(device);
2693 if (action == ATA_HPA_ACTION_PRINT) {
2694 error = ata_read_native_max(device, retry_count, timeout, ccb,
2695 ident_buf, &hpasize);
2697 atahpa_print(ident_buf, hpasize, 1);
2704 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2705 warnx("HPA is not supported by this device");
2711 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2712 warnx("HPA Security is not supported by this device");
2718 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2721 * The ATA spec requires:
2722 * 1. Read native max addr is called directly before set max addr
2723 * 2. Read native max addr is NOT called before any other set max call
2726 case ATA_HPA_ACTION_SET_MAX:
2728 atahpa_set_confirm(device, ident_buf, maxsize,
2735 error = ata_read_native_max(device, retry_count, timeout,
2736 ccb, ident_buf, &hpasize);
2738 error = atahpa_set_max(device, retry_count, timeout,
2739 ccb, is48bit, maxsize, persist);
2741 /* redo identify to get new lba values */
2742 error = ata_do_identify(device, retry_count,
2745 atahpa_print(ident_buf, hpasize, 1);
2750 case ATA_HPA_ACTION_SET_PWD:
2751 error = atahpa_password(device, retry_count, timeout,
2752 ccb, is48bit, &pwd);
2754 printf("HPA password has been set\n");
2757 case ATA_HPA_ACTION_LOCK:
2758 error = atahpa_lock(device, retry_count, timeout,
2761 printf("HPA has been locked\n");
2764 case ATA_HPA_ACTION_UNLOCK:
2765 error = atahpa_unlock(device, retry_count, timeout,
2766 ccb, is48bit, &pwd);
2768 printf("HPA has been unlocked\n");
2771 case ATA_HPA_ACTION_FREEZE_LOCK:
2772 error = atahpa_freeze_lock(device, retry_count, timeout,
2775 printf("HPA has been frozen\n");
2779 errx(1, "Option currently not supported");
2789 atasecurity(struct cam_device *device, int retry_count, int timeout,
2790 int argc, char **argv, char *combinedopt)
2793 struct ata_params *ident_buf;
2794 int error, confirm, quiet, c, action, actions, setpwd;
2795 int security_enabled, erase_timeout, pwdsize;
2796 struct ata_security_password pwd;
2804 memset(&pwd, 0, sizeof(pwd));
2806 /* default action is to print security information */
2807 action = ATA_SECURITY_ACTION_PRINT;
2809 /* user is master by default as its safer that way */
2810 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2811 pwdsize = sizeof(pwd.password);
2813 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2816 action = ATA_SECURITY_ACTION_FREEZE;
2821 if (strcasecmp(optarg, "user") == 0) {
2822 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2823 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2824 } else if (strcasecmp(optarg, "master") == 0) {
2825 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2826 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2828 warnx("-U argument '%s' is invalid (must be "
2829 "'user' or 'master')", optarg);
2835 if (strcasecmp(optarg, "high") == 0) {
2836 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2837 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2838 } else if (strcasecmp(optarg, "maximum") == 0) {
2839 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2840 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2842 warnx("-l argument '%s' is unknown (must be "
2843 "'high' or 'maximum')", optarg);
2849 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2851 action = ATA_SECURITY_ACTION_UNLOCK;
2856 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2858 action = ATA_SECURITY_ACTION_DISABLE;
2863 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2865 action = ATA_SECURITY_ACTION_ERASE;
2870 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2872 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2873 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2878 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2881 if (action == ATA_SECURITY_ACTION_PRINT)
2882 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2884 * Don't increment action as this can be combined
2885 * with other actions.
2898 erase_timeout = atoi(optarg) * 1000;
2904 warnx("too many security actions specified");
2908 if ((ccb = cam_getccb(device)) == NULL) {
2909 warnx("couldn't allocate CCB");
2913 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2920 printf("%s%d: ", device->device_name, device->dev_unit_num);
2921 ata_print_ident(ident_buf);
2922 camxferrate(device);
2925 if (action == ATA_SECURITY_ACTION_PRINT) {
2926 atasecurity_print(ident_buf);
2932 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2933 warnx("Security not supported");
2939 /* default timeout 15 seconds the same as linux hdparm */
2940 timeout = timeout ? timeout : 15 * 1000;
2942 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2944 /* first set the password if requested */
2946 /* confirm we can erase before setting the password if erasing */
2948 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2949 action == ATA_SECURITY_ACTION_ERASE) &&
2950 atasecurity_erase_confirm(device, ident_buf) == 0) {
2956 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2957 pwd.revision = ident_buf->master_passwd_revision;
2958 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2959 --pwd.revision == 0) {
2960 pwd.revision = 0xfffe;
2963 error = atasecurity_set_password(device, ccb, retry_count,
2964 timeout, &pwd, quiet);
2970 security_enabled = 1;
2974 case ATA_SECURITY_ACTION_FREEZE:
2975 error = atasecurity_freeze(device, ccb, retry_count,
2979 case ATA_SECURITY_ACTION_UNLOCK:
2980 if (security_enabled) {
2981 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2982 error = atasecurity_unlock(device, ccb,
2983 retry_count, timeout, &pwd, quiet);
2985 warnx("Can't unlock, drive is not locked");
2989 warnx("Can't unlock, security is disabled");
2994 case ATA_SECURITY_ACTION_DISABLE:
2995 if (security_enabled) {
2996 /* First unlock the drive if its locked */
2997 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2998 error = atasecurity_unlock(device, ccb,
3006 error = atasecurity_disable(device,
3014 warnx("Can't disable security (already disabled)");
3019 case ATA_SECURITY_ACTION_ERASE:
3020 if (security_enabled) {
3021 if (erase_timeout == 0) {
3022 erase_timeout = atasecurity_erase_timeout_msecs(
3023 ident_buf->erase_time);
3026 error = atasecurity_erase(device, ccb, retry_count,
3027 timeout, erase_timeout, &pwd,
3030 warnx("Can't secure erase (security is disabled)");
3035 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3036 if (security_enabled) {
3037 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3038 if (erase_timeout == 0) {
3040 atasecurity_erase_timeout_msecs(
3041 ident_buf->enhanced_erase_time);
3044 error = atasecurity_erase(device, ccb,
3045 retry_count, timeout,
3046 erase_timeout, &pwd,
3049 warnx("Enhanced erase is not supported");
3053 warnx("Can't secure erase (enhanced), "
3054 "(security is disabled)");
3065 #endif /* MINIMALISTIC */
3068 * Parse out a bus, or a bus, target and lun in the following
3074 * Returns the number of parsed components, or 0.
3077 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3078 cam_argmask *arglst)
3083 while (isspace(*tstr) && (*tstr != '\0'))
3086 tmpstr = (char *)strtok(tstr, ":");
3087 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3088 *bus = strtol(tmpstr, NULL, 0);
3089 *arglst |= CAM_ARG_BUS;
3091 tmpstr = (char *)strtok(NULL, ":");
3092 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3093 *target = strtol(tmpstr, NULL, 0);
3094 *arglst |= CAM_ARG_TARGET;
3096 tmpstr = (char *)strtok(NULL, ":");
3097 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3098 *lun = strtol(tmpstr, NULL, 0);
3099 *arglst |= CAM_ARG_LUN;
3109 dorescan_or_reset(int argc, char **argv, int rescan)
3111 static const char must[] =
3112 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3114 path_id_t bus = CAM_BUS_WILDCARD;
3115 target_id_t target = CAM_TARGET_WILDCARD;
3116 lun_id_t lun = CAM_LUN_WILDCARD;
3120 warnx(must, rescan? "rescan" : "reset");
3124 tstr = argv[optind];
3125 while (isspace(*tstr) && (*tstr != '\0'))
3127 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3128 arglist |= CAM_ARG_BUS;
3130 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3131 if (rv != 1 && rv != 3) {
3132 warnx(must, rescan? "rescan" : "reset");
3137 if ((arglist & CAM_ARG_BUS)
3138 && (arglist & CAM_ARG_TARGET)
3139 && (arglist & CAM_ARG_LUN))
3140 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3142 error = rescan_or_reset_bus(bus, rescan);
3148 rescan_or_reset_bus(path_id_t bus, int rescan)
3150 union ccb *ccb = NULL, *matchccb = NULL;
3151 int fd = -1, retval;
3156 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3157 warnx("error opening transport layer device %s", XPT_DEVICE);
3158 warn("%s", XPT_DEVICE);
3162 ccb = malloc(sizeof(*ccb));
3164 warn("failed to allocate CCB");
3168 bzero(ccb, sizeof(*ccb));
3170 if (bus != CAM_BUS_WILDCARD) {
3171 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3172 ccb->ccb_h.path_id = bus;
3173 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3174 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3175 ccb->crcn.flags = CAM_FLAG_NONE;
3177 /* run this at a low priority */
3178 ccb->ccb_h.pinfo.priority = 5;
3180 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3181 warn("CAMIOCOMMAND ioctl failed");
3186 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3187 fprintf(stdout, "%s of bus %d was successful\n",
3188 rescan ? "Re-scan" : "Reset", bus);
3190 fprintf(stdout, "%s of bus %d returned error %#x\n",
3191 rescan ? "Re-scan" : "Reset", bus,
3192 ccb->ccb_h.status & CAM_STATUS_MASK);
3201 * The right way to handle this is to modify the xpt so that it can
3202 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3203 * that isn't implemented, so instead we enumerate the busses and
3204 * send the rescan or reset to those busses in the case where the
3205 * given bus is -1 (wildcard). We don't send a rescan or reset
3206 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3207 * no-op, sending a rescan to the xpt bus would result in a status of
3210 matchccb = malloc(sizeof(*matchccb));
3211 if (matchccb == NULL) {
3212 warn("failed to allocate CCB");
3216 bzero(matchccb, sizeof(*matchccb));
3217 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3218 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3219 bufsize = sizeof(struct dev_match_result) * 20;
3220 matchccb->cdm.match_buf_len = bufsize;
3221 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3222 if (matchccb->cdm.matches == NULL) {
3223 warnx("can't malloc memory for matches");
3227 matchccb->cdm.num_matches = 0;
3229 matchccb->cdm.num_patterns = 1;
3230 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3232 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3233 matchccb->cdm.pattern_buf_len);
3234 if (matchccb->cdm.patterns == NULL) {
3235 warnx("can't malloc memory for patterns");
3239 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3240 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3245 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3246 warn("CAMIOCOMMAND ioctl failed");
3251 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3252 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3253 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3254 warnx("got CAM error %#x, CDM error %d\n",
3255 matchccb->ccb_h.status, matchccb->cdm.status);
3260 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3261 struct bus_match_result *bus_result;
3263 /* This shouldn't happen. */
3264 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3267 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3270 * We don't want to rescan or reset the xpt bus.
3273 if (bus_result->path_id == CAM_XPT_PATH_ID)
3276 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3278 ccb->ccb_h.path_id = bus_result->path_id;
3279 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3280 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3281 ccb->crcn.flags = CAM_FLAG_NONE;
3283 /* run this at a low priority */
3284 ccb->ccb_h.pinfo.priority = 5;
3286 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3287 warn("CAMIOCOMMAND ioctl failed");
3292 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3293 fprintf(stdout, "%s of bus %d was successful\n",
3294 rescan? "Re-scan" : "Reset",
3295 bus_result->path_id);
3298 * Don't bail out just yet, maybe the other
3299 * rescan or reset commands will complete
3302 fprintf(stderr, "%s of bus %d returned error "
3303 "%#x\n", rescan? "Re-scan" : "Reset",
3304 bus_result->path_id,
3305 ccb->ccb_h.status & CAM_STATUS_MASK);
3309 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3310 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3317 if (matchccb != NULL) {
3318 free(matchccb->cdm.patterns);
3319 free(matchccb->cdm.matches);
3328 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3331 struct cam_device *device;
3336 if (bus == CAM_BUS_WILDCARD) {
3337 warnx("invalid bus number %d", bus);
3341 if (target == CAM_TARGET_WILDCARD) {
3342 warnx("invalid target number %d", target);
3346 if (lun == CAM_LUN_WILDCARD) {
3347 warnx("invalid lun number %jx", (uintmax_t)lun);
3353 bzero(&ccb, sizeof(union ccb));
3356 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3357 warnx("error opening transport layer device %s\n",
3359 warn("%s", XPT_DEVICE);
3363 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3364 if (device == NULL) {
3365 warnx("%s", cam_errbuf);
3370 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3371 ccb.ccb_h.path_id = bus;
3372 ccb.ccb_h.target_id = target;
3373 ccb.ccb_h.target_lun = lun;
3374 ccb.ccb_h.timeout = 5000;
3375 ccb.crcn.flags = CAM_FLAG_NONE;
3377 /* run this at a low priority */
3378 ccb.ccb_h.pinfo.priority = 5;
3381 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3382 warn("CAMIOCOMMAND ioctl failed");
3387 if (cam_send_ccb(device, &ccb) < 0) {
3388 warn("error sending XPT_RESET_DEV CCB");
3389 cam_close_device(device);
3397 cam_close_device(device);
3400 * An error code of CAM_BDR_SENT is normal for a BDR request.
3402 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3404 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3405 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3406 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3409 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3410 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3411 ccb.ccb_h.status & CAM_STATUS_MASK);
3416 #ifndef MINIMALISTIC
3418 static struct scsi_nv defect_list_type_map[] = {
3419 { "block", SRDD10_BLOCK_FORMAT },
3420 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3421 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3422 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3423 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3424 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3428 readdefects(struct cam_device *device, int argc, char **argv,
3429 char *combinedopt, int task_attr, int retry_count, int timeout)
3431 union ccb *ccb = NULL;
3432 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3433 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3434 size_t hdr_size = 0, entry_size = 0;
3437 u_int8_t *defect_list = NULL;
3438 u_int8_t list_format = 0;
3439 int list_type_set = 0;
3440 u_int32_t dlist_length = 0;
3441 u_int32_t returned_length = 0, valid_len = 0;
3442 u_int32_t num_returned = 0, num_valid = 0;
3443 u_int32_t max_possible_size = 0, hdr_max = 0;
3444 u_int32_t starting_offset = 0;
3445 u_int8_t returned_format, returned_type;
3447 int summary = 0, quiet = 0;
3449 int lists_specified = 0;
3450 int get_length = 1, first_pass = 1;
3453 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3457 scsi_nv_status status;
3460 status = scsi_get_nv(defect_list_type_map,
3461 sizeof(defect_list_type_map) /
3462 sizeof(defect_list_type_map[0]), optarg,
3463 &entry_num, SCSI_NV_FLAG_IG_CASE);
3465 if (status == SCSI_NV_FOUND) {
3466 list_format = defect_list_type_map[
3470 warnx("%s: %s %s option %s", __func__,
3471 (status == SCSI_NV_AMBIGUOUS) ?
3472 "ambiguous" : "invalid", "defect list type",
3475 goto defect_bailout;
3480 arglist |= CAM_ARG_GLIST;
3483 arglist |= CAM_ARG_PLIST;
3494 starting_offset = strtoul(optarg, &endptr, 0);
3495 if (*endptr != '\0') {
3497 warnx("invalid starting offset %s", optarg);
3498 goto defect_bailout;
3510 if (list_type_set == 0) {
3512 warnx("no defect list format specified");
3513 goto defect_bailout;
3516 if (arglist & CAM_ARG_PLIST) {
3517 list_format |= SRDD10_PLIST;
3521 if (arglist & CAM_ARG_GLIST) {
3522 list_format |= SRDD10_GLIST;
3527 * This implies a summary, and was the previous behavior.
3529 if (lists_specified == 0)
3532 ccb = cam_getccb(device);
3537 * We start off asking for just the header to determine how much
3538 * defect data is available. Some Hitachi drives return an error
3539 * if you ask for more data than the drive has. Once we know the
3540 * length, we retry the command with the returned length.
3542 if (use_12byte == 0)
3543 dlist_length = sizeof(*hdr10);
3545 dlist_length = sizeof(*hdr12);
3548 if (defect_list != NULL) {
3552 defect_list = malloc(dlist_length);
3553 if (defect_list == NULL) {
3554 warnx("can't malloc memory for defect list");
3556 goto defect_bailout;
3560 bzero(defect_list, dlist_length);
3563 * cam_getccb() zeros the CCB header only. So we need to zero the
3564 * payload portion of the ccb.
3566 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3568 scsi_read_defects(&ccb->csio,
3569 /*retries*/ retry_count,
3571 /*tag_action*/ task_attr,
3572 /*list_format*/ list_format,
3573 /*addr_desc_index*/ starting_offset,
3574 /*data_ptr*/ defect_list,
3575 /*dxfer_len*/ dlist_length,
3576 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3577 /*sense_len*/ SSD_FULL_SIZE,
3578 /*timeout*/ timeout ? timeout : 5000);
3580 /* Disable freezing the device queue */
3581 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3583 if (cam_send_ccb(device, ccb) < 0) {
3584 perror("error reading defect list");
3586 if (arglist & CAM_ARG_VERBOSE) {
3587 cam_error_print(device, ccb, CAM_ESF_ALL,
3588 CAM_EPF_ALL, stderr);
3592 goto defect_bailout;
3595 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3597 if (use_12byte == 0) {
3598 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3599 hdr_size = sizeof(*hdr10);
3600 hdr_max = SRDDH10_MAX_LENGTH;
3602 if (valid_len >= hdr_size) {
3603 returned_length = scsi_2btoul(hdr10->length);
3604 returned_format = hdr10->format;
3606 returned_length = 0;
3607 returned_format = 0;
3610 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3611 hdr_size = sizeof(*hdr12);
3612 hdr_max = SRDDH12_MAX_LENGTH;
3614 if (valid_len >= hdr_size) {
3615 returned_length = scsi_4btoul(hdr12->length);
3616 returned_format = hdr12->format;
3618 returned_length = 0;
3619 returned_format = 0;
3623 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3624 switch (returned_type) {
3625 case SRDD10_BLOCK_FORMAT:
3626 entry_size = sizeof(struct scsi_defect_desc_block);
3628 case SRDD10_LONG_BLOCK_FORMAT:
3629 entry_size = sizeof(struct scsi_defect_desc_long_block);
3631 case SRDD10_EXT_PHYS_FORMAT:
3632 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3633 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3635 case SRDD10_EXT_BFI_FORMAT:
3636 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3637 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3640 warnx("Unknown defect format 0x%x\n", returned_type);
3642 goto defect_bailout;
3646 max_possible_size = (hdr_max / entry_size) * entry_size;
3647 num_returned = returned_length / entry_size;
3648 num_valid = min(returned_length, valid_len - hdr_size);
3649 num_valid /= entry_size;
3651 if (get_length != 0) {
3654 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3655 CAM_SCSI_STATUS_ERROR) {
3656 struct scsi_sense_data *sense;
3657 int error_code, sense_key, asc, ascq;
3659 sense = &ccb->csio.sense_data;
3660 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3661 ccb->csio.sense_resid, &error_code, &sense_key,
3662 &asc, &ascq, /*show_errors*/ 1);
3665 * If the drive is reporting that it just doesn't
3666 * support the defect list format, go ahead and use
3667 * the length it reported. Otherwise, the length
3668 * may not be valid, so use the maximum.
3670 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3671 && (asc == 0x1c) && (ascq == 0x00)
3672 && (returned_length > 0)) {
3673 if ((use_12byte == 0)
3674 && (returned_length >= max_possible_size)) {
3679 dlist_length = returned_length + hdr_size;
3680 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3681 && (asc == 0x1f) && (ascq == 0x00)
3682 && (returned_length > 0)) {
3683 /* Partial defect list transfer */
3685 * Hitachi drives return this error
3686 * along with a partial defect list if they
3687 * have more defects than the 10 byte
3688 * command can support. Retry with the 12
3691 if (use_12byte == 0) {
3696 dlist_length = returned_length + hdr_size;
3697 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3698 && (asc == 0x24) && (ascq == 0x00)) {
3699 /* Invalid field in CDB */
3701 * SBC-3 says that if the drive has more
3702 * defects than can be reported with the
3703 * 10 byte command, it should return this
3704 * error and no data. Retry with the 12
3707 if (use_12byte == 0) {
3712 dlist_length = returned_length + hdr_size;
3715 * If we got a SCSI error and no valid length,
3716 * just use the 10 byte maximum. The 12
3717 * byte maximum is too large.
3719 if (returned_length == 0)
3720 dlist_length = SRDD10_MAX_LENGTH;
3722 if ((use_12byte == 0)
3723 && (returned_length >=
3724 max_possible_size)) {
3729 dlist_length = returned_length +
3733 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3736 warnx("Error reading defect header");
3737 if (arglist & CAM_ARG_VERBOSE)
3738 cam_error_print(device, ccb, CAM_ESF_ALL,
3739 CAM_EPF_ALL, stderr);
3740 goto defect_bailout;
3742 if ((use_12byte == 0)
3743 && (returned_length >= max_possible_size)) {
3748 dlist_length = returned_length + hdr_size;
3751 fprintf(stdout, "%u", num_returned);
3753 fprintf(stdout, " defect%s",
3754 (num_returned != 1) ? "s" : "");
3756 fprintf(stdout, "\n");
3758 goto defect_bailout;
3762 * We always limit the list length to the 10-byte maximum
3763 * length (0xffff). The reason is that some controllers
3764 * can't handle larger I/Os, and we can transfer the entire
3765 * 10 byte list in one shot. For drives that support the 12
3766 * byte read defects command, we'll step through the list
3767 * by specifying a starting offset. For drives that don't
3768 * support the 12 byte command's starting offset, we'll
3769 * just display the first 64K.
3771 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3777 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3778 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3779 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3780 struct scsi_sense_data *sense;
3781 int error_code, sense_key, asc, ascq;
3783 sense = &ccb->csio.sense_data;
3784 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3785 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3786 &ascq, /*show_errors*/ 1);
3789 * According to the SCSI spec, if the disk doesn't support
3790 * the requested format, it will generally return a sense
3791 * key of RECOVERED ERROR, and an additional sense code
3792 * of "DEFECT LIST NOT FOUND". HGST drives also return
3793 * Primary/Grown defect list not found errors. So just
3794 * check for an ASC of 0x1c.
3796 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3798 const char *format_str;
3800 format_str = scsi_nv_to_str(defect_list_type_map,
3801 sizeof(defect_list_type_map) /
3802 sizeof(defect_list_type_map[0]),
3803 list_format & SRDD10_DLIST_FORMAT_MASK);
3804 warnx("requested defect format %s not available",
3805 format_str ? format_str : "unknown");
3807 format_str = scsi_nv_to_str(defect_list_type_map,
3808 sizeof(defect_list_type_map) /
3809 sizeof(defect_list_type_map[0]), returned_type);
3810 if (format_str != NULL) {
3811 warnx("Device returned %s format",
3815 warnx("Device returned unknown defect"
3816 " data format %#x", returned_type);
3817 goto defect_bailout;
3821 warnx("Error returned from read defect data command");
3822 if (arglist & CAM_ARG_VERBOSE)
3823 cam_error_print(device, ccb, CAM_ESF_ALL,
3824 CAM_EPF_ALL, stderr);
3825 goto defect_bailout;
3827 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3829 warnx("Error returned from read defect data command");
3830 if (arglist & CAM_ARG_VERBOSE)
3831 cam_error_print(device, ccb, CAM_ESF_ALL,
3832 CAM_EPF_ALL, stderr);
3833 goto defect_bailout;
3836 if (first_pass != 0) {
3837 fprintf(stderr, "Got %d defect", num_returned);
3839 if ((lists_specified == 0) || (num_returned == 0)) {
3840 fprintf(stderr, "s.\n");
3841 goto defect_bailout;
3842 } else if (num_returned == 1)
3843 fprintf(stderr, ":\n");
3845 fprintf(stderr, "s:\n");
3851 * XXX KDM I should probably clean up the printout format for the
3854 switch (returned_type) {
3855 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3856 case SRDD10_EXT_PHYS_FORMAT:
3858 struct scsi_defect_desc_phys_sector *dlist;
3860 dlist = (struct scsi_defect_desc_phys_sector *)
3861 (defect_list + hdr_size);
3863 for (i = 0; i < num_valid; i++) {
3866 sector = scsi_4btoul(dlist[i].sector);
3867 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3868 mads = (sector & SDD_EXT_PHYS_MADS) ?
3870 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3872 if (hex_format == 0)
3873 fprintf(stdout, "%d:%d:%d%s",
3874 scsi_3btoul(dlist[i].cylinder),
3876 scsi_4btoul(dlist[i].sector),
3877 mads ? " - " : "\n");
3879 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3880 scsi_3btoul(dlist[i].cylinder),
3882 scsi_4btoul(dlist[i].sector),
3883 mads ? " - " : "\n");
3886 if (num_valid < num_returned) {
3887 starting_offset += num_valid;
3892 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3893 case SRDD10_EXT_BFI_FORMAT:
3895 struct scsi_defect_desc_bytes_from_index *dlist;
3897 dlist = (struct scsi_defect_desc_bytes_from_index *)
3898 (defect_list + hdr_size);
3900 for (i = 0; i < num_valid; i++) {
3903 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3904 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3905 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3906 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3908 if (hex_format == 0)
3909 fprintf(stdout, "%d:%d:%d%s",
3910 scsi_3btoul(dlist[i].cylinder),
3912 scsi_4btoul(dlist[i].bytes_from_index),
3913 mads ? " - " : "\n");
3915 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3916 scsi_3btoul(dlist[i].cylinder),
3918 scsi_4btoul(dlist[i].bytes_from_index),
3919 mads ? " - " : "\n");
3923 if (num_valid < num_returned) {
3924 starting_offset += num_valid;
3929 case SRDDH10_BLOCK_FORMAT:
3931 struct scsi_defect_desc_block *dlist;
3933 dlist = (struct scsi_defect_desc_block *)
3934 (defect_list + hdr_size);
3936 for (i = 0; i < num_valid; i++) {
3937 if (hex_format == 0)
3938 fprintf(stdout, "%u\n",
3939 scsi_4btoul(dlist[i].address));
3941 fprintf(stdout, "0x%x\n",
3942 scsi_4btoul(dlist[i].address));
3945 if (num_valid < num_returned) {
3946 starting_offset += num_valid;
3952 case SRDD10_LONG_BLOCK_FORMAT:
3954 struct scsi_defect_desc_long_block *dlist;
3956 dlist = (struct scsi_defect_desc_long_block *)
3957 (defect_list + hdr_size);
3959 for (i = 0; i < num_valid; i++) {
3960 if (hex_format == 0)
3961 fprintf(stdout, "%ju\n",
3962 (uintmax_t)scsi_8btou64(
3965 fprintf(stdout, "0x%jx\n",
3966 (uintmax_t)scsi_8btou64(
3970 if (num_valid < num_returned) {
3971 starting_offset += num_valid;
3977 fprintf(stderr, "Unknown defect format 0x%x\n",
3984 if (defect_list != NULL)
3992 #endif /* MINIMALISTIC */
3996 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4000 ccb = cam_getccb(device);
4006 #ifndef MINIMALISTIC
4008 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4009 int task_attr, int retry_count, int timeout, u_int8_t *data,
4015 ccb = cam_getccb(device);
4018 errx(1, "mode_sense: couldn't allocate CCB");
4020 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4022 scsi_mode_sense_subpage(&ccb->csio,
4023 /* retries */ retry_count,
4025 /* tag_action */ task_attr,
4029 /* subpage */ subpage,
4030 /* param_buf */ data,
4031 /* param_len */ datalen,
4032 /* minimum_cmd_size */ 0,
4033 /* sense_len */ SSD_FULL_SIZE,
4034 /* timeout */ timeout ? timeout : 5000);
4036 if (arglist & CAM_ARG_ERR_RECOVER)
4037 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4039 /* Disable freezing the device queue */
4040 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4042 if (((retval = cam_send_ccb(device, ccb)) < 0)
4043 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4044 if (arglist & CAM_ARG_VERBOSE) {
4045 cam_error_print(device, ccb, CAM_ESF_ALL,
4046 CAM_EPF_ALL, stderr);
4049 cam_close_device(device);
4051 err(1, "error sending mode sense command");
4053 errx(1, "error sending mode sense command");
4060 mode_select(struct cam_device *device, int save_pages, int task_attr,
4061 int retry_count, int timeout, u_int8_t *data, int datalen)
4066 ccb = cam_getccb(device);
4069 errx(1, "mode_select: couldn't allocate CCB");
4071 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4073 scsi_mode_select(&ccb->csio,
4074 /* retries */ retry_count,
4076 /* tag_action */ task_attr,
4077 /* scsi_page_fmt */ 1,
4078 /* save_pages */ save_pages,
4079 /* param_buf */ data,
4080 /* param_len */ datalen,
4081 /* sense_len */ SSD_FULL_SIZE,
4082 /* timeout */ timeout ? timeout : 5000);
4084 if (arglist & CAM_ARG_ERR_RECOVER)
4085 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4087 /* Disable freezing the device queue */
4088 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4090 if (((retval = cam_send_ccb(device, ccb)) < 0)
4091 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4092 if (arglist & CAM_ARG_VERBOSE) {
4093 cam_error_print(device, ccb, CAM_ESF_ALL,
4094 CAM_EPF_ALL, stderr);
4097 cam_close_device(device);
4100 err(1, "error sending mode select command");
4102 errx(1, "error sending mode select command");
4110 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4111 int task_attr, int retry_count, int timeout)
4114 int c, page = -1, subpage = -1, pc = 0;
4115 int binary = 0, dbd = 0, edit = 0, list = 0;
4117 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4132 str_subpage = optarg;
4133 strsep(&str_subpage, ",");
4134 page = strtol(optarg, NULL, 0);
4136 subpage = strtol(str_subpage, NULL, 0);
4140 errx(1, "invalid mode page %d", page);
4142 errx(1, "invalid mode subpage %d", subpage);
4145 pc = strtol(optarg, NULL, 0);
4146 if ((pc < 0) || (pc > 3))
4147 errx(1, "invalid page control field %d", pc);
4154 if (page == -1 && list == 0)
4155 errx(1, "you must specify a mode page!");
4158 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4161 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4162 task_attr, retry_count, timeout);
4167 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4168 int task_attr, int retry_count, int timeout)
4171 u_int32_t flags = CAM_DIR_NONE;
4172 u_int8_t *data_ptr = NULL;
4174 u_int8_t atacmd[12];
4175 struct get_hook hook;
4176 int c, data_bytes = 0, valid_bytes;
4182 char *datastr = NULL, *tstr, *resstr = NULL;
4184 int fd_data = 0, fd_res = 0;
4187 ccb = cam_getccb(device);
4190 warnx("scsicmd: error allocating ccb");
4194 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4196 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4200 while (isspace(*tstr) && (*tstr != '\0'))
4202 hook.argc = argc - optind;
4203 hook.argv = argv + optind;
4205 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4208 * Increment optind by the number of arguments the
4209 * encoding routine processed. After each call to
4210 * getopt(3), optind points to the argument that
4211 * getopt should process _next_. In this case,
4212 * that means it points to the first command string
4213 * argument, if there is one. Once we increment
4214 * this, it should point to either the next command
4215 * line argument, or it should be past the end of
4222 while (isspace(*tstr) && (*tstr != '\0'))
4224 hook.argc = argc - optind;
4225 hook.argv = argv + optind;
4227 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4230 * Increment optind by the number of arguments the
4231 * encoding routine processed. After each call to
4232 * getopt(3), optind points to the argument that
4233 * getopt should process _next_. In this case,
4234 * that means it points to the first command string
4235 * argument, if there is one. Once we increment
4236 * this, it should point to either the next command
4237 * line argument, or it should be past the end of
4249 if (arglist & CAM_ARG_CMD_OUT) {
4250 warnx("command must either be "
4251 "read or write, not both");
4253 goto scsicmd_bailout;
4255 arglist |= CAM_ARG_CMD_IN;
4257 data_bytes = strtol(optarg, NULL, 0);
4258 if (data_bytes <= 0) {
4259 warnx("invalid number of input bytes %d",
4262 goto scsicmd_bailout;
4264 hook.argc = argc - optind;
4265 hook.argv = argv + optind;
4268 datastr = cget(&hook, NULL);
4270 * If the user supplied "-" instead of a format, he
4271 * wants the data to be written to stdout.
4273 if ((datastr != NULL)
4274 && (datastr[0] == '-'))
4277 data_ptr = (u_int8_t *)malloc(data_bytes);
4278 if (data_ptr == NULL) {
4279 warnx("can't malloc memory for data_ptr");
4281 goto scsicmd_bailout;
4285 if (arglist & CAM_ARG_CMD_IN) {
4286 warnx("command must either be "
4287 "read or write, not both");
4289 goto scsicmd_bailout;
4291 arglist |= CAM_ARG_CMD_OUT;
4292 flags = CAM_DIR_OUT;
4293 data_bytes = strtol(optarg, NULL, 0);
4294 if (data_bytes <= 0) {
4295 warnx("invalid number of output bytes %d",
4298 goto scsicmd_bailout;
4300 hook.argc = argc - optind;
4301 hook.argv = argv + optind;
4303 datastr = cget(&hook, NULL);
4304 data_ptr = (u_int8_t *)malloc(data_bytes);
4305 if (data_ptr == NULL) {
4306 warnx("can't malloc memory for data_ptr");
4308 goto scsicmd_bailout;
4310 bzero(data_ptr, data_bytes);
4312 * If the user supplied "-" instead of a format, he
4313 * wants the data to be read from stdin.
4315 if ((datastr != NULL)
4316 && (datastr[0] == '-'))
4319 buff_encode_visit(data_ptr, data_bytes, datastr,
4325 hook.argc = argc - optind;
4326 hook.argv = argv + optind;
4328 resstr = cget(&hook, NULL);
4329 if ((resstr != NULL) && (resstr[0] == '-'))
4339 * If fd_data is set, and we're writing to the device, we need to
4340 * read the data the user wants written from stdin.
4342 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4344 int amt_to_read = data_bytes;
4345 u_int8_t *buf_ptr = data_ptr;
4347 for (amt_read = 0; amt_to_read > 0;
4348 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4349 if (amt_read == -1) {
4350 warn("error reading data from stdin");
4352 goto scsicmd_bailout;
4354 amt_to_read -= amt_read;
4355 buf_ptr += amt_read;
4359 if (arglist & CAM_ARG_ERR_RECOVER)
4360 flags |= CAM_PASS_ERR_RECOVER;
4362 /* Disable freezing the device queue */
4363 flags |= CAM_DEV_QFRZDIS;
4367 * This is taken from the SCSI-3 draft spec.
4368 * (T10/1157D revision 0.3)
4369 * The top 3 bits of an opcode are the group code.
4370 * The next 5 bits are the command code.
4371 * Group 0: six byte commands
4372 * Group 1: ten byte commands
4373 * Group 2: ten byte commands
4375 * Group 4: sixteen byte commands
4376 * Group 5: twelve byte commands
4377 * Group 6: vendor specific
4378 * Group 7: vendor specific
4380 switch((cdb[0] >> 5) & 0x7) {
4391 /* computed by buff_encode_visit */
4402 * We should probably use csio_build_visit or something like that
4403 * here, but it's easier to encode arguments as you go. The
4404 * alternative would be skipping the CDB argument and then encoding
4405 * it here, since we've got the data buffer argument by now.
4407 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4409 cam_fill_csio(&ccb->csio,
4410 /*retries*/ retry_count,
4413 /*tag_action*/ task_attr,
4414 /*data_ptr*/ data_ptr,
4415 /*dxfer_len*/ data_bytes,
4416 /*sense_len*/ SSD_FULL_SIZE,
4417 /*cdb_len*/ cdb_len,
4418 /*timeout*/ timeout ? timeout : 5000);
4421 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4423 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4425 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4427 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4429 cam_fill_ataio(&ccb->ataio,
4430 /*retries*/ retry_count,
4434 /*data_ptr*/ data_ptr,
4435 /*dxfer_len*/ data_bytes,
4436 /*timeout*/ timeout ? timeout : 5000);
4439 if (((retval = cam_send_ccb(device, ccb)) < 0)
4440 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4441 const char warnstr[] = "error sending command";
4448 if (arglist & CAM_ARG_VERBOSE) {
4449 cam_error_print(device, ccb, CAM_ESF_ALL,
4450 CAM_EPF_ALL, stderr);
4454 goto scsicmd_bailout;
4457 if (atacmd_len && need_res) {
4459 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4461 fprintf(stdout, "\n");
4464 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4465 ccb->ataio.res.status,
4466 ccb->ataio.res.error,
4467 ccb->ataio.res.lba_low,
4468 ccb->ataio.res.lba_mid,
4469 ccb->ataio.res.lba_high,
4470 ccb->ataio.res.device,
4471 ccb->ataio.res.lba_low_exp,
4472 ccb->ataio.res.lba_mid_exp,
4473 ccb->ataio.res.lba_high_exp,
4474 ccb->ataio.res.sector_count,
4475 ccb->ataio.res.sector_count_exp);
4481 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4483 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4484 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4485 && (arglist & CAM_ARG_CMD_IN)
4486 && (valid_bytes > 0)) {
4488 buff_decode_visit(data_ptr, valid_bytes, datastr,
4490 fprintf(stdout, "\n");
4492 ssize_t amt_written;
4493 int amt_to_write = valid_bytes;
4494 u_int8_t *buf_ptr = data_ptr;
4496 for (amt_written = 0; (amt_to_write > 0) &&
4497 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4498 amt_to_write -= amt_written;
4499 buf_ptr += amt_written;
4501 if (amt_written == -1) {
4502 warn("error writing data to stdout");
4504 goto scsicmd_bailout;
4505 } else if ((amt_written == 0)
4506 && (amt_to_write > 0)) {
4507 warnx("only wrote %u bytes out of %u",
4508 valid_bytes - amt_to_write, valid_bytes);
4515 if ((data_bytes > 0) && (data_ptr != NULL))
4524 camdebug(int argc, char **argv, char *combinedopt)
4527 path_id_t bus = CAM_BUS_WILDCARD;
4528 target_id_t target = CAM_TARGET_WILDCARD;
4529 lun_id_t lun = CAM_LUN_WILDCARD;
4530 char *tstr, *tmpstr = NULL;
4534 bzero(&ccb, sizeof(union ccb));
4536 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4539 arglist |= CAM_ARG_DEBUG_INFO;
4540 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4543 arglist |= CAM_ARG_DEBUG_PERIPH;
4544 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4547 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4548 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4551 arglist |= CAM_ARG_DEBUG_TRACE;
4552 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4555 arglist |= CAM_ARG_DEBUG_XPT;
4556 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4559 arglist |= CAM_ARG_DEBUG_CDB;
4560 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4563 arglist |= CAM_ARG_DEBUG_PROBE;
4564 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4571 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4572 warnx("error opening transport layer device %s", XPT_DEVICE);
4573 warn("%s", XPT_DEVICE);
4580 warnx("you must specify \"off\", \"all\" or a bus,");
4581 warnx("bus:target, or bus:target:lun");
4588 while (isspace(*tstr) && (*tstr != '\0'))
4591 if (strncmp(tstr, "off", 3) == 0) {
4592 ccb.cdbg.flags = CAM_DEBUG_NONE;
4593 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4594 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4595 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4596 } else if (strncmp(tstr, "all", 3) != 0) {
4597 tmpstr = (char *)strtok(tstr, ":");
4598 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4599 bus = strtol(tmpstr, NULL, 0);
4600 arglist |= CAM_ARG_BUS;
4601 tmpstr = (char *)strtok(NULL, ":");
4602 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4603 target = strtol(tmpstr, NULL, 0);
4604 arglist |= CAM_ARG_TARGET;
4605 tmpstr = (char *)strtok(NULL, ":");
4606 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4607 lun = strtol(tmpstr, NULL, 0);
4608 arglist |= CAM_ARG_LUN;
4613 warnx("you must specify \"all\", \"off\", or a bus,");
4614 warnx("bus:target, or bus:target:lun to debug");
4620 ccb.ccb_h.func_code = XPT_DEBUG;
4621 ccb.ccb_h.path_id = bus;
4622 ccb.ccb_h.target_id = target;
4623 ccb.ccb_h.target_lun = lun;
4625 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4626 warn("CAMIOCOMMAND ioctl failed");
4631 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4632 CAM_FUNC_NOTAVAIL) {
4633 warnx("CAM debugging not available");
4634 warnx("you need to put options CAMDEBUG in"
4635 " your kernel config file!");
4637 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4639 warnx("XPT_DEBUG CCB failed with status %#x",
4643 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4645 "Debugging turned off\n");
4648 "Debugging enabled for "
4650 bus, target, (uintmax_t)lun);
4661 tagcontrol(struct cam_device *device, int argc, char **argv,
4671 ccb = cam_getccb(device);
4674 warnx("tagcontrol: error allocating ccb");
4678 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4681 numtags = strtol(optarg, NULL, 0);
4683 warnx("tag count %d is < 0", numtags);
4685 goto tagcontrol_bailout;
4696 cam_path_string(device, pathstr, sizeof(pathstr));
4699 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4700 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4701 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4702 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4703 ccb->crs.openings = numtags;
4706 if (cam_send_ccb(device, ccb) < 0) {
4707 perror("error sending XPT_REL_SIMQ CCB");
4709 goto tagcontrol_bailout;
4712 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4713 warnx("XPT_REL_SIMQ CCB failed");
4714 cam_error_print(device, ccb, CAM_ESF_ALL,
4715 CAM_EPF_ALL, stderr);
4717 goto tagcontrol_bailout;
4722 fprintf(stdout, "%stagged openings now %d\n",
4723 pathstr, ccb->crs.openings);
4726 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4728 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4730 if (cam_send_ccb(device, ccb) < 0) {
4731 perror("error sending XPT_GDEV_STATS CCB");
4733 goto tagcontrol_bailout;
4736 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4737 warnx("XPT_GDEV_STATS CCB failed");
4738 cam_error_print(device, ccb, CAM_ESF_ALL,
4739 CAM_EPF_ALL, stderr);
4741 goto tagcontrol_bailout;
4744 if (arglist & CAM_ARG_VERBOSE) {
4745 fprintf(stdout, "%s", pathstr);
4746 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4747 fprintf(stdout, "%s", pathstr);
4748 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4749 fprintf(stdout, "%s", pathstr);
4750 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4751 fprintf(stdout, "%s", pathstr);
4752 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4753 fprintf(stdout, "%s", pathstr);
4754 fprintf(stdout, "held %d\n", ccb->cgds.held);
4755 fprintf(stdout, "%s", pathstr);
4756 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4757 fprintf(stdout, "%s", pathstr);
4758 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4761 fprintf(stdout, "%s", pathstr);
4762 fprintf(stdout, "device openings: ");
4764 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4765 ccb->cgds.dev_active);
4775 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4779 cam_path_string(device, pathstr, sizeof(pathstr));
4781 if (cts->transport == XPORT_SPI) {
4782 struct ccb_trans_settings_spi *spi =
4783 &cts->xport_specific.spi;
4785 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4787 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4790 if (spi->sync_offset != 0) {
4793 freq = scsi_calc_syncsrate(spi->sync_period);
4794 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4795 pathstr, freq / 1000, freq % 1000);
4799 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4800 fprintf(stdout, "%soffset: %d\n", pathstr,
4804 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4805 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4806 (0x01 << spi->bus_width) * 8);
4809 if (spi->valid & CTS_SPI_VALID_DISC) {
4810 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4811 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4812 "enabled" : "disabled");
4815 if (cts->transport == XPORT_FC) {
4816 struct ccb_trans_settings_fc *fc =
4817 &cts->xport_specific.fc;
4819 if (fc->valid & CTS_FC_VALID_WWNN)
4820 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4821 (long long) fc->wwnn);
4822 if (fc->valid & CTS_FC_VALID_WWPN)
4823 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4824 (long long) fc->wwpn);
4825 if (fc->valid & CTS_FC_VALID_PORT)
4826 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4827 if (fc->valid & CTS_FC_VALID_SPEED)
4828 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4829 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4831 if (cts->transport == XPORT_SAS) {
4832 struct ccb_trans_settings_sas *sas =
4833 &cts->xport_specific.sas;
4835 if (sas->valid & CTS_SAS_VALID_SPEED)
4836 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4837 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4839 if (cts->transport == XPORT_ATA) {
4840 struct ccb_trans_settings_pata *pata =
4841 &cts->xport_specific.ata;
4843 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4844 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4845 ata_mode2string(pata->mode));
4847 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4848 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4851 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4852 fprintf(stdout, "%sPIO transaction length: %d\n",
4853 pathstr, pata->bytecount);
4856 if (cts->transport == XPORT_SATA) {
4857 struct ccb_trans_settings_sata *sata =
4858 &cts->xport_specific.sata;
4860 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4861 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4864 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4865 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4866 ata_mode2string(sata->mode));
4868 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4869 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4872 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4873 fprintf(stdout, "%sPIO transaction length: %d\n",
4874 pathstr, sata->bytecount);
4876 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4877 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4880 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4881 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4884 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4885 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4889 if (cts->protocol == PROTO_ATA) {
4890 struct ccb_trans_settings_ata *ata=
4891 &cts->proto_specific.ata;
4893 if (ata->valid & CTS_ATA_VALID_TQ) {
4894 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4895 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4896 "enabled" : "disabled");
4899 if (cts->protocol == PROTO_SCSI) {
4900 struct ccb_trans_settings_scsi *scsi=
4901 &cts->proto_specific.scsi;
4903 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4904 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4905 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4906 "enabled" : "disabled");
4913 * Get a path inquiry CCB for the specified device.
4916 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4921 ccb = cam_getccb(device);
4923 warnx("get_cpi: couldn't allocate CCB");
4926 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
4927 ccb->ccb_h.func_code = XPT_PATH_INQ;
4928 if (cam_send_ccb(device, ccb) < 0) {
4929 warn("get_cpi: error sending Path Inquiry CCB");
4930 if (arglist & CAM_ARG_VERBOSE)
4931 cam_error_print(device, ccb, CAM_ESF_ALL,
4932 CAM_EPF_ALL, stderr);
4934 goto get_cpi_bailout;
4936 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4937 if (arglist & CAM_ARG_VERBOSE)
4938 cam_error_print(device, ccb, CAM_ESF_ALL,
4939 CAM_EPF_ALL, stderr);
4941 goto get_cpi_bailout;
4943 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4951 * Get a get device CCB for the specified device.
4954 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4959 ccb = cam_getccb(device);
4961 warnx("get_cgd: couldn't allocate CCB");
4964 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
4965 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4966 if (cam_send_ccb(device, ccb) < 0) {
4967 warn("get_cgd: error sending Path Inquiry CCB");
4968 if (arglist & CAM_ARG_VERBOSE)
4969 cam_error_print(device, ccb, CAM_ESF_ALL,
4970 CAM_EPF_ALL, stderr);
4972 goto get_cgd_bailout;
4974 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4975 if (arglist & CAM_ARG_VERBOSE)
4976 cam_error_print(device, ccb, CAM_ESF_ALL,
4977 CAM_EPF_ALL, stderr);
4979 goto get_cgd_bailout;
4981 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4989 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4993 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4994 int timeout, int verbosemode)
4996 union ccb *ccb = NULL;
4997 struct scsi_vpd_supported_page_list sup_pages;
5001 ccb = cam_getccb(dev);
5003 warn("Unable to allocate CCB");
5008 /* cam_getccb cleans up the header, caller has to zero the payload */
5009 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5011 bzero(&sup_pages, sizeof(sup_pages));
5013 scsi_inquiry(&ccb->csio,
5014 /*retries*/ retry_count,
5016 /* tag_action */ MSG_SIMPLE_Q_TAG,
5017 /* inq_buf */ (u_int8_t *)&sup_pages,
5018 /* inq_len */ sizeof(sup_pages),
5020 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5021 /* sense_len */ SSD_FULL_SIZE,
5022 /* timeout */ timeout ? timeout : 5000);
5024 /* Disable freezing the device queue */
5025 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5027 if (retry_count != 0)
5028 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5030 if (cam_send_ccb(dev, ccb) < 0) {
5037 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5038 if (verbosemode != 0)
5039 cam_error_print(dev, ccb, CAM_ESF_ALL,
5040 CAM_EPF_ALL, stderr);
5045 for (i = 0; i < sup_pages.length; i++) {
5046 if (sup_pages.list[i] == page_id) {
5059 * devtype is filled in with the type of device.
5060 * Returns 0 for success, non-zero for failure.
5063 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5064 int verbosemode, camcontrol_devtype *devtype)
5066 struct ccb_getdev cgd;
5069 retval = get_cgd(dev, &cgd);
5073 switch (cgd.protocol) {
5079 *devtype = CC_DT_ATA;
5081 break; /*NOTREACHED*/
5083 *devtype = CC_DT_UNKNOWN;
5085 break; /*NOTREACHED*/
5089 * Check for the ATA Information VPD page (0x89). If this is an
5090 * ATA device behind a SCSI to ATA translation layer, this VPD page
5091 * should be present.
5093 * If that VPD page isn't present, or we get an error back from the
5094 * INQUIRY command, we'll just treat it as a normal SCSI device.
5096 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5097 timeout, verbosemode);
5099 *devtype = CC_DT_ATA_BEHIND_SCSI;
5101 *devtype = CC_DT_SCSI;
5110 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5111 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5112 uint16_t sector_count, uint64_t lba, uint8_t command, uint8_t *data_ptr,
5113 uint16_t dxfer_len, uint8_t sense_len, uint32_t timeout,
5114 int is48bit, camcontrol_devtype devtype)
5116 if (devtype == CC_DT_ATA) {
5117 cam_fill_ataio(&ccb->ataio,
5118 /*retries*/ retry_count,
5121 /*tag_action*/ tag_action,
5122 /*data_ptr*/ data_ptr,
5123 /*dxfer_len*/ dxfer_len,
5124 /*timeout*/ timeout);
5125 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5126 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5129 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5132 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5133 protocol |= AP_EXTEND;
5135 scsi_ata_pass_16(&ccb->csio,
5136 /*retries*/ retry_count,
5139 /*tag_action*/ tag_action,
5140 /*protocol*/ protocol,
5141 /*ata_flags*/ ata_flags,
5142 /*features*/ features,
5143 /*sector_count*/ sector_count,
5145 /*command*/ command,
5147 /*data_ptr*/ data_ptr,
5148 /*dxfer_len*/ dxfer_len,
5149 /*sense_len*/ sense_len,
5150 /*timeout*/ timeout);
5156 cpi_print(struct ccb_pathinq *cpi)
5158 char adapter_str[1024];
5161 snprintf(adapter_str, sizeof(adapter_str),
5162 "%s%d:", cpi->dev_name, cpi->unit_number);
5164 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5167 for (i = 1; i < UINT8_MAX; i = i << 1) {
5170 if ((i & cpi->hba_inquiry) == 0)
5173 fprintf(stdout, "%s supports ", adapter_str);
5177 str = "MDP message";
5180 str = "32 bit wide SCSI";
5183 str = "16 bit wide SCSI";
5186 str = "SDTR message";
5189 str = "linked CDBs";
5192 str = "tag queue messages";
5195 str = "soft reset alternative";
5198 str = "SATA Port Multiplier";
5201 str = "unknown PI bit set";
5204 fprintf(stdout, "%s\n", str);
5207 for (i = 1; i < UINT32_MAX; i = i << 1) {
5210 if ((i & cpi->hba_misc) == 0)
5213 fprintf(stdout, "%s ", adapter_str);
5217 str = "bus scans from high ID to low ID";
5220 str = "removable devices not included in scan";
5222 case PIM_NOINITIATOR:
5223 str = "initiator role not supported";
5225 case PIM_NOBUSRESET:
5226 str = "user has disabled initial BUS RESET or"
5227 " controller is in target/mixed mode";
5230 str = "do not send 6-byte commands";
5233 str = "scan bus sequentially";
5236 str = "unknown PIM bit set";
5239 fprintf(stdout, "%s\n", str);
5242 for (i = 1; i < UINT16_MAX; i = i << 1) {
5245 if ((i & cpi->target_sprt) == 0)
5248 fprintf(stdout, "%s supports ", adapter_str);
5251 str = "target mode processor mode";
5254 str = "target mode phase cog. mode";
5256 case PIT_DISCONNECT:
5257 str = "disconnects in target mode";
5260 str = "terminate I/O message in target mode";
5263 str = "group 6 commands in target mode";
5266 str = "group 7 commands in target mode";
5269 str = "unknown PIT bit set";
5273 fprintf(stdout, "%s\n", str);
5275 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5277 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5279 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5281 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5282 adapter_str, cpi->hpath_id);
5283 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5285 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5286 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5287 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5288 adapter_str, cpi->hba_vendor);
5289 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5290 adapter_str, cpi->hba_device);
5291 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5292 adapter_str, cpi->hba_subvendor);
5293 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5294 adapter_str, cpi->hba_subdevice);
5295 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5296 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5297 if (cpi->base_transfer_speed > 1000)
5298 fprintf(stdout, "%d.%03dMB/sec\n",
5299 cpi->base_transfer_speed / 1000,
5300 cpi->base_transfer_speed % 1000);
5302 fprintf(stdout, "%dKB/sec\n",
5303 (cpi->base_transfer_speed % 1000) * 1000);
5304 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5305 adapter_str, cpi->maxio);
5309 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5310 struct ccb_trans_settings *cts)
5316 ccb = cam_getccb(device);
5319 warnx("get_print_cts: error allocating ccb");
5323 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5325 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5327 if (user_settings == 0)
5328 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5330 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5332 if (cam_send_ccb(device, ccb) < 0) {
5333 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5334 if (arglist & CAM_ARG_VERBOSE)
5335 cam_error_print(device, ccb, CAM_ESF_ALL,
5336 CAM_EPF_ALL, stderr);
5338 goto get_print_cts_bailout;
5341 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5342 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5343 if (arglist & CAM_ARG_VERBOSE)
5344 cam_error_print(device, ccb, CAM_ESF_ALL,
5345 CAM_EPF_ALL, stderr);
5347 goto get_print_cts_bailout;
5351 cts_print(device, &ccb->cts);
5354 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5356 get_print_cts_bailout:
5364 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5365 int timeout, int argc, char **argv, char *combinedopt)
5369 int user_settings = 0;
5371 int disc_enable = -1, tag_enable = -1;
5374 double syncrate = -1;
5377 int change_settings = 0, send_tur = 0;
5378 struct ccb_pathinq cpi;
5380 ccb = cam_getccb(device);
5382 warnx("ratecontrol: error allocating ccb");
5385 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5394 if (strncasecmp(optarg, "enable", 6) == 0)
5396 else if (strncasecmp(optarg, "disable", 7) == 0)
5399 warnx("-D argument \"%s\" is unknown", optarg);
5401 goto ratecontrol_bailout;
5403 change_settings = 1;
5406 mode = ata_string2mode(optarg);
5408 warnx("unknown mode '%s'", optarg);
5410 goto ratecontrol_bailout;
5412 change_settings = 1;
5415 offset = strtol(optarg, NULL, 0);
5417 warnx("offset value %d is < 0", offset);
5419 goto ratecontrol_bailout;
5421 change_settings = 1;
5427 syncrate = atof(optarg);
5429 warnx("sync rate %f is < 0", syncrate);
5431 goto ratecontrol_bailout;
5433 change_settings = 1;
5436 if (strncasecmp(optarg, "enable", 6) == 0)
5438 else if (strncasecmp(optarg, "disable", 7) == 0)
5441 warnx("-T argument \"%s\" is unknown", optarg);
5443 goto ratecontrol_bailout;
5445 change_settings = 1;
5451 bus_width = strtol(optarg, NULL, 0);
5452 if (bus_width < 0) {
5453 warnx("bus width %d is < 0", bus_width);
5455 goto ratecontrol_bailout;
5457 change_settings = 1;
5463 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5465 * Grab path inquiry information, so we can determine whether
5466 * or not the initiator is capable of the things that the user
5469 ccb->ccb_h.func_code = XPT_PATH_INQ;
5470 if (cam_send_ccb(device, ccb) < 0) {
5471 perror("error sending XPT_PATH_INQ CCB");
5472 if (arglist & CAM_ARG_VERBOSE) {
5473 cam_error_print(device, ccb, CAM_ESF_ALL,
5474 CAM_EPF_ALL, stderr);
5477 goto ratecontrol_bailout;
5479 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5480 warnx("XPT_PATH_INQ CCB failed");
5481 if (arglist & CAM_ARG_VERBOSE) {
5482 cam_error_print(device, ccb, CAM_ESF_ALL,
5483 CAM_EPF_ALL, stderr);
5486 goto ratecontrol_bailout;
5488 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5489 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5491 fprintf(stdout, "%s parameters:\n",
5492 user_settings ? "User" : "Current");
5494 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5496 goto ratecontrol_bailout;
5498 if (arglist & CAM_ARG_VERBOSE)
5501 if (change_settings) {
5502 int didsettings = 0;
5503 struct ccb_trans_settings_spi *spi = NULL;
5504 struct ccb_trans_settings_pata *pata = NULL;
5505 struct ccb_trans_settings_sata *sata = NULL;
5506 struct ccb_trans_settings_ata *ata = NULL;
5507 struct ccb_trans_settings_scsi *scsi = NULL;
5509 if (ccb->cts.transport == XPORT_SPI)
5510 spi = &ccb->cts.xport_specific.spi;
5511 if (ccb->cts.transport == XPORT_ATA)
5512 pata = &ccb->cts.xport_specific.ata;
5513 if (ccb->cts.transport == XPORT_SATA)
5514 sata = &ccb->cts.xport_specific.sata;
5515 if (ccb->cts.protocol == PROTO_ATA)
5516 ata = &ccb->cts.proto_specific.ata;
5517 if (ccb->cts.protocol == PROTO_SCSI)
5518 scsi = &ccb->cts.proto_specific.scsi;
5519 ccb->cts.xport_specific.valid = 0;
5520 ccb->cts.proto_specific.valid = 0;
5521 if (spi && disc_enable != -1) {
5522 spi->valid |= CTS_SPI_VALID_DISC;
5523 if (disc_enable == 0)
5524 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5526 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5529 if (tag_enable != -1) {
5530 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5531 warnx("HBA does not support tagged queueing, "
5532 "so you cannot modify tag settings");
5534 goto ratecontrol_bailout;
5537 ata->valid |= CTS_SCSI_VALID_TQ;
5538 if (tag_enable == 0)
5539 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5541 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5544 scsi->valid |= CTS_SCSI_VALID_TQ;
5545 if (tag_enable == 0)
5546 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5548 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5552 if (spi && offset != -1) {
5553 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5554 warnx("HBA is not capable of changing offset");
5556 goto ratecontrol_bailout;
5558 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5559 spi->sync_offset = offset;
5562 if (spi && syncrate != -1) {
5563 int prelim_sync_period;
5565 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5566 warnx("HBA is not capable of changing "
5569 goto ratecontrol_bailout;
5571 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5573 * The sync rate the user gives us is in MHz.
5574 * We need to translate it into KHz for this
5579 * Next, we calculate a "preliminary" sync period
5580 * in tenths of a nanosecond.
5583 prelim_sync_period = 0;
5585 prelim_sync_period = 10000000 / syncrate;
5587 scsi_calc_syncparam(prelim_sync_period);
5590 if (sata && syncrate != -1) {
5591 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5592 warnx("HBA is not capable of changing "
5595 goto ratecontrol_bailout;
5597 if (!user_settings) {
5598 warnx("You can modify only user rate "
5599 "settings for SATA");
5601 goto ratecontrol_bailout;
5603 sata->revision = ata_speed2revision(syncrate * 100);
5604 if (sata->revision < 0) {
5605 warnx("Invalid rate %f", syncrate);
5607 goto ratecontrol_bailout;
5609 sata->valid |= CTS_SATA_VALID_REVISION;
5612 if ((pata || sata) && mode != -1) {
5613 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5614 warnx("HBA is not capable of changing "
5617 goto ratecontrol_bailout;
5619 if (!user_settings) {
5620 warnx("You can modify only user mode "
5621 "settings for ATA/SATA");
5623 goto ratecontrol_bailout;
5627 pata->valid |= CTS_ATA_VALID_MODE;
5630 sata->valid |= CTS_SATA_VALID_MODE;
5635 * The bus_width argument goes like this:
5639 * Therefore, if you shift the number of bits given on the
5640 * command line right by 4, you should get the correct
5643 if (spi && bus_width != -1) {
5645 * We might as well validate things here with a
5646 * decipherable error message, rather than what
5647 * will probably be an indecipherable error message
5648 * by the time it gets back to us.
5650 if ((bus_width == 16)
5651 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5652 warnx("HBA does not support 16 bit bus width");
5654 goto ratecontrol_bailout;
5655 } else if ((bus_width == 32)
5656 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5657 warnx("HBA does not support 32 bit bus width");
5659 goto ratecontrol_bailout;
5660 } else if ((bus_width != 8)
5661 && (bus_width != 16)
5662 && (bus_width != 32)) {
5663 warnx("Invalid bus width %d", bus_width);
5665 goto ratecontrol_bailout;
5667 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5668 spi->bus_width = bus_width >> 4;
5671 if (didsettings == 0) {
5672 goto ratecontrol_bailout;
5674 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5675 if (cam_send_ccb(device, ccb) < 0) {
5676 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5677 if (arglist & CAM_ARG_VERBOSE) {
5678 cam_error_print(device, ccb, CAM_ESF_ALL,
5679 CAM_EPF_ALL, stderr);
5682 goto ratecontrol_bailout;
5684 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5685 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5686 if (arglist & CAM_ARG_VERBOSE) {
5687 cam_error_print(device, ccb, CAM_ESF_ALL,
5688 CAM_EPF_ALL, stderr);
5691 goto ratecontrol_bailout;
5695 retval = testunitready(device, task_attr, retry_count, timeout,
5696 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5698 * If the TUR didn't succeed, just bail.
5702 fprintf(stderr, "Test Unit Ready failed\n");
5703 goto ratecontrol_bailout;
5706 if ((change_settings || send_tur) && !quiet &&
5707 (ccb->cts.transport == XPORT_ATA ||
5708 ccb->cts.transport == XPORT_SATA || send_tur)) {
5709 fprintf(stdout, "New parameters:\n");
5710 retval = get_print_cts(device, user_settings, 0, NULL);
5713 ratecontrol_bailout:
5719 scsiformat(struct cam_device *device, int argc, char **argv,
5720 char *combinedopt, int task_attr, int retry_count, int timeout)
5724 int ycount = 0, quiet = 0;
5725 int error = 0, retval = 0;
5726 int use_timeout = 10800 * 1000;
5728 struct format_defect_list_header fh;
5729 u_int8_t *data_ptr = NULL;
5730 u_int32_t dxfer_len = 0;
5732 int num_warnings = 0;
5735 ccb = cam_getccb(device);
5738 warnx("scsiformat: error allocating ccb");
5742 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5744 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5765 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5766 "following device:\n");
5768 error = scsidoinquiry(device, argc, argv, combinedopt,
5769 task_attr, retry_count, timeout);
5772 warnx("scsiformat: error sending inquiry");
5773 goto scsiformat_bailout;
5778 if (!get_confirmation()) {
5780 goto scsiformat_bailout;
5785 use_timeout = timeout;
5788 fprintf(stdout, "Current format timeout is %d seconds\n",
5789 use_timeout / 1000);
5793 * If the user hasn't disabled questions and didn't specify a
5794 * timeout on the command line, ask them if they want the current
5798 && (timeout == 0)) {
5800 int new_timeout = 0;
5802 fprintf(stdout, "Enter new timeout in seconds or press\n"
5803 "return to keep the current timeout [%d] ",
5804 use_timeout / 1000);
5806 if (fgets(str, sizeof(str), stdin) != NULL) {
5808 new_timeout = atoi(str);
5811 if (new_timeout != 0) {
5812 use_timeout = new_timeout * 1000;
5813 fprintf(stdout, "Using new timeout value %d\n",
5814 use_timeout / 1000);
5819 * Keep this outside the if block below to silence any unused
5820 * variable warnings.
5822 bzero(&fh, sizeof(fh));
5825 * If we're in immediate mode, we've got to include the format
5828 if (immediate != 0) {
5829 fh.byte2 = FU_DLH_IMMED;
5830 data_ptr = (u_int8_t *)&fh;
5831 dxfer_len = sizeof(fh);
5832 byte2 = FU_FMT_DATA;
5833 } else if (quiet == 0) {
5834 fprintf(stdout, "Formatting...");
5838 scsi_format_unit(&ccb->csio,
5839 /* retries */ retry_count,
5841 /* tag_action */ task_attr,
5844 /* data_ptr */ data_ptr,
5845 /* dxfer_len */ dxfer_len,
5846 /* sense_len */ SSD_FULL_SIZE,
5847 /* timeout */ use_timeout);
5849 /* Disable freezing the device queue */
5850 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5852 if (arglist & CAM_ARG_ERR_RECOVER)
5853 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5855 if (((retval = cam_send_ccb(device, ccb)) < 0)
5856 || ((immediate == 0)
5857 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5858 const char errstr[] = "error sending format command";
5865 if (arglist & CAM_ARG_VERBOSE) {
5866 cam_error_print(device, ccb, CAM_ESF_ALL,
5867 CAM_EPF_ALL, stderr);
5870 goto scsiformat_bailout;
5874 * If we ran in non-immediate mode, we already checked for errors
5875 * above and printed out any necessary information. If we're in
5876 * immediate mode, we need to loop through and get status
5877 * information periodically.
5879 if (immediate == 0) {
5881 fprintf(stdout, "Format Complete\n");
5883 goto scsiformat_bailout;
5890 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5893 * There's really no need to do error recovery or
5894 * retries here, since we're just going to sit in a
5895 * loop and wait for the device to finish formatting.
5897 scsi_test_unit_ready(&ccb->csio,
5900 /* tag_action */ task_attr,
5901 /* sense_len */ SSD_FULL_SIZE,
5902 /* timeout */ 5000);
5904 /* Disable freezing the device queue */
5905 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5907 retval = cam_send_ccb(device, ccb);
5910 * If we get an error from the ioctl, bail out. SCSI
5911 * errors are expected.
5914 warn("error sending CAMIOCOMMAND ioctl");
5915 if (arglist & CAM_ARG_VERBOSE) {
5916 cam_error_print(device, ccb, CAM_ESF_ALL,
5917 CAM_EPF_ALL, stderr);
5920 goto scsiformat_bailout;
5923 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5925 if ((status != CAM_REQ_CMP)
5926 && (status == CAM_SCSI_STATUS_ERROR)
5927 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5928 struct scsi_sense_data *sense;
5929 int error_code, sense_key, asc, ascq;
5931 sense = &ccb->csio.sense_data;
5932 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5933 ccb->csio.sense_resid, &error_code, &sense_key,
5934 &asc, &ascq, /*show_errors*/ 1);
5937 * According to the SCSI-2 and SCSI-3 specs, a
5938 * drive that is in the middle of a format should
5939 * return NOT READY with an ASC of "logical unit
5940 * not ready, format in progress". The sense key
5941 * specific bytes will then be a progress indicator.
5943 if ((sense_key == SSD_KEY_NOT_READY)
5944 && (asc == 0x04) && (ascq == 0x04)) {
5947 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5948 ccb->csio.sense_resid, sks) == 0)
5951 u_int64_t percentage;
5953 val = scsi_2btoul(&sks[1]);
5954 percentage = 10000 * val;
5957 "\rFormatting: %ju.%02u %% "
5959 (uintmax_t)(percentage /
5961 (unsigned)((percentage /
5965 } else if ((quiet == 0)
5966 && (++num_warnings <= 1)) {
5967 warnx("Unexpected SCSI Sense Key "
5968 "Specific value returned "
5970 scsi_sense_print(device, &ccb->csio,
5972 warnx("Unable to print status "
5973 "information, but format will "
5975 warnx("will exit when format is "
5980 warnx("Unexpected SCSI error during format");
5981 cam_error_print(device, ccb, CAM_ESF_ALL,
5982 CAM_EPF_ALL, stderr);
5984 goto scsiformat_bailout;
5987 } else if (status != CAM_REQ_CMP) {
5988 warnx("Unexpected CAM status %#x", status);
5989 if (arglist & CAM_ARG_VERBOSE)
5990 cam_error_print(device, ccb, CAM_ESF_ALL,
5991 CAM_EPF_ALL, stderr);
5993 goto scsiformat_bailout;
5996 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5999 fprintf(stdout, "\nFormat Complete\n");
6009 scsisanitize(struct cam_device *device, int argc, char **argv,
6010 char *combinedopt, int task_attr, int retry_count, int timeout)
6013 u_int8_t action = 0;
6015 int ycount = 0, quiet = 0;
6016 int error = 0, retval = 0;
6017 int use_timeout = 10800 * 1000;
6023 const char *pattern = NULL;
6024 u_int8_t *data_ptr = NULL;
6025 u_int32_t dxfer_len = 0;
6027 int num_warnings = 0;
6030 ccb = cam_getccb(device);
6033 warnx("scsisanitize: error allocating ccb");
6037 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6039 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6042 if (strcasecmp(optarg, "overwrite") == 0)
6043 action = SSZ_SERVICE_ACTION_OVERWRITE;
6044 else if (strcasecmp(optarg, "block") == 0)
6045 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6046 else if (strcasecmp(optarg, "crypto") == 0)
6047 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6048 else if (strcasecmp(optarg, "exitfailure") == 0)
6049 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6051 warnx("invalid service operation \"%s\"",
6054 goto scsisanitize_bailout;
6058 passes = strtol(optarg, NULL, 0);
6059 if (passes < 1 || passes > 31) {
6060 warnx("invalid passes value %d", passes);
6062 goto scsisanitize_bailout;
6093 warnx("an action is required");
6095 goto scsisanitize_bailout;
6096 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6097 struct scsi_sanitize_parameter_list *pl;
6101 if (pattern == NULL) {
6102 warnx("overwrite action requires -P argument");
6104 goto scsisanitize_bailout;
6106 fd = open(pattern, O_RDONLY);
6108 warn("cannot open pattern file %s", pattern);
6110 goto scsisanitize_bailout;
6112 if (fstat(fd, &sb) < 0) {
6113 warn("cannot stat pattern file %s", pattern);
6115 goto scsisanitize_bailout;
6118 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6119 warnx("pattern file size exceeds maximum value %d",
6120 SSZPL_MAX_PATTERN_LENGTH);
6122 goto scsisanitize_bailout;
6124 dxfer_len = sizeof(*pl) + sz;
6125 data_ptr = calloc(1, dxfer_len);
6126 if (data_ptr == NULL) {
6127 warnx("cannot allocate parameter list buffer");
6129 goto scsisanitize_bailout;
6132 amt = read(fd, data_ptr + sizeof(*pl), sz);
6134 warn("cannot read pattern file");
6136 goto scsisanitize_bailout;
6137 } else if (amt != sz) {
6138 warnx("short pattern file read");
6140 goto scsisanitize_bailout;
6143 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6149 pl->byte1 |= SSZPL_INVERT;
6150 scsi_ulto2b(sz, pl->length);
6156 else if (invert != 0)
6158 else if (pattern != NULL)
6163 warnx("%s argument only valid with overwrite "
6166 goto scsisanitize_bailout;
6171 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6172 "following device:\n");
6174 error = scsidoinquiry(device, argc, argv, combinedopt,
6175 task_attr, retry_count, timeout);
6178 warnx("scsisanitize: error sending inquiry");
6179 goto scsisanitize_bailout;
6184 if (!get_confirmation()) {
6186 goto scsisanitize_bailout;
6191 use_timeout = timeout;
6194 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6195 use_timeout / 1000);
6199 * If the user hasn't disabled questions and didn't specify a
6200 * timeout on the command line, ask them if they want the current
6204 && (timeout == 0)) {
6206 int new_timeout = 0;
6208 fprintf(stdout, "Enter new timeout in seconds or press\n"
6209 "return to keep the current timeout [%d] ",
6210 use_timeout / 1000);
6212 if (fgets(str, sizeof(str), stdin) != NULL) {
6214 new_timeout = atoi(str);
6217 if (new_timeout != 0) {
6218 use_timeout = new_timeout * 1000;
6219 fprintf(stdout, "Using new timeout value %d\n",
6220 use_timeout / 1000);
6226 byte2 |= SSZ_UNRESTRICTED_EXIT;
6230 scsi_sanitize(&ccb->csio,
6231 /* retries */ retry_count,
6233 /* tag_action */ task_attr,
6236 /* data_ptr */ data_ptr,
6237 /* dxfer_len */ dxfer_len,
6238 /* sense_len */ SSD_FULL_SIZE,
6239 /* timeout */ use_timeout);
6241 /* Disable freezing the device queue */
6242 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6244 if (arglist & CAM_ARG_ERR_RECOVER)
6245 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6247 if (cam_send_ccb(device, ccb) < 0) {
6248 warn("error sending sanitize command");
6250 goto scsisanitize_bailout;
6253 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6254 struct scsi_sense_data *sense;
6255 int error_code, sense_key, asc, ascq;
6257 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6258 CAM_SCSI_STATUS_ERROR) {
6259 sense = &ccb->csio.sense_data;
6260 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6261 ccb->csio.sense_resid, &error_code, &sense_key,
6262 &asc, &ascq, /*show_errors*/ 1);
6264 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6265 asc == 0x20 && ascq == 0x00)
6266 warnx("sanitize is not supported by "
6269 warnx("error sanitizing this device");
6271 warnx("error sanitizing this device");
6273 if (arglist & CAM_ARG_VERBOSE) {
6274 cam_error_print(device, ccb, CAM_ESF_ALL,
6275 CAM_EPF_ALL, stderr);
6278 goto scsisanitize_bailout;
6282 * If we ran in non-immediate mode, we already checked for errors
6283 * above and printed out any necessary information. If we're in
6284 * immediate mode, we need to loop through and get status
6285 * information periodically.
6287 if (immediate == 0) {
6289 fprintf(stdout, "Sanitize Complete\n");
6291 goto scsisanitize_bailout;
6298 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6301 * There's really no need to do error recovery or
6302 * retries here, since we're just going to sit in a
6303 * loop and wait for the device to finish sanitizing.
6305 scsi_test_unit_ready(&ccb->csio,
6308 /* tag_action */ task_attr,
6309 /* sense_len */ SSD_FULL_SIZE,
6310 /* timeout */ 5000);
6312 /* Disable freezing the device queue */
6313 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6315 retval = cam_send_ccb(device, ccb);
6318 * If we get an error from the ioctl, bail out. SCSI
6319 * errors are expected.
6322 warn("error sending CAMIOCOMMAND ioctl");
6323 if (arglist & CAM_ARG_VERBOSE) {
6324 cam_error_print(device, ccb, CAM_ESF_ALL,
6325 CAM_EPF_ALL, stderr);
6328 goto scsisanitize_bailout;
6331 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6333 if ((status != CAM_REQ_CMP)
6334 && (status == CAM_SCSI_STATUS_ERROR)
6335 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6336 struct scsi_sense_data *sense;
6337 int error_code, sense_key, asc, ascq;
6339 sense = &ccb->csio.sense_data;
6340 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6341 ccb->csio.sense_resid, &error_code, &sense_key,
6342 &asc, &ascq, /*show_errors*/ 1);
6345 * According to the SCSI-3 spec, a drive that is in the
6346 * middle of a sanitize should return NOT READY with an
6347 * ASC of "logical unit not ready, sanitize in
6348 * progress". The sense key specific bytes will then
6349 * be a progress indicator.
6351 if ((sense_key == SSD_KEY_NOT_READY)
6352 && (asc == 0x04) && (ascq == 0x1b)) {
6355 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6356 ccb->csio.sense_resid, sks) == 0)
6359 u_int64_t percentage;
6361 val = scsi_2btoul(&sks[1]);
6362 percentage = 10000 * val;
6365 "\rSanitizing: %ju.%02u %% "
6367 (uintmax_t)(percentage /
6369 (unsigned)((percentage /
6373 } else if ((quiet == 0)
6374 && (++num_warnings <= 1)) {
6375 warnx("Unexpected SCSI Sense Key "
6376 "Specific value returned "
6377 "during sanitize:");
6378 scsi_sense_print(device, &ccb->csio,
6380 warnx("Unable to print status "
6381 "information, but sanitze will "
6383 warnx("will exit when sanitize is "
6388 warnx("Unexpected SCSI error during sanitize");
6389 cam_error_print(device, ccb, CAM_ESF_ALL,
6390 CAM_EPF_ALL, stderr);
6392 goto scsisanitize_bailout;
6395 } else if (status != CAM_REQ_CMP) {
6396 warnx("Unexpected CAM status %#x", status);
6397 if (arglist & CAM_ARG_VERBOSE)
6398 cam_error_print(device, ccb, CAM_ESF_ALL,
6399 CAM_EPF_ALL, stderr);
6401 goto scsisanitize_bailout;
6403 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6406 fprintf(stdout, "\nSanitize Complete\n");
6408 scsisanitize_bailout:
6411 if (data_ptr != NULL)
6419 scsireportluns(struct cam_device *device, int argc, char **argv,
6420 char *combinedopt, int task_attr, int retry_count, int timeout)
6423 int c, countonly, lunsonly;
6424 struct scsi_report_luns_data *lundata;
6426 uint8_t report_type;
6427 uint32_t list_len, i, j;
6432 report_type = RPL_REPORT_DEFAULT;
6433 ccb = cam_getccb(device);
6436 warnx("%s: error allocating ccb", __func__);
6440 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6445 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6454 if (strcasecmp(optarg, "default") == 0)
6455 report_type = RPL_REPORT_DEFAULT;
6456 else if (strcasecmp(optarg, "wellknown") == 0)
6457 report_type = RPL_REPORT_WELLKNOWN;
6458 else if (strcasecmp(optarg, "all") == 0)
6459 report_type = RPL_REPORT_ALL;
6461 warnx("%s: invalid report type \"%s\"",
6472 if ((countonly != 0)
6473 && (lunsonly != 0)) {
6474 warnx("%s: you can only specify one of -c or -l", __func__);
6479 * According to SPC-4, the allocation length must be at least 16
6480 * bytes -- enough for the header and one LUN.
6482 alloc_len = sizeof(*lundata) + 8;
6486 lundata = malloc(alloc_len);
6488 if (lundata == NULL) {
6489 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6494 scsi_report_luns(&ccb->csio,
6495 /*retries*/ retry_count,
6497 /*tag_action*/ task_attr,
6498 /*select_report*/ report_type,
6499 /*rpl_buf*/ lundata,
6500 /*alloc_len*/ alloc_len,
6501 /*sense_len*/ SSD_FULL_SIZE,
6502 /*timeout*/ timeout ? timeout : 5000);
6504 /* Disable freezing the device queue */
6505 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6507 if (arglist & CAM_ARG_ERR_RECOVER)
6508 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6510 if (cam_send_ccb(device, ccb) < 0) {
6511 warn("error sending REPORT LUNS command");
6513 if (arglist & CAM_ARG_VERBOSE)
6514 cam_error_print(device, ccb, CAM_ESF_ALL,
6515 CAM_EPF_ALL, stderr);
6521 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6522 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6528 list_len = scsi_4btoul(lundata->length);
6531 * If we need to list the LUNs, and our allocation
6532 * length was too short, reallocate and retry.
6534 if ((countonly == 0)
6535 && (list_len > (alloc_len - sizeof(*lundata)))) {
6536 alloc_len = list_len + sizeof(*lundata);
6542 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6543 ((list_len / 8) > 1) ? "s" : "");
6548 for (i = 0; i < (list_len / 8); i++) {
6552 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6554 fprintf(stdout, ",");
6555 switch (lundata->luns[i].lundata[j] &
6556 RPL_LUNDATA_ATYP_MASK) {
6557 case RPL_LUNDATA_ATYP_PERIPH:
6558 if ((lundata->luns[i].lundata[j] &
6559 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6560 fprintf(stdout, "%d:",
6561 lundata->luns[i].lundata[j] &
6562 RPL_LUNDATA_PERIPH_BUS_MASK);
6564 && ((lundata->luns[i].lundata[j+2] &
6565 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6568 fprintf(stdout, "%d",
6569 lundata->luns[i].lundata[j+1]);
6571 case RPL_LUNDATA_ATYP_FLAT: {
6573 tmplun[0] = lundata->luns[i].lundata[j] &
6574 RPL_LUNDATA_FLAT_LUN_MASK;
6575 tmplun[1] = lundata->luns[i].lundata[j+1];
6577 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6581 case RPL_LUNDATA_ATYP_LUN:
6582 fprintf(stdout, "%d:%d:%d",
6583 (lundata->luns[i].lundata[j+1] &
6584 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6585 lundata->luns[i].lundata[j] &
6586 RPL_LUNDATA_LUN_TARG_MASK,
6587 lundata->luns[i].lundata[j+1] &
6588 RPL_LUNDATA_LUN_LUN_MASK);
6590 case RPL_LUNDATA_ATYP_EXTLUN: {
6591 int field_len_code, eam_code;
6593 eam_code = lundata->luns[i].lundata[j] &
6594 RPL_LUNDATA_EXT_EAM_MASK;
6595 field_len_code = (lundata->luns[i].lundata[j] &
6596 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6598 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6599 && (field_len_code == 0x00)) {
6600 fprintf(stdout, "%d",
6601 lundata->luns[i].lundata[j+1]);
6602 } else if ((eam_code ==
6603 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6604 && (field_len_code == 0x03)) {
6608 * This format takes up all 8 bytes.
6609 * If we aren't starting at offset 0,
6613 fprintf(stdout, "Invalid "
6616 "specified format", j);
6620 bzero(tmp_lun, sizeof(tmp_lun));
6621 bcopy(&lundata->luns[i].lundata[j+1],
6622 &tmp_lun[1], sizeof(tmp_lun) - 1);
6623 fprintf(stdout, "%#jx",
6624 (intmax_t)scsi_8btou64(tmp_lun));
6627 fprintf(stderr, "Unknown Extended LUN"
6628 "Address method %#x, length "
6629 "code %#x", eam_code,
6636 fprintf(stderr, "Unknown LUN address method "
6637 "%#x\n", lundata->luns[i].lundata[0] &
6638 RPL_LUNDATA_ATYP_MASK);
6642 * For the flat addressing method, there are no
6643 * other levels after it.
6648 fprintf(stdout, "\n");
6661 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6662 char *combinedopt, int task_attr, int retry_count, int timeout)
6665 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6666 struct scsi_read_capacity_data rcap;
6667 struct scsi_read_capacity_data_long rcaplong;
6681 ccb = cam_getccb(device);
6684 warnx("%s: error allocating ccb", __func__);
6688 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6690 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6717 if ((blocksizeonly != 0)
6718 && (numblocks != 0)) {
6719 warnx("%s: you can only specify one of -b or -N", __func__);
6724 if ((blocksizeonly != 0)
6725 && (sizeonly != 0)) {
6726 warnx("%s: you can only specify one of -b or -s", __func__);
6733 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6739 && (blocksizeonly != 0)) {
6740 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6745 scsi_read_capacity(&ccb->csio,
6746 /*retries*/ retry_count,
6748 /*tag_action*/ task_attr,
6751 /*timeout*/ timeout ? timeout : 5000);
6753 /* Disable freezing the device queue */
6754 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6756 if (arglist & CAM_ARG_ERR_RECOVER)
6757 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6759 if (cam_send_ccb(device, ccb) < 0) {
6760 warn("error sending READ CAPACITY command");
6762 if (arglist & CAM_ARG_VERBOSE)
6763 cam_error_print(device, ccb, CAM_ESF_ALL,
6764 CAM_EPF_ALL, stderr);
6770 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6771 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6776 maxsector = scsi_4btoul(rcap.addr);
6777 block_len = scsi_4btoul(rcap.length);
6780 * A last block of 2^32-1 means that the true capacity is over 2TB,
6781 * and we need to issue the long READ CAPACITY to get the real
6782 * capacity. Otherwise, we're all set.
6784 if (maxsector != 0xffffffff)
6787 scsi_read_capacity_16(&ccb->csio,
6788 /*retries*/ retry_count,
6790 /*tag_action*/ task_attr,
6794 /*rcap_buf*/ (uint8_t *)&rcaplong,
6795 /*rcap_buf_len*/ sizeof(rcaplong),
6796 /*sense_len*/ SSD_FULL_SIZE,
6797 /*timeout*/ timeout ? timeout : 5000);
6799 /* Disable freezing the device queue */
6800 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6802 if (arglist & CAM_ARG_ERR_RECOVER)
6803 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6805 if (cam_send_ccb(device, ccb) < 0) {
6806 warn("error sending READ CAPACITY (16) command");
6808 if (arglist & CAM_ARG_VERBOSE)
6809 cam_error_print(device, ccb, CAM_ESF_ALL,
6810 CAM_EPF_ALL, stderr);
6816 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6817 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6822 maxsector = scsi_8btou64(rcaplong.addr);
6823 block_len = scsi_4btoul(rcaplong.length);
6826 if (blocksizeonly == 0) {
6828 * Humanize implies !quiet, and also implies numblocks.
6830 if (humanize != 0) {
6835 tmpbytes = (maxsector + 1) * block_len;
6836 ret = humanize_number(tmpstr, sizeof(tmpstr),
6837 tmpbytes, "", HN_AUTOSCALE,
6840 HN_DIVISOR_1000 : 0));
6842 warnx("%s: humanize_number failed!", __func__);
6846 fprintf(stdout, "Device Size: %s%s", tmpstr,
6847 (sizeonly == 0) ? ", " : "\n");
6848 } else if (numblocks != 0) {
6849 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6850 "Blocks: " : "", (uintmax_t)maxsector + 1,
6851 (sizeonly == 0) ? ", " : "\n");
6853 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6854 "Last Block: " : "", (uintmax_t)maxsector,
6855 (sizeonly == 0) ? ", " : "\n");
6859 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6860 "Block Length: " : "", block_len, (quiet == 0) ?
6869 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6870 int retry_count, int timeout)
6874 uint8_t *smp_request = NULL, *smp_response = NULL;
6875 int request_size = 0, response_size = 0;
6876 int fd_request = 0, fd_response = 0;
6877 char *datastr = NULL;
6878 struct get_hook hook;
6883 * Note that at the moment we don't support sending SMP CCBs to
6884 * devices that aren't probed by CAM.
6886 ccb = cam_getccb(device);
6888 warnx("%s: error allocating CCB", __func__);
6892 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
6894 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6897 arglist |= CAM_ARG_CMD_IN;
6898 response_size = strtol(optarg, NULL, 0);
6899 if (response_size <= 0) {
6900 warnx("invalid number of response bytes %d",
6903 goto smpcmd_bailout;
6905 hook.argc = argc - optind;
6906 hook.argv = argv + optind;
6909 datastr = cget(&hook, NULL);
6911 * If the user supplied "-" instead of a format, he
6912 * wants the data to be written to stdout.
6914 if ((datastr != NULL)
6915 && (datastr[0] == '-'))
6918 smp_response = (u_int8_t *)malloc(response_size);
6919 if (smp_response == NULL) {
6920 warn("can't malloc memory for SMP response");
6922 goto smpcmd_bailout;
6926 arglist |= CAM_ARG_CMD_OUT;
6927 request_size = strtol(optarg, NULL, 0);
6928 if (request_size <= 0) {
6929 warnx("invalid number of request bytes %d",
6932 goto smpcmd_bailout;
6934 hook.argc = argc - optind;
6935 hook.argv = argv + optind;
6937 datastr = cget(&hook, NULL);
6938 smp_request = (u_int8_t *)malloc(request_size);
6939 if (smp_request == NULL) {
6940 warn("can't malloc memory for SMP request");
6942 goto smpcmd_bailout;
6944 bzero(smp_request, request_size);
6946 * If the user supplied "-" instead of a format, he
6947 * wants the data to be read from stdin.
6949 if ((datastr != NULL)
6950 && (datastr[0] == '-'))
6953 buff_encode_visit(smp_request, request_size,
6964 * If fd_data is set, and we're writing to the device, we need to
6965 * read the data the user wants written from stdin.
6967 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6969 int amt_to_read = request_size;
6970 u_int8_t *buf_ptr = smp_request;
6972 for (amt_read = 0; amt_to_read > 0;
6973 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6974 if (amt_read == -1) {
6975 warn("error reading data from stdin");
6977 goto smpcmd_bailout;
6979 amt_to_read -= amt_read;
6980 buf_ptr += amt_read;
6984 if (((arglist & CAM_ARG_CMD_IN) == 0)
6985 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6986 warnx("%s: need both the request (-r) and response (-R) "
6987 "arguments", __func__);
6989 goto smpcmd_bailout;
6992 flags |= CAM_DEV_QFRZDIS;
6994 cam_fill_smpio(&ccb->smpio,
6995 /*retries*/ retry_count,
6998 /*smp_request*/ smp_request,
6999 /*smp_request_len*/ request_size,
7000 /*smp_response*/ smp_response,
7001 /*smp_response_len*/ response_size,
7002 /*timeout*/ timeout ? timeout : 5000);
7004 ccb->smpio.flags = SMP_FLAG_NONE;
7006 if (((retval = cam_send_ccb(device, ccb)) < 0)
7007 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7008 const char warnstr[] = "error sending command";
7015 if (arglist & CAM_ARG_VERBOSE) {
7016 cam_error_print(device, ccb, CAM_ESF_ALL,
7017 CAM_EPF_ALL, stderr);
7021 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7022 && (response_size > 0)) {
7023 if (fd_response == 0) {
7024 buff_decode_visit(smp_response, response_size,
7025 datastr, arg_put, NULL);
7026 fprintf(stdout, "\n");
7028 ssize_t amt_written;
7029 int amt_to_write = response_size;
7030 u_int8_t *buf_ptr = smp_response;
7032 for (amt_written = 0; (amt_to_write > 0) &&
7033 (amt_written = write(STDOUT_FILENO, buf_ptr,
7034 amt_to_write)) > 0;){
7035 amt_to_write -= amt_written;
7036 buf_ptr += amt_written;
7038 if (amt_written == -1) {
7039 warn("error writing data to stdout");
7041 goto smpcmd_bailout;
7042 } else if ((amt_written == 0)
7043 && (amt_to_write > 0)) {
7044 warnx("only wrote %u bytes out of %u",
7045 response_size - amt_to_write,
7054 if (smp_request != NULL)
7057 if (smp_response != NULL)
7064 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7065 char *combinedopt, int retry_count, int timeout)
7068 struct smp_report_general_request *request = NULL;
7069 struct smp_report_general_response *response = NULL;
7070 struct sbuf *sb = NULL;
7072 int c, long_response = 0;
7076 * Note that at the moment we don't support sending SMP CCBs to
7077 * devices that aren't probed by CAM.
7079 ccb = cam_getccb(device);
7081 warnx("%s: error allocating CCB", __func__);
7085 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7087 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7096 request = malloc(sizeof(*request));
7097 if (request == NULL) {
7098 warn("%s: unable to allocate %zd bytes", __func__,
7104 response = malloc(sizeof(*response));
7105 if (response == NULL) {
7106 warn("%s: unable to allocate %zd bytes", __func__,
7113 smp_report_general(&ccb->smpio,
7117 /*request_len*/ sizeof(*request),
7118 (uint8_t *)response,
7119 /*response_len*/ sizeof(*response),
7120 /*long_response*/ long_response,
7123 if (((retval = cam_send_ccb(device, ccb)) < 0)
7124 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7125 const char warnstr[] = "error sending command";
7132 if (arglist & CAM_ARG_VERBOSE) {
7133 cam_error_print(device, ccb, CAM_ESF_ALL,
7134 CAM_EPF_ALL, stderr);
7141 * If the device supports the long response bit, try again and see
7142 * if we can get all of the data.
7144 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7145 && (long_response == 0)) {
7146 ccb->ccb_h.status = CAM_REQ_INPROG;
7147 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7153 * XXX KDM detect and decode SMP errors here.
7155 sb = sbuf_new_auto();
7157 warnx("%s: error allocating sbuf", __func__);
7161 smp_report_general_sbuf(response, sizeof(*response), sb);
7163 if (sbuf_finish(sb) != 0) {
7164 warnx("%s: sbuf_finish", __func__);
7168 printf("%s", sbuf_data(sb));
7174 if (request != NULL)
7177 if (response != NULL)
7186 static struct camcontrol_opts phy_ops[] = {
7187 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7188 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7189 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7190 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7191 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7192 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7193 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7194 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7195 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7200 smpphycontrol(struct cam_device *device, int argc, char **argv,
7201 char *combinedopt, int retry_count, int timeout)
7204 struct smp_phy_control_request *request = NULL;
7205 struct smp_phy_control_response *response = NULL;
7206 int long_response = 0;
7209 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7211 uint64_t attached_dev_name = 0;
7212 int dev_name_set = 0;
7213 uint32_t min_plr = 0, max_plr = 0;
7214 uint32_t pp_timeout_val = 0;
7215 int slumber_partial = 0;
7216 int set_pp_timeout_val = 0;
7220 * Note that at the moment we don't support sending SMP CCBs to
7221 * devices that aren't probed by CAM.
7223 ccb = cam_getccb(device);
7225 warnx("%s: error allocating CCB", __func__);
7229 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7231 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7239 if (strcasecmp(optarg, "enable") == 0)
7241 else if (strcasecmp(optarg, "disable") == 0)
7244 warnx("%s: Invalid argument %s", __func__,
7251 slumber_partial |= enable <<
7252 SMP_PC_SAS_SLUMBER_SHIFT;
7255 slumber_partial |= enable <<
7256 SMP_PC_SAS_PARTIAL_SHIFT;
7259 slumber_partial |= enable <<
7260 SMP_PC_SATA_SLUMBER_SHIFT;
7263 slumber_partial |= enable <<
7264 SMP_PC_SATA_PARTIAL_SHIFT;
7267 warnx("%s: programmer error", __func__);
7270 break; /*NOTREACHED*/
7275 attached_dev_name = (uintmax_t)strtoumax(optarg,
7284 * We don't do extensive checking here, so this
7285 * will continue to work when new speeds come out.
7287 min_plr = strtoul(optarg, NULL, 0);
7289 || (min_plr > 0xf)) {
7290 warnx("%s: invalid link rate %x",
7298 * We don't do extensive checking here, so this
7299 * will continue to work when new speeds come out.
7301 max_plr = strtoul(optarg, NULL, 0);
7303 || (max_plr > 0xf)) {
7304 warnx("%s: invalid link rate %x",
7311 camcontrol_optret optreturn;
7312 cam_argmask argnums;
7315 if (phy_op_set != 0) {
7316 warnx("%s: only one phy operation argument "
7317 "(-o) allowed", __func__);
7325 * Allow the user to specify the phy operation
7326 * numerically, as well as with a name. This will
7327 * future-proof it a bit, so options that are added
7328 * in future specs can be used.
7330 if (isdigit(optarg[0])) {
7331 phy_operation = strtoul(optarg, NULL, 0);
7332 if ((phy_operation == 0)
7333 || (phy_operation > 0xff)) {
7334 warnx("%s: invalid phy operation %#x",
7335 __func__, phy_operation);
7341 optreturn = getoption(phy_ops, optarg, &phy_operation,
7344 if (optreturn == CC_OR_AMBIGUOUS) {
7345 warnx("%s: ambiguous option %s", __func__,
7350 } else if (optreturn == CC_OR_NOT_FOUND) {
7351 warnx("%s: option %s not found", __func__,
7363 pp_timeout_val = strtoul(optarg, NULL, 0);
7364 if (pp_timeout_val > 15) {
7365 warnx("%s: invalid partial pathway timeout "
7366 "value %u, need a value less than 16",
7367 __func__, pp_timeout_val);
7371 set_pp_timeout_val = 1;
7379 warnx("%s: a PHY (-p phy) argument is required",__func__);
7384 if (((dev_name_set != 0)
7385 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7386 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7387 && (dev_name_set == 0))) {
7388 warnx("%s: -d name and -o setdevname arguments both "
7389 "required to set device name", __func__);
7394 request = malloc(sizeof(*request));
7395 if (request == NULL) {
7396 warn("%s: unable to allocate %zd bytes", __func__,
7402 response = malloc(sizeof(*response));
7403 if (response == NULL) {
7404 warn("%s: unable to allocate %zd bytes", __func__,
7410 smp_phy_control(&ccb->smpio,
7415 (uint8_t *)response,
7418 /*expected_exp_change_count*/ 0,
7421 (set_pp_timeout_val != 0) ? 1 : 0,
7429 if (((retval = cam_send_ccb(device, ccb)) < 0)
7430 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7431 const char warnstr[] = "error sending command";
7438 if (arglist & CAM_ARG_VERBOSE) {
7440 * Use CAM_EPF_NORMAL so we only get one line of
7441 * SMP command decoding.
7443 cam_error_print(device, ccb, CAM_ESF_ALL,
7444 CAM_EPF_NORMAL, stderr);
7450 /* XXX KDM print out something here for success? */
7455 if (request != NULL)
7458 if (response != NULL)
7465 smpmaninfo(struct cam_device *device, int argc, char **argv,
7466 char *combinedopt, int retry_count, int timeout)
7469 struct smp_report_manuf_info_request request;
7470 struct smp_report_manuf_info_response response;
7471 struct sbuf *sb = NULL;
7472 int long_response = 0;
7477 * Note that at the moment we don't support sending SMP CCBs to
7478 * devices that aren't probed by CAM.
7480 ccb = cam_getccb(device);
7482 warnx("%s: error allocating CCB", __func__);
7486 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7488 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7497 bzero(&request, sizeof(request));
7498 bzero(&response, sizeof(response));
7500 smp_report_manuf_info(&ccb->smpio,
7505 (uint8_t *)&response,
7510 if (((retval = cam_send_ccb(device, ccb)) < 0)
7511 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7512 const char warnstr[] = "error sending command";
7519 if (arglist & CAM_ARG_VERBOSE) {
7520 cam_error_print(device, ccb, CAM_ESF_ALL,
7521 CAM_EPF_ALL, stderr);
7527 sb = sbuf_new_auto();
7529 warnx("%s: error allocating sbuf", __func__);
7533 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7535 if (sbuf_finish(sb) != 0) {
7536 warnx("%s: sbuf_finish", __func__);
7540 printf("%s", sbuf_data(sb));
7554 getdevid(struct cam_devitem *item)
7557 union ccb *ccb = NULL;
7559 struct cam_device *dev;
7561 dev = cam_open_btl(item->dev_match.path_id,
7562 item->dev_match.target_id,
7563 item->dev_match.target_lun, O_RDWR, NULL);
7566 warnx("%s", cam_errbuf);
7571 item->device_id_len = 0;
7573 ccb = cam_getccb(dev);
7575 warnx("%s: error allocating CCB", __func__);
7580 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7583 * On the first try, we just probe for the size of the data, and
7584 * then allocate that much memory and try again.
7587 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7588 ccb->ccb_h.flags = CAM_DIR_IN;
7589 ccb->cdai.flags = CDAI_FLAG_NONE;
7590 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7591 ccb->cdai.bufsiz = item->device_id_len;
7592 if (item->device_id_len != 0)
7593 ccb->cdai.buf = (uint8_t *)item->device_id;
7595 if (cam_send_ccb(dev, ccb) < 0) {
7596 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7601 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7602 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7607 if (item->device_id_len == 0) {
7609 * This is our first time through. Allocate the buffer,
7610 * and then go back to get the data.
7612 if (ccb->cdai.provsiz == 0) {
7613 warnx("%s: invalid .provsiz field returned with "
7614 "XPT_GDEV_ADVINFO CCB", __func__);
7618 item->device_id_len = ccb->cdai.provsiz;
7619 item->device_id = malloc(item->device_id_len);
7620 if (item->device_id == NULL) {
7621 warn("%s: unable to allocate %d bytes", __func__,
7622 item->device_id_len);
7626 ccb->ccb_h.status = CAM_REQ_INPROG;
7632 cam_close_device(dev);
7641 * XXX KDM merge this code with getdevtree()?
7644 buildbusdevlist(struct cam_devlist *devlist)
7647 int bufsize, fd = -1;
7648 struct dev_match_pattern *patterns;
7649 struct cam_devitem *item = NULL;
7650 int skip_device = 0;
7653 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7654 warn("couldn't open %s", XPT_DEVICE);
7658 bzero(&ccb, sizeof(union ccb));
7660 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7661 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7662 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7664 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7665 bufsize = sizeof(struct dev_match_result) * 100;
7666 ccb.cdm.match_buf_len = bufsize;
7667 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7668 if (ccb.cdm.matches == NULL) {
7669 warnx("can't malloc memory for matches");
7673 ccb.cdm.num_matches = 0;
7674 ccb.cdm.num_patterns = 2;
7675 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7676 ccb.cdm.num_patterns;
7678 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7679 if (patterns == NULL) {
7680 warnx("can't malloc memory for patterns");
7685 ccb.cdm.patterns = patterns;
7686 bzero(patterns, ccb.cdm.pattern_buf_len);
7688 patterns[0].type = DEV_MATCH_DEVICE;
7689 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7690 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7691 patterns[1].type = DEV_MATCH_PERIPH;
7692 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7693 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7696 * We do the ioctl multiple times if necessary, in case there are
7697 * more than 100 nodes in the EDT.
7702 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7703 warn("error sending CAMIOCOMMAND ioctl");
7708 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7709 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7710 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7711 warnx("got CAM error %#x, CDM error %d\n",
7712 ccb.ccb_h.status, ccb.cdm.status);
7717 for (i = 0; i < ccb.cdm.num_matches; i++) {
7718 switch (ccb.cdm.matches[i].type) {
7719 case DEV_MATCH_DEVICE: {
7720 struct device_match_result *dev_result;
7723 &ccb.cdm.matches[i].result.device_result;
7725 if (dev_result->flags &
7726 DEV_RESULT_UNCONFIGURED) {
7732 item = malloc(sizeof(*item));
7734 warn("%s: unable to allocate %zd bytes",
7735 __func__, sizeof(*item));
7739 bzero(item, sizeof(*item));
7740 bcopy(dev_result, &item->dev_match,
7741 sizeof(*dev_result));
7742 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7745 if (getdevid(item) != 0) {
7751 case DEV_MATCH_PERIPH: {
7752 struct periph_match_result *periph_result;
7755 &ccb.cdm.matches[i].result.periph_result;
7757 if (skip_device != 0)
7759 item->num_periphs++;
7760 item->periph_matches = realloc(
7761 item->periph_matches,
7763 sizeof(struct periph_match_result));
7764 if (item->periph_matches == NULL) {
7765 warn("%s: error allocating periph "
7770 bcopy(periph_result, &item->periph_matches[
7771 item->num_periphs - 1],
7772 sizeof(*periph_result));
7776 fprintf(stderr, "%s: unexpected match "
7777 "type %d\n", __func__,
7778 ccb.cdm.matches[i].type);
7781 break; /*NOTREACHED*/
7784 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7785 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7793 free(ccb.cdm.matches);
7796 freebusdevlist(devlist);
7802 freebusdevlist(struct cam_devlist *devlist)
7804 struct cam_devitem *item, *item2;
7806 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7807 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7809 free(item->device_id);
7810 free(item->periph_matches);
7815 static struct cam_devitem *
7816 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7818 struct cam_devitem *item;
7820 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7821 struct scsi_vpd_id_descriptor *idd;
7824 * XXX KDM look for LUN IDs as well?
7826 idd = scsi_get_devid(item->device_id,
7827 item->device_id_len,
7828 scsi_devid_is_sas_target);
7832 if (scsi_8btou64(idd->identifier) == sasaddr)
7840 smpphylist(struct cam_device *device, int argc, char **argv,
7841 char *combinedopt, int retry_count, int timeout)
7843 struct smp_report_general_request *rgrequest = NULL;
7844 struct smp_report_general_response *rgresponse = NULL;
7845 struct smp_discover_request *disrequest = NULL;
7846 struct smp_discover_response *disresponse = NULL;
7847 struct cam_devlist devlist;
7849 int long_response = 0;
7856 * Note that at the moment we don't support sending SMP CCBs to
7857 * devices that aren't probed by CAM.
7859 ccb = cam_getccb(device);
7861 warnx("%s: error allocating CCB", __func__);
7865 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7866 STAILQ_INIT(&devlist.dev_queue);
7868 rgrequest = malloc(sizeof(*rgrequest));
7869 if (rgrequest == NULL) {
7870 warn("%s: unable to allocate %zd bytes", __func__,
7871 sizeof(*rgrequest));
7876 rgresponse = malloc(sizeof(*rgresponse));
7877 if (rgresponse == NULL) {
7878 warn("%s: unable to allocate %zd bytes", __func__,
7879 sizeof(*rgresponse));
7884 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7897 smp_report_general(&ccb->smpio,
7901 /*request_len*/ sizeof(*rgrequest),
7902 (uint8_t *)rgresponse,
7903 /*response_len*/ sizeof(*rgresponse),
7904 /*long_response*/ long_response,
7907 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7909 if (((retval = cam_send_ccb(device, ccb)) < 0)
7910 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7911 const char warnstr[] = "error sending command";
7918 if (arglist & CAM_ARG_VERBOSE) {
7919 cam_error_print(device, ccb, CAM_ESF_ALL,
7920 CAM_EPF_ALL, stderr);
7926 num_phys = rgresponse->num_phys;
7928 if (num_phys == 0) {
7930 fprintf(stdout, "%s: No Phys reported\n", __func__);
7935 devlist.path_id = device->path_id;
7937 retval = buildbusdevlist(&devlist);
7942 fprintf(stdout, "%d PHYs:\n", num_phys);
7943 fprintf(stdout, "PHY Attached SAS Address\n");
7946 disrequest = malloc(sizeof(*disrequest));
7947 if (disrequest == NULL) {
7948 warn("%s: unable to allocate %zd bytes", __func__,
7949 sizeof(*disrequest));
7954 disresponse = malloc(sizeof(*disresponse));
7955 if (disresponse == NULL) {
7956 warn("%s: unable to allocate %zd bytes", __func__,
7957 sizeof(*disresponse));
7962 for (i = 0; i < num_phys; i++) {
7963 struct cam_devitem *item;
7964 struct device_match_result *dev_match;
7965 char vendor[16], product[48], revision[16];
7969 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7971 ccb->ccb_h.status = CAM_REQ_INPROG;
7972 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7974 smp_discover(&ccb->smpio,
7978 sizeof(*disrequest),
7979 (uint8_t *)disresponse,
7980 sizeof(*disresponse),
7982 /*ignore_zone_group*/ 0,
7986 if (((retval = cam_send_ccb(device, ccb)) < 0)
7987 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7988 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7989 const char warnstr[] = "error sending command";
7996 if (arglist & CAM_ARG_VERBOSE) {
7997 cam_error_print(device, ccb, CAM_ESF_ALL,
7998 CAM_EPF_ALL, stderr);
8004 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8006 fprintf(stdout, "%3d <vacant>\n", i);
8010 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8013 item = findsasdevice(&devlist,
8014 scsi_8btou64(disresponse->attached_sas_address));
8018 || (item != NULL)) {
8019 fprintf(stdout, "%3d 0x%016jx", i,
8020 (uintmax_t)scsi_8btou64(
8021 disresponse->attached_sas_address));
8023 fprintf(stdout, "\n");
8026 } else if (quiet != 0)
8029 dev_match = &item->dev_match;
8031 if (dev_match->protocol == PROTO_SCSI) {
8032 cam_strvis(vendor, dev_match->inq_data.vendor,
8033 sizeof(dev_match->inq_data.vendor),
8035 cam_strvis(product, dev_match->inq_data.product,
8036 sizeof(dev_match->inq_data.product),
8038 cam_strvis(revision, dev_match->inq_data.revision,
8039 sizeof(dev_match->inq_data.revision),
8041 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8043 } else if ((dev_match->protocol == PROTO_ATA)
8044 || (dev_match->protocol == PROTO_SATAPM)) {
8045 cam_strvis(product, dev_match->ident_data.model,
8046 sizeof(dev_match->ident_data.model),
8048 cam_strvis(revision, dev_match->ident_data.revision,
8049 sizeof(dev_match->ident_data.revision),
8051 sprintf(tmpstr, "<%s %s>", product, revision);
8053 sprintf(tmpstr, "<>");
8055 fprintf(stdout, " %-33s ", tmpstr);
8058 * If we have 0 periphs, that's a bug...
8060 if (item->num_periphs == 0) {
8061 fprintf(stdout, "\n");
8065 fprintf(stdout, "(");
8066 for (j = 0; j < item->num_periphs; j++) {
8068 fprintf(stdout, ",");
8070 fprintf(stdout, "%s%d",
8071 item->periph_matches[j].periph_name,
8072 item->periph_matches[j].unit_number);
8075 fprintf(stdout, ")\n");
8089 freebusdevlist(&devlist);
8095 atapm(struct cam_device *device, int argc, char **argv,
8096 char *combinedopt, int retry_count, int timeout)
8104 ccb = cam_getccb(device);
8107 warnx("%s: error allocating ccb", __func__);
8111 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8120 if (strcmp(argv[1], "idle") == 0) {
8122 cmd = ATA_IDLE_IMMEDIATE;
8125 } else if (strcmp(argv[1], "standby") == 0) {
8127 cmd = ATA_STANDBY_IMMEDIATE;
8129 cmd = ATA_STANDBY_CMD;
8137 else if (t <= (240 * 5))
8139 else if (t <= (252 * 5))
8140 /* special encoding for 21 minutes */
8142 else if (t <= (11 * 30 * 60))
8143 sc = (t - 1) / (30 * 60) + 241;
8147 retval = ata_do_28bit_cmd(device,
8149 /*retries*/retry_count,
8150 /*flags*/CAM_DIR_NONE,
8151 /*protocol*/AP_PROTO_NON_DATA,
8152 /*tag_action*/MSG_SIMPLE_Q_TAG,
8159 /*timeout*/timeout ? timeout : 30 * 1000,
8167 ataaxm(struct cam_device *device, int argc, char **argv,
8168 char *combinedopt, int retry_count, int timeout)
8176 ccb = cam_getccb(device);
8179 warnx("%s: error allocating ccb", __func__);
8183 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8193 if (strcmp(argv[1], "apm") == 0) {
8209 retval = ata_do_28bit_cmd(device,
8211 /*retries*/retry_count,
8212 /*flags*/CAM_DIR_NONE,
8213 /*protocol*/AP_PROTO_NON_DATA,
8214 /*tag_action*/MSG_SIMPLE_Q_TAG,
8215 /*command*/ATA_SETFEATURES,
8221 /*timeout*/timeout ? timeout : 30 * 1000,
8229 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8230 int show_sa_errors, int sa_set, int service_action,
8231 int timeout_desc, int task_attr, int retry_count, int timeout,
8232 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
8234 union ccb *ccb = NULL;
8235 uint8_t *buf = NULL;
8236 uint32_t alloc_len = 0, num_opcodes;
8237 uint32_t valid_len = 0;
8238 uint32_t avail_len = 0;
8239 struct scsi_report_supported_opcodes_all *all_hdr;
8240 struct scsi_report_supported_opcodes_one *one;
8245 * Make it clear that we haven't yet allocated or filled anything.
8250 ccb = cam_getccb(device);
8252 warnx("couldn't allocate CCB");
8257 /* cam_getccb cleans up the header, caller has to zero the payload */
8258 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8260 if (opcode_set != 0) {
8261 options |= RSO_OPTIONS_OC;
8263 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8266 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8267 sizeof(struct scsi_report_supported_opcodes_descr));
8270 if (timeout_desc != 0) {
8271 options |= RSO_RCTD;
8272 alloc_len += num_opcodes *
8273 sizeof(struct scsi_report_supported_opcodes_timeout);
8277 options |= RSO_OPTIONS_OC_SA;
8278 if (show_sa_errors != 0)
8279 options &= ~RSO_OPTIONS_OC;
8288 buf = malloc(alloc_len);
8290 warn("Unable to allocate %u bytes", alloc_len);
8294 bzero(buf, alloc_len);
8296 scsi_report_supported_opcodes(&ccb->csio,
8297 /*retries*/ retry_count,
8299 /*tag_action*/ task_attr,
8300 /*options*/ options,
8301 /*req_opcode*/ opcode,
8302 /*req_service_action*/ service_action,
8304 /*dxfer_len*/ alloc_len,
8305 /*sense_len*/ SSD_FULL_SIZE,
8306 /*timeout*/ timeout ? timeout : 10000);
8308 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8310 if (retry_count != 0)
8311 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8313 if (cam_send_ccb(device, ccb) < 0) {
8314 perror("error sending REPORT SUPPORTED OPERATION CODES");
8319 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8320 if (verbosemode != 0)
8321 cam_error_print(device, ccb, CAM_ESF_ALL,
8322 CAM_EPF_ALL, stderr);
8328 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8330 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8331 && (valid_len >= sizeof(*all_hdr))) {
8332 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8333 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8334 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8335 && (valid_len >= sizeof(*one))) {
8336 uint32_t cdb_length;
8338 one = (struct scsi_report_supported_opcodes_one *)buf;
8339 cdb_length = scsi_2btoul(one->cdb_length);
8340 avail_len = sizeof(*one) + cdb_length;
8341 if (one->support & RSO_ONE_CTDP) {
8342 struct scsi_report_supported_opcodes_timeout *td;
8344 td = (struct scsi_report_supported_opcodes_timeout *)
8346 if (valid_len >= (avail_len + sizeof(td->length))) {
8347 avail_len += scsi_2btoul(td->length) +
8350 avail_len += sizeof(*td);
8356 * avail_len could be zero if we didn't get enough data back from
8357 * thet target to determine
8359 if ((avail_len != 0)
8360 && (avail_len > valid_len)) {
8361 alloc_len = avail_len;
8365 *fill_len = valid_len;
8377 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8378 int req_sa, uint8_t *buf, uint32_t valid_len)
8380 struct scsi_report_supported_opcodes_one *one;
8381 struct scsi_report_supported_opcodes_timeout *td;
8382 uint32_t cdb_len = 0, td_len = 0;
8383 const char *op_desc = NULL;
8387 one = (struct scsi_report_supported_opcodes_one *)buf;
8390 * If we don't have the full single opcode descriptor, no point in
8393 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8395 warnx("Only %u bytes returned, not enough to verify support",
8401 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8403 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8406 printf(", SA 0x%x", req_sa);
8409 switch (one->support & RSO_ONE_SUP_MASK) {
8410 case RSO_ONE_SUP_UNAVAIL:
8411 printf("No command support information currently available\n");
8413 case RSO_ONE_SUP_NOT_SUP:
8414 printf("Command not supported\n");
8417 break; /*NOTREACHED*/
8418 case RSO_ONE_SUP_AVAIL:
8419 printf("Command is supported, complies with a SCSI standard\n");
8421 case RSO_ONE_SUP_VENDOR:
8422 printf("Command is supported, vendor-specific "
8423 "implementation\n");
8426 printf("Unknown command support flags 0x%#x\n",
8427 one->support & RSO_ONE_SUP_MASK);
8432 * If we don't have the CDB length, it isn't exactly an error, the
8433 * command probably isn't supported.
8435 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8439 cdb_len = scsi_2btoul(one->cdb_length);
8442 * If our valid data doesn't include the full reported length,
8443 * return. The caller should have detected this and adjusted his
8444 * allocation length to get all of the available data.
8446 if (valid_len < sizeof(*one) + cdb_len) {
8452 * If all we have is the opcode, there is no point in printing out
8460 printf("CDB usage bitmap:");
8461 for (i = 0; i < cdb_len; i++) {
8462 printf(" %02x", one->cdb_usage[i]);
8467 * If we don't have a timeout descriptor, we're done.
8469 if ((one->support & RSO_ONE_CTDP) == 0)
8473 * If we don't have enough valid length to include the timeout
8474 * descriptor length, we're done.
8476 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8479 td = (struct scsi_report_supported_opcodes_timeout *)
8480 &buf[sizeof(*one) + cdb_len];
8481 td_len = scsi_2btoul(td->length);
8482 td_len += sizeof(td->length);
8485 * If we don't have the full timeout descriptor, we're done.
8487 if (td_len < sizeof(*td))
8491 * If we don't have enough valid length to contain the full timeout
8492 * descriptor, we're done.
8494 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8497 printf("Timeout information:\n");
8498 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8499 printf("Nominal timeout: %u seconds\n",
8500 scsi_4btoul(td->nominal_time));
8501 printf("Recommended timeout: %u seconds\n",
8502 scsi_4btoul(td->recommended_time));
8509 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8512 struct scsi_report_supported_opcodes_all *hdr;
8513 struct scsi_report_supported_opcodes_descr *desc;
8514 uint32_t avail_len = 0, used_len = 0;
8518 if (valid_len < sizeof(*hdr)) {
8519 warnx("%s: not enough returned data (%u bytes) opcode list",
8520 __func__, valid_len);
8524 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8525 avail_len = scsi_4btoul(hdr->length);
8526 avail_len += sizeof(hdr->length);
8528 * Take the lesser of the amount of data the drive claims is
8529 * available, and the amount of data the HBA says was returned.
8531 avail_len = MIN(avail_len, valid_len);
8533 used_len = sizeof(hdr->length);
8535 printf("%-6s %4s %8s ",
8536 "Opcode", "SA", "CDB len" );
8539 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8540 printf(" Description\n");
8542 while ((avail_len - used_len) > sizeof(*desc)) {
8543 struct scsi_report_supported_opcodes_timeout *td;
8545 const char *op_desc = NULL;
8547 cur_ptr = &buf[used_len];
8548 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8550 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8551 if (op_desc == NULL)
8552 op_desc = "UNKNOWN";
8554 printf("0x%02x %#4x %8u ", desc->opcode,
8555 scsi_2btoul(desc->service_action),
8556 scsi_2btoul(desc->cdb_length));
8558 used_len += sizeof(*desc);
8560 if ((desc->flags & RSO_CTDP) == 0) {
8561 printf(" %s\n", op_desc);
8566 * If we don't have enough space to fit a timeout
8567 * descriptor, then we're done.
8569 if (avail_len - used_len < sizeof(*td)) {
8570 used_len = avail_len;
8571 printf(" %s\n", op_desc);
8574 cur_ptr = &buf[used_len];
8575 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8576 td_len = scsi_2btoul(td->length);
8577 td_len += sizeof(td->length);
8581 * If the given timeout descriptor length is less than what
8582 * we understand, skip it.
8584 if (td_len < sizeof(*td)) {
8585 printf(" %s\n", op_desc);
8589 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8590 scsi_4btoul(td->nominal_time),
8591 scsi_4btoul(td->recommended_time), op_desc);
8598 scsiopcodes(struct cam_device *device, int argc, char **argv,
8599 char *combinedopt, int task_attr, int retry_count, int timeout,
8603 uint32_t opcode = 0, service_action = 0;
8604 int td_set = 0, opcode_set = 0, sa_set = 0;
8605 int show_sa_errors = 1;
8606 uint32_t valid_len = 0;
8607 uint8_t *buf = NULL;
8611 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8617 opcode = strtoul(optarg, &endptr, 0);
8618 if (*endptr != '\0') {
8619 warnx("Invalid opcode \"%s\", must be a number",
8624 if (opcode > 0xff) {
8625 warnx("Invalid opcode 0x%#x, must be between"
8626 "0 and 0xff inclusive", opcode);
8633 service_action = strtoul(optarg, &endptr, 0);
8634 if (*endptr != '\0') {
8635 warnx("Invalid service action \"%s\", must "
8636 "be a number", optarg);
8640 if (service_action > 0xffff) {
8641 warnx("Invalid service action 0x%#x, must "
8642 "be between 0 and 0xffff inclusive",
8657 && (opcode_set == 0)) {
8658 warnx("You must specify an opcode with -o if a service "
8663 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8664 sa_set, service_action, td_set, task_attr,
8665 retry_count, timeout, verbosemode, &valid_len,
8670 if ((opcode_set != 0)
8672 retval = scsiprintoneopcode(device, opcode, sa_set,
8673 service_action, buf, valid_len);
8675 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8684 #endif /* MINIMALISTIC */
8687 scsireprobe(struct cam_device *device)
8692 ccb = cam_getccb(device);
8695 warnx("%s: error allocating ccb", __func__);
8699 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8701 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8703 if (cam_send_ccb(device, ccb) < 0) {
8704 warn("error sending XPT_REPROBE_LUN CCB");
8709 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8710 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8722 usage(int printlong)
8725 fprintf(printlong ? stdout : stderr,
8726 "usage: camcontrol <command> [device id][generic args][command args]\n"
8727 " camcontrol devlist [-b] [-v]\n"
8728 #ifndef MINIMALISTIC
8729 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8730 " camcontrol tur [dev_id][generic args]\n"
8731 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8732 " camcontrol identify [dev_id][generic args] [-v]\n"
8733 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8734 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8736 " camcontrol start [dev_id][generic args]\n"
8737 " camcontrol stop [dev_id][generic args]\n"
8738 " camcontrol load [dev_id][generic args]\n"
8739 " camcontrol eject [dev_id][generic args]\n"
8740 " camcontrol reprobe [dev_id][generic args]\n"
8741 #endif /* MINIMALISTIC */
8742 " camcontrol rescan <all | bus[:target:lun]>\n"
8743 " camcontrol reset <all | bus[:target:lun]>\n"
8744 #ifndef MINIMALISTIC
8745 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8746 " [-q][-s][-S offset][-X]\n"
8747 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8748 " [-P pagectl][-e | -b][-d]\n"
8749 " camcontrol cmd [dev_id][generic args]\n"
8750 " <-a cmd [args] | -c cmd [args]>\n"
8751 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8752 " camcontrol smpcmd [dev_id][generic args]\n"
8753 " <-r len fmt [args]> <-R len fmt [args]>\n"
8754 " camcontrol smprg [dev_id][generic args][-l]\n"
8755 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8756 " [-o operation][-d name][-m rate][-M rate]\n"
8757 " [-T pp_timeout][-a enable|disable]\n"
8758 " [-A enable|disable][-s enable|disable]\n"
8759 " [-S enable|disable]\n"
8760 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8761 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8762 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8763 " <all|bus[:target[:lun]]|off>\n"
8764 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8765 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8766 " [-D <enable|disable>][-M mode][-O offset]\n"
8767 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8768 " [-U][-W bus_width]\n"
8769 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8770 " camcontrol sanitize [dev_id][generic args]\n"
8771 " [-a overwrite|block|crypto|exitfailure]\n"
8772 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8774 " camcontrol idle [dev_id][generic args][-t time]\n"
8775 " camcontrol standby [dev_id][generic args][-t time]\n"
8776 " camcontrol sleep [dev_id][generic args]\n"
8777 " camcontrol apm [dev_id][generic args][-l level]\n"
8778 " camcontrol aam [dev_id][generic args][-l level]\n"
8779 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8781 " camcontrol security [dev_id][generic args]\n"
8782 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8783 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8784 " [-U <user|master>] [-y]\n"
8785 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8786 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8787 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8788 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8789 " [-s scope][-S][-T type][-U]\n"
8790 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8791 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8792 " [-p part][-s start][-T type][-V vol]\n"
8793 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8795 #endif /* MINIMALISTIC */
8796 " camcontrol help\n");
8799 #ifndef MINIMALISTIC
8801 "Specify one of the following options:\n"
8802 "devlist list all CAM devices\n"
8803 "periphlist list all CAM peripheral drivers attached to a device\n"
8804 "tur send a test unit ready to the named device\n"
8805 "inquiry send a SCSI inquiry command to the named device\n"
8806 "identify send a ATA identify command to the named device\n"
8807 "reportluns send a SCSI report luns command to the device\n"
8808 "readcap send a SCSI read capacity command to the device\n"
8809 "start send a Start Unit command to the device\n"
8810 "stop send a Stop Unit command to the device\n"
8811 "load send a Start Unit command to the device with the load bit set\n"
8812 "eject send a Stop Unit command to the device with the eject bit set\n"
8813 "reprobe update capacity information of the given device\n"
8814 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8815 "reset reset all busses, the given bus, or bus:target:lun\n"
8816 "defects read the defect list of the specified device\n"
8817 "modepage display or edit (-e) the given mode page\n"
8818 "cmd send the given SCSI command, may need -i or -o as well\n"
8819 "smpcmd send the given SMP command, requires -o and -i\n"
8820 "smprg send the SMP Report General command\n"
8821 "smppc send the SMP PHY Control command, requires -p\n"
8822 "smpphylist display phys attached to a SAS expander\n"
8823 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8824 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8825 "tags report or set the number of transaction slots for a device\n"
8826 "negotiate report or set device negotiation parameters\n"
8827 "format send the SCSI FORMAT UNIT command to the named device\n"
8828 "sanitize send the SCSI SANITIZE command to the named device\n"
8829 "idle send the ATA IDLE command to the named device\n"
8830 "standby send the ATA STANDBY command to the named device\n"
8831 "sleep send the ATA SLEEP command to the named device\n"
8832 "fwdownload program firmware of the named device with the given image\n"
8833 "security report or send ATA security commands to the named device\n"
8834 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8835 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8836 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8837 "help this message\n"
8838 "Device Identifiers:\n"
8839 "bus:target specify the bus and target, lun defaults to 0\n"
8840 "bus:target:lun specify the bus, target and lun\n"
8841 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8842 "Generic arguments:\n"
8843 "-v be verbose, print out sense information\n"
8844 "-t timeout command timeout in seconds, overrides default timeout\n"
8845 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8846 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8847 "-E have the kernel attempt to perform SCSI error recovery\n"
8848 "-C count specify the SCSI command retry count (needs -E to work)\n"
8849 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
8850 "modepage arguments:\n"
8851 "-l list all available mode pages\n"
8852 "-m page specify the mode page to view or edit\n"
8853 "-e edit the specified mode page\n"
8854 "-b force view to binary mode\n"
8855 "-d disable block descriptors for mode sense\n"
8856 "-P pgctl page control field 0-3\n"
8857 "defects arguments:\n"
8858 "-f format specify defect list format (block, bfi or phys)\n"
8859 "-G get the grown defect list\n"
8860 "-P get the permanent defect list\n"
8861 "inquiry arguments:\n"
8862 "-D get the standard inquiry data\n"
8863 "-S get the serial number\n"
8864 "-R get the transfer rate, etc.\n"
8865 "reportluns arguments:\n"
8866 "-c only report a count of available LUNs\n"
8867 "-l only print out luns, and not a count\n"
8868 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
8869 "readcap arguments\n"
8870 "-b only report the blocksize\n"
8871 "-h human readable device size, base 2\n"
8872 "-H human readable device size, base 10\n"
8873 "-N print the number of blocks instead of last block\n"
8874 "-q quiet, print numbers only\n"
8875 "-s only report the last block/device size\n"
8877 "-c cdb [args] specify the SCSI CDB\n"
8878 "-i len fmt specify input data and input data format\n"
8879 "-o len fmt [args] specify output data and output data fmt\n"
8880 "smpcmd arguments:\n"
8881 "-r len fmt [args] specify the SMP command to be sent\n"
8882 "-R len fmt [args] specify SMP response format\n"
8883 "smprg arguments:\n"
8884 "-l specify the long response format\n"
8885 "smppc arguments:\n"
8886 "-p phy specify the PHY to operate on\n"
8887 "-l specify the long request/response format\n"
8888 "-o operation specify the phy control operation\n"
8889 "-d name set the attached device name\n"
8890 "-m rate set the minimum physical link rate\n"
8891 "-M rate set the maximum physical link rate\n"
8892 "-T pp_timeout set the partial pathway timeout value\n"
8893 "-a enable|disable enable or disable SATA slumber\n"
8894 "-A enable|disable enable or disable SATA partial phy power\n"
8895 "-s enable|disable enable or disable SAS slumber\n"
8896 "-S enable|disable enable or disable SAS partial phy power\n"
8897 "smpphylist arguments:\n"
8898 "-l specify the long response format\n"
8899 "-q only print phys with attached devices\n"
8900 "smpmaninfo arguments:\n"
8901 "-l specify the long response format\n"
8902 "debug arguments:\n"
8903 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
8904 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
8905 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
8906 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
8908 "-N tags specify the number of tags to use for this device\n"
8909 "-q be quiet, don't report the number of tags\n"
8910 "-v report a number of tag-related parameters\n"
8911 "negotiate arguments:\n"
8912 "-a send a test unit ready after negotiation\n"
8913 "-c report/set current negotiation settings\n"
8914 "-D <arg> \"enable\" or \"disable\" disconnection\n"
8915 "-M mode set ATA mode\n"
8916 "-O offset set command delay offset\n"
8917 "-q be quiet, don't report anything\n"
8918 "-R syncrate synchronization rate in MHz\n"
8919 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
8920 "-U report/set user negotiation settings\n"
8921 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
8922 "-v also print a Path Inquiry CCB for the controller\n"
8923 "format arguments:\n"
8924 "-q be quiet, don't print status messages\n"
8925 "-r run in report only mode\n"
8926 "-w don't send immediate format command\n"
8927 "-y don't ask any questions\n"
8928 "sanitize arguments:\n"
8929 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
8930 "-c passes overwrite passes to perform (1 to 31)\n"
8931 "-I invert overwrite pattern after each pass\n"
8932 "-P pattern path to overwrite pattern file\n"
8933 "-q be quiet, don't print status messages\n"
8934 "-r run in report only mode\n"
8935 "-U run operation in unrestricted completion exit mode\n"
8936 "-w don't send immediate sanitize command\n"
8937 "-y don't ask any questions\n"
8938 "idle/standby arguments:\n"
8939 "-t <arg> number of seconds before respective state.\n"
8940 "fwdownload arguments:\n"
8941 "-f fw_image path to firmware image file\n"
8942 "-q don't print informational messages, only errors\n"
8943 "-s run in simulation mode\n"
8944 "-v print info for every firmware segment sent to device\n"
8945 "-y don't ask any questions\n"
8946 "security arguments:\n"
8947 "-d pwd disable security using the given password for the selected\n"
8949 "-e pwd erase the device using the given pwd for the selected user\n"
8950 "-f freeze the security configuration of the specified device\n"
8951 "-h pwd enhanced erase the device using the given pwd for the\n"
8953 "-k pwd unlock the device using the given pwd for the selected\n"
8955 "-l <high|maximum> specifies which security level to set: high or maximum\n"
8956 "-q be quiet, do not print any status messages\n"
8957 "-s pwd password the device (enable security) using the given\n"
8958 " pwd for the selected user\n"
8959 "-T timeout overrides the timeout (seconds) used for erase operation\n"
8960 "-U <user|master> specifies which user to set: user or master\n"
8961 "-y don't ask any questions\n"
8963 "-f freeze the HPA configuration of the device\n"
8964 "-l lock the HPA configuration of the device\n"
8965 "-P make the HPA max sectors persist\n"
8966 "-p pwd Set the HPA configuration password required for unlock\n"
8968 "-q be quiet, do not print any status messages\n"
8969 "-s sectors configures the maximum user accessible sectors of the\n"
8971 "-U pwd unlock the HPA configuration of the device\n"
8972 "-y don't ask any questions\n"
8973 "persist arguments:\n"
8974 "-i action specify read_keys, read_reservation, report_cap, or\n"
8975 " read_full_status\n"
8976 "-o action specify register, register_ignore, reserve, release,\n"
8977 " clear, preempt, preempt_abort, register_move, replace_lost\n"
8978 "-a set the All Target Ports (ALL_TG_PT) bit\n"
8979 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
8980 "-k key specify the Reservation Key\n"
8981 "-K sa_key specify the Service Action Reservation Key\n"
8982 "-p set the Activate Persist Through Power Loss bit\n"
8983 "-R rtp specify the Relative Target Port\n"
8984 "-s scope specify the scope: lun, extent, element or a number\n"
8985 "-S specify Transport ID for register, requires -I\n"
8986 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
8987 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
8988 "-U unregister the current initiator for register_move\n"
8989 "attrib arguments:\n"
8990 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
8992 "-w attr specify an attribute to write, one -w argument per attr\n"
8993 "-a attr_num only display this attribute number\n"
8994 "-c get cached attributes\n"
8995 "-e elem_addr request attributes for the given element in a changer\n"
8996 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
8997 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
8998 " field_none, field_desc, field_num, field_size, field_rw\n"
8999 "-p partition request attributes for the given partition\n"
9000 "-s start_attr request attributes starting at the given number\n"
9001 "-T elem_type specify the element type (used with -e)\n"
9002 "-V logical_vol specify the logical volume ID\n"
9003 "opcodes arguments:\n"
9004 "-o opcode specify the individual opcode to list\n"
9005 "-s service_action specify the service action for the opcode\n"
9006 "-N do not return SCSI error for unsupported SA\n"
9007 "-T request nominal and recommended timeout values\n"
9009 #endif /* MINIMALISTIC */
9013 main(int argc, char **argv)
9016 char *device = NULL;
9018 struct cam_device *cam_dev = NULL;
9019 int timeout = 0, retry_count = 1;
9020 camcontrol_optret optreturn;
9022 const char *mainopt = "C:En:Q:t:u:v";
9023 const char *subopt = NULL;
9024 char combinedopt[256];
9025 int error = 0, optstart = 2;
9026 int task_attr = MSG_SIMPLE_Q_TAG;
9028 #ifndef MINIMALISTIC
9032 #endif /* MINIMALISTIC */
9034 cmdlist = CAM_CMD_NONE;
9035 arglist = CAM_ARG_NONE;
9043 * Get the base option.
9045 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9047 if (optreturn == CC_OR_AMBIGUOUS) {
9048 warnx("ambiguous option %s", argv[1]);
9051 } else if (optreturn == CC_OR_NOT_FOUND) {
9052 warnx("option %s not found", argv[1]);
9058 * Ahh, getopt(3) is a pain.
9060 * This is a gross hack. There really aren't many other good
9061 * options (excuse the pun) for parsing options in a situation like
9062 * this. getopt is kinda braindead, so you end up having to run
9063 * through the options twice, and give each invocation of getopt
9064 * the option string for the other invocation.
9066 * You would think that you could just have two groups of options.
9067 * The first group would get parsed by the first invocation of
9068 * getopt, and the second group would get parsed by the second
9069 * invocation of getopt. It doesn't quite work out that way. When
9070 * the first invocation of getopt finishes, it leaves optind pointing
9071 * to the argument _after_ the first argument in the second group.
9072 * So when the second invocation of getopt comes around, it doesn't
9073 * recognize the first argument it gets and then bails out.
9075 * A nice alternative would be to have a flag for getopt that says
9076 * "just keep parsing arguments even when you encounter an unknown
9077 * argument", but there isn't one. So there's no real clean way to
9078 * easily parse two sets of arguments without having one invocation
9079 * of getopt know about the other.
9081 * Without this hack, the first invocation of getopt would work as
9082 * long as the generic arguments are first, but the second invocation
9083 * (in the subfunction) would fail in one of two ways. In the case
9084 * where you don't set optreset, it would fail because optind may be
9085 * pointing to the argument after the one it should be pointing at.
9086 * In the case where you do set optreset, and reset optind, it would
9087 * fail because getopt would run into the first set of options, which
9088 * it doesn't understand.
9090 * All of this would "sort of" work if you could somehow figure out
9091 * whether optind had been incremented one option too far. The
9092 * mechanics of that, however, are more daunting than just giving
9093 * both invocations all of the expect options for either invocation.
9095 * Needless to say, I wouldn't mind if someone invented a better
9096 * (non-GPL!) command line parsing interface than getopt. I
9097 * wouldn't mind if someone added more knobs to getopt to make it
9098 * work better. Who knows, I may talk myself into doing it someday,
9099 * if the standards weenies let me. As it is, it just leads to
9100 * hackery like this and causes people to avoid it in some cases.
9102 * KDM, September 8th, 1998
9105 sprintf(combinedopt, "%s%s", mainopt, subopt);
9107 sprintf(combinedopt, "%s", mainopt);
9110 * For these options we do not parse optional device arguments and
9111 * we do not open a passthrough device.
9113 if ((cmdlist == CAM_CMD_RESCAN)
9114 || (cmdlist == CAM_CMD_RESET)
9115 || (cmdlist == CAM_CMD_DEVTREE)
9116 || (cmdlist == CAM_CMD_USAGE)
9117 || (cmdlist == CAM_CMD_DEBUG))
9120 #ifndef MINIMALISTIC
9122 && (argc > 2 && argv[2][0] != '-')) {
9126 if (isdigit(argv[2][0])) {
9127 /* device specified as bus:target[:lun] */
9128 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9130 errx(1, "numeric device specification must "
9131 "be either bus:target, or "
9133 /* default to 0 if lun was not specified */
9134 if ((arglist & CAM_ARG_LUN) == 0) {
9136 arglist |= CAM_ARG_LUN;
9140 if (cam_get_device(argv[2], name, sizeof name, &unit)
9142 errx(1, "%s", cam_errbuf);
9143 device = strdup(name);
9144 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9148 #endif /* MINIMALISTIC */
9150 * Start getopt processing at argv[2/3], since we've already
9151 * accepted argv[1..2] as the command name, and as a possible
9157 * Now we run through the argument list looking for generic
9158 * options, and ignoring options that possibly belong to
9161 while ((c = getopt(argc, argv, combinedopt))!= -1){
9164 retry_count = strtol(optarg, NULL, 0);
9165 if (retry_count < 0)
9166 errx(1, "retry count %d is < 0",
9168 arglist |= CAM_ARG_RETRIES;
9171 arglist |= CAM_ARG_ERR_RECOVER;
9174 arglist |= CAM_ARG_DEVICE;
9176 while (isspace(*tstr) && (*tstr != '\0'))
9178 device = (char *)strdup(tstr);
9182 int table_entry = 0;
9185 while (isspace(*tstr) && (*tstr != '\0'))
9187 if (isdigit(*tstr)) {
9188 task_attr = strtol(tstr, &endptr, 0);
9189 if (*endptr != '\0') {
9190 errx(1, "Invalid queue option "
9195 scsi_nv_status status;
9197 table_size = sizeof(task_attrs) /
9198 sizeof(task_attrs[0]);
9199 status = scsi_get_nv(task_attrs,
9200 table_size, tstr, &table_entry,
9201 SCSI_NV_FLAG_IG_CASE);
9202 if (status == SCSI_NV_FOUND)
9203 task_attr = task_attrs[
9206 errx(1, "%s option %s",
9207 (status == SCSI_NV_AMBIGUOUS)?
9208 "ambiguous" : "invalid",
9215 timeout = strtol(optarg, NULL, 0);
9217 errx(1, "invalid timeout %d", timeout);
9218 /* Convert the timeout from seconds to ms */
9220 arglist |= CAM_ARG_TIMEOUT;
9223 arglist |= CAM_ARG_UNIT;
9224 unit = strtol(optarg, NULL, 0);
9227 arglist |= CAM_ARG_VERBOSE;
9234 #ifndef MINIMALISTIC
9236 * For most commands we'll want to open the passthrough device
9237 * associated with the specified device. In the case of the rescan
9238 * commands, we don't use a passthrough device at all, just the
9239 * transport layer device.
9242 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9243 && (((arglist & CAM_ARG_DEVICE) == 0)
9244 || ((arglist & CAM_ARG_UNIT) == 0))) {
9245 errx(1, "subcommand \"%s\" requires a valid device "
9246 "identifier", argv[1]);
9249 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9250 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9251 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9253 errx(1,"%s", cam_errbuf);
9255 #endif /* MINIMALISTIC */
9258 * Reset optind to 2, and reset getopt, so these routines can parse
9259 * the arguments again.
9265 #ifndef MINIMALISTIC
9266 case CAM_CMD_DEVLIST:
9267 error = getdevlist(cam_dev);
9270 error = atahpa(cam_dev, retry_count, timeout,
9271 argc, argv, combinedopt);
9273 #endif /* MINIMALISTIC */
9274 case CAM_CMD_DEVTREE:
9275 error = getdevtree(argc, argv, combinedopt);
9277 #ifndef MINIMALISTIC
9279 error = testunitready(cam_dev, task_attr, retry_count,
9282 case CAM_CMD_INQUIRY:
9283 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9284 task_attr, retry_count, timeout);
9286 case CAM_CMD_IDENTIFY:
9287 error = ataidentify(cam_dev, retry_count, timeout);
9289 case CAM_CMD_STARTSTOP:
9290 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9291 arglist & CAM_ARG_EJECT, task_attr,
9292 retry_count, timeout);
9294 #endif /* MINIMALISTIC */
9295 case CAM_CMD_RESCAN:
9296 error = dorescan_or_reset(argc, argv, 1);
9299 error = dorescan_or_reset(argc, argv, 0);
9301 #ifndef MINIMALISTIC
9302 case CAM_CMD_READ_DEFECTS:
9303 error = readdefects(cam_dev, argc, argv, combinedopt,
9304 task_attr, retry_count, timeout);
9306 case CAM_CMD_MODE_PAGE:
9307 modepage(cam_dev, argc, argv, combinedopt,
9308 task_attr, retry_count, timeout);
9310 case CAM_CMD_SCSI_CMD:
9311 error = scsicmd(cam_dev, argc, argv, combinedopt,
9312 task_attr, retry_count, timeout);
9314 case CAM_CMD_SMP_CMD:
9315 error = smpcmd(cam_dev, argc, argv, combinedopt,
9316 retry_count, timeout);
9318 case CAM_CMD_SMP_RG:
9319 error = smpreportgeneral(cam_dev, argc, argv,
9320 combinedopt, retry_count,
9323 case CAM_CMD_SMP_PC:
9324 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9325 retry_count, timeout);
9327 case CAM_CMD_SMP_PHYLIST:
9328 error = smpphylist(cam_dev, argc, argv, combinedopt,
9329 retry_count, timeout);
9331 case CAM_CMD_SMP_MANINFO:
9332 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9333 retry_count, timeout);
9336 error = camdebug(argc, argv, combinedopt);
9339 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9342 error = ratecontrol(cam_dev, task_attr, retry_count,
9343 timeout, argc, argv, combinedopt);
9345 case CAM_CMD_FORMAT:
9346 error = scsiformat(cam_dev, argc, argv,
9347 combinedopt, task_attr, retry_count,
9350 case CAM_CMD_REPORTLUNS:
9351 error = scsireportluns(cam_dev, argc, argv,
9352 combinedopt, task_attr,
9353 retry_count, timeout);
9355 case CAM_CMD_READCAP:
9356 error = scsireadcapacity(cam_dev, argc, argv,
9357 combinedopt, task_attr,
9358 retry_count, timeout);
9361 case CAM_CMD_STANDBY:
9363 error = atapm(cam_dev, argc, argv,
9364 combinedopt, retry_count, timeout);
9368 error = ataaxm(cam_dev, argc, argv,
9369 combinedopt, retry_count, timeout);
9371 case CAM_CMD_SECURITY:
9372 error = atasecurity(cam_dev, retry_count, timeout,
9373 argc, argv, combinedopt);
9375 case CAM_CMD_DOWNLOAD_FW:
9376 error = fwdownload(cam_dev, argc, argv, combinedopt,
9377 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
9380 case CAM_CMD_SANITIZE:
9381 error = scsisanitize(cam_dev, argc, argv,
9382 combinedopt, task_attr,
9383 retry_count, timeout);
9385 case CAM_CMD_PERSIST:
9386 error = scsipersist(cam_dev, argc, argv, combinedopt,
9387 task_attr, retry_count, timeout,
9388 arglist & CAM_ARG_VERBOSE,
9389 arglist & CAM_ARG_ERR_RECOVER);
9391 case CAM_CMD_ATTRIB:
9392 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9393 task_attr, retry_count, timeout,
9394 arglist & CAM_ARG_VERBOSE,
9395 arglist & CAM_ARG_ERR_RECOVER);
9397 case CAM_CMD_OPCODES:
9398 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9399 task_attr, retry_count, timeout,
9400 arglist & CAM_ARG_VERBOSE);
9402 case CAM_CMD_REPROBE:
9403 error = scsireprobe(cam_dev);
9406 #endif /* MINIMALISTIC */
9416 if (cam_dev != NULL)
9417 cam_close_device(cam_dev);