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
106 CAM_ARG_NONE = 0x00000000,
107 CAM_ARG_VERBOSE = 0x00000001,
108 CAM_ARG_DEVICE = 0x00000002,
109 CAM_ARG_BUS = 0x00000004,
110 CAM_ARG_TARGET = 0x00000008,
111 CAM_ARG_LUN = 0x00000010,
112 CAM_ARG_EJECT = 0x00000020,
113 CAM_ARG_UNIT = 0x00000040,
114 CAM_ARG_FORMAT_BLOCK = 0x00000080,
115 CAM_ARG_FORMAT_BFI = 0x00000100,
116 CAM_ARG_FORMAT_PHYS = 0x00000200,
117 CAM_ARG_PLIST = 0x00000400,
118 CAM_ARG_GLIST = 0x00000800,
119 CAM_ARG_GET_SERIAL = 0x00001000,
120 CAM_ARG_GET_STDINQ = 0x00002000,
121 CAM_ARG_GET_XFERRATE = 0x00004000,
122 CAM_ARG_INQ_MASK = 0x00007000,
123 CAM_ARG_MODE_EDIT = 0x00008000,
124 CAM_ARG_PAGE_CNTL = 0x00010000,
125 CAM_ARG_TIMEOUT = 0x00020000,
126 CAM_ARG_CMD_IN = 0x00040000,
127 CAM_ARG_CMD_OUT = 0x00080000,
128 CAM_ARG_DBD = 0x00100000,
129 CAM_ARG_ERR_RECOVER = 0x00200000,
130 CAM_ARG_RETRIES = 0x00400000,
131 CAM_ARG_START_UNIT = 0x00800000,
132 CAM_ARG_DEBUG_INFO = 0x01000000,
133 CAM_ARG_DEBUG_TRACE = 0x02000000,
134 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
135 CAM_ARG_DEBUG_CDB = 0x08000000,
136 CAM_ARG_DEBUG_XPT = 0x10000000,
137 CAM_ARG_DEBUG_PERIPH = 0x20000000,
138 CAM_ARG_DEBUG_PROBE = 0x40000000,
141 struct camcontrol_opts {
149 struct ata_res_pass16 {
150 u_int16_t reserved[5];
153 u_int8_t sector_count_exp;
154 u_int8_t sector_count;
155 u_int8_t lba_low_exp;
157 u_int8_t lba_mid_exp;
159 u_int8_t lba_high_exp;
165 struct ata_set_max_pwd
168 u_int8_t password[32];
169 u_int16_t reserved2[239];
172 static const char scsicmd_opts[] = "a:c:dfi:o:r";
173 static const char readdefect_opts[] = "f:GPqsS:X";
174 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
175 static const char smprg_opts[] = "l";
176 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
177 static const char smpphylist_opts[] = "lq";
181 static struct camcontrol_opts option_table[] = {
183 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
184 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
185 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
186 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
187 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
188 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
189 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
190 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
191 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
192 #endif /* MINIMALISTIC */
193 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
194 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
196 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
197 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
198 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
199 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
200 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
201 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
202 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
203 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
204 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
205 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
206 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
207 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
208 #endif /* MINIMALISTIC */
209 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
211 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
212 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
213 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
214 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
215 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
216 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
217 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
218 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
219 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
220 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
221 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
222 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
223 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
224 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:ys"},
225 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
226 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
227 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
228 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
229 #endif /* MINIMALISTIC */
230 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
231 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
232 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
237 struct device_match_result dev_match;
239 struct periph_match_result *periph_matches;
240 struct scsi_vpd_device_id *device_id;
242 STAILQ_ENTRY(cam_devitem) links;
246 STAILQ_HEAD(, cam_devitem) dev_queue;
250 static cam_cmdmask cmdlist;
251 static cam_argmask arglist;
253 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
254 uint32_t *cmdnum, cam_argmask *argnum,
255 const char **subopt);
257 static int getdevlist(struct cam_device *device);
258 #endif /* MINIMALISTIC */
259 static int getdevtree(int argc, char **argv, char *combinedopt);
261 static int testunitready(struct cam_device *device, int retry_count,
262 int timeout, int quiet);
263 static int scsistart(struct cam_device *device, int startstop, int loadeject,
264 int retry_count, int timeout);
265 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
266 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
267 static int camxferrate(struct cam_device *device);
268 #endif /* MINIMALISTIC */
269 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
270 lun_id_t *lun, cam_argmask *arglst);
271 static int dorescan_or_reset(int argc, char **argv, int rescan);
272 static int rescan_or_reset_bus(path_id_t bus, int rescan);
273 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
274 lun_id_t lun, int scan);
276 static int readdefects(struct cam_device *device, int argc, char **argv,
277 char *combinedopt, int retry_count, int timeout);
278 static void modepage(struct cam_device *device, int argc, char **argv,
279 char *combinedopt, int retry_count, int timeout);
280 static int scsicmd(struct cam_device *device, int argc, char **argv,
281 char *combinedopt, int retry_count, int timeout);
282 static int smpcmd(struct cam_device *device, int argc, char **argv,
283 char *combinedopt, int retry_count, int timeout);
284 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
285 char *combinedopt, int retry_count, int timeout);
286 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
287 char *combinedopt, int retry_count, int timeout);
288 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
289 char *combinedopt, int retry_count, int timeout);
290 static int getdevid(struct cam_devitem *item);
291 static int buildbusdevlist(struct cam_devlist *devlist);
292 static void freebusdevlist(struct cam_devlist *devlist);
293 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
295 static int smpphylist(struct cam_device *device, int argc, char **argv,
296 char *combinedopt, int retry_count, int timeout);
297 static int tagcontrol(struct cam_device *device, int argc, char **argv,
299 static void cts_print(struct cam_device *device,
300 struct ccb_trans_settings *cts);
301 static void cpi_print(struct ccb_pathinq *cpi);
302 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
303 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
304 static int get_print_cts(struct cam_device *device, int user_settings,
305 int quiet, struct ccb_trans_settings *cts);
306 static int ratecontrol(struct cam_device *device, int retry_count,
307 int timeout, int argc, char **argv, char *combinedopt);
308 static int scsiformat(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int retry_count, int timeout);
310 static int scsisanitize(struct cam_device *device, int argc, char **argv,
311 char *combinedopt, int retry_count, int timeout);
312 static int scsireportluns(struct cam_device *device, int argc, char **argv,
313 char *combinedopt, int retry_count, int timeout);
314 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int retry_count, int timeout);
316 static int atapm(struct cam_device *device, int argc, char **argv,
317 char *combinedopt, int retry_count, int timeout);
318 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
319 int argc, char **argv, char *combinedopt);
320 static int atahpa(struct cam_device *device, int retry_count, int timeout,
321 int argc, char **argv, char *combinedopt);
323 #endif /* MINIMALISTIC */
325 #define min(a,b) (((a)<(b))?(a):(b))
328 #define max(a,b) (((a)>(b))?(a):(b))
332 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
333 cam_argmask *argnum, const char **subopt)
335 struct camcontrol_opts *opts;
338 for (opts = table; (opts != NULL) && (opts->optname != NULL);
340 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
341 *cmdnum = opts->cmdnum;
342 *argnum = opts->argnum;
343 *subopt = opts->subopt;
344 if (++num_matches > 1)
345 return(CC_OR_AMBIGUOUS);
352 return(CC_OR_NOT_FOUND);
357 getdevlist(struct cam_device *device)
363 ccb = cam_getccb(device);
365 ccb->ccb_h.func_code = XPT_GDEVLIST;
366 ccb->ccb_h.flags = CAM_DIR_NONE;
367 ccb->ccb_h.retry_count = 1;
369 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
370 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
371 if (cam_send_ccb(device, ccb) < 0) {
372 perror("error getting device list");
379 switch (ccb->cgdl.status) {
380 case CAM_GDEVLIST_MORE_DEVS:
381 strcpy(status, "MORE");
383 case CAM_GDEVLIST_LAST_DEVICE:
384 strcpy(status, "LAST");
386 case CAM_GDEVLIST_LIST_CHANGED:
387 strcpy(status, "CHANGED");
389 case CAM_GDEVLIST_ERROR:
390 strcpy(status, "ERROR");
395 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
396 ccb->cgdl.periph_name,
397 ccb->cgdl.unit_number,
398 ccb->cgdl.generation,
403 * If the list has changed, we need to start over from the
406 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
414 #endif /* MINIMALISTIC */
417 getdevtree(int argc, char **argv, char *combinedopt)
428 while ((c = getopt(argc, argv, combinedopt)) != -1) {
431 if ((arglist & CAM_ARG_VERBOSE) == 0)
439 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
440 warn("couldn't open %s", XPT_DEVICE);
444 bzero(&ccb, sizeof(union ccb));
446 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
447 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
448 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
450 ccb.ccb_h.func_code = XPT_DEV_MATCH;
451 bufsize = sizeof(struct dev_match_result) * 100;
452 ccb.cdm.match_buf_len = bufsize;
453 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
454 if (ccb.cdm.matches == NULL) {
455 warnx("can't malloc memory for matches");
459 ccb.cdm.num_matches = 0;
462 * We fetch all nodes, since we display most of them in the default
463 * case, and all in the verbose case.
465 ccb.cdm.num_patterns = 0;
466 ccb.cdm.pattern_buf_len = 0;
469 * We do the ioctl multiple times if necessary, in case there are
470 * more than 100 nodes in the EDT.
473 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
474 warn("error sending CAMIOCOMMAND ioctl");
479 if ((ccb.ccb_h.status != CAM_REQ_CMP)
480 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
481 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
482 warnx("got CAM error %#x, CDM error %d\n",
483 ccb.ccb_h.status, ccb.cdm.status);
488 for (i = 0; i < ccb.cdm.num_matches; i++) {
489 switch (ccb.cdm.matches[i].type) {
490 case DEV_MATCH_BUS: {
491 struct bus_match_result *bus_result;
494 * Only print the bus information if the
495 * user turns on the verbose flag.
497 if ((busonly == 0) &&
498 (arglist & CAM_ARG_VERBOSE) == 0)
502 &ccb.cdm.matches[i].result.bus_result;
505 fprintf(stdout, ")\n");
509 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
511 bus_result->dev_name,
512 bus_result->unit_number,
514 (busonly ? "" : ":"));
517 case DEV_MATCH_DEVICE: {
518 struct device_match_result *dev_result;
519 char vendor[16], product[48], revision[16];
520 char fw[5], tmpstr[256];
526 &ccb.cdm.matches[i].result.device_result;
528 if ((dev_result->flags
529 & DEV_RESULT_UNCONFIGURED)
530 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
536 if (dev_result->protocol == PROTO_SCSI) {
537 cam_strvis(vendor, dev_result->inq_data.vendor,
538 sizeof(dev_result->inq_data.vendor),
541 dev_result->inq_data.product,
542 sizeof(dev_result->inq_data.product),
545 dev_result->inq_data.revision,
546 sizeof(dev_result->inq_data.revision),
548 sprintf(tmpstr, "<%s %s %s>", vendor, product,
550 } else if (dev_result->protocol == PROTO_ATA ||
551 dev_result->protocol == PROTO_SATAPM) {
553 dev_result->ident_data.model,
554 sizeof(dev_result->ident_data.model),
557 dev_result->ident_data.revision,
558 sizeof(dev_result->ident_data.revision),
560 sprintf(tmpstr, "<%s %s>", product,
562 } else if (dev_result->protocol == PROTO_SEMB) {
563 struct sep_identify_data *sid;
565 sid = (struct sep_identify_data *)
566 &dev_result->ident_data;
567 cam_strvis(vendor, sid->vendor_id,
568 sizeof(sid->vendor_id),
570 cam_strvis(product, sid->product_id,
571 sizeof(sid->product_id),
573 cam_strvis(revision, sid->product_rev,
574 sizeof(sid->product_rev),
576 cam_strvis(fw, sid->firmware_rev,
577 sizeof(sid->firmware_rev),
579 sprintf(tmpstr, "<%s %s %s %s>",
580 vendor, product, revision, fw);
582 sprintf(tmpstr, "<>");
585 fprintf(stdout, ")\n");
589 fprintf(stdout, "%-33s at scbus%d "
590 "target %d lun %jx (",
593 dev_result->target_id,
594 (uintmax_t)dev_result->target_lun);
600 case DEV_MATCH_PERIPH: {
601 struct periph_match_result *periph_result;
604 &ccb.cdm.matches[i].result.periph_result;
606 if (busonly || skip_device != 0)
610 fprintf(stdout, ",");
612 fprintf(stdout, "%s%d",
613 periph_result->periph_name,
614 periph_result->unit_number);
620 fprintf(stdout, "unknown match type\n");
625 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
626 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
629 fprintf(stdout, ")\n");
638 testunitready(struct cam_device *device, int retry_count, int timeout,
644 ccb = cam_getccb(device);
646 scsi_test_unit_ready(&ccb->csio,
647 /* retries */ retry_count,
649 /* tag_action */ MSG_SIMPLE_Q_TAG,
650 /* sense_len */ SSD_FULL_SIZE,
651 /* timeout */ timeout ? timeout : 5000);
653 /* Disable freezing the device queue */
654 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
656 if (arglist & CAM_ARG_ERR_RECOVER)
657 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
659 if (cam_send_ccb(device, ccb) < 0) {
661 perror("error sending test unit ready");
663 if (arglist & CAM_ARG_VERBOSE) {
664 cam_error_print(device, ccb, CAM_ESF_ALL,
665 CAM_EPF_ALL, stderr);
672 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
674 fprintf(stdout, "Unit is ready\n");
677 fprintf(stdout, "Unit is not ready\n");
680 if (arglist & CAM_ARG_VERBOSE) {
681 cam_error_print(device, ccb, CAM_ESF_ALL,
682 CAM_EPF_ALL, stderr);
692 scsistart(struct cam_device *device, int startstop, int loadeject,
693 int retry_count, int timeout)
698 ccb = cam_getccb(device);
701 * If we're stopping, send an ordered tag so the drive in question
702 * will finish any previously queued writes before stopping. If
703 * the device isn't capable of tagged queueing, or if tagged
704 * queueing is turned off, the tag action is a no-op.
706 scsi_start_stop(&ccb->csio,
707 /* retries */ retry_count,
709 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
711 /* start/stop */ startstop,
712 /* load_eject */ loadeject,
714 /* sense_len */ SSD_FULL_SIZE,
715 /* timeout */ timeout ? timeout : 120000);
717 /* Disable freezing the device queue */
718 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
720 if (arglist & CAM_ARG_ERR_RECOVER)
721 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
723 if (cam_send_ccb(device, ccb) < 0) {
724 perror("error sending start unit");
726 if (arglist & CAM_ARG_VERBOSE) {
727 cam_error_print(device, ccb, CAM_ESF_ALL,
728 CAM_EPF_ALL, stderr);
735 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
737 fprintf(stdout, "Unit started successfully");
739 fprintf(stdout,", Media loaded\n");
741 fprintf(stdout,"\n");
743 fprintf(stdout, "Unit stopped successfully");
745 fprintf(stdout, ", Media ejected\n");
747 fprintf(stdout, "\n");
753 "Error received from start unit command\n");
756 "Error received from stop unit command\n");
758 if (arglist & CAM_ARG_VERBOSE) {
759 cam_error_print(device, ccb, CAM_ESF_ALL,
760 CAM_EPF_ALL, stderr);
770 scsidoinquiry(struct cam_device *device, int argc, char **argv,
771 char *combinedopt, int retry_count, int timeout)
776 while ((c = getopt(argc, argv, combinedopt)) != -1) {
779 arglist |= CAM_ARG_GET_STDINQ;
782 arglist |= CAM_ARG_GET_XFERRATE;
785 arglist |= CAM_ARG_GET_SERIAL;
793 * If the user didn't specify any inquiry options, he wants all of
796 if ((arglist & CAM_ARG_INQ_MASK) == 0)
797 arglist |= CAM_ARG_INQ_MASK;
799 if (arglist & CAM_ARG_GET_STDINQ)
800 error = scsiinquiry(device, retry_count, timeout);
805 if (arglist & CAM_ARG_GET_SERIAL)
806 scsiserial(device, retry_count, timeout);
811 if (arglist & CAM_ARG_GET_XFERRATE)
812 error = camxferrate(device);
818 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
821 struct scsi_inquiry_data *inq_buf;
824 ccb = cam_getccb(device);
827 warnx("couldn't allocate CCB");
831 /* cam_getccb cleans up the header, caller has to zero the payload */
832 bzero(&(&ccb->ccb_h)[1],
833 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
835 inq_buf = (struct scsi_inquiry_data *)malloc(
836 sizeof(struct scsi_inquiry_data));
838 if (inq_buf == NULL) {
840 warnx("can't malloc memory for inquiry\n");
843 bzero(inq_buf, sizeof(*inq_buf));
846 * Note that although the size of the inquiry buffer is the full
847 * 256 bytes specified in the SCSI spec, we only tell the device
848 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
849 * two reasons for this:
851 * - The SCSI spec says that when a length field is only 1 byte,
852 * a value of 0 will be interpreted as 256. Therefore
853 * scsi_inquiry() will convert an inq_len (which is passed in as
854 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
855 * to 0. Evidently, very few devices meet the spec in that
856 * regard. Some devices, like many Seagate disks, take the 0 as
857 * 0, and don't return any data. One Pioneer DVD-R drive
858 * returns more data than the command asked for.
860 * So, since there are numerous devices that just don't work
861 * right with the full inquiry size, we don't send the full size.
863 * - The second reason not to use the full inquiry data length is
864 * that we don't need it here. The only reason we issue a
865 * standard inquiry is to get the vendor name, device name,
866 * and revision so scsi_print_inquiry() can print them.
868 * If, at some point in the future, more inquiry data is needed for
869 * some reason, this code should use a procedure similar to the
870 * probe code. i.e., issue a short inquiry, and determine from
871 * the additional length passed back from the device how much
872 * inquiry data the device supports. Once the amount the device
873 * supports is determined, issue an inquiry for that amount and no
878 scsi_inquiry(&ccb->csio,
879 /* retries */ retry_count,
881 /* tag_action */ MSG_SIMPLE_Q_TAG,
882 /* inq_buf */ (u_int8_t *)inq_buf,
883 /* inq_len */ SHORT_INQUIRY_LENGTH,
886 /* sense_len */ SSD_FULL_SIZE,
887 /* timeout */ timeout ? timeout : 5000);
889 /* Disable freezing the device queue */
890 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
892 if (arglist & CAM_ARG_ERR_RECOVER)
893 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
895 if (cam_send_ccb(device, ccb) < 0) {
896 perror("error sending SCSI inquiry");
898 if (arglist & CAM_ARG_VERBOSE) {
899 cam_error_print(device, ccb, CAM_ESF_ALL,
900 CAM_EPF_ALL, stderr);
907 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
910 if (arglist & CAM_ARG_VERBOSE) {
911 cam_error_print(device, ccb, CAM_ESF_ALL,
912 CAM_EPF_ALL, stderr);
923 fprintf(stdout, "%s%d: ", device->device_name,
924 device->dev_unit_num);
925 scsi_print_inquiry(inq_buf);
933 scsiserial(struct cam_device *device, int retry_count, int timeout)
936 struct scsi_vpd_unit_serial_number *serial_buf;
937 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
940 ccb = cam_getccb(device);
943 warnx("couldn't allocate CCB");
947 /* cam_getccb cleans up the header, caller has to zero the payload */
948 bzero(&(&ccb->ccb_h)[1],
949 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
951 serial_buf = (struct scsi_vpd_unit_serial_number *)
952 malloc(sizeof(*serial_buf));
954 if (serial_buf == NULL) {
956 warnx("can't malloc memory for serial number");
960 scsi_inquiry(&ccb->csio,
961 /*retries*/ retry_count,
963 /* tag_action */ MSG_SIMPLE_Q_TAG,
964 /* inq_buf */ (u_int8_t *)serial_buf,
965 /* inq_len */ sizeof(*serial_buf),
967 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
968 /* sense_len */ SSD_FULL_SIZE,
969 /* timeout */ timeout ? timeout : 5000);
971 /* Disable freezing the device queue */
972 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
974 if (arglist & CAM_ARG_ERR_RECOVER)
975 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
977 if (cam_send_ccb(device, ccb) < 0) {
978 warn("error getting serial number");
980 if (arglist & CAM_ARG_VERBOSE) {
981 cam_error_print(device, ccb, CAM_ESF_ALL,
982 CAM_EPF_ALL, stderr);
990 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
993 if (arglist & CAM_ARG_VERBOSE) {
994 cam_error_print(device, ccb, CAM_ESF_ALL,
995 CAM_EPF_ALL, stderr);
1006 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1007 serial_num[serial_buf->length] = '\0';
1009 if ((arglist & CAM_ARG_GET_STDINQ)
1010 || (arglist & CAM_ARG_GET_XFERRATE))
1011 fprintf(stdout, "%s%d: Serial Number ",
1012 device->device_name, device->dev_unit_num);
1014 fprintf(stdout, "%.60s\n", serial_num);
1022 camxferrate(struct cam_device *device)
1024 struct ccb_pathinq cpi;
1026 u_int32_t speed = 0;
1031 if ((retval = get_cpi(device, &cpi)) != 0)
1034 ccb = cam_getccb(device);
1037 warnx("couldn't allocate CCB");
1041 bzero(&(&ccb->ccb_h)[1],
1042 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
1044 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1045 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1047 if (((retval = cam_send_ccb(device, ccb)) < 0)
1048 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1049 const char error_string[] = "error getting transfer settings";
1054 warnx(error_string);
1056 if (arglist & CAM_ARG_VERBOSE)
1057 cam_error_print(device, ccb, CAM_ESF_ALL,
1058 CAM_EPF_ALL, stderr);
1062 goto xferrate_bailout;
1066 speed = cpi.base_transfer_speed;
1068 if (ccb->cts.transport == XPORT_SPI) {
1069 struct ccb_trans_settings_spi *spi =
1070 &ccb->cts.xport_specific.spi;
1072 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1073 freq = scsi_calc_syncsrate(spi->sync_period);
1076 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1077 speed *= (0x01 << spi->bus_width);
1079 } else if (ccb->cts.transport == XPORT_FC) {
1080 struct ccb_trans_settings_fc *fc =
1081 &ccb->cts.xport_specific.fc;
1083 if (fc->valid & CTS_FC_VALID_SPEED)
1084 speed = fc->bitrate;
1085 } else if (ccb->cts.transport == XPORT_SAS) {
1086 struct ccb_trans_settings_sas *sas =
1087 &ccb->cts.xport_specific.sas;
1089 if (sas->valid & CTS_SAS_VALID_SPEED)
1090 speed = sas->bitrate;
1091 } else if (ccb->cts.transport == XPORT_ATA) {
1092 struct ccb_trans_settings_pata *pata =
1093 &ccb->cts.xport_specific.ata;
1095 if (pata->valid & CTS_ATA_VALID_MODE)
1096 speed = ata_mode2speed(pata->mode);
1097 } else if (ccb->cts.transport == XPORT_SATA) {
1098 struct ccb_trans_settings_sata *sata =
1099 &ccb->cts.xport_specific.sata;
1101 if (sata->valid & CTS_SATA_VALID_REVISION)
1102 speed = ata_revision2speed(sata->revision);
1107 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1108 device->device_name, device->dev_unit_num,
1111 fprintf(stdout, "%s%d: %dKB/s transfers",
1112 device->device_name, device->dev_unit_num,
1116 if (ccb->cts.transport == XPORT_SPI) {
1117 struct ccb_trans_settings_spi *spi =
1118 &ccb->cts.xport_specific.spi;
1120 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1121 && (spi->sync_offset != 0))
1122 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1123 freq % 1000, spi->sync_offset);
1125 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1126 && (spi->bus_width > 0)) {
1127 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1128 && (spi->sync_offset != 0)) {
1129 fprintf(stdout, ", ");
1131 fprintf(stdout, " (");
1133 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1134 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1135 && (spi->sync_offset != 0)) {
1136 fprintf(stdout, ")");
1138 } else if (ccb->cts.transport == XPORT_ATA) {
1139 struct ccb_trans_settings_pata *pata =
1140 &ccb->cts.xport_specific.ata;
1143 if (pata->valid & CTS_ATA_VALID_MODE)
1144 printf("%s, ", ata_mode2string(pata->mode));
1145 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1146 printf("ATAPI %dbytes, ", pata->atapi);
1147 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1148 printf("PIO %dbytes", pata->bytecount);
1150 } else if (ccb->cts.transport == XPORT_SATA) {
1151 struct ccb_trans_settings_sata *sata =
1152 &ccb->cts.xport_specific.sata;
1155 if (sata->valid & CTS_SATA_VALID_REVISION)
1156 printf("SATA %d.x, ", sata->revision);
1159 if (sata->valid & CTS_SATA_VALID_MODE)
1160 printf("%s, ", ata_mode2string(sata->mode));
1161 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1162 printf("ATAPI %dbytes, ", sata->atapi);
1163 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1164 printf("PIO %dbytes", sata->bytecount);
1168 if (ccb->cts.protocol == PROTO_SCSI) {
1169 struct ccb_trans_settings_scsi *scsi =
1170 &ccb->cts.proto_specific.scsi;
1171 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1172 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1173 fprintf(stdout, ", Command Queueing Enabled");
1178 fprintf(stdout, "\n");
1188 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1190 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1191 ((u_int32_t)parm->lba_size_2 << 16);
1193 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1194 ((u_int64_t)parm->lba_size48_2 << 16) |
1195 ((u_int64_t)parm->lba_size48_3 << 32) |
1196 ((u_int64_t)parm->lba_size48_4 << 48);
1200 "Support Enabled Value\n");
1203 printf("Host Protected Area (HPA) ");
1204 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1205 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1206 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1209 printf("HPA - Security ");
1210 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1220 atasata(struct ata_params *parm)
1224 if (parm->satacapabilities != 0xffff &&
1225 parm->satacapabilities != 0x0000)
1232 atacapprint(struct ata_params *parm)
1234 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1235 ((u_int32_t)parm->lba_size_2 << 16);
1237 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1238 ((u_int64_t)parm->lba_size48_2 << 16) |
1239 ((u_int64_t)parm->lba_size48_3 << 32) |
1240 ((u_int64_t)parm->lba_size48_4 << 48);
1243 printf("protocol ");
1244 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1245 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1246 if (parm->satacapabilities & ATA_SATA_GEN3)
1247 printf(" SATA 3.x\n");
1248 else if (parm->satacapabilities & ATA_SATA_GEN2)
1249 printf(" SATA 2.x\n");
1250 else if (parm->satacapabilities & ATA_SATA_GEN1)
1251 printf(" SATA 1.x\n");
1257 printf("device model %.40s\n", parm->model);
1258 printf("firmware revision %.8s\n", parm->revision);
1259 printf("serial number %.20s\n", parm->serial);
1260 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1261 printf("WWN %04x%04x%04x%04x\n",
1262 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1264 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1265 printf("media serial number %.30s\n",
1266 parm->media_serial);
1269 printf("cylinders %d\n", parm->cylinders);
1270 printf("heads %d\n", parm->heads);
1271 printf("sectors/track %d\n", parm->sectors);
1272 printf("sector size logical %u, physical %lu, offset %lu\n",
1273 ata_logical_sector_size(parm),
1274 (unsigned long)ata_physical_sector_size(parm),
1275 (unsigned long)ata_logical_sector_offset(parm));
1277 if (parm->config == ATA_PROTO_CFA ||
1278 (parm->support.command2 & ATA_SUPPORT_CFA))
1279 printf("CFA supported\n");
1281 printf("LBA%ssupported ",
1282 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1284 printf("%d sectors\n", lbasize);
1288 printf("LBA48%ssupported ",
1289 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1291 printf("%ju sectors\n", (uintmax_t)lbasize48);
1295 printf("PIO supported PIO");
1296 switch (ata_max_pmode(parm)) {
1312 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1313 printf(" w/o IORDY");
1316 printf("DMA%ssupported ",
1317 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1318 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1319 if (parm->mwdmamodes & 0xff) {
1321 if (parm->mwdmamodes & 0x04)
1323 else if (parm->mwdmamodes & 0x02)
1325 else if (parm->mwdmamodes & 0x01)
1329 if ((parm->atavalid & ATA_FLAG_88) &&
1330 (parm->udmamodes & 0xff)) {
1332 if (parm->udmamodes & 0x40)
1334 else if (parm->udmamodes & 0x20)
1336 else if (parm->udmamodes & 0x10)
1338 else if (parm->udmamodes & 0x08)
1340 else if (parm->udmamodes & 0x04)
1342 else if (parm->udmamodes & 0x02)
1344 else if (parm->udmamodes & 0x01)
1351 if (parm->media_rotation_rate == 1) {
1352 printf("media RPM non-rotating\n");
1353 } else if (parm->media_rotation_rate >= 0x0401 &&
1354 parm->media_rotation_rate <= 0xFFFE) {
1355 printf("media RPM %d\n",
1356 parm->media_rotation_rate);
1360 "Support Enabled Value Vendor\n");
1361 printf("read ahead %s %s\n",
1362 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1363 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1364 printf("write cache %s %s\n",
1365 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1366 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1367 printf("flush cache %s %s\n",
1368 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1369 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1370 printf("overlap %s\n",
1371 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1372 printf("Tagged Command Queuing (TCQ) %s %s",
1373 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1374 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1375 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1376 printf(" %d tags\n",
1377 ATA_QUEUE_LEN(parm->queue) + 1);
1380 printf("Native Command Queuing (NCQ) ");
1381 if (parm->satacapabilities != 0xffff &&
1382 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1383 printf("yes %d tags\n",
1384 ATA_QUEUE_LEN(parm->queue) + 1);
1388 printf("NCQ Queue Management %s\n", atasata(parm) &&
1389 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1391 printf("NCQ Streaming %s\n", atasata(parm) &&
1392 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1394 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1395 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1398 printf("SMART %s %s\n",
1399 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1400 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1401 printf("microcode download %s %s\n",
1402 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1403 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1404 printf("security %s %s\n",
1405 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1406 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1407 printf("power management %s %s\n",
1408 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1409 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1410 printf("advanced power management %s %s",
1411 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1412 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1413 if (parm->support.command2 & ATA_SUPPORT_APM) {
1414 printf(" %d/0x%02X\n",
1415 parm->apm_value & 0xff, parm->apm_value & 0xff);
1418 printf("automatic acoustic management %s %s",
1419 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1420 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1421 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1422 printf(" %d/0x%02X %d/0x%02X\n",
1423 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1424 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1425 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1426 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1429 printf("media status notification %s %s\n",
1430 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1431 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1432 printf("power-up in Standby %s %s\n",
1433 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1434 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1435 printf("write-read-verify %s %s",
1436 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1437 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1438 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1439 printf(" %d/0x%x\n",
1440 parm->wrv_mode, parm->wrv_mode);
1443 printf("unload %s %s\n",
1444 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1445 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1446 printf("general purpose logging %s %s\n",
1447 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1448 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1449 printf("free-fall %s %s\n",
1450 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1451 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1452 printf("Data Set Management (DSM/TRIM) ");
1453 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1455 printf("DSM - max 512byte blocks ");
1456 if (parm->max_dsm_blocks == 0x00)
1457 printf("yes not specified\n");
1460 parm->max_dsm_blocks);
1462 printf("DSM - deterministic read ");
1463 if (parm->support3 & ATA_SUPPORT_DRAT) {
1464 if (parm->support3 & ATA_SUPPORT_RZAT)
1465 printf("yes zeroed\n");
1467 printf("yes any value\n");
1477 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1479 struct ata_pass_16 *ata_pass_16;
1480 struct ata_cmd ata_cmd;
1482 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1483 ata_cmd.command = ata_pass_16->command;
1484 ata_cmd.control = ata_pass_16->control;
1485 ata_cmd.features = ata_pass_16->features;
1487 if (arglist & CAM_ARG_VERBOSE) {
1488 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1489 ata_op_string(&ata_cmd),
1490 ccb->csio.ccb_h.timeout);
1493 /* Disable freezing the device queue */
1494 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1496 if (arglist & CAM_ARG_ERR_RECOVER)
1497 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1499 if (cam_send_ccb(device, ccb) < 0) {
1500 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1501 warn("error sending ATA %s via pass_16",
1502 ata_op_string(&ata_cmd));
1505 if (arglist & CAM_ARG_VERBOSE) {
1506 cam_error_print(device, ccb, CAM_ESF_ALL,
1507 CAM_EPF_ALL, stderr);
1513 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1514 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1515 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1516 warnx("ATA %s via pass_16 failed",
1517 ata_op_string(&ata_cmd));
1519 if (arglist & CAM_ARG_VERBOSE) {
1520 cam_error_print(device, ccb, CAM_ESF_ALL,
1521 CAM_EPF_ALL, stderr);
1532 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1534 if (arglist & CAM_ARG_VERBOSE) {
1535 warnx("sending ATA %s with timeout of %u msecs",
1536 ata_op_string(&(ccb->ataio.cmd)),
1537 ccb->ataio.ccb_h.timeout);
1540 /* Disable freezing the device queue */
1541 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1543 if (arglist & CAM_ARG_ERR_RECOVER)
1544 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1546 if (cam_send_ccb(device, ccb) < 0) {
1547 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1548 warn("error sending ATA %s",
1549 ata_op_string(&(ccb->ataio.cmd)));
1552 if (arglist & CAM_ARG_VERBOSE) {
1553 cam_error_print(device, ccb, CAM_ESF_ALL,
1554 CAM_EPF_ALL, stderr);
1560 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1561 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1562 warnx("ATA %s failed: %d",
1563 ata_op_string(&(ccb->ataio.cmd)), quiet);
1566 if (arglist & CAM_ARG_VERBOSE) {
1567 cam_error_print(device, ccb, CAM_ESF_ALL,
1568 CAM_EPF_ALL, stderr);
1578 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1579 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1580 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1581 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1582 u_int16_t dxfer_len, int timeout, int quiet)
1584 if (data_ptr != NULL) {
1585 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1586 AP_FLAG_TLEN_SECT_CNT;
1587 if (flags & CAM_DIR_OUT)
1588 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1590 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1592 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1595 bzero(&(&ccb->ccb_h)[1],
1596 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1598 scsi_ata_pass_16(&ccb->csio,
1612 /*sense_len*/SSD_FULL_SIZE,
1615 return scsi_cam_pass_16_send(device, ccb, quiet);
1619 ata_try_pass_16(struct cam_device *device)
1621 struct ccb_pathinq cpi;
1623 if (get_cpi(device, &cpi) != 0) {
1624 warnx("couldn't get CPI");
1628 if (cpi.protocol == PROTO_SCSI) {
1629 /* possibly compatible with pass_16 */
1633 /* likely not compatible with pass_16 */
1638 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1639 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1640 u_int8_t command, u_int8_t features, u_int32_t lba,
1641 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1642 int timeout, int quiet)
1646 switch (ata_try_pass_16(device)) {
1650 /* Try using SCSI Passthrough */
1651 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1652 0, tag_action, command, features, lba,
1653 sector_count, data_ptr, dxfer_len,
1657 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1658 sizeof(struct ccb_hdr));
1659 cam_fill_ataio(&ccb->ataio,
1668 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1669 return ata_cam_send(device, ccb, quiet);
1673 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1674 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1675 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1676 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1677 u_int16_t dxfer_len, int timeout, int force48bit)
1681 retval = ata_try_pass_16(device);
1688 /* Try using SCSI Passthrough */
1689 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1690 ata_flags, tag_action, command, features,
1691 lba, sector_count, data_ptr, dxfer_len,
1694 if (ata_flags & AP_FLAG_CHK_COND) {
1695 /* Decode ata_res from sense data */
1696 struct ata_res_pass16 *res_pass16;
1697 struct ata_res *res;
1701 /* sense_data is 4 byte aligned */
1702 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1703 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1704 ptr[i] = le16toh(ptr[i]);
1706 /* sense_data is 4 byte aligned */
1707 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1708 &ccb->csio.sense_data;
1709 res = &ccb->ataio.res;
1710 res->flags = res_pass16->flags;
1711 res->status = res_pass16->status;
1712 res->error = res_pass16->error;
1713 res->lba_low = res_pass16->lba_low;
1714 res->lba_mid = res_pass16->lba_mid;
1715 res->lba_high = res_pass16->lba_high;
1716 res->device = res_pass16->device;
1717 res->lba_low_exp = res_pass16->lba_low_exp;
1718 res->lba_mid_exp = res_pass16->lba_mid_exp;
1719 res->lba_high_exp = res_pass16->lba_high_exp;
1720 res->sector_count = res_pass16->sector_count;
1721 res->sector_count_exp = res_pass16->sector_count_exp;
1727 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1728 sizeof(struct ccb_hdr));
1729 cam_fill_ataio(&ccb->ataio,
1738 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1739 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1741 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1743 if (ata_flags & AP_FLAG_CHK_COND)
1744 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1746 return ata_cam_send(device, ccb, 0);
1750 dump_data(uint16_t *ptr, uint32_t len)
1754 for (i = 0; i < len / 2; i++) {
1756 printf(" %3d: ", i);
1757 printf("%04hx ", ptr[i]);
1766 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1767 int is48bit, u_int64_t *hpasize)
1769 struct ata_res *res;
1771 res = &ccb->ataio.res;
1772 if (res->status & ATA_STATUS_ERROR) {
1773 if (arglist & CAM_ARG_VERBOSE) {
1774 cam_error_print(device, ccb, CAM_ESF_ALL,
1775 CAM_EPF_ALL, stderr);
1776 printf("error = 0x%02x, sector_count = 0x%04x, "
1777 "device = 0x%02x, status = 0x%02x\n",
1778 res->error, res->sector_count,
1779 res->device, res->status);
1782 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1783 warnx("Max address has already been set since "
1784 "last power-on or hardware reset");
1790 if (arglist & CAM_ARG_VERBOSE) {
1791 fprintf(stdout, "%s%d: Raw native max data:\n",
1792 device->device_name, device->dev_unit_num);
1793 /* res is 4 byte aligned */
1794 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1796 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1797 "status = 0x%02x\n", res->error, res->sector_count,
1798 res->device, res->status);
1801 if (hpasize != NULL) {
1803 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1804 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1805 ((res->lba_high << 16) | (res->lba_mid << 8) |
1808 *hpasize = (((res->device & 0x0f) << 24) |
1809 (res->lba_high << 16) | (res->lba_mid << 8) |
1818 ata_read_native_max(struct cam_device *device, int retry_count,
1819 u_int32_t timeout, union ccb *ccb,
1820 struct ata_params *parm, u_int64_t *hpasize)
1826 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1827 protocol = AP_PROTO_NON_DATA;
1830 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1831 protocol |= AP_EXTEND;
1833 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1836 error = ata_do_cmd(device,
1839 /*flags*/CAM_DIR_NONE,
1840 /*protocol*/protocol,
1841 /*ata_flags*/AP_FLAG_CHK_COND,
1842 /*tag_action*/MSG_SIMPLE_Q_TAG,
1849 timeout ? timeout : 1000,
1855 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1859 atahpa_set_max(struct cam_device *device, int retry_count,
1860 u_int32_t timeout, union ccb *ccb,
1861 int is48bit, u_int64_t maxsize, int persist)
1867 protocol = AP_PROTO_NON_DATA;
1870 cmd = ATA_SET_MAX_ADDRESS48;
1871 protocol |= AP_EXTEND;
1873 cmd = ATA_SET_MAX_ADDRESS;
1876 /* lba's are zero indexed so the max lba is requested max - 1 */
1880 error = ata_do_cmd(device,
1883 /*flags*/CAM_DIR_NONE,
1884 /*protocol*/protocol,
1885 /*ata_flags*/AP_FLAG_CHK_COND,
1886 /*tag_action*/MSG_SIMPLE_Q_TAG,
1888 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1890 /*sector_count*/persist,
1893 timeout ? timeout : 1000,
1899 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1903 atahpa_password(struct cam_device *device, int retry_count,
1904 u_int32_t timeout, union ccb *ccb,
1905 int is48bit, struct ata_set_max_pwd *pwd)
1911 protocol = AP_PROTO_PIO_OUT;
1912 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1914 error = ata_do_cmd(device,
1917 /*flags*/CAM_DIR_OUT,
1918 /*protocol*/protocol,
1919 /*ata_flags*/AP_FLAG_CHK_COND,
1920 /*tag_action*/MSG_SIMPLE_Q_TAG,
1922 /*features*/ATA_HPA_FEAT_SET_PWD,
1925 /*data_ptr*/(u_int8_t*)pwd,
1926 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1927 timeout ? timeout : 1000,
1933 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1937 atahpa_lock(struct cam_device *device, int retry_count,
1938 u_int32_t timeout, union ccb *ccb, int is48bit)
1944 protocol = AP_PROTO_NON_DATA;
1945 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1947 error = ata_do_cmd(device,
1950 /*flags*/CAM_DIR_NONE,
1951 /*protocol*/protocol,
1952 /*ata_flags*/AP_FLAG_CHK_COND,
1953 /*tag_action*/MSG_SIMPLE_Q_TAG,
1955 /*features*/ATA_HPA_FEAT_LOCK,
1960 timeout ? timeout : 1000,
1966 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1970 atahpa_unlock(struct cam_device *device, int retry_count,
1971 u_int32_t timeout, union ccb *ccb,
1972 int is48bit, struct ata_set_max_pwd *pwd)
1978 protocol = AP_PROTO_PIO_OUT;
1979 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1981 error = ata_do_cmd(device,
1984 /*flags*/CAM_DIR_OUT,
1985 /*protocol*/protocol,
1986 /*ata_flags*/AP_FLAG_CHK_COND,
1987 /*tag_action*/MSG_SIMPLE_Q_TAG,
1989 /*features*/ATA_HPA_FEAT_UNLOCK,
1992 /*data_ptr*/(u_int8_t*)pwd,
1993 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1994 timeout ? timeout : 1000,
2000 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2004 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2005 u_int32_t timeout, union ccb *ccb, int is48bit)
2011 protocol = AP_PROTO_NON_DATA;
2012 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2014 error = ata_do_cmd(device,
2017 /*flags*/CAM_DIR_NONE,
2018 /*protocol*/protocol,
2019 /*ata_flags*/AP_FLAG_CHK_COND,
2020 /*tag_action*/MSG_SIMPLE_Q_TAG,
2022 /*features*/ATA_HPA_FEAT_FREEZE,
2027 timeout ? timeout : 1000,
2033 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2038 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2039 union ccb *ccb, struct ata_params** ident_bufp)
2041 struct ata_params *ident_buf;
2042 struct ccb_pathinq cpi;
2043 struct ccb_getdev cgd;
2046 u_int8_t command, retry_command;
2048 if (get_cpi(device, &cpi) != 0) {
2049 warnx("couldn't get CPI");
2053 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2054 if (cpi.protocol == PROTO_ATA) {
2055 if (get_cgd(device, &cgd) != 0) {
2056 warnx("couldn't get CGD");
2060 command = (cgd.protocol == PROTO_ATA) ?
2061 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2064 /* We don't know which for sure so try both */
2065 command = ATA_ATA_IDENTIFY;
2066 retry_command = ATA_ATAPI_IDENTIFY;
2069 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2071 warnx("can't calloc memory for identify\n");
2075 error = ata_do_28bit_cmd(device,
2077 /*retries*/retry_count,
2078 /*flags*/CAM_DIR_IN,
2079 /*protocol*/AP_PROTO_PIO_IN,
2080 /*tag_action*/MSG_SIMPLE_Q_TAG,
2084 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2085 /*data_ptr*/(u_int8_t *)ptr,
2086 /*dxfer_len*/sizeof(struct ata_params),
2087 /*timeout*/timeout ? timeout : 30 * 1000,
2091 if (retry_command == 0) {
2095 error = ata_do_28bit_cmd(device,
2097 /*retries*/retry_count,
2098 /*flags*/CAM_DIR_IN,
2099 /*protocol*/AP_PROTO_PIO_IN,
2100 /*tag_action*/MSG_SIMPLE_Q_TAG,
2101 /*command*/retry_command,
2104 /*sector_count*/(u_int8_t)
2105 sizeof(struct ata_params),
2106 /*data_ptr*/(u_int8_t *)ptr,
2107 /*dxfer_len*/sizeof(struct ata_params),
2108 /*timeout*/timeout ? timeout : 30 * 1000,
2118 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2119 ptr[i] = le16toh(ptr[i]);
2124 if (arglist & CAM_ARG_VERBOSE) {
2125 fprintf(stdout, "%s%d: Raw identify data:\n",
2126 device->device_name, device->dev_unit_num);
2127 dump_data(ptr, sizeof(struct ata_params));
2130 /* check for invalid (all zero) response */
2132 warnx("Invalid identify response detected");
2137 ident_buf = (struct ata_params *)ptr;
2138 if (strncmp(ident_buf->model, "FX", 2) &&
2139 strncmp(ident_buf->model, "NEC", 3) &&
2140 strncmp(ident_buf->model, "Pioneer", 7) &&
2141 strncmp(ident_buf->model, "SHARP", 5)) {
2142 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2143 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2144 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2145 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2147 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2148 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2149 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2150 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2151 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2152 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2153 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2154 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2155 sizeof(ident_buf->media_serial));
2157 *ident_bufp = ident_buf;
2164 ataidentify(struct cam_device *device, int retry_count, int timeout)
2167 struct ata_params *ident_buf;
2170 if ((ccb = cam_getccb(device)) == NULL) {
2171 warnx("couldn't allocate CCB");
2175 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2180 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2181 if (ata_read_native_max(device, retry_count, timeout, ccb,
2182 ident_buf, &hpasize) != 0) {
2190 printf("%s%d: ", device->device_name, device->dev_unit_num);
2191 ata_print_ident(ident_buf);
2192 camxferrate(device);
2193 atacapprint(ident_buf);
2194 atahpa_print(ident_buf, hpasize, 0);
2201 #endif /* MINIMALISTIC */
2204 #ifndef MINIMALISTIC
2206 ATA_SECURITY_ACTION_PRINT,
2207 ATA_SECURITY_ACTION_FREEZE,
2208 ATA_SECURITY_ACTION_UNLOCK,
2209 ATA_SECURITY_ACTION_DISABLE,
2210 ATA_SECURITY_ACTION_ERASE,
2211 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2212 ATA_SECURITY_ACTION_SET_PASSWORD
2216 atasecurity_print_time(u_int16_t tw)
2220 printf("unspecified");
2222 printf("> 508 min");
2224 printf("%i min", 2 * tw);
2228 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2232 return 2 * 3600 * 1000; /* default: two hours */
2233 else if (timeout > 255)
2234 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2236 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2241 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2245 bzero(&cmd, sizeof(cmd));
2246 cmd.command = command;
2247 printf("Issuing %s", ata_op_string(&cmd));
2250 char pass[sizeof(pwd->password)+1];
2252 /* pwd->password may not be null terminated */
2253 pass[sizeof(pwd->password)] = '\0';
2254 strncpy(pass, pwd->password, sizeof(pwd->password));
2255 printf(" password='%s', user='%s'",
2257 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2260 if (command == ATA_SECURITY_SET_PASSWORD) {
2261 printf(", mode='%s'",
2262 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2263 "maximum" : "high");
2271 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2272 int retry_count, u_int32_t timeout, int quiet)
2276 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2278 return ata_do_28bit_cmd(device,
2281 /*flags*/CAM_DIR_NONE,
2282 /*protocol*/AP_PROTO_NON_DATA,
2283 /*tag_action*/MSG_SIMPLE_Q_TAG,
2284 /*command*/ATA_SECURITY_FREEZE_LOCK,
2295 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2296 int retry_count, u_int32_t timeout,
2297 struct ata_security_password *pwd, int quiet)
2301 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2303 return ata_do_28bit_cmd(device,
2306 /*flags*/CAM_DIR_OUT,
2307 /*protocol*/AP_PROTO_PIO_OUT,
2308 /*tag_action*/MSG_SIMPLE_Q_TAG,
2309 /*command*/ATA_SECURITY_UNLOCK,
2313 /*data_ptr*/(u_int8_t *)pwd,
2314 /*dxfer_len*/sizeof(*pwd),
2320 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2321 int retry_count, u_int32_t timeout,
2322 struct ata_security_password *pwd, int quiet)
2326 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2327 return ata_do_28bit_cmd(device,
2330 /*flags*/CAM_DIR_OUT,
2331 /*protocol*/AP_PROTO_PIO_OUT,
2332 /*tag_action*/MSG_SIMPLE_Q_TAG,
2333 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2337 /*data_ptr*/(u_int8_t *)pwd,
2338 /*dxfer_len*/sizeof(*pwd),
2345 atasecurity_erase_confirm(struct cam_device *device,
2346 struct ata_params* ident_buf)
2349 printf("\nYou are about to ERASE ALL DATA from the following"
2350 " device:\n%s%d,%s%d: ", device->device_name,
2351 device->dev_unit_num, device->given_dev_name,
2352 device->given_unit_number);
2353 ata_print_ident(ident_buf);
2357 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2359 if (fgets(str, sizeof(str), stdin) != NULL) {
2360 if (strncasecmp(str, "yes", 3) == 0) {
2362 } else if (strncasecmp(str, "no", 2) == 0) {
2365 printf("Please answer \"yes\" or "
2376 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2377 int retry_count, u_int32_t timeout,
2378 u_int32_t erase_timeout,
2379 struct ata_security_password *pwd, int quiet)
2384 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2386 error = ata_do_28bit_cmd(device,
2389 /*flags*/CAM_DIR_NONE,
2390 /*protocol*/AP_PROTO_NON_DATA,
2391 /*tag_action*/MSG_SIMPLE_Q_TAG,
2392 /*command*/ATA_SECURITY_ERASE_PREPARE,
2405 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2407 error = ata_do_28bit_cmd(device,
2410 /*flags*/CAM_DIR_OUT,
2411 /*protocol*/AP_PROTO_PIO_OUT,
2412 /*tag_action*/MSG_SIMPLE_Q_TAG,
2413 /*command*/ATA_SECURITY_ERASE_UNIT,
2417 /*data_ptr*/(u_int8_t *)pwd,
2418 /*dxfer_len*/sizeof(*pwd),
2419 /*timeout*/erase_timeout,
2422 if (error == 0 && quiet == 0)
2423 printf("\nErase Complete\n");
2429 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2430 int retry_count, u_int32_t timeout,
2431 struct ata_security_password *pwd, int quiet)
2435 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2437 return ata_do_28bit_cmd(device,
2440 /*flags*/CAM_DIR_OUT,
2441 /*protocol*/AP_PROTO_PIO_OUT,
2442 /*tag_action*/MSG_SIMPLE_Q_TAG,
2443 /*command*/ATA_SECURITY_SET_PASSWORD,
2447 /*data_ptr*/(u_int8_t *)pwd,
2448 /*dxfer_len*/sizeof(*pwd),
2454 atasecurity_print(struct ata_params *parm)
2457 printf("\nSecurity Option Value\n");
2458 if (arglist & CAM_ARG_VERBOSE) {
2459 printf("status %04x\n",
2460 parm->security_status);
2462 printf("supported %s\n",
2463 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2464 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2466 printf("enabled %s\n",
2467 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2468 printf("drive locked %s\n",
2469 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2470 printf("security config frozen %s\n",
2471 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2472 printf("count expired %s\n",
2473 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2474 printf("security level %s\n",
2475 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2476 printf("enhanced erase supported %s\n",
2477 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2478 printf("erase time ");
2479 atasecurity_print_time(parm->erase_time);
2481 printf("enhanced erase time ");
2482 atasecurity_print_time(parm->enhanced_erase_time);
2484 printf("master password rev %04x%s\n",
2485 parm->master_passwd_revision,
2486 parm->master_passwd_revision == 0x0000 ||
2487 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2491 * Validates and copies the password in optarg to the passed buffer.
2492 * If the password in optarg is the same length as the buffer then
2493 * the data will still be copied but no null termination will occur.
2496 ata_getpwd(u_int8_t *passwd, int max, char opt)
2500 len = strlen(optarg);
2502 warnx("-%c password is too long", opt);
2504 } else if (len == 0) {
2505 warnx("-%c password is missing", opt);
2507 } else if (optarg[0] == '-'){
2508 warnx("-%c password starts with '-' (generic arg?)", opt);
2510 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2511 warnx("-%c password conflicts with existing password from -%c",
2516 /* Callers pass in a buffer which does NOT need to be terminated */
2517 strncpy(passwd, optarg, max);
2524 ATA_HPA_ACTION_PRINT,
2525 ATA_HPA_ACTION_SET_MAX,
2526 ATA_HPA_ACTION_SET_PWD,
2527 ATA_HPA_ACTION_LOCK,
2528 ATA_HPA_ACTION_UNLOCK,
2529 ATA_HPA_ACTION_FREEZE_LOCK
2533 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2534 u_int64_t maxsize, int persist)
2536 printf("\nYou are about to configure HPA to limit the user accessible\n"
2537 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2538 persist ? "persistently" : "temporarily",
2539 device->device_name, device->dev_unit_num,
2540 device->given_dev_name, device->given_unit_number);
2541 ata_print_ident(ident_buf);
2545 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2547 if (NULL != fgets(str, sizeof(str), stdin)) {
2548 if (0 == strncasecmp(str, "yes", 3)) {
2550 } else if (0 == strncasecmp(str, "no", 2)) {
2553 printf("Please answer \"yes\" or "
2564 atahpa(struct cam_device *device, int retry_count, int timeout,
2565 int argc, char **argv, char *combinedopt)
2568 struct ata_params *ident_buf;
2569 struct ccb_getdev cgd;
2570 struct ata_set_max_pwd pwd;
2571 int error, confirm, quiet, c, action, actions, persist;
2572 int security, is48bit, pwdsize;
2573 u_int64_t hpasize, maxsize;
2582 memset(&pwd, 0, sizeof(pwd));
2584 /* default action is to print hpa information */
2585 action = ATA_HPA_ACTION_PRINT;
2586 pwdsize = sizeof(pwd.password);
2588 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2591 action = ATA_HPA_ACTION_SET_MAX;
2592 maxsize = strtoumax(optarg, NULL, 0);
2597 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2599 action = ATA_HPA_ACTION_SET_PWD;
2605 action = ATA_HPA_ACTION_LOCK;
2611 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2613 action = ATA_HPA_ACTION_UNLOCK;
2619 action = ATA_HPA_ACTION_FREEZE_LOCK;
2639 warnx("too many hpa actions specified");
2643 if (get_cgd(device, &cgd) != 0) {
2644 warnx("couldn't get CGD");
2648 ccb = cam_getccb(device);
2650 warnx("couldn't allocate CCB");
2654 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2661 printf("%s%d: ", device->device_name, device->dev_unit_num);
2662 ata_print_ident(ident_buf);
2663 camxferrate(device);
2666 if (action == ATA_HPA_ACTION_PRINT) {
2667 error = ata_read_native_max(device, retry_count, timeout, ccb,
2668 ident_buf, &hpasize);
2670 atahpa_print(ident_buf, hpasize, 1);
2677 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2678 warnx("HPA is not supported by this device");
2684 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2685 warnx("HPA Security is not supported by this device");
2691 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2694 * The ATA spec requires:
2695 * 1. Read native max addr is called directly before set max addr
2696 * 2. Read native max addr is NOT called before any other set max call
2699 case ATA_HPA_ACTION_SET_MAX:
2701 atahpa_set_confirm(device, ident_buf, maxsize,
2708 error = ata_read_native_max(device, retry_count, timeout,
2709 ccb, ident_buf, &hpasize);
2711 error = atahpa_set_max(device, retry_count, timeout,
2712 ccb, is48bit, maxsize, persist);
2714 /* redo identify to get new lba values */
2715 error = ata_do_identify(device, retry_count,
2718 atahpa_print(ident_buf, hpasize, 1);
2723 case ATA_HPA_ACTION_SET_PWD:
2724 error = atahpa_password(device, retry_count, timeout,
2725 ccb, is48bit, &pwd);
2727 printf("HPA password has been set\n");
2730 case ATA_HPA_ACTION_LOCK:
2731 error = atahpa_lock(device, retry_count, timeout,
2734 printf("HPA has been locked\n");
2737 case ATA_HPA_ACTION_UNLOCK:
2738 error = atahpa_unlock(device, retry_count, timeout,
2739 ccb, is48bit, &pwd);
2741 printf("HPA has been unlocked\n");
2744 case ATA_HPA_ACTION_FREEZE_LOCK:
2745 error = atahpa_freeze_lock(device, retry_count, timeout,
2748 printf("HPA has been frozen\n");
2752 errx(1, "Option currently not supported");
2762 atasecurity(struct cam_device *device, int retry_count, int timeout,
2763 int argc, char **argv, char *combinedopt)
2766 struct ata_params *ident_buf;
2767 int error, confirm, quiet, c, action, actions, setpwd;
2768 int security_enabled, erase_timeout, pwdsize;
2769 struct ata_security_password pwd;
2777 memset(&pwd, 0, sizeof(pwd));
2779 /* default action is to print security information */
2780 action = ATA_SECURITY_ACTION_PRINT;
2782 /* user is master by default as its safer that way */
2783 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2784 pwdsize = sizeof(pwd.password);
2786 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2789 action = ATA_SECURITY_ACTION_FREEZE;
2794 if (strcasecmp(optarg, "user") == 0) {
2795 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2796 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2797 } else if (strcasecmp(optarg, "master") == 0) {
2798 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2799 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2801 warnx("-U argument '%s' is invalid (must be "
2802 "'user' or 'master')", optarg);
2808 if (strcasecmp(optarg, "high") == 0) {
2809 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2810 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2811 } else if (strcasecmp(optarg, "maximum") == 0) {
2812 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2813 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2815 warnx("-l argument '%s' is unknown (must be "
2816 "'high' or 'maximum')", optarg);
2822 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2824 action = ATA_SECURITY_ACTION_UNLOCK;
2829 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2831 action = ATA_SECURITY_ACTION_DISABLE;
2836 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2838 action = ATA_SECURITY_ACTION_ERASE;
2843 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2845 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2846 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2851 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2854 if (action == ATA_SECURITY_ACTION_PRINT)
2855 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2857 * Don't increment action as this can be combined
2858 * with other actions.
2871 erase_timeout = atoi(optarg) * 1000;
2877 warnx("too many security actions specified");
2881 if ((ccb = cam_getccb(device)) == NULL) {
2882 warnx("couldn't allocate CCB");
2886 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2893 printf("%s%d: ", device->device_name, device->dev_unit_num);
2894 ata_print_ident(ident_buf);
2895 camxferrate(device);
2898 if (action == ATA_SECURITY_ACTION_PRINT) {
2899 atasecurity_print(ident_buf);
2905 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2906 warnx("Security not supported");
2912 /* default timeout 15 seconds the same as linux hdparm */
2913 timeout = timeout ? timeout : 15 * 1000;
2915 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2917 /* first set the password if requested */
2919 /* confirm we can erase before setting the password if erasing */
2921 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2922 action == ATA_SECURITY_ACTION_ERASE) &&
2923 atasecurity_erase_confirm(device, ident_buf) == 0) {
2929 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2930 pwd.revision = ident_buf->master_passwd_revision;
2931 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2932 --pwd.revision == 0) {
2933 pwd.revision = 0xfffe;
2936 error = atasecurity_set_password(device, ccb, retry_count,
2937 timeout, &pwd, quiet);
2943 security_enabled = 1;
2947 case ATA_SECURITY_ACTION_FREEZE:
2948 error = atasecurity_freeze(device, ccb, retry_count,
2952 case ATA_SECURITY_ACTION_UNLOCK:
2953 if (security_enabled) {
2954 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2955 error = atasecurity_unlock(device, ccb,
2956 retry_count, timeout, &pwd, quiet);
2958 warnx("Can't unlock, drive is not locked");
2962 warnx("Can't unlock, security is disabled");
2967 case ATA_SECURITY_ACTION_DISABLE:
2968 if (security_enabled) {
2969 /* First unlock the drive if its locked */
2970 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2971 error = atasecurity_unlock(device, ccb,
2979 error = atasecurity_disable(device,
2987 warnx("Can't disable security (already disabled)");
2992 case ATA_SECURITY_ACTION_ERASE:
2993 if (security_enabled) {
2994 if (erase_timeout == 0) {
2995 erase_timeout = atasecurity_erase_timeout_msecs(
2996 ident_buf->erase_time);
2999 error = atasecurity_erase(device, ccb, retry_count,
3000 timeout, erase_timeout, &pwd,
3003 warnx("Can't secure erase (security is disabled)");
3008 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3009 if (security_enabled) {
3010 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3011 if (erase_timeout == 0) {
3013 atasecurity_erase_timeout_msecs(
3014 ident_buf->enhanced_erase_time);
3017 error = atasecurity_erase(device, ccb,
3018 retry_count, timeout,
3019 erase_timeout, &pwd,
3022 warnx("Enhanced erase is not supported");
3026 warnx("Can't secure erase (enhanced), "
3027 "(security is disabled)");
3038 #endif /* MINIMALISTIC */
3041 * Parse out a bus, or a bus, target and lun in the following
3047 * Returns the number of parsed components, or 0.
3050 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3051 cam_argmask *arglst)
3056 while (isspace(*tstr) && (*tstr != '\0'))
3059 tmpstr = (char *)strtok(tstr, ":");
3060 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3061 *bus = strtol(tmpstr, NULL, 0);
3062 *arglst |= CAM_ARG_BUS;
3064 tmpstr = (char *)strtok(NULL, ":");
3065 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3066 *target = strtol(tmpstr, NULL, 0);
3067 *arglst |= CAM_ARG_TARGET;
3069 tmpstr = (char *)strtok(NULL, ":");
3070 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3071 *lun = strtol(tmpstr, NULL, 0);
3072 *arglst |= CAM_ARG_LUN;
3082 dorescan_or_reset(int argc, char **argv, int rescan)
3084 static const char must[] =
3085 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3087 path_id_t bus = CAM_BUS_WILDCARD;
3088 target_id_t target = CAM_TARGET_WILDCARD;
3089 lun_id_t lun = CAM_LUN_WILDCARD;
3093 warnx(must, rescan? "rescan" : "reset");
3097 tstr = argv[optind];
3098 while (isspace(*tstr) && (*tstr != '\0'))
3100 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3101 arglist |= CAM_ARG_BUS;
3103 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3104 if (rv != 1 && rv != 3) {
3105 warnx(must, rescan? "rescan" : "reset");
3110 if ((arglist & CAM_ARG_BUS)
3111 && (arglist & CAM_ARG_TARGET)
3112 && (arglist & CAM_ARG_LUN))
3113 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3115 error = rescan_or_reset_bus(bus, rescan);
3121 rescan_or_reset_bus(path_id_t bus, int rescan)
3123 union ccb ccb, matchccb;
3129 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3130 warnx("error opening transport layer device %s", XPT_DEVICE);
3131 warn("%s", XPT_DEVICE);
3135 if (bus != CAM_BUS_WILDCARD) {
3136 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3137 ccb.ccb_h.path_id = bus;
3138 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3139 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3140 ccb.crcn.flags = CAM_FLAG_NONE;
3142 /* run this at a low priority */
3143 ccb.ccb_h.pinfo.priority = 5;
3145 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3146 warn("CAMIOCOMMAND ioctl failed");
3151 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3152 fprintf(stdout, "%s of bus %d was successful\n",
3153 rescan ? "Re-scan" : "Reset", bus);
3155 fprintf(stdout, "%s of bus %d returned error %#x\n",
3156 rescan ? "Re-scan" : "Reset", bus,
3157 ccb.ccb_h.status & CAM_STATUS_MASK);
3168 * The right way to handle this is to modify the xpt so that it can
3169 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3170 * that isn't implemented, so instead we enumerate the busses and
3171 * send the rescan or reset to those busses in the case where the
3172 * given bus is -1 (wildcard). We don't send a rescan or reset
3173 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3174 * no-op, sending a rescan to the xpt bus would result in a status of
3177 bzero(&(&matchccb.ccb_h)[1],
3178 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3179 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3180 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3181 bufsize = sizeof(struct dev_match_result) * 20;
3182 matchccb.cdm.match_buf_len = bufsize;
3183 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3184 if (matchccb.cdm.matches == NULL) {
3185 warnx("can't malloc memory for matches");
3189 matchccb.cdm.num_matches = 0;
3191 matchccb.cdm.num_patterns = 1;
3192 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3194 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3195 matchccb.cdm.pattern_buf_len);
3196 if (matchccb.cdm.patterns == NULL) {
3197 warnx("can't malloc memory for patterns");
3201 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3202 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3207 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3208 warn("CAMIOCOMMAND ioctl failed");
3213 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3214 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3215 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3216 warnx("got CAM error %#x, CDM error %d\n",
3217 matchccb.ccb_h.status, matchccb.cdm.status);
3222 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3223 struct bus_match_result *bus_result;
3225 /* This shouldn't happen. */
3226 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3229 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3232 * We don't want to rescan or reset the xpt bus.
3235 if (bus_result->path_id == CAM_XPT_PATH_ID)
3238 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3240 ccb.ccb_h.path_id = bus_result->path_id;
3241 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3242 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3243 ccb.crcn.flags = CAM_FLAG_NONE;
3245 /* run this at a low priority */
3246 ccb.ccb_h.pinfo.priority = 5;
3248 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3249 warn("CAMIOCOMMAND ioctl failed");
3254 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3255 fprintf(stdout, "%s of bus %d was successful\n",
3256 rescan? "Re-scan" : "Reset",
3257 bus_result->path_id);
3260 * Don't bail out just yet, maybe the other
3261 * rescan or reset commands will complete
3264 fprintf(stderr, "%s of bus %d returned error "
3265 "%#x\n", rescan? "Re-scan" : "Reset",
3266 bus_result->path_id,
3267 ccb.ccb_h.status & CAM_STATUS_MASK);
3271 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3272 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3279 if (matchccb.cdm.patterns != NULL)
3280 free(matchccb.cdm.patterns);
3281 if (matchccb.cdm.matches != NULL)
3282 free(matchccb.cdm.matches);
3288 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3291 struct cam_device *device;
3296 if (bus == CAM_BUS_WILDCARD) {
3297 warnx("invalid bus number %d", bus);
3301 if (target == CAM_TARGET_WILDCARD) {
3302 warnx("invalid target number %d", target);
3306 if (lun == CAM_LUN_WILDCARD) {
3307 warnx("invalid lun number %jx", (uintmax_t)lun);
3313 bzero(&ccb, sizeof(union ccb));
3316 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3317 warnx("error opening transport layer device %s\n",
3319 warn("%s", XPT_DEVICE);
3323 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3324 if (device == NULL) {
3325 warnx("%s", cam_errbuf);
3330 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3331 ccb.ccb_h.path_id = bus;
3332 ccb.ccb_h.target_id = target;
3333 ccb.ccb_h.target_lun = lun;
3334 ccb.ccb_h.timeout = 5000;
3335 ccb.crcn.flags = CAM_FLAG_NONE;
3337 /* run this at a low priority */
3338 ccb.ccb_h.pinfo.priority = 5;
3341 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3342 warn("CAMIOCOMMAND ioctl failed");
3347 if (cam_send_ccb(device, &ccb) < 0) {
3348 warn("error sending XPT_RESET_DEV CCB");
3349 cam_close_device(device);
3357 cam_close_device(device);
3360 * An error code of CAM_BDR_SENT is normal for a BDR request.
3362 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3364 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3365 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3366 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3369 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3370 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3371 ccb.ccb_h.status & CAM_STATUS_MASK);
3376 #ifndef MINIMALISTIC
3378 static struct scsi_nv defect_list_type_map[] = {
3379 { "block", SRDD10_BLOCK_FORMAT },
3380 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3381 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3382 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3383 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3384 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3388 readdefects(struct cam_device *device, int argc, char **argv,
3389 char *combinedopt, int retry_count, int timeout)
3391 union ccb *ccb = NULL;
3392 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3393 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3394 size_t hdr_size = 0, entry_size = 0;
3397 u_int8_t *defect_list = NULL;
3398 u_int8_t list_format = 0;
3399 int list_type_set = 0;
3400 u_int32_t dlist_length = 0;
3401 u_int32_t returned_length = 0, valid_len = 0;
3402 u_int32_t num_returned = 0, num_valid = 0;
3403 u_int32_t max_possible_size = 0, hdr_max = 0;
3404 u_int32_t starting_offset = 0;
3405 u_int8_t returned_format, returned_type;
3407 int summary = 0, quiet = 0;
3409 int lists_specified = 0;
3410 int get_length = 1, first_pass = 1;
3413 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3417 scsi_nv_status status;
3420 status = scsi_get_nv(defect_list_type_map,
3421 sizeof(defect_list_type_map) /
3422 sizeof(defect_list_type_map[0]), optarg,
3423 &entry_num, SCSI_NV_FLAG_IG_CASE);
3425 if (status == SCSI_NV_FOUND) {
3426 list_format = defect_list_type_map[
3430 warnx("%s: %s %s option %s", __func__,
3431 (status == SCSI_NV_AMBIGUOUS) ?
3432 "ambiguous" : "invalid", "defect list type",
3435 goto defect_bailout;
3440 arglist |= CAM_ARG_GLIST;
3443 arglist |= CAM_ARG_PLIST;
3454 starting_offset = strtoul(optarg, &endptr, 0);
3455 if (*endptr != '\0') {
3457 warnx("invalid starting offset %s", optarg);
3458 goto defect_bailout;
3470 if (list_type_set == 0) {
3472 warnx("no defect list format specified");
3473 goto defect_bailout;
3476 if (arglist & CAM_ARG_PLIST) {
3477 list_format |= SRDD10_PLIST;
3481 if (arglist & CAM_ARG_GLIST) {
3482 list_format |= SRDD10_GLIST;
3487 * This implies a summary, and was the previous behavior.
3489 if (lists_specified == 0)
3492 ccb = cam_getccb(device);
3497 * We start off asking for just the header to determine how much
3498 * defect data is available. Some Hitachi drives return an error
3499 * if you ask for more data than the drive has. Once we know the
3500 * length, we retry the command with the returned length.
3502 if (use_12byte == 0)
3503 dlist_length = sizeof(*hdr10);
3505 dlist_length = sizeof(*hdr12);
3508 if (defect_list != NULL) {
3512 defect_list = malloc(dlist_length);
3513 if (defect_list == NULL) {
3514 warnx("can't malloc memory for defect list");
3516 goto defect_bailout;
3520 bzero(defect_list, dlist_length);
3523 * cam_getccb() zeros the CCB header only. So we need to zero the
3524 * payload portion of the ccb.
3526 bzero(&(&ccb->ccb_h)[1],
3527 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3529 scsi_read_defects(&ccb->csio,
3530 /*retries*/ retry_count,
3532 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3533 /*list_format*/ list_format,
3534 /*addr_desc_index*/ starting_offset,
3535 /*data_ptr*/ defect_list,
3536 /*dxfer_len*/ dlist_length,
3537 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3538 /*sense_len*/ SSD_FULL_SIZE,
3539 /*timeout*/ timeout ? timeout : 5000);
3541 /* Disable freezing the device queue */
3542 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3544 if (cam_send_ccb(device, ccb) < 0) {
3545 perror("error reading defect list");
3547 if (arglist & CAM_ARG_VERBOSE) {
3548 cam_error_print(device, ccb, CAM_ESF_ALL,
3549 CAM_EPF_ALL, stderr);
3553 goto defect_bailout;
3556 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3558 if (use_12byte == 0) {
3559 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3560 hdr_size = sizeof(*hdr10);
3561 hdr_max = SRDDH10_MAX_LENGTH;
3563 if (valid_len >= hdr_size) {
3564 returned_length = scsi_2btoul(hdr10->length);
3565 returned_format = hdr10->format;
3567 returned_length = 0;
3568 returned_format = 0;
3571 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3572 hdr_size = sizeof(*hdr12);
3573 hdr_max = SRDDH12_MAX_LENGTH;
3575 if (valid_len >= hdr_size) {
3576 returned_length = scsi_4btoul(hdr12->length);
3577 returned_format = hdr12->format;
3579 returned_length = 0;
3580 returned_format = 0;
3584 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3585 switch (returned_type) {
3586 case SRDD10_BLOCK_FORMAT:
3587 entry_size = sizeof(struct scsi_defect_desc_block);
3589 case SRDD10_LONG_BLOCK_FORMAT:
3590 entry_size = sizeof(struct scsi_defect_desc_long_block);
3592 case SRDD10_EXT_PHYS_FORMAT:
3593 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3594 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3596 case SRDD10_EXT_BFI_FORMAT:
3597 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3598 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3601 warnx("Unknown defect format 0x%x\n", returned_type);
3603 goto defect_bailout;
3607 max_possible_size = (hdr_max / entry_size) * entry_size;
3608 num_returned = returned_length / entry_size;
3609 num_valid = min(returned_length, valid_len - hdr_size);
3610 num_valid /= entry_size;
3612 if (get_length != 0) {
3615 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3616 CAM_SCSI_STATUS_ERROR) {
3617 struct scsi_sense_data *sense;
3618 int error_code, sense_key, asc, ascq;
3620 sense = &ccb->csio.sense_data;
3621 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3622 ccb->csio.sense_resid, &error_code, &sense_key,
3623 &asc, &ascq, /*show_errors*/ 1);
3626 * If the drive is reporting that it just doesn't
3627 * support the defect list format, go ahead and use
3628 * the length it reported. Otherwise, the length
3629 * may not be valid, so use the maximum.
3631 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3632 && (asc == 0x1c) && (ascq == 0x00)
3633 && (returned_length > 0)) {
3634 if ((use_12byte == 0)
3635 && (returned_length >= max_possible_size)) {
3640 dlist_length = returned_length + hdr_size;
3641 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3642 && (asc == 0x1f) && (ascq == 0x00)
3643 && (returned_length > 0)) {
3644 /* Partial defect list transfer */
3646 * Hitachi drives return this error
3647 * along with a partial defect list if they
3648 * have more defects than the 10 byte
3649 * command can support. Retry with the 12
3652 if (use_12byte == 0) {
3657 dlist_length = returned_length + hdr_size;
3658 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3659 && (asc == 0x24) && (ascq == 0x00)) {
3660 /* Invalid field in CDB */
3662 * SBC-3 says that if the drive has more
3663 * defects than can be reported with the
3664 * 10 byte command, it should return this
3665 * error and no data. Retry with the 12
3668 if (use_12byte == 0) {
3673 dlist_length = returned_length + hdr_size;
3676 * If we got a SCSI error and no valid length,
3677 * just use the 10 byte maximum. The 12
3678 * byte maximum is too large.
3680 if (returned_length == 0)
3681 dlist_length = SRDD10_MAX_LENGTH;
3683 if ((use_12byte == 0)
3684 && (returned_length >=
3685 max_possible_size)) {
3690 dlist_length = returned_length +
3694 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3697 warnx("Error reading defect header");
3698 if (arglist & CAM_ARG_VERBOSE)
3699 cam_error_print(device, ccb, CAM_ESF_ALL,
3700 CAM_EPF_ALL, stderr);
3701 goto defect_bailout;
3703 if ((use_12byte == 0)
3704 && (returned_length >= max_possible_size)) {
3709 dlist_length = returned_length + hdr_size;
3712 fprintf(stdout, "%u", num_returned);
3714 fprintf(stdout, " defect%s",
3715 (num_returned != 1) ? "s" : "");
3717 fprintf(stdout, "\n");
3719 goto defect_bailout;
3723 * We always limit the list length to the 10-byte maximum
3724 * length (0xffff). The reason is that some controllers
3725 * can't handle larger I/Os, and we can transfer the entire
3726 * 10 byte list in one shot. For drives that support the 12
3727 * byte read defects command, we'll step through the list
3728 * by specifying a starting offset. For drives that don't
3729 * support the 12 byte command's starting offset, we'll
3730 * just display the first 64K.
3732 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3738 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3739 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3740 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3741 struct scsi_sense_data *sense;
3742 int error_code, sense_key, asc, ascq;
3744 sense = &ccb->csio.sense_data;
3745 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3746 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3747 &ascq, /*show_errors*/ 1);
3750 * According to the SCSI spec, if the disk doesn't support
3751 * the requested format, it will generally return a sense
3752 * key of RECOVERED ERROR, and an additional sense code
3753 * of "DEFECT LIST NOT FOUND". HGST drives also return
3754 * Primary/Grown defect list not found errors. So just
3755 * check for an ASC of 0x1c.
3757 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3759 const char *format_str;
3761 format_str = scsi_nv_to_str(defect_list_type_map,
3762 sizeof(defect_list_type_map) /
3763 sizeof(defect_list_type_map[0]),
3764 list_format & SRDD10_DLIST_FORMAT_MASK);
3765 warnx("requested defect format %s not available",
3766 format_str ? format_str : "unknown");
3768 format_str = scsi_nv_to_str(defect_list_type_map,
3769 sizeof(defect_list_type_map) /
3770 sizeof(defect_list_type_map[0]), returned_type);
3771 if (format_str != NULL) {
3772 warnx("Device returned %s format",
3776 warnx("Device returned unknown defect"
3777 " data format %#x", returned_type);
3778 goto defect_bailout;
3782 warnx("Error returned from read defect data command");
3783 if (arglist & CAM_ARG_VERBOSE)
3784 cam_error_print(device, ccb, CAM_ESF_ALL,
3785 CAM_EPF_ALL, stderr);
3786 goto defect_bailout;
3788 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3790 warnx("Error returned from read defect data command");
3791 if (arglist & CAM_ARG_VERBOSE)
3792 cam_error_print(device, ccb, CAM_ESF_ALL,
3793 CAM_EPF_ALL, stderr);
3794 goto defect_bailout;
3797 if (first_pass != 0) {
3798 fprintf(stderr, "Got %d defect", num_returned);
3800 if ((lists_specified == 0) || (num_returned == 0)) {
3801 fprintf(stderr, "s.\n");
3802 goto defect_bailout;
3803 } else if (num_returned == 1)
3804 fprintf(stderr, ":\n");
3806 fprintf(stderr, "s:\n");
3812 * XXX KDM I should probably clean up the printout format for the
3815 switch (returned_type) {
3816 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3817 case SRDD10_EXT_PHYS_FORMAT:
3819 struct scsi_defect_desc_phys_sector *dlist;
3821 dlist = (struct scsi_defect_desc_phys_sector *)
3822 (defect_list + hdr_size);
3824 for (i = 0; i < num_valid; i++) {
3827 sector = scsi_4btoul(dlist[i].sector);
3828 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3829 mads = (sector & SDD_EXT_PHYS_MADS) ?
3831 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3833 if (hex_format == 0)
3834 fprintf(stdout, "%d:%d:%d%s",
3835 scsi_3btoul(dlist[i].cylinder),
3837 scsi_4btoul(dlist[i].sector),
3838 mads ? " - " : "\n");
3840 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3841 scsi_3btoul(dlist[i].cylinder),
3843 scsi_4btoul(dlist[i].sector),
3844 mads ? " - " : "\n");
3847 if (num_valid < num_returned) {
3848 starting_offset += num_valid;
3853 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3854 case SRDD10_EXT_BFI_FORMAT:
3856 struct scsi_defect_desc_bytes_from_index *dlist;
3858 dlist = (struct scsi_defect_desc_bytes_from_index *)
3859 (defect_list + hdr_size);
3861 for (i = 0; i < num_valid; i++) {
3864 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3865 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3866 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3867 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3869 if (hex_format == 0)
3870 fprintf(stdout, "%d:%d:%d%s",
3871 scsi_3btoul(dlist[i].cylinder),
3873 scsi_4btoul(dlist[i].bytes_from_index),
3874 mads ? " - " : "\n");
3876 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3877 scsi_3btoul(dlist[i].cylinder),
3879 scsi_4btoul(dlist[i].bytes_from_index),
3880 mads ? " - " : "\n");
3884 if (num_valid < num_returned) {
3885 starting_offset += num_valid;
3890 case SRDDH10_BLOCK_FORMAT:
3892 struct scsi_defect_desc_block *dlist;
3894 dlist = (struct scsi_defect_desc_block *)
3895 (defect_list + hdr_size);
3897 for (i = 0; i < num_valid; i++) {
3898 if (hex_format == 0)
3899 fprintf(stdout, "%u\n",
3900 scsi_4btoul(dlist[i].address));
3902 fprintf(stdout, "0x%x\n",
3903 scsi_4btoul(dlist[i].address));
3906 if (num_valid < num_returned) {
3907 starting_offset += num_valid;
3913 case SRDD10_LONG_BLOCK_FORMAT:
3915 struct scsi_defect_desc_long_block *dlist;
3917 dlist = (struct scsi_defect_desc_long_block *)
3918 (defect_list + hdr_size);
3920 for (i = 0; i < num_valid; i++) {
3921 if (hex_format == 0)
3922 fprintf(stdout, "%ju\n",
3923 (uintmax_t)scsi_8btou64(
3926 fprintf(stdout, "0x%jx\n",
3927 (uintmax_t)scsi_8btou64(
3931 if (num_valid < num_returned) {
3932 starting_offset += num_valid;
3938 fprintf(stderr, "Unknown defect format 0x%x\n",
3945 if (defect_list != NULL)
3953 #endif /* MINIMALISTIC */
3957 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3961 ccb = cam_getccb(device);
3967 #ifndef MINIMALISTIC
3969 mode_sense(struct cam_device *device, int mode_page, int page_control,
3970 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3975 ccb = cam_getccb(device);
3978 errx(1, "mode_sense: couldn't allocate CCB");
3980 bzero(&(&ccb->ccb_h)[1],
3981 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3983 scsi_mode_sense(&ccb->csio,
3984 /* retries */ retry_count,
3986 /* tag_action */ MSG_SIMPLE_Q_TAG,
3988 /* page_code */ page_control << 6,
3989 /* page */ mode_page,
3990 /* param_buf */ data,
3991 /* param_len */ datalen,
3992 /* sense_len */ SSD_FULL_SIZE,
3993 /* timeout */ timeout ? timeout : 5000);
3995 if (arglist & CAM_ARG_ERR_RECOVER)
3996 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3998 /* Disable freezing the device queue */
3999 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4001 if (((retval = cam_send_ccb(device, ccb)) < 0)
4002 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4003 if (arglist & CAM_ARG_VERBOSE) {
4004 cam_error_print(device, ccb, CAM_ESF_ALL,
4005 CAM_EPF_ALL, stderr);
4008 cam_close_device(device);
4010 err(1, "error sending mode sense command");
4012 errx(1, "error sending mode sense command");
4019 mode_select(struct cam_device *device, int save_pages, int retry_count,
4020 int timeout, u_int8_t *data, int datalen)
4025 ccb = cam_getccb(device);
4028 errx(1, "mode_select: couldn't allocate CCB");
4030 bzero(&(&ccb->ccb_h)[1],
4031 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4033 scsi_mode_select(&ccb->csio,
4034 /* retries */ retry_count,
4036 /* tag_action */ MSG_SIMPLE_Q_TAG,
4037 /* scsi_page_fmt */ 1,
4038 /* save_pages */ save_pages,
4039 /* param_buf */ data,
4040 /* param_len */ datalen,
4041 /* sense_len */ SSD_FULL_SIZE,
4042 /* timeout */ timeout ? timeout : 5000);
4044 if (arglist & CAM_ARG_ERR_RECOVER)
4045 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4047 /* Disable freezing the device queue */
4048 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4050 if (((retval = cam_send_ccb(device, ccb)) < 0)
4051 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4052 if (arglist & CAM_ARG_VERBOSE) {
4053 cam_error_print(device, ccb, CAM_ESF_ALL,
4054 CAM_EPF_ALL, stderr);
4057 cam_close_device(device);
4060 err(1, "error sending mode select command");
4062 errx(1, "error sending mode select command");
4070 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4071 int retry_count, int timeout)
4073 int c, mode_page = -1, page_control = 0;
4074 int binary = 0, list = 0;
4076 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4082 arglist |= CAM_ARG_DBD;
4085 arglist |= CAM_ARG_MODE_EDIT;
4091 mode_page = strtol(optarg, NULL, 0);
4093 errx(1, "invalid mode page %d", mode_page);
4096 page_control = strtol(optarg, NULL, 0);
4097 if ((page_control < 0) || (page_control > 3))
4098 errx(1, "invalid page control field %d",
4100 arglist |= CAM_ARG_PAGE_CNTL;
4107 if (mode_page == -1 && list == 0)
4108 errx(1, "you must specify a mode page!");
4111 mode_list(device, page_control, arglist & CAM_ARG_DBD,
4112 retry_count, timeout);
4114 mode_edit(device, mode_page, page_control,
4115 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
4116 retry_count, timeout);
4121 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4122 int retry_count, int timeout)
4125 u_int32_t flags = CAM_DIR_NONE;
4126 u_int8_t *data_ptr = NULL;
4128 u_int8_t atacmd[12];
4129 struct get_hook hook;
4130 int c, data_bytes = 0;
4136 char *datastr = NULL, *tstr, *resstr = NULL;
4138 int fd_data = 0, fd_res = 0;
4141 ccb = cam_getccb(device);
4144 warnx("scsicmd: error allocating ccb");
4148 bzero(&(&ccb->ccb_h)[1],
4149 sizeof(union ccb) - sizeof(struct ccb_hdr));
4151 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4155 while (isspace(*tstr) && (*tstr != '\0'))
4157 hook.argc = argc - optind;
4158 hook.argv = argv + optind;
4160 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4163 * Increment optind by the number of arguments the
4164 * encoding routine processed. After each call to
4165 * getopt(3), optind points to the argument that
4166 * getopt should process _next_. In this case,
4167 * that means it points to the first command string
4168 * argument, if there is one. Once we increment
4169 * this, it should point to either the next command
4170 * line argument, or it should be past the end of
4177 while (isspace(*tstr) && (*tstr != '\0'))
4179 hook.argc = argc - optind;
4180 hook.argv = argv + optind;
4182 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4185 * Increment optind by the number of arguments the
4186 * encoding routine processed. After each call to
4187 * getopt(3), optind points to the argument that
4188 * getopt should process _next_. In this case,
4189 * that means it points to the first command string
4190 * argument, if there is one. Once we increment
4191 * this, it should point to either the next command
4192 * line argument, or it should be past the end of
4204 if (arglist & CAM_ARG_CMD_OUT) {
4205 warnx("command must either be "
4206 "read or write, not both");
4208 goto scsicmd_bailout;
4210 arglist |= CAM_ARG_CMD_IN;
4212 data_bytes = strtol(optarg, NULL, 0);
4213 if (data_bytes <= 0) {
4214 warnx("invalid number of input bytes %d",
4217 goto scsicmd_bailout;
4219 hook.argc = argc - optind;
4220 hook.argv = argv + optind;
4223 datastr = cget(&hook, NULL);
4225 * If the user supplied "-" instead of a format, he
4226 * wants the data to be written to stdout.
4228 if ((datastr != NULL)
4229 && (datastr[0] == '-'))
4232 data_ptr = (u_int8_t *)malloc(data_bytes);
4233 if (data_ptr == NULL) {
4234 warnx("can't malloc memory for data_ptr");
4236 goto scsicmd_bailout;
4240 if (arglist & CAM_ARG_CMD_IN) {
4241 warnx("command must either be "
4242 "read or write, not both");
4244 goto scsicmd_bailout;
4246 arglist |= CAM_ARG_CMD_OUT;
4247 flags = CAM_DIR_OUT;
4248 data_bytes = strtol(optarg, NULL, 0);
4249 if (data_bytes <= 0) {
4250 warnx("invalid number of output bytes %d",
4253 goto scsicmd_bailout;
4255 hook.argc = argc - optind;
4256 hook.argv = argv + optind;
4258 datastr = cget(&hook, NULL);
4259 data_ptr = (u_int8_t *)malloc(data_bytes);
4260 if (data_ptr == NULL) {
4261 warnx("can't malloc memory for data_ptr");
4263 goto scsicmd_bailout;
4265 bzero(data_ptr, data_bytes);
4267 * If the user supplied "-" instead of a format, he
4268 * wants the data to be read from stdin.
4270 if ((datastr != NULL)
4271 && (datastr[0] == '-'))
4274 buff_encode_visit(data_ptr, data_bytes, datastr,
4280 hook.argc = argc - optind;
4281 hook.argv = argv + optind;
4283 resstr = cget(&hook, NULL);
4284 if ((resstr != NULL) && (resstr[0] == '-'))
4294 * If fd_data is set, and we're writing to the device, we need to
4295 * read the data the user wants written from stdin.
4297 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4299 int amt_to_read = data_bytes;
4300 u_int8_t *buf_ptr = data_ptr;
4302 for (amt_read = 0; amt_to_read > 0;
4303 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4304 if (amt_read == -1) {
4305 warn("error reading data from stdin");
4307 goto scsicmd_bailout;
4309 amt_to_read -= amt_read;
4310 buf_ptr += amt_read;
4314 if (arglist & CAM_ARG_ERR_RECOVER)
4315 flags |= CAM_PASS_ERR_RECOVER;
4317 /* Disable freezing the device queue */
4318 flags |= CAM_DEV_QFRZDIS;
4322 * This is taken from the SCSI-3 draft spec.
4323 * (T10/1157D revision 0.3)
4324 * The top 3 bits of an opcode are the group code.
4325 * The next 5 bits are the command code.
4326 * Group 0: six byte commands
4327 * Group 1: ten byte commands
4328 * Group 2: ten byte commands
4330 * Group 4: sixteen byte commands
4331 * Group 5: twelve byte commands
4332 * Group 6: vendor specific
4333 * Group 7: vendor specific
4335 switch((cdb[0] >> 5) & 0x7) {
4346 /* computed by buff_encode_visit */
4357 * We should probably use csio_build_visit or something like that
4358 * here, but it's easier to encode arguments as you go. The
4359 * alternative would be skipping the CDB argument and then encoding
4360 * it here, since we've got the data buffer argument by now.
4362 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4364 cam_fill_csio(&ccb->csio,
4365 /*retries*/ retry_count,
4368 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4369 /*data_ptr*/ data_ptr,
4370 /*dxfer_len*/ data_bytes,
4371 /*sense_len*/ SSD_FULL_SIZE,
4372 /*cdb_len*/ cdb_len,
4373 /*timeout*/ timeout ? timeout : 5000);
4376 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4378 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4380 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4382 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4384 cam_fill_ataio(&ccb->ataio,
4385 /*retries*/ retry_count,
4389 /*data_ptr*/ data_ptr,
4390 /*dxfer_len*/ data_bytes,
4391 /*timeout*/ timeout ? timeout : 5000);
4394 if (((retval = cam_send_ccb(device, ccb)) < 0)
4395 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4396 const char warnstr[] = "error sending command";
4403 if (arglist & CAM_ARG_VERBOSE) {
4404 cam_error_print(device, ccb, CAM_ESF_ALL,
4405 CAM_EPF_ALL, stderr);
4409 goto scsicmd_bailout;
4412 if (atacmd_len && need_res) {
4414 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4416 fprintf(stdout, "\n");
4419 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4420 ccb->ataio.res.status,
4421 ccb->ataio.res.error,
4422 ccb->ataio.res.lba_low,
4423 ccb->ataio.res.lba_mid,
4424 ccb->ataio.res.lba_high,
4425 ccb->ataio.res.device,
4426 ccb->ataio.res.lba_low_exp,
4427 ccb->ataio.res.lba_mid_exp,
4428 ccb->ataio.res.lba_high_exp,
4429 ccb->ataio.res.sector_count,
4430 ccb->ataio.res.sector_count_exp);
4435 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4436 && (arglist & CAM_ARG_CMD_IN)
4437 && (data_bytes > 0)) {
4439 buff_decode_visit(data_ptr, data_bytes, datastr,
4441 fprintf(stdout, "\n");
4443 ssize_t amt_written;
4444 int amt_to_write = data_bytes;
4445 u_int8_t *buf_ptr = data_ptr;
4447 for (amt_written = 0; (amt_to_write > 0) &&
4448 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4449 amt_to_write -= amt_written;
4450 buf_ptr += amt_written;
4452 if (amt_written == -1) {
4453 warn("error writing data to stdout");
4455 goto scsicmd_bailout;
4456 } else if ((amt_written == 0)
4457 && (amt_to_write > 0)) {
4458 warnx("only wrote %u bytes out of %u",
4459 data_bytes - amt_to_write, data_bytes);
4466 if ((data_bytes > 0) && (data_ptr != NULL))
4475 camdebug(int argc, char **argv, char *combinedopt)
4478 path_id_t bus = CAM_BUS_WILDCARD;
4479 target_id_t target = CAM_TARGET_WILDCARD;
4480 lun_id_t lun = CAM_LUN_WILDCARD;
4481 char *tstr, *tmpstr = NULL;
4485 bzero(&ccb, sizeof(union ccb));
4487 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4490 arglist |= CAM_ARG_DEBUG_INFO;
4491 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4494 arglist |= CAM_ARG_DEBUG_PERIPH;
4495 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4498 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4499 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4502 arglist |= CAM_ARG_DEBUG_TRACE;
4503 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4506 arglist |= CAM_ARG_DEBUG_XPT;
4507 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4510 arglist |= CAM_ARG_DEBUG_CDB;
4511 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4514 arglist |= CAM_ARG_DEBUG_PROBE;
4515 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4522 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4523 warnx("error opening transport layer device %s", XPT_DEVICE);
4524 warn("%s", XPT_DEVICE);
4531 warnx("you must specify \"off\", \"all\" or a bus,");
4532 warnx("bus:target, or bus:target:lun");
4539 while (isspace(*tstr) && (*tstr != '\0'))
4542 if (strncmp(tstr, "off", 3) == 0) {
4543 ccb.cdbg.flags = CAM_DEBUG_NONE;
4544 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4545 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4546 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4547 } else if (strncmp(tstr, "all", 3) != 0) {
4548 tmpstr = (char *)strtok(tstr, ":");
4549 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4550 bus = strtol(tmpstr, NULL, 0);
4551 arglist |= CAM_ARG_BUS;
4552 tmpstr = (char *)strtok(NULL, ":");
4553 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4554 target = strtol(tmpstr, NULL, 0);
4555 arglist |= CAM_ARG_TARGET;
4556 tmpstr = (char *)strtok(NULL, ":");
4557 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4558 lun = strtol(tmpstr, NULL, 0);
4559 arglist |= CAM_ARG_LUN;
4564 warnx("you must specify \"all\", \"off\", or a bus,");
4565 warnx("bus:target, or bus:target:lun to debug");
4571 ccb.ccb_h.func_code = XPT_DEBUG;
4572 ccb.ccb_h.path_id = bus;
4573 ccb.ccb_h.target_id = target;
4574 ccb.ccb_h.target_lun = lun;
4576 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4577 warn("CAMIOCOMMAND ioctl failed");
4582 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4583 CAM_FUNC_NOTAVAIL) {
4584 warnx("CAM debugging not available");
4585 warnx("you need to put options CAMDEBUG in"
4586 " your kernel config file!");
4588 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4590 warnx("XPT_DEBUG CCB failed with status %#x",
4594 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4596 "Debugging turned off\n");
4599 "Debugging enabled for "
4601 bus, target, (uintmax_t)lun);
4612 tagcontrol(struct cam_device *device, int argc, char **argv,
4622 ccb = cam_getccb(device);
4625 warnx("tagcontrol: error allocating ccb");
4629 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4632 numtags = strtol(optarg, NULL, 0);
4634 warnx("tag count %d is < 0", numtags);
4636 goto tagcontrol_bailout;
4647 cam_path_string(device, pathstr, sizeof(pathstr));
4650 bzero(&(&ccb->ccb_h)[1],
4651 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4652 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4653 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4654 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4655 ccb->crs.openings = numtags;
4658 if (cam_send_ccb(device, ccb) < 0) {
4659 perror("error sending XPT_REL_SIMQ CCB");
4661 goto tagcontrol_bailout;
4664 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4665 warnx("XPT_REL_SIMQ CCB failed");
4666 cam_error_print(device, ccb, CAM_ESF_ALL,
4667 CAM_EPF_ALL, stderr);
4669 goto tagcontrol_bailout;
4674 fprintf(stdout, "%stagged openings now %d\n",
4675 pathstr, ccb->crs.openings);
4678 bzero(&(&ccb->ccb_h)[1],
4679 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4681 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4683 if (cam_send_ccb(device, ccb) < 0) {
4684 perror("error sending XPT_GDEV_STATS CCB");
4686 goto tagcontrol_bailout;
4689 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4690 warnx("XPT_GDEV_STATS CCB failed");
4691 cam_error_print(device, ccb, CAM_ESF_ALL,
4692 CAM_EPF_ALL, stderr);
4694 goto tagcontrol_bailout;
4697 if (arglist & CAM_ARG_VERBOSE) {
4698 fprintf(stdout, "%s", pathstr);
4699 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4700 fprintf(stdout, "%s", pathstr);
4701 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4702 fprintf(stdout, "%s", pathstr);
4703 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4704 fprintf(stdout, "%s", pathstr);
4705 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4706 fprintf(stdout, "%s", pathstr);
4707 fprintf(stdout, "held %d\n", ccb->cgds.held);
4708 fprintf(stdout, "%s", pathstr);
4709 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4710 fprintf(stdout, "%s", pathstr);
4711 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4714 fprintf(stdout, "%s", pathstr);
4715 fprintf(stdout, "device openings: ");
4717 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4718 ccb->cgds.dev_active);
4728 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4732 cam_path_string(device, pathstr, sizeof(pathstr));
4734 if (cts->transport == XPORT_SPI) {
4735 struct ccb_trans_settings_spi *spi =
4736 &cts->xport_specific.spi;
4738 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4740 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4743 if (spi->sync_offset != 0) {
4746 freq = scsi_calc_syncsrate(spi->sync_period);
4747 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4748 pathstr, freq / 1000, freq % 1000);
4752 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4753 fprintf(stdout, "%soffset: %d\n", pathstr,
4757 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4758 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4759 (0x01 << spi->bus_width) * 8);
4762 if (spi->valid & CTS_SPI_VALID_DISC) {
4763 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4764 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4765 "enabled" : "disabled");
4768 if (cts->transport == XPORT_FC) {
4769 struct ccb_trans_settings_fc *fc =
4770 &cts->xport_specific.fc;
4772 if (fc->valid & CTS_FC_VALID_WWNN)
4773 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4774 (long long) fc->wwnn);
4775 if (fc->valid & CTS_FC_VALID_WWPN)
4776 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4777 (long long) fc->wwpn);
4778 if (fc->valid & CTS_FC_VALID_PORT)
4779 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4780 if (fc->valid & CTS_FC_VALID_SPEED)
4781 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4782 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4784 if (cts->transport == XPORT_SAS) {
4785 struct ccb_trans_settings_sas *sas =
4786 &cts->xport_specific.sas;
4788 if (sas->valid & CTS_SAS_VALID_SPEED)
4789 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4790 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4792 if (cts->transport == XPORT_ATA) {
4793 struct ccb_trans_settings_pata *pata =
4794 &cts->xport_specific.ata;
4796 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4797 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4798 ata_mode2string(pata->mode));
4800 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4801 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4804 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4805 fprintf(stdout, "%sPIO transaction length: %d\n",
4806 pathstr, pata->bytecount);
4809 if (cts->transport == XPORT_SATA) {
4810 struct ccb_trans_settings_sata *sata =
4811 &cts->xport_specific.sata;
4813 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4814 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4817 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4818 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4819 ata_mode2string(sata->mode));
4821 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4822 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4825 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4826 fprintf(stdout, "%sPIO transaction length: %d\n",
4827 pathstr, sata->bytecount);
4829 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4830 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4833 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4834 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4837 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4838 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4842 if (cts->protocol == PROTO_ATA) {
4843 struct ccb_trans_settings_ata *ata=
4844 &cts->proto_specific.ata;
4846 if (ata->valid & CTS_ATA_VALID_TQ) {
4847 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4848 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4849 "enabled" : "disabled");
4852 if (cts->protocol == PROTO_SCSI) {
4853 struct ccb_trans_settings_scsi *scsi=
4854 &cts->proto_specific.scsi;
4856 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4857 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4858 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4859 "enabled" : "disabled");
4866 * Get a path inquiry CCB for the specified device.
4869 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4874 ccb = cam_getccb(device);
4876 warnx("get_cpi: couldn't allocate CCB");
4879 bzero(&(&ccb->ccb_h)[1],
4880 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4881 ccb->ccb_h.func_code = XPT_PATH_INQ;
4882 if (cam_send_ccb(device, ccb) < 0) {
4883 warn("get_cpi: error sending Path Inquiry CCB");
4884 if (arglist & CAM_ARG_VERBOSE)
4885 cam_error_print(device, ccb, CAM_ESF_ALL,
4886 CAM_EPF_ALL, stderr);
4888 goto get_cpi_bailout;
4890 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4891 if (arglist & CAM_ARG_VERBOSE)
4892 cam_error_print(device, ccb, CAM_ESF_ALL,
4893 CAM_EPF_ALL, stderr);
4895 goto get_cpi_bailout;
4897 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4905 * Get a get device CCB for the specified device.
4908 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4913 ccb = cam_getccb(device);
4915 warnx("get_cgd: couldn't allocate CCB");
4918 bzero(&(&ccb->ccb_h)[1],
4919 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4920 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4921 if (cam_send_ccb(device, ccb) < 0) {
4922 warn("get_cgd: error sending Path Inquiry CCB");
4923 if (arglist & CAM_ARG_VERBOSE)
4924 cam_error_print(device, ccb, CAM_ESF_ALL,
4925 CAM_EPF_ALL, stderr);
4927 goto get_cgd_bailout;
4929 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4930 if (arglist & CAM_ARG_VERBOSE)
4931 cam_error_print(device, ccb, CAM_ESF_ALL,
4932 CAM_EPF_ALL, stderr);
4934 goto get_cgd_bailout;
4936 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4943 /* return the type of disk (really the command type) */
4945 get_disk_type(struct cam_device *device)
4947 struct ccb_getdev cgd;
4949 (void) memset(&cgd, 0x0, sizeof(cgd));
4950 get_cgd(device, &cgd);
4951 switch(cgd.protocol) {
4964 cpi_print(struct ccb_pathinq *cpi)
4966 char adapter_str[1024];
4969 snprintf(adapter_str, sizeof(adapter_str),
4970 "%s%d:", cpi->dev_name, cpi->unit_number);
4972 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
4975 for (i = 1; i < 0xff; i = i << 1) {
4978 if ((i & cpi->hba_inquiry) == 0)
4981 fprintf(stdout, "%s supports ", adapter_str);
4985 str = "MDP message";
4988 str = "32 bit wide SCSI";
4991 str = "16 bit wide SCSI";
4994 str = "SDTR message";
4997 str = "linked CDBs";
5000 str = "tag queue messages";
5003 str = "soft reset alternative";
5006 str = "SATA Port Multiplier";
5009 str = "unknown PI bit set";
5012 fprintf(stdout, "%s\n", str);
5015 for (i = 1; i < 0xff; i = i << 1) {
5018 if ((i & cpi->hba_misc) == 0)
5021 fprintf(stdout, "%s ", adapter_str);
5025 str = "bus scans from high ID to low ID";
5028 str = "removable devices not included in scan";
5030 case PIM_NOINITIATOR:
5031 str = "initiator role not supported";
5033 case PIM_NOBUSRESET:
5034 str = "user has disabled initial BUS RESET or"
5035 " controller is in target/mixed mode";
5038 str = "do not send 6-byte commands";
5041 str = "scan bus sequentially";
5044 str = "unknown PIM bit set";
5047 fprintf(stdout, "%s\n", str);
5050 for (i = 1; i < 0xff; i = i << 1) {
5053 if ((i & cpi->target_sprt) == 0)
5056 fprintf(stdout, "%s supports ", adapter_str);
5059 str = "target mode processor mode";
5062 str = "target mode phase cog. mode";
5064 case PIT_DISCONNECT:
5065 str = "disconnects in target mode";
5068 str = "terminate I/O message in target mode";
5071 str = "group 6 commands in target mode";
5074 str = "group 7 commands in target mode";
5077 str = "unknown PIT bit set";
5081 fprintf(stdout, "%s\n", str);
5083 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5085 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5087 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5089 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5090 adapter_str, cpi->hpath_id);
5091 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5093 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5094 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5095 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5096 adapter_str, cpi->hba_vendor);
5097 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5098 adapter_str, cpi->hba_device);
5099 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5100 adapter_str, cpi->hba_subvendor);
5101 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5102 adapter_str, cpi->hba_subdevice);
5103 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5104 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5105 if (cpi->base_transfer_speed > 1000)
5106 fprintf(stdout, "%d.%03dMB/sec\n",
5107 cpi->base_transfer_speed / 1000,
5108 cpi->base_transfer_speed % 1000);
5110 fprintf(stdout, "%dKB/sec\n",
5111 (cpi->base_transfer_speed % 1000) * 1000);
5112 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5113 adapter_str, cpi->maxio);
5117 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5118 struct ccb_trans_settings *cts)
5124 ccb = cam_getccb(device);
5127 warnx("get_print_cts: error allocating ccb");
5131 bzero(&(&ccb->ccb_h)[1],
5132 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5134 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5136 if (user_settings == 0)
5137 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5139 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5141 if (cam_send_ccb(device, ccb) < 0) {
5142 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5143 if (arglist & CAM_ARG_VERBOSE)
5144 cam_error_print(device, ccb, CAM_ESF_ALL,
5145 CAM_EPF_ALL, stderr);
5147 goto get_print_cts_bailout;
5150 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5151 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5152 if (arglist & CAM_ARG_VERBOSE)
5153 cam_error_print(device, ccb, CAM_ESF_ALL,
5154 CAM_EPF_ALL, stderr);
5156 goto get_print_cts_bailout;
5160 cts_print(device, &ccb->cts);
5163 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5165 get_print_cts_bailout:
5173 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5174 int argc, char **argv, char *combinedopt)
5178 int user_settings = 0;
5180 int disc_enable = -1, tag_enable = -1;
5183 double syncrate = -1;
5186 int change_settings = 0, send_tur = 0;
5187 struct ccb_pathinq cpi;
5189 ccb = cam_getccb(device);
5191 warnx("ratecontrol: error allocating ccb");
5194 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5203 if (strncasecmp(optarg, "enable", 6) == 0)
5205 else if (strncasecmp(optarg, "disable", 7) == 0)
5208 warnx("-D argument \"%s\" is unknown", optarg);
5210 goto ratecontrol_bailout;
5212 change_settings = 1;
5215 mode = ata_string2mode(optarg);
5217 warnx("unknown mode '%s'", optarg);
5219 goto ratecontrol_bailout;
5221 change_settings = 1;
5224 offset = strtol(optarg, NULL, 0);
5226 warnx("offset value %d is < 0", offset);
5228 goto ratecontrol_bailout;
5230 change_settings = 1;
5236 syncrate = atof(optarg);
5238 warnx("sync rate %f is < 0", syncrate);
5240 goto ratecontrol_bailout;
5242 change_settings = 1;
5245 if (strncasecmp(optarg, "enable", 6) == 0)
5247 else if (strncasecmp(optarg, "disable", 7) == 0)
5250 warnx("-T argument \"%s\" is unknown", optarg);
5252 goto ratecontrol_bailout;
5254 change_settings = 1;
5260 bus_width = strtol(optarg, NULL, 0);
5261 if (bus_width < 0) {
5262 warnx("bus width %d is < 0", bus_width);
5264 goto ratecontrol_bailout;
5266 change_settings = 1;
5272 bzero(&(&ccb->ccb_h)[1],
5273 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
5275 * Grab path inquiry information, so we can determine whether
5276 * or not the initiator is capable of the things that the user
5279 ccb->ccb_h.func_code = XPT_PATH_INQ;
5280 if (cam_send_ccb(device, ccb) < 0) {
5281 perror("error sending XPT_PATH_INQ CCB");
5282 if (arglist & CAM_ARG_VERBOSE) {
5283 cam_error_print(device, ccb, CAM_ESF_ALL,
5284 CAM_EPF_ALL, stderr);
5287 goto ratecontrol_bailout;
5289 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5290 warnx("XPT_PATH_INQ CCB failed");
5291 if (arglist & CAM_ARG_VERBOSE) {
5292 cam_error_print(device, ccb, CAM_ESF_ALL,
5293 CAM_EPF_ALL, stderr);
5296 goto ratecontrol_bailout;
5298 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5299 bzero(&(&ccb->ccb_h)[1],
5300 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5302 fprintf(stdout, "%s parameters:\n",
5303 user_settings ? "User" : "Current");
5305 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5307 goto ratecontrol_bailout;
5309 if (arglist & CAM_ARG_VERBOSE)
5312 if (change_settings) {
5313 int didsettings = 0;
5314 struct ccb_trans_settings_spi *spi = NULL;
5315 struct ccb_trans_settings_pata *pata = NULL;
5316 struct ccb_trans_settings_sata *sata = NULL;
5317 struct ccb_trans_settings_ata *ata = NULL;
5318 struct ccb_trans_settings_scsi *scsi = NULL;
5320 if (ccb->cts.transport == XPORT_SPI)
5321 spi = &ccb->cts.xport_specific.spi;
5322 if (ccb->cts.transport == XPORT_ATA)
5323 pata = &ccb->cts.xport_specific.ata;
5324 if (ccb->cts.transport == XPORT_SATA)
5325 sata = &ccb->cts.xport_specific.sata;
5326 if (ccb->cts.protocol == PROTO_ATA)
5327 ata = &ccb->cts.proto_specific.ata;
5328 if (ccb->cts.protocol == PROTO_SCSI)
5329 scsi = &ccb->cts.proto_specific.scsi;
5330 ccb->cts.xport_specific.valid = 0;
5331 ccb->cts.proto_specific.valid = 0;
5332 if (spi && disc_enable != -1) {
5333 spi->valid |= CTS_SPI_VALID_DISC;
5334 if (disc_enable == 0)
5335 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5337 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5340 if (tag_enable != -1) {
5341 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5342 warnx("HBA does not support tagged queueing, "
5343 "so you cannot modify tag settings");
5345 goto ratecontrol_bailout;
5348 ata->valid |= CTS_SCSI_VALID_TQ;
5349 if (tag_enable == 0)
5350 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5352 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5355 scsi->valid |= CTS_SCSI_VALID_TQ;
5356 if (tag_enable == 0)
5357 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5359 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5363 if (spi && offset != -1) {
5364 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5365 warnx("HBA is not capable of changing offset");
5367 goto ratecontrol_bailout;
5369 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5370 spi->sync_offset = offset;
5373 if (spi && syncrate != -1) {
5374 int prelim_sync_period;
5376 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5377 warnx("HBA is not capable of changing "
5380 goto ratecontrol_bailout;
5382 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5384 * The sync rate the user gives us is in MHz.
5385 * We need to translate it into KHz for this
5390 * Next, we calculate a "preliminary" sync period
5391 * in tenths of a nanosecond.
5394 prelim_sync_period = 0;
5396 prelim_sync_period = 10000000 / syncrate;
5398 scsi_calc_syncparam(prelim_sync_period);
5401 if (sata && syncrate != -1) {
5402 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5403 warnx("HBA is not capable of changing "
5406 goto ratecontrol_bailout;
5408 if (!user_settings) {
5409 warnx("You can modify only user rate "
5410 "settings for SATA");
5412 goto ratecontrol_bailout;
5414 sata->revision = ata_speed2revision(syncrate * 100);
5415 if (sata->revision < 0) {
5416 warnx("Invalid rate %f", syncrate);
5418 goto ratecontrol_bailout;
5420 sata->valid |= CTS_SATA_VALID_REVISION;
5423 if ((pata || sata) && mode != -1) {
5424 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5425 warnx("HBA is not capable of changing "
5428 goto ratecontrol_bailout;
5430 if (!user_settings) {
5431 warnx("You can modify only user mode "
5432 "settings for ATA/SATA");
5434 goto ratecontrol_bailout;
5438 pata->valid |= CTS_ATA_VALID_MODE;
5441 sata->valid |= CTS_SATA_VALID_MODE;
5446 * The bus_width argument goes like this:
5450 * Therefore, if you shift the number of bits given on the
5451 * command line right by 4, you should get the correct
5454 if (spi && bus_width != -1) {
5456 * We might as well validate things here with a
5457 * decipherable error message, rather than what
5458 * will probably be an indecipherable error message
5459 * by the time it gets back to us.
5461 if ((bus_width == 16)
5462 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5463 warnx("HBA does not support 16 bit bus width");
5465 goto ratecontrol_bailout;
5466 } else if ((bus_width == 32)
5467 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5468 warnx("HBA does not support 32 bit bus width");
5470 goto ratecontrol_bailout;
5471 } else if ((bus_width != 8)
5472 && (bus_width != 16)
5473 && (bus_width != 32)) {
5474 warnx("Invalid bus width %d", bus_width);
5476 goto ratecontrol_bailout;
5478 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5479 spi->bus_width = bus_width >> 4;
5482 if (didsettings == 0) {
5483 goto ratecontrol_bailout;
5485 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5486 if (cam_send_ccb(device, ccb) < 0) {
5487 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5488 if (arglist & CAM_ARG_VERBOSE) {
5489 cam_error_print(device, ccb, CAM_ESF_ALL,
5490 CAM_EPF_ALL, stderr);
5493 goto ratecontrol_bailout;
5495 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5496 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5497 if (arglist & CAM_ARG_VERBOSE) {
5498 cam_error_print(device, ccb, CAM_ESF_ALL,
5499 CAM_EPF_ALL, stderr);
5502 goto ratecontrol_bailout;
5506 retval = testunitready(device, retry_count, timeout,
5507 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5509 * If the TUR didn't succeed, just bail.
5513 fprintf(stderr, "Test Unit Ready failed\n");
5514 goto ratecontrol_bailout;
5517 if ((change_settings || send_tur) && !quiet &&
5518 (ccb->cts.transport == XPORT_ATA ||
5519 ccb->cts.transport == XPORT_SATA || send_tur)) {
5520 fprintf(stdout, "New parameters:\n");
5521 retval = get_print_cts(device, user_settings, 0, NULL);
5524 ratecontrol_bailout:
5530 scsiformat(struct cam_device *device, int argc, char **argv,
5531 char *combinedopt, int retry_count, int timeout)
5535 int ycount = 0, quiet = 0;
5536 int error = 0, retval = 0;
5537 int use_timeout = 10800 * 1000;
5539 struct format_defect_list_header fh;
5540 u_int8_t *data_ptr = NULL;
5541 u_int32_t dxfer_len = 0;
5543 int num_warnings = 0;
5546 ccb = cam_getccb(device);
5549 warnx("scsiformat: error allocating ccb");
5553 bzero(&(&ccb->ccb_h)[1],
5554 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5556 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5577 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5578 "following device:\n");
5580 error = scsidoinquiry(device, argc, argv, combinedopt,
5581 retry_count, timeout);
5584 warnx("scsiformat: error sending inquiry");
5585 goto scsiformat_bailout;
5590 if (!get_confirmation()) {
5592 goto scsiformat_bailout;
5597 use_timeout = timeout;
5600 fprintf(stdout, "Current format timeout is %d seconds\n",
5601 use_timeout / 1000);
5605 * If the user hasn't disabled questions and didn't specify a
5606 * timeout on the command line, ask them if they want the current
5610 && (timeout == 0)) {
5612 int new_timeout = 0;
5614 fprintf(stdout, "Enter new timeout in seconds or press\n"
5615 "return to keep the current timeout [%d] ",
5616 use_timeout / 1000);
5618 if (fgets(str, sizeof(str), stdin) != NULL) {
5620 new_timeout = atoi(str);
5623 if (new_timeout != 0) {
5624 use_timeout = new_timeout * 1000;
5625 fprintf(stdout, "Using new timeout value %d\n",
5626 use_timeout / 1000);
5631 * Keep this outside the if block below to silence any unused
5632 * variable warnings.
5634 bzero(&fh, sizeof(fh));
5637 * If we're in immediate mode, we've got to include the format
5640 if (immediate != 0) {
5641 fh.byte2 = FU_DLH_IMMED;
5642 data_ptr = (u_int8_t *)&fh;
5643 dxfer_len = sizeof(fh);
5644 byte2 = FU_FMT_DATA;
5645 } else if (quiet == 0) {
5646 fprintf(stdout, "Formatting...");
5650 scsi_format_unit(&ccb->csio,
5651 /* retries */ retry_count,
5653 /* tag_action */ MSG_SIMPLE_Q_TAG,
5656 /* data_ptr */ data_ptr,
5657 /* dxfer_len */ dxfer_len,
5658 /* sense_len */ SSD_FULL_SIZE,
5659 /* timeout */ use_timeout);
5661 /* Disable freezing the device queue */
5662 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5664 if (arglist & CAM_ARG_ERR_RECOVER)
5665 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5667 if (((retval = cam_send_ccb(device, ccb)) < 0)
5668 || ((immediate == 0)
5669 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5670 const char errstr[] = "error sending format command";
5677 if (arglist & CAM_ARG_VERBOSE) {
5678 cam_error_print(device, ccb, CAM_ESF_ALL,
5679 CAM_EPF_ALL, stderr);
5682 goto scsiformat_bailout;
5686 * If we ran in non-immediate mode, we already checked for errors
5687 * above and printed out any necessary information. If we're in
5688 * immediate mode, we need to loop through and get status
5689 * information periodically.
5691 if (immediate == 0) {
5693 fprintf(stdout, "Format Complete\n");
5695 goto scsiformat_bailout;
5702 bzero(&(&ccb->ccb_h)[1],
5703 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5706 * There's really no need to do error recovery or
5707 * retries here, since we're just going to sit in a
5708 * loop and wait for the device to finish formatting.
5710 scsi_test_unit_ready(&ccb->csio,
5713 /* tag_action */ MSG_SIMPLE_Q_TAG,
5714 /* sense_len */ SSD_FULL_SIZE,
5715 /* timeout */ 5000);
5717 /* Disable freezing the device queue */
5718 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5720 retval = cam_send_ccb(device, ccb);
5723 * If we get an error from the ioctl, bail out. SCSI
5724 * errors are expected.
5727 warn("error sending CAMIOCOMMAND ioctl");
5728 if (arglist & CAM_ARG_VERBOSE) {
5729 cam_error_print(device, ccb, CAM_ESF_ALL,
5730 CAM_EPF_ALL, stderr);
5733 goto scsiformat_bailout;
5736 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5738 if ((status != CAM_REQ_CMP)
5739 && (status == CAM_SCSI_STATUS_ERROR)
5740 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5741 struct scsi_sense_data *sense;
5742 int error_code, sense_key, asc, ascq;
5744 sense = &ccb->csio.sense_data;
5745 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5746 ccb->csio.sense_resid, &error_code, &sense_key,
5747 &asc, &ascq, /*show_errors*/ 1);
5750 * According to the SCSI-2 and SCSI-3 specs, a
5751 * drive that is in the middle of a format should
5752 * return NOT READY with an ASC of "logical unit
5753 * not ready, format in progress". The sense key
5754 * specific bytes will then be a progress indicator.
5756 if ((sense_key == SSD_KEY_NOT_READY)
5757 && (asc == 0x04) && (ascq == 0x04)) {
5760 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5761 ccb->csio.sense_resid, sks) == 0)
5764 u_int64_t percentage;
5766 val = scsi_2btoul(&sks[1]);
5767 percentage = 10000 * val;
5770 "\rFormatting: %ju.%02u %% "
5772 (uintmax_t)(percentage /
5774 (unsigned)((percentage /
5778 } else if ((quiet == 0)
5779 && (++num_warnings <= 1)) {
5780 warnx("Unexpected SCSI Sense Key "
5781 "Specific value returned "
5783 scsi_sense_print(device, &ccb->csio,
5785 warnx("Unable to print status "
5786 "information, but format will "
5788 warnx("will exit when format is "
5793 warnx("Unexpected SCSI error during format");
5794 cam_error_print(device, ccb, CAM_ESF_ALL,
5795 CAM_EPF_ALL, stderr);
5797 goto scsiformat_bailout;
5800 } else if (status != CAM_REQ_CMP) {
5801 warnx("Unexpected CAM status %#x", status);
5802 if (arglist & CAM_ARG_VERBOSE)
5803 cam_error_print(device, ccb, CAM_ESF_ALL,
5804 CAM_EPF_ALL, stderr);
5806 goto scsiformat_bailout;
5809 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5812 fprintf(stdout, "\nFormat Complete\n");
5822 scsisanitize(struct cam_device *device, int argc, char **argv,
5823 char *combinedopt, int retry_count, int timeout)
5826 u_int8_t action = 0;
5828 int ycount = 0, quiet = 0;
5829 int error = 0, retval = 0;
5830 int use_timeout = 10800 * 1000;
5836 const char *pattern = NULL;
5837 u_int8_t *data_ptr = NULL;
5838 u_int32_t dxfer_len = 0;
5840 int num_warnings = 0;
5843 ccb = cam_getccb(device);
5846 warnx("scsisanitize: error allocating ccb");
5850 bzero(&(&ccb->ccb_h)[1],
5851 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5853 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5856 if (strcasecmp(optarg, "overwrite") == 0)
5857 action = SSZ_SERVICE_ACTION_OVERWRITE;
5858 else if (strcasecmp(optarg, "block") == 0)
5859 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
5860 else if (strcasecmp(optarg, "crypto") == 0)
5861 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
5862 else if (strcasecmp(optarg, "exitfailure") == 0)
5863 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
5865 warnx("invalid service operation \"%s\"",
5868 goto scsisanitize_bailout;
5872 passes = strtol(optarg, NULL, 0);
5873 if (passes < 1 || passes > 31) {
5874 warnx("invalid passes value %d", passes);
5876 goto scsisanitize_bailout;
5907 warnx("an action is required");
5909 goto scsisanitize_bailout;
5910 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
5911 struct scsi_sanitize_parameter_list *pl;
5915 if (pattern == NULL) {
5916 warnx("overwrite action requires -P argument");
5918 goto scsisanitize_bailout;
5920 fd = open(pattern, O_RDONLY);
5922 warn("cannot open pattern file %s", pattern);
5924 goto scsisanitize_bailout;
5926 if (fstat(fd, &sb) < 0) {
5927 warn("cannot stat pattern file %s", pattern);
5929 goto scsisanitize_bailout;
5932 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
5933 warnx("pattern file size exceeds maximum value %d",
5934 SSZPL_MAX_PATTERN_LENGTH);
5936 goto scsisanitize_bailout;
5938 dxfer_len = sizeof(*pl) + sz;
5939 data_ptr = calloc(1, dxfer_len);
5940 if (data_ptr == NULL) {
5941 warnx("cannot allocate parameter list buffer");
5943 goto scsisanitize_bailout;
5946 amt = read(fd, data_ptr + sizeof(*pl), sz);
5948 warn("cannot read pattern file");
5950 goto scsisanitize_bailout;
5951 } else if (amt != sz) {
5952 warnx("short pattern file read");
5954 goto scsisanitize_bailout;
5957 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
5963 pl->byte1 |= SSZPL_INVERT;
5964 scsi_ulto2b(sz, pl->length);
5970 else if (invert != 0)
5972 else if (pattern != NULL)
5977 warnx("%s argument only valid with overwrite "
5980 goto scsisanitize_bailout;
5985 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5986 "following device:\n");
5988 error = scsidoinquiry(device, argc, argv, combinedopt,
5989 retry_count, timeout);
5992 warnx("scsisanitize: error sending inquiry");
5993 goto scsisanitize_bailout;
5998 if (!get_confirmation()) {
6000 goto scsisanitize_bailout;
6005 use_timeout = timeout;
6008 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6009 use_timeout / 1000);
6013 * If the user hasn't disabled questions and didn't specify a
6014 * timeout on the command line, ask them if they want the current
6018 && (timeout == 0)) {
6020 int new_timeout = 0;
6022 fprintf(stdout, "Enter new timeout in seconds or press\n"
6023 "return to keep the current timeout [%d] ",
6024 use_timeout / 1000);
6026 if (fgets(str, sizeof(str), stdin) != NULL) {
6028 new_timeout = atoi(str);
6031 if (new_timeout != 0) {
6032 use_timeout = new_timeout * 1000;
6033 fprintf(stdout, "Using new timeout value %d\n",
6034 use_timeout / 1000);
6040 byte2 |= SSZ_UNRESTRICTED_EXIT;
6044 scsi_sanitize(&ccb->csio,
6045 /* retries */ retry_count,
6047 /* tag_action */ MSG_SIMPLE_Q_TAG,
6050 /* data_ptr */ data_ptr,
6051 /* dxfer_len */ dxfer_len,
6052 /* sense_len */ SSD_FULL_SIZE,
6053 /* timeout */ use_timeout);
6055 /* Disable freezing the device queue */
6056 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6058 if (arglist & CAM_ARG_ERR_RECOVER)
6059 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6061 if (cam_send_ccb(device, ccb) < 0) {
6062 warn("error sending sanitize command");
6064 goto scsisanitize_bailout;
6067 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6068 struct scsi_sense_data *sense;
6069 int error_code, sense_key, asc, ascq;
6071 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6072 CAM_SCSI_STATUS_ERROR) {
6073 sense = &ccb->csio.sense_data;
6074 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6075 ccb->csio.sense_resid, &error_code, &sense_key,
6076 &asc, &ascq, /*show_errors*/ 1);
6078 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6079 asc == 0x20 && ascq == 0x00)
6080 warnx("sanitize is not supported by "
6083 warnx("error sanitizing this device");
6085 warnx("error sanitizing this device");
6087 if (arglist & CAM_ARG_VERBOSE) {
6088 cam_error_print(device, ccb, CAM_ESF_ALL,
6089 CAM_EPF_ALL, stderr);
6092 goto scsisanitize_bailout;
6096 * If we ran in non-immediate mode, we already checked for errors
6097 * above and printed out any necessary information. If we're in
6098 * immediate mode, we need to loop through and get status
6099 * information periodically.
6101 if (immediate == 0) {
6103 fprintf(stdout, "Sanitize Complete\n");
6105 goto scsisanitize_bailout;
6112 bzero(&(&ccb->ccb_h)[1],
6113 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6116 * There's really no need to do error recovery or
6117 * retries here, since we're just going to sit in a
6118 * loop and wait for the device to finish sanitizing.
6120 scsi_test_unit_ready(&ccb->csio,
6123 /* tag_action */ MSG_SIMPLE_Q_TAG,
6124 /* sense_len */ SSD_FULL_SIZE,
6125 /* timeout */ 5000);
6127 /* Disable freezing the device queue */
6128 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6130 retval = cam_send_ccb(device, ccb);
6133 * If we get an error from the ioctl, bail out. SCSI
6134 * errors are expected.
6137 warn("error sending CAMIOCOMMAND ioctl");
6138 if (arglist & CAM_ARG_VERBOSE) {
6139 cam_error_print(device, ccb, CAM_ESF_ALL,
6140 CAM_EPF_ALL, stderr);
6143 goto scsisanitize_bailout;
6146 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6148 if ((status != CAM_REQ_CMP)
6149 && (status == CAM_SCSI_STATUS_ERROR)
6150 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6151 struct scsi_sense_data *sense;
6152 int error_code, sense_key, asc, ascq;
6154 sense = &ccb->csio.sense_data;
6155 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6156 ccb->csio.sense_resid, &error_code, &sense_key,
6157 &asc, &ascq, /*show_errors*/ 1);
6160 * According to the SCSI-3 spec, a drive that is in the
6161 * middle of a sanitize should return NOT READY with an
6162 * ASC of "logical unit not ready, sanitize in
6163 * progress". The sense key specific bytes will then
6164 * be a progress indicator.
6166 if ((sense_key == SSD_KEY_NOT_READY)
6167 && (asc == 0x04) && (ascq == 0x1b)) {
6170 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6171 ccb->csio.sense_resid, sks) == 0)
6174 u_int64_t percentage;
6176 val = scsi_2btoul(&sks[1]);
6177 percentage = 10000 * val;
6180 "\rSanitizing: %ju.%02u %% "
6182 (uintmax_t)(percentage /
6184 (unsigned)((percentage /
6188 } else if ((quiet == 0)
6189 && (++num_warnings <= 1)) {
6190 warnx("Unexpected SCSI Sense Key "
6191 "Specific value returned "
6192 "during sanitize:");
6193 scsi_sense_print(device, &ccb->csio,
6195 warnx("Unable to print status "
6196 "information, but sanitze will "
6198 warnx("will exit when sanitize is "
6203 warnx("Unexpected SCSI error during sanitize");
6204 cam_error_print(device, ccb, CAM_ESF_ALL,
6205 CAM_EPF_ALL, stderr);
6207 goto scsisanitize_bailout;
6210 } else if (status != CAM_REQ_CMP) {
6211 warnx("Unexpected CAM status %#x", status);
6212 if (arglist & CAM_ARG_VERBOSE)
6213 cam_error_print(device, ccb, CAM_ESF_ALL,
6214 CAM_EPF_ALL, stderr);
6216 goto scsisanitize_bailout;
6218 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6221 fprintf(stdout, "\nSanitize Complete\n");
6223 scsisanitize_bailout:
6226 if (data_ptr != NULL)
6234 scsireportluns(struct cam_device *device, int argc, char **argv,
6235 char *combinedopt, int retry_count, int timeout)
6238 int c, countonly, lunsonly;
6239 struct scsi_report_luns_data *lundata;
6241 uint8_t report_type;
6242 uint32_t list_len, i, j;
6247 report_type = RPL_REPORT_DEFAULT;
6248 ccb = cam_getccb(device);
6251 warnx("%s: error allocating ccb", __func__);
6255 bzero(&(&ccb->ccb_h)[1],
6256 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6261 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6270 if (strcasecmp(optarg, "default") == 0)
6271 report_type = RPL_REPORT_DEFAULT;
6272 else if (strcasecmp(optarg, "wellknown") == 0)
6273 report_type = RPL_REPORT_WELLKNOWN;
6274 else if (strcasecmp(optarg, "all") == 0)
6275 report_type = RPL_REPORT_ALL;
6277 warnx("%s: invalid report type \"%s\"",
6288 if ((countonly != 0)
6289 && (lunsonly != 0)) {
6290 warnx("%s: you can only specify one of -c or -l", __func__);
6295 * According to SPC-4, the allocation length must be at least 16
6296 * bytes -- enough for the header and one LUN.
6298 alloc_len = sizeof(*lundata) + 8;
6302 lundata = malloc(alloc_len);
6304 if (lundata == NULL) {
6305 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6310 scsi_report_luns(&ccb->csio,
6311 /*retries*/ retry_count,
6313 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6314 /*select_report*/ report_type,
6315 /*rpl_buf*/ lundata,
6316 /*alloc_len*/ alloc_len,
6317 /*sense_len*/ SSD_FULL_SIZE,
6318 /*timeout*/ timeout ? timeout : 5000);
6320 /* Disable freezing the device queue */
6321 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6323 if (arglist & CAM_ARG_ERR_RECOVER)
6324 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6326 if (cam_send_ccb(device, ccb) < 0) {
6327 warn("error sending REPORT LUNS command");
6329 if (arglist & CAM_ARG_VERBOSE)
6330 cam_error_print(device, ccb, CAM_ESF_ALL,
6331 CAM_EPF_ALL, stderr);
6337 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6338 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6344 list_len = scsi_4btoul(lundata->length);
6347 * If we need to list the LUNs, and our allocation
6348 * length was too short, reallocate and retry.
6350 if ((countonly == 0)
6351 && (list_len > (alloc_len - sizeof(*lundata)))) {
6352 alloc_len = list_len + sizeof(*lundata);
6358 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6359 ((list_len / 8) > 1) ? "s" : "");
6364 for (i = 0; i < (list_len / 8); i++) {
6368 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6370 fprintf(stdout, ",");
6371 switch (lundata->luns[i].lundata[j] &
6372 RPL_LUNDATA_ATYP_MASK) {
6373 case RPL_LUNDATA_ATYP_PERIPH:
6374 if ((lundata->luns[i].lundata[j] &
6375 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6376 fprintf(stdout, "%d:",
6377 lundata->luns[i].lundata[j] &
6378 RPL_LUNDATA_PERIPH_BUS_MASK);
6380 && ((lundata->luns[i].lundata[j+2] &
6381 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6384 fprintf(stdout, "%d",
6385 lundata->luns[i].lundata[j+1]);
6387 case RPL_LUNDATA_ATYP_FLAT: {
6389 tmplun[0] = lundata->luns[i].lundata[j] &
6390 RPL_LUNDATA_FLAT_LUN_MASK;
6391 tmplun[1] = lundata->luns[i].lundata[j+1];
6393 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6397 case RPL_LUNDATA_ATYP_LUN:
6398 fprintf(stdout, "%d:%d:%d",
6399 (lundata->luns[i].lundata[j+1] &
6400 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6401 lundata->luns[i].lundata[j] &
6402 RPL_LUNDATA_LUN_TARG_MASK,
6403 lundata->luns[i].lundata[j+1] &
6404 RPL_LUNDATA_LUN_LUN_MASK);
6406 case RPL_LUNDATA_ATYP_EXTLUN: {
6407 int field_len_code, eam_code;
6409 eam_code = lundata->luns[i].lundata[j] &
6410 RPL_LUNDATA_EXT_EAM_MASK;
6411 field_len_code = (lundata->luns[i].lundata[j] &
6412 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6414 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6415 && (field_len_code == 0x00)) {
6416 fprintf(stdout, "%d",
6417 lundata->luns[i].lundata[j+1]);
6418 } else if ((eam_code ==
6419 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6420 && (field_len_code == 0x03)) {
6424 * This format takes up all 8 bytes.
6425 * If we aren't starting at offset 0,
6429 fprintf(stdout, "Invalid "
6432 "specified format", j);
6436 bzero(tmp_lun, sizeof(tmp_lun));
6437 bcopy(&lundata->luns[i].lundata[j+1],
6438 &tmp_lun[1], sizeof(tmp_lun) - 1);
6439 fprintf(stdout, "%#jx",
6440 (intmax_t)scsi_8btou64(tmp_lun));
6443 fprintf(stderr, "Unknown Extended LUN"
6444 "Address method %#x, length "
6445 "code %#x", eam_code,
6452 fprintf(stderr, "Unknown LUN address method "
6453 "%#x\n", lundata->luns[i].lundata[0] &
6454 RPL_LUNDATA_ATYP_MASK);
6458 * For the flat addressing method, there are no
6459 * other levels after it.
6464 fprintf(stdout, "\n");
6477 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6478 char *combinedopt, int retry_count, int timeout)
6481 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6482 struct scsi_read_capacity_data rcap;
6483 struct scsi_read_capacity_data_long rcaplong;
6497 ccb = cam_getccb(device);
6500 warnx("%s: error allocating ccb", __func__);
6504 bzero(&(&ccb->ccb_h)[1],
6505 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6507 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6534 if ((blocksizeonly != 0)
6535 && (numblocks != 0)) {
6536 warnx("%s: you can only specify one of -b or -N", __func__);
6541 if ((blocksizeonly != 0)
6542 && (sizeonly != 0)) {
6543 warnx("%s: you can only specify one of -b or -s", __func__);
6550 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6556 && (blocksizeonly != 0)) {
6557 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6562 scsi_read_capacity(&ccb->csio,
6563 /*retries*/ retry_count,
6565 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6568 /*timeout*/ timeout ? timeout : 5000);
6570 /* Disable freezing the device queue */
6571 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6573 if (arglist & CAM_ARG_ERR_RECOVER)
6574 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6576 if (cam_send_ccb(device, ccb) < 0) {
6577 warn("error sending READ CAPACITY command");
6579 if (arglist & CAM_ARG_VERBOSE)
6580 cam_error_print(device, ccb, CAM_ESF_ALL,
6581 CAM_EPF_ALL, stderr);
6587 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6588 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6593 maxsector = scsi_4btoul(rcap.addr);
6594 block_len = scsi_4btoul(rcap.length);
6597 * A last block of 2^32-1 means that the true capacity is over 2TB,
6598 * and we need to issue the long READ CAPACITY to get the real
6599 * capacity. Otherwise, we're all set.
6601 if (maxsector != 0xffffffff)
6604 scsi_read_capacity_16(&ccb->csio,
6605 /*retries*/ retry_count,
6607 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6611 /*rcap_buf*/ (uint8_t *)&rcaplong,
6612 /*rcap_buf_len*/ sizeof(rcaplong),
6613 /*sense_len*/ SSD_FULL_SIZE,
6614 /*timeout*/ timeout ? timeout : 5000);
6616 /* Disable freezing the device queue */
6617 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6619 if (arglist & CAM_ARG_ERR_RECOVER)
6620 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6622 if (cam_send_ccb(device, ccb) < 0) {
6623 warn("error sending READ CAPACITY (16) command");
6625 if (arglist & CAM_ARG_VERBOSE)
6626 cam_error_print(device, ccb, CAM_ESF_ALL,
6627 CAM_EPF_ALL, stderr);
6633 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6634 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6639 maxsector = scsi_8btou64(rcaplong.addr);
6640 block_len = scsi_4btoul(rcaplong.length);
6643 if (blocksizeonly == 0) {
6645 * Humanize implies !quiet, and also implies numblocks.
6647 if (humanize != 0) {
6652 tmpbytes = (maxsector + 1) * block_len;
6653 ret = humanize_number(tmpstr, sizeof(tmpstr),
6654 tmpbytes, "", HN_AUTOSCALE,
6657 HN_DIVISOR_1000 : 0));
6659 warnx("%s: humanize_number failed!", __func__);
6663 fprintf(stdout, "Device Size: %s%s", tmpstr,
6664 (sizeonly == 0) ? ", " : "\n");
6665 } else if (numblocks != 0) {
6666 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6667 "Blocks: " : "", (uintmax_t)maxsector + 1,
6668 (sizeonly == 0) ? ", " : "\n");
6670 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6671 "Last Block: " : "", (uintmax_t)maxsector,
6672 (sizeonly == 0) ? ", " : "\n");
6676 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6677 "Block Length: " : "", block_len, (quiet == 0) ?
6686 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6687 int retry_count, int timeout)
6691 uint8_t *smp_request = NULL, *smp_response = NULL;
6692 int request_size = 0, response_size = 0;
6693 int fd_request = 0, fd_response = 0;
6694 char *datastr = NULL;
6695 struct get_hook hook;
6700 * Note that at the moment we don't support sending SMP CCBs to
6701 * devices that aren't probed by CAM.
6703 ccb = cam_getccb(device);
6705 warnx("%s: error allocating CCB", __func__);
6709 bzero(&(&ccb->ccb_h)[1],
6710 sizeof(union ccb) - sizeof(struct ccb_hdr));
6712 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6715 arglist |= CAM_ARG_CMD_IN;
6716 response_size = strtol(optarg, NULL, 0);
6717 if (response_size <= 0) {
6718 warnx("invalid number of response bytes %d",
6721 goto smpcmd_bailout;
6723 hook.argc = argc - optind;
6724 hook.argv = argv + optind;
6727 datastr = cget(&hook, NULL);
6729 * If the user supplied "-" instead of a format, he
6730 * wants the data to be written to stdout.
6732 if ((datastr != NULL)
6733 && (datastr[0] == '-'))
6736 smp_response = (u_int8_t *)malloc(response_size);
6737 if (smp_response == NULL) {
6738 warn("can't malloc memory for SMP response");
6740 goto smpcmd_bailout;
6744 arglist |= CAM_ARG_CMD_OUT;
6745 request_size = strtol(optarg, NULL, 0);
6746 if (request_size <= 0) {
6747 warnx("invalid number of request bytes %d",
6750 goto smpcmd_bailout;
6752 hook.argc = argc - optind;
6753 hook.argv = argv + optind;
6755 datastr = cget(&hook, NULL);
6756 smp_request = (u_int8_t *)malloc(request_size);
6757 if (smp_request == NULL) {
6758 warn("can't malloc memory for SMP request");
6760 goto smpcmd_bailout;
6762 bzero(smp_request, request_size);
6764 * If the user supplied "-" instead of a format, he
6765 * wants the data to be read from stdin.
6767 if ((datastr != NULL)
6768 && (datastr[0] == '-'))
6771 buff_encode_visit(smp_request, request_size,
6782 * If fd_data is set, and we're writing to the device, we need to
6783 * read the data the user wants written from stdin.
6785 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6787 int amt_to_read = request_size;
6788 u_int8_t *buf_ptr = smp_request;
6790 for (amt_read = 0; amt_to_read > 0;
6791 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6792 if (amt_read == -1) {
6793 warn("error reading data from stdin");
6795 goto smpcmd_bailout;
6797 amt_to_read -= amt_read;
6798 buf_ptr += amt_read;
6802 if (((arglist & CAM_ARG_CMD_IN) == 0)
6803 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6804 warnx("%s: need both the request (-r) and response (-R) "
6805 "arguments", __func__);
6807 goto smpcmd_bailout;
6810 flags |= CAM_DEV_QFRZDIS;
6812 cam_fill_smpio(&ccb->smpio,
6813 /*retries*/ retry_count,
6816 /*smp_request*/ smp_request,
6817 /*smp_request_len*/ request_size,
6818 /*smp_response*/ smp_response,
6819 /*smp_response_len*/ response_size,
6820 /*timeout*/ timeout ? timeout : 5000);
6822 ccb->smpio.flags = SMP_FLAG_NONE;
6824 if (((retval = cam_send_ccb(device, ccb)) < 0)
6825 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6826 const char warnstr[] = "error sending command";
6833 if (arglist & CAM_ARG_VERBOSE) {
6834 cam_error_print(device, ccb, CAM_ESF_ALL,
6835 CAM_EPF_ALL, stderr);
6839 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6840 && (response_size > 0)) {
6841 if (fd_response == 0) {
6842 buff_decode_visit(smp_response, response_size,
6843 datastr, arg_put, NULL);
6844 fprintf(stdout, "\n");
6846 ssize_t amt_written;
6847 int amt_to_write = response_size;
6848 u_int8_t *buf_ptr = smp_response;
6850 for (amt_written = 0; (amt_to_write > 0) &&
6851 (amt_written = write(STDOUT_FILENO, buf_ptr,
6852 amt_to_write)) > 0;){
6853 amt_to_write -= amt_written;
6854 buf_ptr += amt_written;
6856 if (amt_written == -1) {
6857 warn("error writing data to stdout");
6859 goto smpcmd_bailout;
6860 } else if ((amt_written == 0)
6861 && (amt_to_write > 0)) {
6862 warnx("only wrote %u bytes out of %u",
6863 response_size - amt_to_write,
6872 if (smp_request != NULL)
6875 if (smp_response != NULL)
6882 smpreportgeneral(struct cam_device *device, int argc, char **argv,
6883 char *combinedopt, int retry_count, int timeout)
6886 struct smp_report_general_request *request = NULL;
6887 struct smp_report_general_response *response = NULL;
6888 struct sbuf *sb = NULL;
6890 int c, long_response = 0;
6894 * Note that at the moment we don't support sending SMP CCBs to
6895 * devices that aren't probed by CAM.
6897 ccb = cam_getccb(device);
6899 warnx("%s: error allocating CCB", __func__);
6903 bzero(&(&ccb->ccb_h)[1],
6904 sizeof(union ccb) - sizeof(struct ccb_hdr));
6906 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6915 request = malloc(sizeof(*request));
6916 if (request == NULL) {
6917 warn("%s: unable to allocate %zd bytes", __func__,
6923 response = malloc(sizeof(*response));
6924 if (response == NULL) {
6925 warn("%s: unable to allocate %zd bytes", __func__,
6932 smp_report_general(&ccb->smpio,
6936 /*request_len*/ sizeof(*request),
6937 (uint8_t *)response,
6938 /*response_len*/ sizeof(*response),
6939 /*long_response*/ long_response,
6942 if (((retval = cam_send_ccb(device, ccb)) < 0)
6943 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6944 const char warnstr[] = "error sending command";
6951 if (arglist & CAM_ARG_VERBOSE) {
6952 cam_error_print(device, ccb, CAM_ESF_ALL,
6953 CAM_EPF_ALL, stderr);
6960 * If the device supports the long response bit, try again and see
6961 * if we can get all of the data.
6963 if ((response->long_response & SMP_RG_LONG_RESPONSE)
6964 && (long_response == 0)) {
6965 ccb->ccb_h.status = CAM_REQ_INPROG;
6966 bzero(&(&ccb->ccb_h)[1],
6967 sizeof(union ccb) - sizeof(struct ccb_hdr));
6973 * XXX KDM detect and decode SMP errors here.
6975 sb = sbuf_new_auto();
6977 warnx("%s: error allocating sbuf", __func__);
6981 smp_report_general_sbuf(response, sizeof(*response), sb);
6983 if (sbuf_finish(sb) != 0) {
6984 warnx("%s: sbuf_finish", __func__);
6988 printf("%s", sbuf_data(sb));
6994 if (request != NULL)
6997 if (response != NULL)
7006 static struct camcontrol_opts phy_ops[] = {
7007 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7008 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7009 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7010 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7011 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7012 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7013 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7014 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7015 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7020 smpphycontrol(struct cam_device *device, int argc, char **argv,
7021 char *combinedopt, int retry_count, int timeout)
7024 struct smp_phy_control_request *request = NULL;
7025 struct smp_phy_control_response *response = NULL;
7026 int long_response = 0;
7029 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7031 uint64_t attached_dev_name = 0;
7032 int dev_name_set = 0;
7033 uint32_t min_plr = 0, max_plr = 0;
7034 uint32_t pp_timeout_val = 0;
7035 int slumber_partial = 0;
7036 int set_pp_timeout_val = 0;
7040 * Note that at the moment we don't support sending SMP CCBs to
7041 * devices that aren't probed by CAM.
7043 ccb = cam_getccb(device);
7045 warnx("%s: error allocating CCB", __func__);
7049 bzero(&(&ccb->ccb_h)[1],
7050 sizeof(union ccb) - sizeof(struct ccb_hdr));
7052 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7060 if (strcasecmp(optarg, "enable") == 0)
7062 else if (strcasecmp(optarg, "disable") == 0)
7065 warnx("%s: Invalid argument %s", __func__,
7072 slumber_partial |= enable <<
7073 SMP_PC_SAS_SLUMBER_SHIFT;
7076 slumber_partial |= enable <<
7077 SMP_PC_SAS_PARTIAL_SHIFT;
7080 slumber_partial |= enable <<
7081 SMP_PC_SATA_SLUMBER_SHIFT;
7084 slumber_partial |= enable <<
7085 SMP_PC_SATA_PARTIAL_SHIFT;
7088 warnx("%s: programmer error", __func__);
7091 break; /*NOTREACHED*/
7096 attached_dev_name = (uintmax_t)strtoumax(optarg,
7105 * We don't do extensive checking here, so this
7106 * will continue to work when new speeds come out.
7108 min_plr = strtoul(optarg, NULL, 0);
7110 || (min_plr > 0xf)) {
7111 warnx("%s: invalid link rate %x",
7119 * We don't do extensive checking here, so this
7120 * will continue to work when new speeds come out.
7122 max_plr = strtoul(optarg, NULL, 0);
7124 || (max_plr > 0xf)) {
7125 warnx("%s: invalid link rate %x",
7132 camcontrol_optret optreturn;
7133 cam_argmask argnums;
7136 if (phy_op_set != 0) {
7137 warnx("%s: only one phy operation argument "
7138 "(-o) allowed", __func__);
7146 * Allow the user to specify the phy operation
7147 * numerically, as well as with a name. This will
7148 * future-proof it a bit, so options that are added
7149 * in future specs can be used.
7151 if (isdigit(optarg[0])) {
7152 phy_operation = strtoul(optarg, NULL, 0);
7153 if ((phy_operation == 0)
7154 || (phy_operation > 0xff)) {
7155 warnx("%s: invalid phy operation %#x",
7156 __func__, phy_operation);
7162 optreturn = getoption(phy_ops, optarg, &phy_operation,
7165 if (optreturn == CC_OR_AMBIGUOUS) {
7166 warnx("%s: ambiguous option %s", __func__,
7171 } else if (optreturn == CC_OR_NOT_FOUND) {
7172 warnx("%s: option %s not found", __func__,
7184 pp_timeout_val = strtoul(optarg, NULL, 0);
7185 if (pp_timeout_val > 15) {
7186 warnx("%s: invalid partial pathway timeout "
7187 "value %u, need a value less than 16",
7188 __func__, pp_timeout_val);
7192 set_pp_timeout_val = 1;
7200 warnx("%s: a PHY (-p phy) argument is required",__func__);
7205 if (((dev_name_set != 0)
7206 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7207 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7208 && (dev_name_set == 0))) {
7209 warnx("%s: -d name and -o setdevname arguments both "
7210 "required to set device name", __func__);
7215 request = malloc(sizeof(*request));
7216 if (request == NULL) {
7217 warn("%s: unable to allocate %zd bytes", __func__,
7223 response = malloc(sizeof(*response));
7224 if (response == NULL) {
7225 warn("%s: unable to allocate %zd bytes", __func__,
7231 smp_phy_control(&ccb->smpio,
7236 (uint8_t *)response,
7239 /*expected_exp_change_count*/ 0,
7242 (set_pp_timeout_val != 0) ? 1 : 0,
7250 if (((retval = cam_send_ccb(device, ccb)) < 0)
7251 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7252 const char warnstr[] = "error sending command";
7259 if (arglist & CAM_ARG_VERBOSE) {
7261 * Use CAM_EPF_NORMAL so we only get one line of
7262 * SMP command decoding.
7264 cam_error_print(device, ccb, CAM_ESF_ALL,
7265 CAM_EPF_NORMAL, stderr);
7271 /* XXX KDM print out something here for success? */
7276 if (request != NULL)
7279 if (response != NULL)
7286 smpmaninfo(struct cam_device *device, int argc, char **argv,
7287 char *combinedopt, int retry_count, int timeout)
7290 struct smp_report_manuf_info_request request;
7291 struct smp_report_manuf_info_response response;
7292 struct sbuf *sb = NULL;
7293 int long_response = 0;
7298 * Note that at the moment we don't support sending SMP CCBs to
7299 * devices that aren't probed by CAM.
7301 ccb = cam_getccb(device);
7303 warnx("%s: error allocating CCB", __func__);
7307 bzero(&(&ccb->ccb_h)[1],
7308 sizeof(union ccb) - sizeof(struct ccb_hdr));
7310 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7319 bzero(&request, sizeof(request));
7320 bzero(&response, sizeof(response));
7322 smp_report_manuf_info(&ccb->smpio,
7327 (uint8_t *)&response,
7332 if (((retval = cam_send_ccb(device, ccb)) < 0)
7333 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7334 const char warnstr[] = "error sending command";
7341 if (arglist & CAM_ARG_VERBOSE) {
7342 cam_error_print(device, ccb, CAM_ESF_ALL,
7343 CAM_EPF_ALL, stderr);
7349 sb = sbuf_new_auto();
7351 warnx("%s: error allocating sbuf", __func__);
7355 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7357 if (sbuf_finish(sb) != 0) {
7358 warnx("%s: sbuf_finish", __func__);
7362 printf("%s", sbuf_data(sb));
7376 getdevid(struct cam_devitem *item)
7379 union ccb *ccb = NULL;
7381 struct cam_device *dev;
7383 dev = cam_open_btl(item->dev_match.path_id,
7384 item->dev_match.target_id,
7385 item->dev_match.target_lun, O_RDWR, NULL);
7388 warnx("%s", cam_errbuf);
7393 item->device_id_len = 0;
7395 ccb = cam_getccb(dev);
7397 warnx("%s: error allocating CCB", __func__);
7402 bzero(&(&ccb->ccb_h)[1],
7403 sizeof(union ccb) - sizeof(struct ccb_hdr));
7406 * On the first try, we just probe for the size of the data, and
7407 * then allocate that much memory and try again.
7410 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7411 ccb->ccb_h.flags = CAM_DIR_IN;
7412 ccb->cdai.flags = CDAI_FLAG_NONE;
7413 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7414 ccb->cdai.bufsiz = item->device_id_len;
7415 if (item->device_id_len != 0)
7416 ccb->cdai.buf = (uint8_t *)item->device_id;
7418 if (cam_send_ccb(dev, ccb) < 0) {
7419 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7424 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7425 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7430 if (item->device_id_len == 0) {
7432 * This is our first time through. Allocate the buffer,
7433 * and then go back to get the data.
7435 if (ccb->cdai.provsiz == 0) {
7436 warnx("%s: invalid .provsiz field returned with "
7437 "XPT_GDEV_ADVINFO CCB", __func__);
7441 item->device_id_len = ccb->cdai.provsiz;
7442 item->device_id = malloc(item->device_id_len);
7443 if (item->device_id == NULL) {
7444 warn("%s: unable to allocate %d bytes", __func__,
7445 item->device_id_len);
7449 ccb->ccb_h.status = CAM_REQ_INPROG;
7455 cam_close_device(dev);
7464 * XXX KDM merge this code with getdevtree()?
7467 buildbusdevlist(struct cam_devlist *devlist)
7470 int bufsize, fd = -1;
7471 struct dev_match_pattern *patterns;
7472 struct cam_devitem *item = NULL;
7473 int skip_device = 0;
7476 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7477 warn("couldn't open %s", XPT_DEVICE);
7481 bzero(&ccb, sizeof(union ccb));
7483 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7484 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7485 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7487 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7488 bufsize = sizeof(struct dev_match_result) * 100;
7489 ccb.cdm.match_buf_len = bufsize;
7490 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7491 if (ccb.cdm.matches == NULL) {
7492 warnx("can't malloc memory for matches");
7496 ccb.cdm.num_matches = 0;
7497 ccb.cdm.num_patterns = 2;
7498 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7499 ccb.cdm.num_patterns;
7501 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7502 if (patterns == NULL) {
7503 warnx("can't malloc memory for patterns");
7508 ccb.cdm.patterns = patterns;
7509 bzero(patterns, ccb.cdm.pattern_buf_len);
7511 patterns[0].type = DEV_MATCH_DEVICE;
7512 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7513 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7514 patterns[1].type = DEV_MATCH_PERIPH;
7515 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7516 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7519 * We do the ioctl multiple times if necessary, in case there are
7520 * more than 100 nodes in the EDT.
7525 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7526 warn("error sending CAMIOCOMMAND ioctl");
7531 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7532 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7533 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7534 warnx("got CAM error %#x, CDM error %d\n",
7535 ccb.ccb_h.status, ccb.cdm.status);
7540 for (i = 0; i < ccb.cdm.num_matches; i++) {
7541 switch (ccb.cdm.matches[i].type) {
7542 case DEV_MATCH_DEVICE: {
7543 struct device_match_result *dev_result;
7546 &ccb.cdm.matches[i].result.device_result;
7548 if (dev_result->flags &
7549 DEV_RESULT_UNCONFIGURED) {
7555 item = malloc(sizeof(*item));
7557 warn("%s: unable to allocate %zd bytes",
7558 __func__, sizeof(*item));
7562 bzero(item, sizeof(*item));
7563 bcopy(dev_result, &item->dev_match,
7564 sizeof(*dev_result));
7565 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7568 if (getdevid(item) != 0) {
7574 case DEV_MATCH_PERIPH: {
7575 struct periph_match_result *periph_result;
7578 &ccb.cdm.matches[i].result.periph_result;
7580 if (skip_device != 0)
7582 item->num_periphs++;
7583 item->periph_matches = realloc(
7584 item->periph_matches,
7586 sizeof(struct periph_match_result));
7587 if (item->periph_matches == NULL) {
7588 warn("%s: error allocating periph "
7593 bcopy(periph_result, &item->periph_matches[
7594 item->num_periphs - 1],
7595 sizeof(*periph_result));
7599 fprintf(stderr, "%s: unexpected match "
7600 "type %d\n", __func__,
7601 ccb.cdm.matches[i].type);
7604 break; /*NOTREACHED*/
7607 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7608 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7616 free(ccb.cdm.matches);
7619 freebusdevlist(devlist);
7625 freebusdevlist(struct cam_devlist *devlist)
7627 struct cam_devitem *item, *item2;
7629 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7630 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7632 free(item->device_id);
7633 free(item->periph_matches);
7638 static struct cam_devitem *
7639 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7641 struct cam_devitem *item;
7643 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7644 struct scsi_vpd_id_descriptor *idd;
7647 * XXX KDM look for LUN IDs as well?
7649 idd = scsi_get_devid(item->device_id,
7650 item->device_id_len,
7651 scsi_devid_is_sas_target);
7655 if (scsi_8btou64(idd->identifier) == sasaddr)
7663 smpphylist(struct cam_device *device, int argc, char **argv,
7664 char *combinedopt, int retry_count, int timeout)
7666 struct smp_report_general_request *rgrequest = NULL;
7667 struct smp_report_general_response *rgresponse = NULL;
7668 struct smp_discover_request *disrequest = NULL;
7669 struct smp_discover_response *disresponse = NULL;
7670 struct cam_devlist devlist;
7672 int long_response = 0;
7679 * Note that at the moment we don't support sending SMP CCBs to
7680 * devices that aren't probed by CAM.
7682 ccb = cam_getccb(device);
7684 warnx("%s: error allocating CCB", __func__);
7688 bzero(&(&ccb->ccb_h)[1],
7689 sizeof(union ccb) - sizeof(struct ccb_hdr));
7690 STAILQ_INIT(&devlist.dev_queue);
7692 rgrequest = malloc(sizeof(*rgrequest));
7693 if (rgrequest == NULL) {
7694 warn("%s: unable to allocate %zd bytes", __func__,
7695 sizeof(*rgrequest));
7700 rgresponse = malloc(sizeof(*rgresponse));
7701 if (rgresponse == NULL) {
7702 warn("%s: unable to allocate %zd bytes", __func__,
7703 sizeof(*rgresponse));
7708 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7721 smp_report_general(&ccb->smpio,
7725 /*request_len*/ sizeof(*rgrequest),
7726 (uint8_t *)rgresponse,
7727 /*response_len*/ sizeof(*rgresponse),
7728 /*long_response*/ long_response,
7731 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7733 if (((retval = cam_send_ccb(device, ccb)) < 0)
7734 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7735 const char warnstr[] = "error sending command";
7742 if (arglist & CAM_ARG_VERBOSE) {
7743 cam_error_print(device, ccb, CAM_ESF_ALL,
7744 CAM_EPF_ALL, stderr);
7750 num_phys = rgresponse->num_phys;
7752 if (num_phys == 0) {
7754 fprintf(stdout, "%s: No Phys reported\n", __func__);
7759 devlist.path_id = device->path_id;
7761 retval = buildbusdevlist(&devlist);
7766 fprintf(stdout, "%d PHYs:\n", num_phys);
7767 fprintf(stdout, "PHY Attached SAS Address\n");
7770 disrequest = malloc(sizeof(*disrequest));
7771 if (disrequest == NULL) {
7772 warn("%s: unable to allocate %zd bytes", __func__,
7773 sizeof(*disrequest));
7778 disresponse = malloc(sizeof(*disresponse));
7779 if (disresponse == NULL) {
7780 warn("%s: unable to allocate %zd bytes", __func__,
7781 sizeof(*disresponse));
7786 for (i = 0; i < num_phys; i++) {
7787 struct cam_devitem *item;
7788 struct device_match_result *dev_match;
7789 char vendor[16], product[48], revision[16];
7793 bzero(&(&ccb->ccb_h)[1],
7794 sizeof(union ccb) - sizeof(struct ccb_hdr));
7796 ccb->ccb_h.status = CAM_REQ_INPROG;
7797 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7799 smp_discover(&ccb->smpio,
7803 sizeof(*disrequest),
7804 (uint8_t *)disresponse,
7805 sizeof(*disresponse),
7807 /*ignore_zone_group*/ 0,
7811 if (((retval = cam_send_ccb(device, ccb)) < 0)
7812 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7813 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7814 const char warnstr[] = "error sending command";
7821 if (arglist & CAM_ARG_VERBOSE) {
7822 cam_error_print(device, ccb, CAM_ESF_ALL,
7823 CAM_EPF_ALL, stderr);
7829 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7831 fprintf(stdout, "%3d <vacant>\n", i);
7835 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7838 item = findsasdevice(&devlist,
7839 scsi_8btou64(disresponse->attached_sas_address));
7843 || (item != NULL)) {
7844 fprintf(stdout, "%3d 0x%016jx", i,
7845 (uintmax_t)scsi_8btou64(
7846 disresponse->attached_sas_address));
7848 fprintf(stdout, "\n");
7851 } else if (quiet != 0)
7854 dev_match = &item->dev_match;
7856 if (dev_match->protocol == PROTO_SCSI) {
7857 cam_strvis(vendor, dev_match->inq_data.vendor,
7858 sizeof(dev_match->inq_data.vendor),
7860 cam_strvis(product, dev_match->inq_data.product,
7861 sizeof(dev_match->inq_data.product),
7863 cam_strvis(revision, dev_match->inq_data.revision,
7864 sizeof(dev_match->inq_data.revision),
7866 sprintf(tmpstr, "<%s %s %s>", vendor, product,
7868 } else if ((dev_match->protocol == PROTO_ATA)
7869 || (dev_match->protocol == PROTO_SATAPM)) {
7870 cam_strvis(product, dev_match->ident_data.model,
7871 sizeof(dev_match->ident_data.model),
7873 cam_strvis(revision, dev_match->ident_data.revision,
7874 sizeof(dev_match->ident_data.revision),
7876 sprintf(tmpstr, "<%s %s>", product, revision);
7878 sprintf(tmpstr, "<>");
7880 fprintf(stdout, " %-33s ", tmpstr);
7883 * If we have 0 periphs, that's a bug...
7885 if (item->num_periphs == 0) {
7886 fprintf(stdout, "\n");
7890 fprintf(stdout, "(");
7891 for (j = 0; j < item->num_periphs; j++) {
7893 fprintf(stdout, ",");
7895 fprintf(stdout, "%s%d",
7896 item->periph_matches[j].periph_name,
7897 item->periph_matches[j].unit_number);
7900 fprintf(stdout, ")\n");
7914 freebusdevlist(&devlist);
7920 atapm(struct cam_device *device, int argc, char **argv,
7921 char *combinedopt, int retry_count, int timeout)
7929 ccb = cam_getccb(device);
7932 warnx("%s: error allocating ccb", __func__);
7936 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7945 if (strcmp(argv[1], "idle") == 0) {
7947 cmd = ATA_IDLE_IMMEDIATE;
7950 } else if (strcmp(argv[1], "standby") == 0) {
7952 cmd = ATA_STANDBY_IMMEDIATE;
7954 cmd = ATA_STANDBY_CMD;
7962 else if (t <= (240 * 5))
7964 else if (t <= (252 * 5))
7965 /* special encoding for 21 minutes */
7967 else if (t <= (11 * 30 * 60))
7968 sc = (t - 1) / (30 * 60) + 241;
7972 retval = ata_do_28bit_cmd(device,
7974 /*retries*/retry_count,
7975 /*flags*/CAM_DIR_NONE,
7976 /*protocol*/AP_PROTO_NON_DATA,
7977 /*tag_action*/MSG_SIMPLE_Q_TAG,
7984 /*timeout*/timeout ? timeout : 30 * 1000,
7992 ataaxm(struct cam_device *device, int argc, char **argv,
7993 char *combinedopt, int retry_count, int timeout)
8001 ccb = cam_getccb(device);
8004 warnx("%s: error allocating ccb", __func__);
8008 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8018 if (strcmp(argv[1], "apm") == 0) {
8034 retval = ata_do_28bit_cmd(device,
8036 /*retries*/retry_count,
8037 /*flags*/CAM_DIR_NONE,
8038 /*protocol*/AP_PROTO_NON_DATA,
8039 /*tag_action*/MSG_SIMPLE_Q_TAG,
8040 /*command*/ATA_SETFEATURES,
8046 /*timeout*/timeout ? timeout : 30 * 1000,
8053 #endif /* MINIMALISTIC */
8056 usage(int printlong)
8059 fprintf(printlong ? stdout : stderr,
8060 "usage: camcontrol <command> [device id][generic args][command args]\n"
8061 " camcontrol devlist [-b] [-v]\n"
8062 #ifndef MINIMALISTIC
8063 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8064 " camcontrol tur [dev_id][generic args]\n"
8065 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8066 " camcontrol identify [dev_id][generic args] [-v]\n"
8067 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8068 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8070 " camcontrol start [dev_id][generic args]\n"
8071 " camcontrol stop [dev_id][generic args]\n"
8072 " camcontrol load [dev_id][generic args]\n"
8073 " camcontrol eject [dev_id][generic args]\n"
8074 #endif /* MINIMALISTIC */
8075 " camcontrol rescan <all | bus[:target:lun]>\n"
8076 " camcontrol reset <all | bus[:target:lun]>\n"
8077 #ifndef MINIMALISTIC
8078 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8079 " [-q][-s][-S offset][-X]\n"
8080 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8081 " [-P pagectl][-e | -b][-d]\n"
8082 " camcontrol cmd [dev_id][generic args]\n"
8083 " <-a cmd [args] | -c cmd [args]>\n"
8084 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8085 " camcontrol smpcmd [dev_id][generic args]\n"
8086 " <-r len fmt [args]> <-R len fmt [args]>\n"
8087 " camcontrol smprg [dev_id][generic args][-l]\n"
8088 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8089 " [-o operation][-d name][-m rate][-M rate]\n"
8090 " [-T pp_timeout][-a enable|disable]\n"
8091 " [-A enable|disable][-s enable|disable]\n"
8092 " [-S enable|disable]\n"
8093 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8094 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8095 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8096 " <all|bus[:target[:lun]]|off>\n"
8097 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8098 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8099 " [-D <enable|disable>][-M mode][-O offset]\n"
8100 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8101 " [-U][-W bus_width]\n"
8102 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8103 " camcontrol sanitize [dev_id][generic args]\n"
8104 " [-a overwrite|block|crypto|exitfailure]\n"
8105 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8107 " camcontrol idle [dev_id][generic args][-t time]\n"
8108 " camcontrol standby [dev_id][generic args][-t time]\n"
8109 " camcontrol sleep [dev_id][generic args]\n"
8110 " camcontrol apm [dev_id][generic args][-l level]\n"
8111 " camcontrol aam [dev_id][generic args][-l level]\n"
8112 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
8113 " camcontrol security [dev_id][generic args]\n"
8114 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8115 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8116 " [-U <user|master>] [-y]\n"
8117 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8118 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8119 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8120 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8121 " [-s scope][-S][-T type][-U]\n"
8122 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8123 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8124 " [-p part][-s start][-T type][-V vol]\n"
8125 #endif /* MINIMALISTIC */
8126 " camcontrol help\n");
8129 #ifndef MINIMALISTIC
8131 "Specify one of the following options:\n"
8132 "devlist list all CAM devices\n"
8133 "periphlist list all CAM peripheral drivers attached to a device\n"
8134 "tur send a test unit ready to the named device\n"
8135 "inquiry send a SCSI inquiry command to the named device\n"
8136 "identify send a ATA identify command to the named device\n"
8137 "reportluns send a SCSI report luns command to the device\n"
8138 "readcap send a SCSI read capacity command to the device\n"
8139 "start send a Start Unit command to the device\n"
8140 "stop send a Stop Unit command to the device\n"
8141 "load send a Start Unit command to the device with the load bit set\n"
8142 "eject send a Stop Unit command to the device with the eject bit set\n"
8143 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8144 "reset reset all busses, the given bus, or bus:target:lun\n"
8145 "defects read the defect list of the specified device\n"
8146 "modepage display or edit (-e) the given mode page\n"
8147 "cmd send the given SCSI command, may need -i or -o as well\n"
8148 "smpcmd send the given SMP command, requires -o and -i\n"
8149 "smprg send the SMP Report General command\n"
8150 "smppc send the SMP PHY Control command, requires -p\n"
8151 "smpphylist display phys attached to a SAS expander\n"
8152 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8153 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8154 "tags report or set the number of transaction slots for a device\n"
8155 "negotiate report or set device negotiation parameters\n"
8156 "format send the SCSI FORMAT UNIT command to the named device\n"
8157 "sanitize send the SCSI SANITIZE command to the named device\n"
8158 "idle send the ATA IDLE command to the named device\n"
8159 "standby send the ATA STANDBY command to the named device\n"
8160 "sleep send the ATA SLEEP command to the named device\n"
8161 "fwdownload program firmware of the named device with the given image\n"
8162 "security report or send ATA security commands to the named device\n"
8163 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8164 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8165 "help this message\n"
8166 "Device Identifiers:\n"
8167 "bus:target specify the bus and target, lun defaults to 0\n"
8168 "bus:target:lun specify the bus, target and lun\n"
8169 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8170 "Generic arguments:\n"
8171 "-v be verbose, print out sense information\n"
8172 "-t timeout command timeout in seconds, overrides default timeout\n"
8173 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8174 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8175 "-E have the kernel attempt to perform SCSI error recovery\n"
8176 "-C count specify the SCSI command retry count (needs -E to work)\n"
8177 "modepage arguments:\n"
8178 "-l list all available mode pages\n"
8179 "-m page specify the mode page to view or edit\n"
8180 "-e edit the specified mode page\n"
8181 "-b force view to binary mode\n"
8182 "-d disable block descriptors for mode sense\n"
8183 "-P pgctl page control field 0-3\n"
8184 "defects arguments:\n"
8185 "-f format specify defect list format (block, bfi or phys)\n"
8186 "-G get the grown defect list\n"
8187 "-P get the permanent defect list\n"
8188 "inquiry arguments:\n"
8189 "-D get the standard inquiry data\n"
8190 "-S get the serial number\n"
8191 "-R get the transfer rate, etc.\n"
8192 "reportluns arguments:\n"
8193 "-c only report a count of available LUNs\n"
8194 "-l only print out luns, and not a count\n"
8195 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
8196 "readcap arguments\n"
8197 "-b only report the blocksize\n"
8198 "-h human readable device size, base 2\n"
8199 "-H human readable device size, base 10\n"
8200 "-N print the number of blocks instead of last block\n"
8201 "-q quiet, print numbers only\n"
8202 "-s only report the last block/device size\n"
8204 "-c cdb [args] specify the SCSI CDB\n"
8205 "-i len fmt specify input data and input data format\n"
8206 "-o len fmt [args] specify output data and output data fmt\n"
8207 "smpcmd arguments:\n"
8208 "-r len fmt [args] specify the SMP command to be sent\n"
8209 "-R len fmt [args] specify SMP response format\n"
8210 "smprg arguments:\n"
8211 "-l specify the long response format\n"
8212 "smppc arguments:\n"
8213 "-p phy specify the PHY to operate on\n"
8214 "-l specify the long request/response format\n"
8215 "-o operation specify the phy control operation\n"
8216 "-d name set the attached device name\n"
8217 "-m rate set the minimum physical link rate\n"
8218 "-M rate set the maximum physical link rate\n"
8219 "-T pp_timeout set the partial pathway timeout value\n"
8220 "-a enable|disable enable or disable SATA slumber\n"
8221 "-A enable|disable enable or disable SATA partial phy power\n"
8222 "-s enable|disable enable or disable SAS slumber\n"
8223 "-S enable|disable enable or disable SAS partial phy power\n"
8224 "smpphylist arguments:\n"
8225 "-l specify the long response format\n"
8226 "-q only print phys with attached devices\n"
8227 "smpmaninfo arguments:\n"
8228 "-l specify the long response format\n"
8229 "debug arguments:\n"
8230 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
8231 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
8232 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
8233 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
8235 "-N tags specify the number of tags to use for this device\n"
8236 "-q be quiet, don't report the number of tags\n"
8237 "-v report a number of tag-related parameters\n"
8238 "negotiate arguments:\n"
8239 "-a send a test unit ready after negotiation\n"
8240 "-c report/set current negotiation settings\n"
8241 "-D <arg> \"enable\" or \"disable\" disconnection\n"
8242 "-M mode set ATA mode\n"
8243 "-O offset set command delay offset\n"
8244 "-q be quiet, don't report anything\n"
8245 "-R syncrate synchronization rate in MHz\n"
8246 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
8247 "-U report/set user negotiation settings\n"
8248 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
8249 "-v also print a Path Inquiry CCB for the controller\n"
8250 "format arguments:\n"
8251 "-q be quiet, don't print status messages\n"
8252 "-r run in report only mode\n"
8253 "-w don't send immediate format command\n"
8254 "-y don't ask any questions\n"
8255 "sanitize arguments:\n"
8256 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
8257 "-c passes overwrite passes to perform (1 to 31)\n"
8258 "-I invert overwrite pattern after each pass\n"
8259 "-P pattern path to overwrite pattern file\n"
8260 "-q be quiet, don't print status messages\n"
8261 "-r run in report only mode\n"
8262 "-U run operation in unrestricted completion exit mode\n"
8263 "-w don't send immediate sanitize command\n"
8264 "-y don't ask any questions\n"
8265 "idle/standby arguments:\n"
8266 "-t <arg> number of seconds before respective state.\n"
8267 "fwdownload arguments:\n"
8268 "-f fw_image path to firmware image file\n"
8269 "-y don't ask any questions\n"
8270 "-s run in simulation mode\n"
8271 "-v print info for every firmware segment sent to device\n"
8272 "security arguments:\n"
8273 "-d pwd disable security using the given password for the selected\n"
8275 "-e pwd erase the device using the given pwd for the selected user\n"
8276 "-f freeze the security configuration of the specified device\n"
8277 "-h pwd enhanced erase the device using the given pwd for the\n"
8279 "-k pwd unlock the device using the given pwd for the selected\n"
8281 "-l <high|maximum> specifies which security level to set: high or maximum\n"
8282 "-q be quiet, do not print any status messages\n"
8283 "-s pwd password the device (enable security) using the given\n"
8284 " pwd for the selected user\n"
8285 "-T timeout overrides the timeout (seconds) used for erase operation\n"
8286 "-U <user|master> specifies which user to set: user or master\n"
8287 "-y don't ask any questions\n"
8289 "-f freeze the HPA configuration of the device\n"
8290 "-l lock the HPA configuration of the device\n"
8291 "-P make the HPA max sectors persist\n"
8292 "-p pwd Set the HPA configuration password required for unlock\n"
8294 "-q be quiet, do not print any status messages\n"
8295 "-s sectors configures the maximum user accessible sectors of the\n"
8297 "-U pwd unlock the HPA configuration of the device\n"
8298 "-y don't ask any questions\n"
8299 "persist arguments:\n"
8300 "-i action specify read_keys, read_reservation, report_cap, or\n"
8301 " read_full_status\n"
8302 "-o action specify register, register_ignore, reserve, release,\n"
8303 " clear, preempt, preempt_abort, register_move, replace_lost\n"
8304 "-a set the All Target Ports (ALL_TG_PT) bit\n"
8305 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
8306 "-k key specify the Reservation Key\n"
8307 "-K sa_key specify the Service Action Reservation Key\n"
8308 "-p set the Activate Persist Through Power Loss bit\n"
8309 "-R rtp specify the Relative Target Port\n"
8310 "-s scope specify the scope: lun, extent, element or a number\n"
8311 "-S specify Transport ID for register, requires -I\n"
8312 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
8313 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
8314 "-U unregister the current initiator for register_move\n"
8315 "attrib arguments:\n"
8316 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
8318 "-w attr specify an attribute to write, one -w argument per attr\n"
8319 "-a attr_num only display this attribute number\n"
8320 "-c get cached attributes\n"
8321 "-e elem_addr request attributes for the given element in a changer\n"
8322 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
8323 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
8324 " field_none, field_desc, field_num, field_size, field_rw\n"
8325 "-p partition request attributes for the given partition\n"
8326 "-s start_attr request attributes starting at the given number\n"
8327 "-T elem_type specify the element type (used with -e)\n"
8328 "-V logical_vol specify the logical volume ID\n"
8330 #endif /* MINIMALISTIC */
8334 main(int argc, char **argv)
8337 char *device = NULL;
8339 struct cam_device *cam_dev = NULL;
8340 int timeout = 0, retry_count = 1;
8341 camcontrol_optret optreturn;
8343 const char *mainopt = "C:En:t:u:v";
8344 const char *subopt = NULL;
8345 char combinedopt[256];
8346 int error = 0, optstart = 2;
8348 #ifndef MINIMALISTIC
8352 #endif /* MINIMALISTIC */
8354 cmdlist = CAM_CMD_NONE;
8355 arglist = CAM_ARG_NONE;
8363 * Get the base option.
8365 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
8367 if (optreturn == CC_OR_AMBIGUOUS) {
8368 warnx("ambiguous option %s", argv[1]);
8371 } else if (optreturn == CC_OR_NOT_FOUND) {
8372 warnx("option %s not found", argv[1]);
8378 * Ahh, getopt(3) is a pain.
8380 * This is a gross hack. There really aren't many other good
8381 * options (excuse the pun) for parsing options in a situation like
8382 * this. getopt is kinda braindead, so you end up having to run
8383 * through the options twice, and give each invocation of getopt
8384 * the option string for the other invocation.
8386 * You would think that you could just have two groups of options.
8387 * The first group would get parsed by the first invocation of
8388 * getopt, and the second group would get parsed by the second
8389 * invocation of getopt. It doesn't quite work out that way. When
8390 * the first invocation of getopt finishes, it leaves optind pointing
8391 * to the argument _after_ the first argument in the second group.
8392 * So when the second invocation of getopt comes around, it doesn't
8393 * recognize the first argument it gets and then bails out.
8395 * A nice alternative would be to have a flag for getopt that says
8396 * "just keep parsing arguments even when you encounter an unknown
8397 * argument", but there isn't one. So there's no real clean way to
8398 * easily parse two sets of arguments without having one invocation
8399 * of getopt know about the other.
8401 * Without this hack, the first invocation of getopt would work as
8402 * long as the generic arguments are first, but the second invocation
8403 * (in the subfunction) would fail in one of two ways. In the case
8404 * where you don't set optreset, it would fail because optind may be
8405 * pointing to the argument after the one it should be pointing at.
8406 * In the case where you do set optreset, and reset optind, it would
8407 * fail because getopt would run into the first set of options, which
8408 * it doesn't understand.
8410 * All of this would "sort of" work if you could somehow figure out
8411 * whether optind had been incremented one option too far. The
8412 * mechanics of that, however, are more daunting than just giving
8413 * both invocations all of the expect options for either invocation.
8415 * Needless to say, I wouldn't mind if someone invented a better
8416 * (non-GPL!) command line parsing interface than getopt. I
8417 * wouldn't mind if someone added more knobs to getopt to make it
8418 * work better. Who knows, I may talk myself into doing it someday,
8419 * if the standards weenies let me. As it is, it just leads to
8420 * hackery like this and causes people to avoid it in some cases.
8422 * KDM, September 8th, 1998
8425 sprintf(combinedopt, "%s%s", mainopt, subopt);
8427 sprintf(combinedopt, "%s", mainopt);
8430 * For these options we do not parse optional device arguments and
8431 * we do not open a passthrough device.
8433 if ((cmdlist == CAM_CMD_RESCAN)
8434 || (cmdlist == CAM_CMD_RESET)
8435 || (cmdlist == CAM_CMD_DEVTREE)
8436 || (cmdlist == CAM_CMD_USAGE)
8437 || (cmdlist == CAM_CMD_DEBUG))
8440 #ifndef MINIMALISTIC
8442 && (argc > 2 && argv[2][0] != '-')) {
8446 if (isdigit(argv[2][0])) {
8447 /* device specified as bus:target[:lun] */
8448 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
8450 errx(1, "numeric device specification must "
8451 "be either bus:target, or "
8453 /* default to 0 if lun was not specified */
8454 if ((arglist & CAM_ARG_LUN) == 0) {
8456 arglist |= CAM_ARG_LUN;
8460 if (cam_get_device(argv[2], name, sizeof name, &unit)
8462 errx(1, "%s", cam_errbuf);
8463 device = strdup(name);
8464 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
8468 #endif /* MINIMALISTIC */
8470 * Start getopt processing at argv[2/3], since we've already
8471 * accepted argv[1..2] as the command name, and as a possible
8477 * Now we run through the argument list looking for generic
8478 * options, and ignoring options that possibly belong to
8481 while ((c = getopt(argc, argv, combinedopt))!= -1){
8484 retry_count = strtol(optarg, NULL, 0);
8485 if (retry_count < 0)
8486 errx(1, "retry count %d is < 0",
8488 arglist |= CAM_ARG_RETRIES;
8491 arglist |= CAM_ARG_ERR_RECOVER;
8494 arglist |= CAM_ARG_DEVICE;
8496 while (isspace(*tstr) && (*tstr != '\0'))
8498 device = (char *)strdup(tstr);
8501 timeout = strtol(optarg, NULL, 0);
8503 errx(1, "invalid timeout %d", timeout);
8504 /* Convert the timeout from seconds to ms */
8506 arglist |= CAM_ARG_TIMEOUT;
8509 arglist |= CAM_ARG_UNIT;
8510 unit = strtol(optarg, NULL, 0);
8513 arglist |= CAM_ARG_VERBOSE;
8520 #ifndef MINIMALISTIC
8522 * For most commands we'll want to open the passthrough device
8523 * associated with the specified device. In the case of the rescan
8524 * commands, we don't use a passthrough device at all, just the
8525 * transport layer device.
8528 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
8529 && (((arglist & CAM_ARG_DEVICE) == 0)
8530 || ((arglist & CAM_ARG_UNIT) == 0))) {
8531 errx(1, "subcommand \"%s\" requires a valid device "
8532 "identifier", argv[1]);
8535 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
8536 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
8537 cam_open_spec_device(device,unit,O_RDWR,NULL)))
8539 errx(1,"%s", cam_errbuf);
8541 #endif /* MINIMALISTIC */
8544 * Reset optind to 2, and reset getopt, so these routines can parse
8545 * the arguments again.
8551 #ifndef MINIMALISTIC
8552 case CAM_CMD_DEVLIST:
8553 error = getdevlist(cam_dev);
8556 error = atahpa(cam_dev, retry_count, timeout,
8557 argc, argv, combinedopt);
8559 #endif /* MINIMALISTIC */
8560 case CAM_CMD_DEVTREE:
8561 error = getdevtree(argc, argv, combinedopt);
8563 #ifndef MINIMALISTIC
8565 error = testunitready(cam_dev, retry_count, timeout, 0);
8567 case CAM_CMD_INQUIRY:
8568 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
8569 retry_count, timeout);
8571 case CAM_CMD_IDENTIFY:
8572 error = ataidentify(cam_dev, retry_count, timeout);
8574 case CAM_CMD_STARTSTOP:
8575 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
8576 arglist & CAM_ARG_EJECT, retry_count,
8579 #endif /* MINIMALISTIC */
8580 case CAM_CMD_RESCAN:
8581 error = dorescan_or_reset(argc, argv, 1);
8584 error = dorescan_or_reset(argc, argv, 0);
8586 #ifndef MINIMALISTIC
8587 case CAM_CMD_READ_DEFECTS:
8588 error = readdefects(cam_dev, argc, argv, combinedopt,
8589 retry_count, timeout);
8591 case CAM_CMD_MODE_PAGE:
8592 modepage(cam_dev, argc, argv, combinedopt,
8593 retry_count, timeout);
8595 case CAM_CMD_SCSI_CMD:
8596 error = scsicmd(cam_dev, argc, argv, combinedopt,
8597 retry_count, timeout);
8599 case CAM_CMD_SMP_CMD:
8600 error = smpcmd(cam_dev, argc, argv, combinedopt,
8601 retry_count, timeout);
8603 case CAM_CMD_SMP_RG:
8604 error = smpreportgeneral(cam_dev, argc, argv,
8605 combinedopt, retry_count,
8608 case CAM_CMD_SMP_PC:
8609 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
8610 retry_count, timeout);
8612 case CAM_CMD_SMP_PHYLIST:
8613 error = smpphylist(cam_dev, argc, argv, combinedopt,
8614 retry_count, timeout);
8616 case CAM_CMD_SMP_MANINFO:
8617 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
8618 retry_count, timeout);
8621 error = camdebug(argc, argv, combinedopt);
8624 error = tagcontrol(cam_dev, argc, argv, combinedopt);
8627 error = ratecontrol(cam_dev, retry_count, timeout,
8628 argc, argv, combinedopt);
8630 case CAM_CMD_FORMAT:
8631 error = scsiformat(cam_dev, argc, argv,
8632 combinedopt, retry_count, timeout);
8634 case CAM_CMD_REPORTLUNS:
8635 error = scsireportluns(cam_dev, argc, argv,
8636 combinedopt, retry_count,
8639 case CAM_CMD_READCAP:
8640 error = scsireadcapacity(cam_dev, argc, argv,
8641 combinedopt, retry_count,
8645 case CAM_CMD_STANDBY:
8647 error = atapm(cam_dev, argc, argv,
8648 combinedopt, retry_count, timeout);
8652 error = ataaxm(cam_dev, argc, argv,
8653 combinedopt, retry_count, timeout);
8655 case CAM_CMD_SECURITY:
8656 error = atasecurity(cam_dev, retry_count, timeout,
8657 argc, argv, combinedopt);
8659 case CAM_CMD_DOWNLOAD_FW:
8660 error = fwdownload(cam_dev, argc, argv, combinedopt,
8661 arglist & CAM_ARG_VERBOSE, retry_count, timeout,
8662 get_disk_type(cam_dev));
8664 case CAM_CMD_SANITIZE:
8665 error = scsisanitize(cam_dev, argc, argv,
8666 combinedopt, retry_count, timeout);
8668 case CAM_CMD_PERSIST:
8669 error = scsipersist(cam_dev, argc, argv, combinedopt,
8670 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
8671 arglist & CAM_ARG_ERR_RECOVER);
8673 case CAM_CMD_ATTRIB:
8674 error = scsiattrib(cam_dev, argc, argv, combinedopt,
8675 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
8676 arglist & CAM_ARG_ERR_RECOVER);
8678 #endif /* MINIMALISTIC */
8688 if (cam_dev != NULL)
8689 cam_close_device(cam_dev);