2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
55 #include <cam/cam_debug.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/scsi/scsi_all.h>
58 #include <cam/scsi/scsi_da.h>
59 #include <cam/scsi/scsi_pass.h>
60 #include <cam/scsi/scsi_message.h>
61 #include <cam/scsi/smp_all.h>
62 #include <cam/ata/ata_all.h>
64 #include "camcontrol.h"
67 CAM_CMD_NONE = 0x00000000,
68 CAM_CMD_DEVLIST = 0x00000001,
69 CAM_CMD_TUR = 0x00000002,
70 CAM_CMD_INQUIRY = 0x00000003,
71 CAM_CMD_STARTSTOP = 0x00000004,
72 CAM_CMD_RESCAN = 0x00000005,
73 CAM_CMD_READ_DEFECTS = 0x00000006,
74 CAM_CMD_MODE_PAGE = 0x00000007,
75 CAM_CMD_SCSI_CMD = 0x00000008,
76 CAM_CMD_DEVTREE = 0x00000009,
77 CAM_CMD_USAGE = 0x0000000a,
78 CAM_CMD_DEBUG = 0x0000000b,
79 CAM_CMD_RESET = 0x0000000c,
80 CAM_CMD_FORMAT = 0x0000000d,
81 CAM_CMD_TAG = 0x0000000e,
82 CAM_CMD_RATE = 0x0000000f,
83 CAM_CMD_DETACH = 0x00000010,
84 CAM_CMD_REPORTLUNS = 0x00000011,
85 CAM_CMD_READCAP = 0x00000012,
86 CAM_CMD_IDENTIFY = 0x00000013,
87 CAM_CMD_IDLE = 0x00000014,
88 CAM_CMD_STANDBY = 0x00000015,
89 CAM_CMD_SLEEP = 0x00000016,
90 CAM_CMD_SMP_CMD = 0x00000017,
91 CAM_CMD_SMP_RG = 0x00000018,
92 CAM_CMD_SMP_PC = 0x00000019,
93 CAM_CMD_SMP_PHYLIST = 0x0000001a,
94 CAM_CMD_SMP_MANINFO = 0x0000001b,
95 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
96 CAM_CMD_SECURITY = 0x0000001d,
97 CAM_CMD_HPA = 0x0000001e,
98 CAM_CMD_SANITIZE = 0x0000001f,
99 CAM_CMD_PERSIST = 0x00000020,
100 CAM_CMD_APM = 0x00000021,
101 CAM_CMD_AAM = 0x00000022,
102 CAM_CMD_ATTRIB = 0x00000023,
103 CAM_CMD_OPCODES = 0x00000024,
104 CAM_CMD_REPROBE = 0x00000025,
105 CAM_CMD_ZONE = 0x00000026,
106 CAM_CMD_EPC = 0x00000027,
107 CAM_CMD_TIMESTAMP = 0x00000028
111 CAM_ARG_NONE = 0x00000000,
112 CAM_ARG_VERBOSE = 0x00000001,
113 CAM_ARG_DEVICE = 0x00000002,
114 CAM_ARG_BUS = 0x00000004,
115 CAM_ARG_TARGET = 0x00000008,
116 CAM_ARG_LUN = 0x00000010,
117 CAM_ARG_EJECT = 0x00000020,
118 CAM_ARG_UNIT = 0x00000040,
119 CAM_ARG_FORMAT_BLOCK = 0x00000080,
120 CAM_ARG_FORMAT_BFI = 0x00000100,
121 CAM_ARG_FORMAT_PHYS = 0x00000200,
122 CAM_ARG_PLIST = 0x00000400,
123 CAM_ARG_GLIST = 0x00000800,
124 CAM_ARG_GET_SERIAL = 0x00001000,
125 CAM_ARG_GET_STDINQ = 0x00002000,
126 CAM_ARG_GET_XFERRATE = 0x00004000,
127 CAM_ARG_INQ_MASK = 0x00007000,
128 CAM_ARG_MODE_EDIT = 0x00008000,
129 CAM_ARG_PAGE_CNTL = 0x00010000,
130 CAM_ARG_TIMEOUT = 0x00020000,
131 CAM_ARG_CMD_IN = 0x00040000,
132 CAM_ARG_CMD_OUT = 0x00080000,
133 CAM_ARG_DBD = 0x00100000,
134 CAM_ARG_ERR_RECOVER = 0x00200000,
135 CAM_ARG_RETRIES = 0x00400000,
136 CAM_ARG_START_UNIT = 0x00800000,
137 CAM_ARG_DEBUG_INFO = 0x01000000,
138 CAM_ARG_DEBUG_TRACE = 0x02000000,
139 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
140 CAM_ARG_DEBUG_CDB = 0x08000000,
141 CAM_ARG_DEBUG_XPT = 0x10000000,
142 CAM_ARG_DEBUG_PERIPH = 0x20000000,
143 CAM_ARG_DEBUG_PROBE = 0x40000000,
146 struct camcontrol_opts {
154 struct ata_res_pass16 {
155 u_int16_t reserved[5];
158 u_int8_t sector_count_exp;
159 u_int8_t sector_count;
160 u_int8_t lba_low_exp;
162 u_int8_t lba_mid_exp;
164 u_int8_t lba_high_exp;
170 struct ata_set_max_pwd
173 u_int8_t password[32];
174 u_int16_t reserved2[239];
177 static const char scsicmd_opts[] = "a:c:dfi:o:r";
178 static const char readdefect_opts[] = "f:GPqsS:X";
179 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
180 static const char smprg_opts[] = "l";
181 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
182 static const char smpphylist_opts[] = "lq";
186 static struct camcontrol_opts option_table[] = {
188 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
189 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
190 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
191 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
192 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
193 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
194 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
195 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
196 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
197 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
198 #endif /* MINIMALISTIC */
199 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
200 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
202 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
203 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
204 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
205 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
206 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
207 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
208 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
209 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
210 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
211 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
212 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
213 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
214 #endif /* MINIMALISTIC */
215 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
217 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
218 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
219 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
220 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
221 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
222 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
223 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
224 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
225 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
226 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
227 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
228 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
229 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
230 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
231 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
232 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
233 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
234 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
235 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
236 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
237 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
238 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
239 #endif /* MINIMALISTIC */
240 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
241 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
242 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
247 struct device_match_result dev_match;
249 struct periph_match_result *periph_matches;
250 struct scsi_vpd_device_id *device_id;
252 STAILQ_ENTRY(cam_devitem) links;
256 STAILQ_HEAD(, cam_devitem) dev_queue;
260 static cam_cmdmask cmdlist;
261 static cam_argmask arglist;
263 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
264 uint32_t *cmdnum, cam_argmask *argnum,
265 const char **subopt);
267 static int getdevlist(struct cam_device *device);
268 #endif /* MINIMALISTIC */
269 static int getdevtree(int argc, char **argv, char *combinedopt);
271 static int testunitready(struct cam_device *device, int retry_count,
272 int timeout, int quiet);
273 static int scsistart(struct cam_device *device, int startstop, int loadeject,
274 int retry_count, int timeout);
275 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
276 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
277 #endif /* MINIMALISTIC */
278 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
279 lun_id_t *lun, cam_argmask *arglst);
280 static int dorescan_or_reset(int argc, char **argv, int rescan);
281 static int rescan_or_reset_bus(path_id_t bus, int rescan);
282 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
283 lun_id_t lun, int scan);
285 static int readdefects(struct cam_device *device, int argc, char **argv,
286 char *combinedopt, int retry_count, int timeout);
287 static void modepage(struct cam_device *device, int argc, char **argv,
288 char *combinedopt, int retry_count, int timeout);
289 static int scsicmd(struct cam_device *device, int argc, char **argv,
290 char *combinedopt, int retry_count, int timeout);
291 static int smpcmd(struct cam_device *device, int argc, char **argv,
292 char *combinedopt, int retry_count, int timeout);
293 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
294 char *combinedopt, int retry_count, int timeout);
295 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
296 char *combinedopt, int retry_count, int timeout);
297 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
298 char *combinedopt, int retry_count, int timeout);
299 static int getdevid(struct cam_devitem *item);
300 static int buildbusdevlist(struct cam_devlist *devlist);
301 static void freebusdevlist(struct cam_devlist *devlist);
302 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
304 static int smpphylist(struct cam_device *device, int argc, char **argv,
305 char *combinedopt, int retry_count, int timeout);
306 static int tagcontrol(struct cam_device *device, int argc, char **argv,
308 static void cts_print(struct cam_device *device,
309 struct ccb_trans_settings *cts);
310 static void cpi_print(struct ccb_pathinq *cpi);
311 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
312 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
313 static int get_print_cts(struct cam_device *device, int user_settings,
314 int quiet, struct ccb_trans_settings *cts);
315 static int ratecontrol(struct cam_device *device, int retry_count,
316 int timeout, int argc, char **argv, char *combinedopt);
317 static int scsiformat(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int scsisanitize(struct cam_device *device, int argc, char **argv,
320 char *combinedopt, int retry_count, int timeout);
321 static int scsireportluns(struct cam_device *device, int argc, char **argv,
322 char *combinedopt, int retry_count, int timeout);
323 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
324 char *combinedopt, int retry_count, int timeout);
325 static int atapm(struct cam_device *device, int argc, char **argv,
326 char *combinedopt, int retry_count, int timeout);
327 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
328 int argc, char **argv, char *combinedopt);
329 static int atahpa(struct cam_device *device, int retry_count, int timeout,
330 int argc, char **argv, char *combinedopt);
331 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
332 int sa_set, int req_sa, uint8_t *buf,
334 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
336 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
337 char *combinedopt, int retry_count, int timeout,
339 static int scsireprobe(struct cam_device *device);
341 #endif /* MINIMALISTIC */
343 #define min(a,b) (((a)<(b))?(a):(b))
346 #define max(a,b) (((a)>(b))?(a):(b))
350 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
351 cam_argmask *argnum, const char **subopt)
353 struct camcontrol_opts *opts;
356 for (opts = table; (opts != NULL) && (opts->optname != NULL);
358 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
359 *cmdnum = opts->cmdnum;
360 *argnum = opts->argnum;
361 *subopt = opts->subopt;
362 if (++num_matches > 1)
363 return(CC_OR_AMBIGUOUS);
370 return(CC_OR_NOT_FOUND);
375 getdevlist(struct cam_device *device)
381 ccb = cam_getccb(device);
383 ccb->ccb_h.func_code = XPT_GDEVLIST;
384 ccb->ccb_h.flags = CAM_DIR_NONE;
385 ccb->ccb_h.retry_count = 1;
387 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
388 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
389 if (cam_send_ccb(device, ccb) < 0) {
390 perror("error getting device list");
397 switch (ccb->cgdl.status) {
398 case CAM_GDEVLIST_MORE_DEVS:
399 strcpy(status, "MORE");
401 case CAM_GDEVLIST_LAST_DEVICE:
402 strcpy(status, "LAST");
404 case CAM_GDEVLIST_LIST_CHANGED:
405 strcpy(status, "CHANGED");
407 case CAM_GDEVLIST_ERROR:
408 strcpy(status, "ERROR");
413 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
414 ccb->cgdl.periph_name,
415 ccb->cgdl.unit_number,
416 ccb->cgdl.generation,
421 * If the list has changed, we need to start over from the
424 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
432 #endif /* MINIMALISTIC */
435 getdevtree(int argc, char **argv, char *combinedopt)
446 while ((c = getopt(argc, argv, combinedopt)) != -1) {
449 if ((arglist & CAM_ARG_VERBOSE) == 0)
457 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
458 warn("couldn't open %s", XPT_DEVICE);
462 bzero(&ccb, sizeof(union ccb));
464 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
465 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
466 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
468 ccb.ccb_h.func_code = XPT_DEV_MATCH;
469 bufsize = sizeof(struct dev_match_result) * 100;
470 ccb.cdm.match_buf_len = bufsize;
471 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
472 if (ccb.cdm.matches == NULL) {
473 warnx("can't malloc memory for matches");
477 ccb.cdm.num_matches = 0;
480 * We fetch all nodes, since we display most of them in the default
481 * case, and all in the verbose case.
483 ccb.cdm.num_patterns = 0;
484 ccb.cdm.pattern_buf_len = 0;
487 * We do the ioctl multiple times if necessary, in case there are
488 * more than 100 nodes in the EDT.
491 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
492 warn("error sending CAMIOCOMMAND ioctl");
497 if ((ccb.ccb_h.status != CAM_REQ_CMP)
498 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
499 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
500 warnx("got CAM error %#x, CDM error %d\n",
501 ccb.ccb_h.status, ccb.cdm.status);
506 for (i = 0; i < ccb.cdm.num_matches; i++) {
507 switch (ccb.cdm.matches[i].type) {
508 case DEV_MATCH_BUS: {
509 struct bus_match_result *bus_result;
512 * Only print the bus information if the
513 * user turns on the verbose flag.
515 if ((busonly == 0) &&
516 (arglist & CAM_ARG_VERBOSE) == 0)
520 &ccb.cdm.matches[i].result.bus_result;
523 fprintf(stdout, ")\n");
527 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
529 bus_result->dev_name,
530 bus_result->unit_number,
532 (busonly ? "" : ":"));
535 case DEV_MATCH_DEVICE: {
536 struct device_match_result *dev_result;
537 char vendor[16], product[48], revision[16];
538 char fw[5], tmpstr[256];
544 &ccb.cdm.matches[i].result.device_result;
546 if ((dev_result->flags
547 & DEV_RESULT_UNCONFIGURED)
548 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
554 if (dev_result->protocol == PROTO_SCSI) {
555 cam_strvis(vendor, dev_result->inq_data.vendor,
556 sizeof(dev_result->inq_data.vendor),
559 dev_result->inq_data.product,
560 sizeof(dev_result->inq_data.product),
563 dev_result->inq_data.revision,
564 sizeof(dev_result->inq_data.revision),
566 sprintf(tmpstr, "<%s %s %s>", vendor, product,
568 } else if (dev_result->protocol == PROTO_ATA ||
569 dev_result->protocol == PROTO_SATAPM) {
571 dev_result->ident_data.model,
572 sizeof(dev_result->ident_data.model),
575 dev_result->ident_data.revision,
576 sizeof(dev_result->ident_data.revision),
578 sprintf(tmpstr, "<%s %s>", product,
580 } else if (dev_result->protocol == PROTO_SEMB) {
581 struct sep_identify_data *sid;
583 sid = (struct sep_identify_data *)
584 &dev_result->ident_data;
585 cam_strvis(vendor, sid->vendor_id,
586 sizeof(sid->vendor_id),
588 cam_strvis(product, sid->product_id,
589 sizeof(sid->product_id),
591 cam_strvis(revision, sid->product_rev,
592 sizeof(sid->product_rev),
594 cam_strvis(fw, sid->firmware_rev,
595 sizeof(sid->firmware_rev),
597 sprintf(tmpstr, "<%s %s %s %s>",
598 vendor, product, revision, fw);
600 sprintf(tmpstr, "<>");
603 fprintf(stdout, ")\n");
607 fprintf(stdout, "%-33s at scbus%d "
608 "target %d lun %jx (",
611 dev_result->target_id,
612 (uintmax_t)dev_result->target_lun);
618 case DEV_MATCH_PERIPH: {
619 struct periph_match_result *periph_result;
622 &ccb.cdm.matches[i].result.periph_result;
624 if (busonly || skip_device != 0)
628 fprintf(stdout, ",");
630 fprintf(stdout, "%s%d",
631 periph_result->periph_name,
632 periph_result->unit_number);
638 fprintf(stdout, "unknown match type\n");
643 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
644 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
647 fprintf(stdout, ")\n");
656 testunitready(struct cam_device *device, int retry_count, int timeout,
662 ccb = cam_getccb(device);
664 scsi_test_unit_ready(&ccb->csio,
665 /* retries */ retry_count,
667 /* tag_action */ MSG_SIMPLE_Q_TAG,
668 /* sense_len */ SSD_FULL_SIZE,
669 /* timeout */ timeout ? timeout : 5000);
671 /* Disable freezing the device queue */
672 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
674 if (arglist & CAM_ARG_ERR_RECOVER)
675 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
677 if (cam_send_ccb(device, ccb) < 0) {
679 perror("error sending test unit ready");
681 if (arglist & CAM_ARG_VERBOSE) {
682 cam_error_print(device, ccb, CAM_ESF_ALL,
683 CAM_EPF_ALL, stderr);
690 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
692 fprintf(stdout, "Unit is ready\n");
695 fprintf(stdout, "Unit is not ready\n");
698 if (arglist & CAM_ARG_VERBOSE) {
699 cam_error_print(device, ccb, CAM_ESF_ALL,
700 CAM_EPF_ALL, stderr);
710 scsistart(struct cam_device *device, int startstop, int loadeject,
711 int retry_count, int timeout)
716 ccb = cam_getccb(device);
719 * If we're stopping, send an ordered tag so the drive in question
720 * will finish any previously queued writes before stopping. If
721 * the device isn't capable of tagged queueing, or if tagged
722 * queueing is turned off, the tag action is a no-op.
724 scsi_start_stop(&ccb->csio,
725 /* retries */ retry_count,
727 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
729 /* start/stop */ startstop,
730 /* load_eject */ loadeject,
732 /* sense_len */ SSD_FULL_SIZE,
733 /* timeout */ timeout ? timeout : 120000);
735 /* Disable freezing the device queue */
736 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
738 if (arglist & CAM_ARG_ERR_RECOVER)
739 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
741 if (cam_send_ccb(device, ccb) < 0) {
742 perror("error sending start unit");
744 if (arglist & CAM_ARG_VERBOSE) {
745 cam_error_print(device, ccb, CAM_ESF_ALL,
746 CAM_EPF_ALL, stderr);
753 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
755 fprintf(stdout, "Unit started successfully");
757 fprintf(stdout,", Media loaded\n");
759 fprintf(stdout,"\n");
761 fprintf(stdout, "Unit stopped successfully");
763 fprintf(stdout, ", Media ejected\n");
765 fprintf(stdout, "\n");
771 "Error received from start unit command\n");
774 "Error received from stop unit command\n");
776 if (arglist & CAM_ARG_VERBOSE) {
777 cam_error_print(device, ccb, CAM_ESF_ALL,
778 CAM_EPF_ALL, stderr);
788 scsidoinquiry(struct cam_device *device, int argc, char **argv,
789 char *combinedopt, int retry_count, int timeout)
794 while ((c = getopt(argc, argv, combinedopt)) != -1) {
797 arglist |= CAM_ARG_GET_STDINQ;
800 arglist |= CAM_ARG_GET_XFERRATE;
803 arglist |= CAM_ARG_GET_SERIAL;
811 * If the user didn't specify any inquiry options, he wants all of
814 if ((arglist & CAM_ARG_INQ_MASK) == 0)
815 arglist |= CAM_ARG_INQ_MASK;
817 if (arglist & CAM_ARG_GET_STDINQ)
818 error = scsiinquiry(device, retry_count, timeout);
823 if (arglist & CAM_ARG_GET_SERIAL)
824 scsiserial(device, retry_count, timeout);
826 if (arglist & CAM_ARG_GET_XFERRATE)
827 error = camxferrate(device);
833 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
836 struct scsi_inquiry_data *inq_buf;
839 ccb = cam_getccb(device);
842 warnx("couldn't allocate CCB");
846 /* cam_getccb cleans up the header, caller has to zero the payload */
847 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
849 inq_buf = (struct scsi_inquiry_data *)malloc(
850 sizeof(struct scsi_inquiry_data));
852 if (inq_buf == NULL) {
854 warnx("can't malloc memory for inquiry\n");
857 bzero(inq_buf, sizeof(*inq_buf));
860 * Note that although the size of the inquiry buffer is the full
861 * 256 bytes specified in the SCSI spec, we only tell the device
862 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
863 * two reasons for this:
865 * - The SCSI spec says that when a length field is only 1 byte,
866 * a value of 0 will be interpreted as 256. Therefore
867 * scsi_inquiry() will convert an inq_len (which is passed in as
868 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
869 * to 0. Evidently, very few devices meet the spec in that
870 * regard. Some devices, like many Seagate disks, take the 0 as
871 * 0, and don't return any data. One Pioneer DVD-R drive
872 * returns more data than the command asked for.
874 * So, since there are numerous devices that just don't work
875 * right with the full inquiry size, we don't send the full size.
877 * - The second reason not to use the full inquiry data length is
878 * that we don't need it here. The only reason we issue a
879 * standard inquiry is to get the vendor name, device name,
880 * and revision so scsi_print_inquiry() can print them.
882 * If, at some point in the future, more inquiry data is needed for
883 * some reason, this code should use a procedure similar to the
884 * probe code. i.e., issue a short inquiry, and determine from
885 * the additional length passed back from the device how much
886 * inquiry data the device supports. Once the amount the device
887 * supports is determined, issue an inquiry for that amount and no
892 scsi_inquiry(&ccb->csio,
893 /* retries */ retry_count,
895 /* tag_action */ MSG_SIMPLE_Q_TAG,
896 /* inq_buf */ (u_int8_t *)inq_buf,
897 /* inq_len */ SHORT_INQUIRY_LENGTH,
900 /* sense_len */ SSD_FULL_SIZE,
901 /* timeout */ timeout ? timeout : 5000);
903 /* Disable freezing the device queue */
904 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
906 if (arglist & CAM_ARG_ERR_RECOVER)
907 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
909 if (cam_send_ccb(device, ccb) < 0) {
910 perror("error sending SCSI inquiry");
912 if (arglist & CAM_ARG_VERBOSE) {
913 cam_error_print(device, ccb, CAM_ESF_ALL,
914 CAM_EPF_ALL, stderr);
921 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
924 if (arglist & CAM_ARG_VERBOSE) {
925 cam_error_print(device, ccb, CAM_ESF_ALL,
926 CAM_EPF_ALL, stderr);
937 fprintf(stdout, "%s%d: ", device->device_name,
938 device->dev_unit_num);
939 scsi_print_inquiry(inq_buf);
947 scsiserial(struct cam_device *device, int retry_count, int timeout)
950 struct scsi_vpd_unit_serial_number *serial_buf;
951 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
954 ccb = cam_getccb(device);
957 warnx("couldn't allocate CCB");
961 /* cam_getccb cleans up the header, caller has to zero the payload */
962 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
964 serial_buf = (struct scsi_vpd_unit_serial_number *)
965 malloc(sizeof(*serial_buf));
967 if (serial_buf == NULL) {
969 warnx("can't malloc memory for serial number");
973 scsi_inquiry(&ccb->csio,
974 /*retries*/ retry_count,
976 /* tag_action */ MSG_SIMPLE_Q_TAG,
977 /* inq_buf */ (u_int8_t *)serial_buf,
978 /* inq_len */ sizeof(*serial_buf),
980 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
981 /* sense_len */ SSD_FULL_SIZE,
982 /* timeout */ timeout ? timeout : 5000);
984 /* Disable freezing the device queue */
985 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
987 if (arglist & CAM_ARG_ERR_RECOVER)
988 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
990 if (cam_send_ccb(device, ccb) < 0) {
991 warn("error getting serial number");
993 if (arglist & CAM_ARG_VERBOSE) {
994 cam_error_print(device, ccb, CAM_ESF_ALL,
995 CAM_EPF_ALL, stderr);
1003 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1006 if (arglist & CAM_ARG_VERBOSE) {
1007 cam_error_print(device, ccb, CAM_ESF_ALL,
1008 CAM_EPF_ALL, stderr);
1019 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1020 serial_num[serial_buf->length] = '\0';
1022 if ((arglist & CAM_ARG_GET_STDINQ)
1023 || (arglist & CAM_ARG_GET_XFERRATE))
1024 fprintf(stdout, "%s%d: Serial Number ",
1025 device->device_name, device->dev_unit_num);
1027 fprintf(stdout, "%.60s\n", serial_num);
1035 camxferrate(struct cam_device *device)
1037 struct ccb_pathinq cpi;
1039 u_int32_t speed = 0;
1044 if ((retval = get_cpi(device, &cpi)) != 0)
1047 ccb = cam_getccb(device);
1050 warnx("couldn't allocate CCB");
1054 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1056 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1057 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1059 if (((retval = cam_send_ccb(device, ccb)) < 0)
1060 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1061 const char error_string[] = "error getting transfer settings";
1066 warnx(error_string);
1068 if (arglist & CAM_ARG_VERBOSE)
1069 cam_error_print(device, ccb, CAM_ESF_ALL,
1070 CAM_EPF_ALL, stderr);
1074 goto xferrate_bailout;
1078 speed = cpi.base_transfer_speed;
1080 if (ccb->cts.transport == XPORT_SPI) {
1081 struct ccb_trans_settings_spi *spi =
1082 &ccb->cts.xport_specific.spi;
1084 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1085 freq = scsi_calc_syncsrate(spi->sync_period);
1088 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1089 speed *= (0x01 << spi->bus_width);
1091 } else if (ccb->cts.transport == XPORT_FC) {
1092 struct ccb_trans_settings_fc *fc =
1093 &ccb->cts.xport_specific.fc;
1095 if (fc->valid & CTS_FC_VALID_SPEED)
1096 speed = fc->bitrate;
1097 } else if (ccb->cts.transport == XPORT_SAS) {
1098 struct ccb_trans_settings_sas *sas =
1099 &ccb->cts.xport_specific.sas;
1101 if (sas->valid & CTS_SAS_VALID_SPEED)
1102 speed = sas->bitrate;
1103 } else if (ccb->cts.transport == XPORT_ATA) {
1104 struct ccb_trans_settings_pata *pata =
1105 &ccb->cts.xport_specific.ata;
1107 if (pata->valid & CTS_ATA_VALID_MODE)
1108 speed = ata_mode2speed(pata->mode);
1109 } else if (ccb->cts.transport == XPORT_SATA) {
1110 struct ccb_trans_settings_sata *sata =
1111 &ccb->cts.xport_specific.sata;
1113 if (sata->valid & CTS_SATA_VALID_REVISION)
1114 speed = ata_revision2speed(sata->revision);
1119 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1120 device->device_name, device->dev_unit_num,
1123 fprintf(stdout, "%s%d: %dKB/s transfers",
1124 device->device_name, device->dev_unit_num,
1128 if (ccb->cts.transport == XPORT_SPI) {
1129 struct ccb_trans_settings_spi *spi =
1130 &ccb->cts.xport_specific.spi;
1132 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1133 && (spi->sync_offset != 0))
1134 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1135 freq % 1000, spi->sync_offset);
1137 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1138 && (spi->bus_width > 0)) {
1139 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1140 && (spi->sync_offset != 0)) {
1141 fprintf(stdout, ", ");
1143 fprintf(stdout, " (");
1145 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1146 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1147 && (spi->sync_offset != 0)) {
1148 fprintf(stdout, ")");
1150 } else if (ccb->cts.transport == XPORT_ATA) {
1151 struct ccb_trans_settings_pata *pata =
1152 &ccb->cts.xport_specific.ata;
1155 if (pata->valid & CTS_ATA_VALID_MODE)
1156 printf("%s, ", ata_mode2string(pata->mode));
1157 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1158 printf("ATAPI %dbytes, ", pata->atapi);
1159 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1160 printf("PIO %dbytes", pata->bytecount);
1162 } else if (ccb->cts.transport == XPORT_SATA) {
1163 struct ccb_trans_settings_sata *sata =
1164 &ccb->cts.xport_specific.sata;
1167 if (sata->valid & CTS_SATA_VALID_REVISION)
1168 printf("SATA %d.x, ", sata->revision);
1171 if (sata->valid & CTS_SATA_VALID_MODE)
1172 printf("%s, ", ata_mode2string(sata->mode));
1173 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1174 printf("ATAPI %dbytes, ", sata->atapi);
1175 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1176 printf("PIO %dbytes", sata->bytecount);
1180 if (ccb->cts.protocol == PROTO_SCSI) {
1181 struct ccb_trans_settings_scsi *scsi =
1182 &ccb->cts.proto_specific.scsi;
1183 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1184 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1185 fprintf(stdout, ", Command Queueing Enabled");
1190 fprintf(stdout, "\n");
1200 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1202 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1203 ((u_int32_t)parm->lba_size_2 << 16);
1205 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1206 ((u_int64_t)parm->lba_size48_2 << 16) |
1207 ((u_int64_t)parm->lba_size48_3 << 32) |
1208 ((u_int64_t)parm->lba_size48_4 << 48);
1212 "Support Enabled Value\n");
1215 printf("Host Protected Area (HPA) ");
1216 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1217 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1218 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1221 printf("HPA - Security ");
1222 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1232 atasata(struct ata_params *parm)
1236 if (parm->satacapabilities != 0xffff &&
1237 parm->satacapabilities != 0x0000)
1244 atacapprint(struct ata_params *parm)
1246 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1247 ((u_int32_t)parm->lba_size_2 << 16);
1249 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1250 ((u_int64_t)parm->lba_size48_2 << 16) |
1251 ((u_int64_t)parm->lba_size48_3 << 32) |
1252 ((u_int64_t)parm->lba_size48_4 << 48);
1255 printf("protocol ");
1256 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1257 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1258 if (parm->satacapabilities & ATA_SATA_GEN3)
1259 printf(" SATA 3.x\n");
1260 else if (parm->satacapabilities & ATA_SATA_GEN2)
1261 printf(" SATA 2.x\n");
1262 else if (parm->satacapabilities & ATA_SATA_GEN1)
1263 printf(" SATA 1.x\n");
1269 printf("device model %.40s\n", parm->model);
1270 printf("firmware revision %.8s\n", parm->revision);
1271 printf("serial number %.20s\n", parm->serial);
1272 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1273 printf("WWN %04x%04x%04x%04x\n",
1274 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1276 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1277 printf("media serial number %.30s\n",
1278 parm->media_serial);
1281 printf("cylinders %d\n", parm->cylinders);
1282 printf("heads %d\n", parm->heads);
1283 printf("sectors/track %d\n", parm->sectors);
1284 printf("sector size logical %u, physical %lu, offset %lu\n",
1285 ata_logical_sector_size(parm),
1286 (unsigned long)ata_physical_sector_size(parm),
1287 (unsigned long)ata_logical_sector_offset(parm));
1289 if (parm->config == ATA_PROTO_CFA ||
1290 (parm->support.command2 & ATA_SUPPORT_CFA))
1291 printf("CFA supported\n");
1293 printf("LBA%ssupported ",
1294 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1296 printf("%d sectors\n", lbasize);
1300 printf("LBA48%ssupported ",
1301 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1303 printf("%ju sectors\n", (uintmax_t)lbasize48);
1307 printf("PIO supported PIO");
1308 switch (ata_max_pmode(parm)) {
1324 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1325 printf(" w/o IORDY");
1328 printf("DMA%ssupported ",
1329 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1330 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1331 if (parm->mwdmamodes & 0xff) {
1333 if (parm->mwdmamodes & 0x04)
1335 else if (parm->mwdmamodes & 0x02)
1337 else if (parm->mwdmamodes & 0x01)
1341 if ((parm->atavalid & ATA_FLAG_88) &&
1342 (parm->udmamodes & 0xff)) {
1344 if (parm->udmamodes & 0x40)
1346 else if (parm->udmamodes & 0x20)
1348 else if (parm->udmamodes & 0x10)
1350 else if (parm->udmamodes & 0x08)
1352 else if (parm->udmamodes & 0x04)
1354 else if (parm->udmamodes & 0x02)
1356 else if (parm->udmamodes & 0x01)
1363 if (parm->media_rotation_rate == 1) {
1364 printf("media RPM non-rotating\n");
1365 } else if (parm->media_rotation_rate >= 0x0401 &&
1366 parm->media_rotation_rate <= 0xFFFE) {
1367 printf("media RPM %d\n",
1368 parm->media_rotation_rate);
1372 "Support Enabled Value Vendor\n");
1373 printf("read ahead %s %s\n",
1374 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1375 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1376 printf("write cache %s %s\n",
1377 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1378 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1379 printf("flush cache %s %s\n",
1380 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1381 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1382 printf("overlap %s\n",
1383 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1384 printf("Tagged Command Queuing (TCQ) %s %s",
1385 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1386 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1387 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1388 printf(" %d tags\n",
1389 ATA_QUEUE_LEN(parm->queue) + 1);
1392 printf("Native Command Queuing (NCQ) ");
1393 if (parm->satacapabilities != 0xffff &&
1394 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1395 printf("yes %d tags\n",
1396 ATA_QUEUE_LEN(parm->queue) + 1);
1400 printf("NCQ Queue Management %s\n", atasata(parm) &&
1401 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1403 printf("NCQ Streaming %s\n", atasata(parm) &&
1404 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1406 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1407 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1410 printf("SMART %s %s\n",
1411 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1412 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1413 printf("microcode download %s %s\n",
1414 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1415 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1416 printf("security %s %s\n",
1417 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1418 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1419 printf("power management %s %s\n",
1420 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1421 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1422 printf("advanced power management %s %s",
1423 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1424 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1425 if (parm->support.command2 & ATA_SUPPORT_APM) {
1426 printf(" %d/0x%02X\n",
1427 parm->apm_value & 0xff, parm->apm_value & 0xff);
1430 printf("automatic acoustic management %s %s",
1431 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1432 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1433 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1434 printf(" %d/0x%02X %d/0x%02X\n",
1435 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1436 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1437 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1438 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1441 printf("media status notification %s %s\n",
1442 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1443 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1444 printf("power-up in Standby %s %s\n",
1445 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1446 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1447 printf("write-read-verify %s %s",
1448 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1449 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1450 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1451 printf(" %d/0x%x\n",
1452 parm->wrv_mode, parm->wrv_mode);
1455 printf("unload %s %s\n",
1456 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1457 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1458 printf("general purpose logging %s %s\n",
1459 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1460 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1461 printf("free-fall %s %s\n",
1462 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1463 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1464 printf("Data Set Management (DSM/TRIM) ");
1465 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1467 printf("DSM - max 512byte blocks ");
1468 if (parm->max_dsm_blocks == 0x00)
1469 printf("yes not specified\n");
1472 parm->max_dsm_blocks);
1474 printf("DSM - deterministic read ");
1475 if (parm->support3 & ATA_SUPPORT_DRAT) {
1476 if (parm->support3 & ATA_SUPPORT_RZAT)
1477 printf("yes zeroed\n");
1479 printf("yes any value\n");
1489 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1491 struct ata_pass_16 *ata_pass_16;
1492 struct ata_cmd ata_cmd;
1494 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1495 ata_cmd.command = ata_pass_16->command;
1496 ata_cmd.control = ata_pass_16->control;
1497 ata_cmd.features = ata_pass_16->features;
1499 if (arglist & CAM_ARG_VERBOSE) {
1500 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1501 ata_op_string(&ata_cmd),
1502 ccb->csio.ccb_h.timeout);
1505 /* Disable freezing the device queue */
1506 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1508 if (arglist & CAM_ARG_ERR_RECOVER)
1509 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1511 if (cam_send_ccb(device, ccb) < 0) {
1512 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1513 warn("error sending ATA %s via pass_16",
1514 ata_op_string(&ata_cmd));
1517 if (arglist & CAM_ARG_VERBOSE) {
1518 cam_error_print(device, ccb, CAM_ESF_ALL,
1519 CAM_EPF_ALL, stderr);
1525 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1526 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1527 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1528 warnx("ATA %s via pass_16 failed",
1529 ata_op_string(&ata_cmd));
1531 if (arglist & CAM_ARG_VERBOSE) {
1532 cam_error_print(device, ccb, CAM_ESF_ALL,
1533 CAM_EPF_ALL, stderr);
1544 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1546 if (arglist & CAM_ARG_VERBOSE) {
1547 warnx("sending ATA %s with timeout of %u msecs",
1548 ata_op_string(&(ccb->ataio.cmd)),
1549 ccb->ataio.ccb_h.timeout);
1552 /* Disable freezing the device queue */
1553 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1555 if (arglist & CAM_ARG_ERR_RECOVER)
1556 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1558 if (cam_send_ccb(device, ccb) < 0) {
1559 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1560 warn("error sending ATA %s",
1561 ata_op_string(&(ccb->ataio.cmd)));
1564 if (arglist & CAM_ARG_VERBOSE) {
1565 cam_error_print(device, ccb, CAM_ESF_ALL,
1566 CAM_EPF_ALL, stderr);
1572 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1573 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1574 warnx("ATA %s failed: %d",
1575 ata_op_string(&(ccb->ataio.cmd)), quiet);
1578 if (arglist & CAM_ARG_VERBOSE) {
1579 cam_error_print(device, ccb, CAM_ESF_ALL,
1580 CAM_EPF_ALL, stderr);
1590 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1591 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1592 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1593 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1594 u_int16_t dxfer_len, int timeout, int quiet)
1596 if (data_ptr != NULL) {
1597 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1598 AP_FLAG_TLEN_SECT_CNT;
1599 if (flags & CAM_DIR_OUT)
1600 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1602 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1604 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1607 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1609 scsi_ata_pass_16(&ccb->csio,
1623 /*sense_len*/SSD_FULL_SIZE,
1626 return scsi_cam_pass_16_send(device, ccb, quiet);
1630 ata_try_pass_16(struct cam_device *device)
1632 struct ccb_pathinq cpi;
1634 if (get_cpi(device, &cpi) != 0) {
1635 warnx("couldn't get CPI");
1639 if (cpi.protocol == PROTO_SCSI) {
1640 /* possibly compatible with pass_16 */
1644 /* likely not compatible with pass_16 */
1649 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1650 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1651 u_int8_t command, u_int8_t features, u_int32_t lba,
1652 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1653 int timeout, int quiet)
1657 switch (ata_try_pass_16(device)) {
1661 /* Try using SCSI Passthrough */
1662 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1663 0, tag_action, command, features, lba,
1664 sector_count, data_ptr, dxfer_len,
1668 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1669 cam_fill_ataio(&ccb->ataio,
1678 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1679 return ata_cam_send(device, ccb, quiet);
1683 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1684 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1685 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1686 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1687 u_int16_t dxfer_len, int timeout, int force48bit)
1691 retval = ata_try_pass_16(device);
1698 /* Try using SCSI Passthrough */
1699 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1700 ata_flags, tag_action, command, features,
1701 lba, sector_count, data_ptr, dxfer_len,
1704 if (ata_flags & AP_FLAG_CHK_COND) {
1705 /* Decode ata_res from sense data */
1706 struct ata_res_pass16 *res_pass16;
1707 struct ata_res *res;
1711 /* sense_data is 4 byte aligned */
1712 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1713 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1714 ptr[i] = le16toh(ptr[i]);
1716 /* sense_data is 4 byte aligned */
1717 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1718 &ccb->csio.sense_data;
1719 res = &ccb->ataio.res;
1720 res->flags = res_pass16->flags;
1721 res->status = res_pass16->status;
1722 res->error = res_pass16->error;
1723 res->lba_low = res_pass16->lba_low;
1724 res->lba_mid = res_pass16->lba_mid;
1725 res->lba_high = res_pass16->lba_high;
1726 res->device = res_pass16->device;
1727 res->lba_low_exp = res_pass16->lba_low_exp;
1728 res->lba_mid_exp = res_pass16->lba_mid_exp;
1729 res->lba_high_exp = res_pass16->lba_high_exp;
1730 res->sector_count = res_pass16->sector_count;
1731 res->sector_count_exp = res_pass16->sector_count_exp;
1737 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1738 cam_fill_ataio(&ccb->ataio,
1747 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1748 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1750 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1752 if (ata_flags & AP_FLAG_CHK_COND)
1753 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1755 return ata_cam_send(device, ccb, 0);
1759 dump_data(uint16_t *ptr, uint32_t len)
1763 for (i = 0; i < len / 2; i++) {
1765 printf(" %3d: ", i);
1766 printf("%04hx ", ptr[i]);
1775 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1776 int is48bit, u_int64_t *hpasize)
1778 struct ata_res *res;
1780 res = &ccb->ataio.res;
1781 if (res->status & ATA_STATUS_ERROR) {
1782 if (arglist & CAM_ARG_VERBOSE) {
1783 cam_error_print(device, ccb, CAM_ESF_ALL,
1784 CAM_EPF_ALL, stderr);
1785 printf("error = 0x%02x, sector_count = 0x%04x, "
1786 "device = 0x%02x, status = 0x%02x\n",
1787 res->error, res->sector_count,
1788 res->device, res->status);
1791 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1792 warnx("Max address has already been set since "
1793 "last power-on or hardware reset");
1799 if (arglist & CAM_ARG_VERBOSE) {
1800 fprintf(stdout, "%s%d: Raw native max data:\n",
1801 device->device_name, device->dev_unit_num);
1802 /* res is 4 byte aligned */
1803 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1805 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1806 "status = 0x%02x\n", res->error, res->sector_count,
1807 res->device, res->status);
1810 if (hpasize != NULL) {
1812 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1813 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1814 ((res->lba_high << 16) | (res->lba_mid << 8) |
1817 *hpasize = (((res->device & 0x0f) << 24) |
1818 (res->lba_high << 16) | (res->lba_mid << 8) |
1827 ata_read_native_max(struct cam_device *device, int retry_count,
1828 u_int32_t timeout, union ccb *ccb,
1829 struct ata_params *parm, u_int64_t *hpasize)
1835 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1836 protocol = AP_PROTO_NON_DATA;
1839 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1840 protocol |= AP_EXTEND;
1842 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1845 error = ata_do_cmd(device,
1848 /*flags*/CAM_DIR_NONE,
1849 /*protocol*/protocol,
1850 /*ata_flags*/AP_FLAG_CHK_COND,
1851 /*tag_action*/MSG_SIMPLE_Q_TAG,
1858 timeout ? timeout : 1000,
1864 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1868 atahpa_set_max(struct cam_device *device, int retry_count,
1869 u_int32_t timeout, union ccb *ccb,
1870 int is48bit, u_int64_t maxsize, int persist)
1876 protocol = AP_PROTO_NON_DATA;
1879 cmd = ATA_SET_MAX_ADDRESS48;
1880 protocol |= AP_EXTEND;
1882 cmd = ATA_SET_MAX_ADDRESS;
1885 /* lba's are zero indexed so the max lba is requested max - 1 */
1889 error = ata_do_cmd(device,
1892 /*flags*/CAM_DIR_NONE,
1893 /*protocol*/protocol,
1894 /*ata_flags*/AP_FLAG_CHK_COND,
1895 /*tag_action*/MSG_SIMPLE_Q_TAG,
1897 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1899 /*sector_count*/persist,
1902 timeout ? timeout : 1000,
1908 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1912 atahpa_password(struct cam_device *device, int retry_count,
1913 u_int32_t timeout, union ccb *ccb,
1914 int is48bit, struct ata_set_max_pwd *pwd)
1920 protocol = AP_PROTO_PIO_OUT;
1921 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1923 error = ata_do_cmd(device,
1926 /*flags*/CAM_DIR_OUT,
1927 /*protocol*/protocol,
1928 /*ata_flags*/AP_FLAG_CHK_COND,
1929 /*tag_action*/MSG_SIMPLE_Q_TAG,
1931 /*features*/ATA_HPA_FEAT_SET_PWD,
1934 /*data_ptr*/(u_int8_t*)pwd,
1935 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1936 timeout ? timeout : 1000,
1942 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1946 atahpa_lock(struct cam_device *device, int retry_count,
1947 u_int32_t timeout, union ccb *ccb, int is48bit)
1953 protocol = AP_PROTO_NON_DATA;
1954 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1956 error = ata_do_cmd(device,
1959 /*flags*/CAM_DIR_NONE,
1960 /*protocol*/protocol,
1961 /*ata_flags*/AP_FLAG_CHK_COND,
1962 /*tag_action*/MSG_SIMPLE_Q_TAG,
1964 /*features*/ATA_HPA_FEAT_LOCK,
1969 timeout ? timeout : 1000,
1975 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1979 atahpa_unlock(struct cam_device *device, int retry_count,
1980 u_int32_t timeout, union ccb *ccb,
1981 int is48bit, struct ata_set_max_pwd *pwd)
1987 protocol = AP_PROTO_PIO_OUT;
1988 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1990 error = ata_do_cmd(device,
1993 /*flags*/CAM_DIR_OUT,
1994 /*protocol*/protocol,
1995 /*ata_flags*/AP_FLAG_CHK_COND,
1996 /*tag_action*/MSG_SIMPLE_Q_TAG,
1998 /*features*/ATA_HPA_FEAT_UNLOCK,
2001 /*data_ptr*/(u_int8_t*)pwd,
2002 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2003 timeout ? timeout : 1000,
2009 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2013 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2014 u_int32_t timeout, union ccb *ccb, int is48bit)
2020 protocol = AP_PROTO_NON_DATA;
2021 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2023 error = ata_do_cmd(device,
2026 /*flags*/CAM_DIR_NONE,
2027 /*protocol*/protocol,
2028 /*ata_flags*/AP_FLAG_CHK_COND,
2029 /*tag_action*/MSG_SIMPLE_Q_TAG,
2031 /*features*/ATA_HPA_FEAT_FREEZE,
2036 timeout ? timeout : 1000,
2042 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2047 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2048 union ccb *ccb, struct ata_params** ident_bufp)
2050 struct ata_params *ident_buf;
2051 struct ccb_pathinq cpi;
2052 struct ccb_getdev cgd;
2055 u_int8_t command, retry_command;
2057 if (get_cpi(device, &cpi) != 0) {
2058 warnx("couldn't get CPI");
2062 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2063 if (cpi.protocol == PROTO_ATA) {
2064 if (get_cgd(device, &cgd) != 0) {
2065 warnx("couldn't get CGD");
2069 command = (cgd.protocol == PROTO_ATA) ?
2070 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2073 /* We don't know which for sure so try both */
2074 command = ATA_ATA_IDENTIFY;
2075 retry_command = ATA_ATAPI_IDENTIFY;
2078 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2080 warnx("can't calloc memory for identify\n");
2084 error = ata_do_28bit_cmd(device,
2086 /*retries*/retry_count,
2087 /*flags*/CAM_DIR_IN,
2088 /*protocol*/AP_PROTO_PIO_IN,
2089 /*tag_action*/MSG_SIMPLE_Q_TAG,
2093 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2094 /*data_ptr*/(u_int8_t *)ptr,
2095 /*dxfer_len*/sizeof(struct ata_params),
2096 /*timeout*/timeout ? timeout : 30 * 1000,
2100 if (retry_command == 0) {
2104 error = ata_do_28bit_cmd(device,
2106 /*retries*/retry_count,
2107 /*flags*/CAM_DIR_IN,
2108 /*protocol*/AP_PROTO_PIO_IN,
2109 /*tag_action*/MSG_SIMPLE_Q_TAG,
2110 /*command*/retry_command,
2113 /*sector_count*/(u_int8_t)
2114 sizeof(struct ata_params),
2115 /*data_ptr*/(u_int8_t *)ptr,
2116 /*dxfer_len*/sizeof(struct ata_params),
2117 /*timeout*/timeout ? timeout : 30 * 1000,
2127 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2128 ptr[i] = le16toh(ptr[i]);
2133 if (arglist & CAM_ARG_VERBOSE) {
2134 fprintf(stdout, "%s%d: Raw identify data:\n",
2135 device->device_name, device->dev_unit_num);
2136 dump_data(ptr, sizeof(struct ata_params));
2139 /* check for invalid (all zero) response */
2141 warnx("Invalid identify response detected");
2146 ident_buf = (struct ata_params *)ptr;
2147 if (strncmp(ident_buf->model, "FX", 2) &&
2148 strncmp(ident_buf->model, "NEC", 3) &&
2149 strncmp(ident_buf->model, "Pioneer", 7) &&
2150 strncmp(ident_buf->model, "SHARP", 5)) {
2151 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2152 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2153 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2154 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2156 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2157 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2158 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2159 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2160 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2161 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2162 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2163 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2164 sizeof(ident_buf->media_serial));
2166 *ident_bufp = ident_buf;
2173 ataidentify(struct cam_device *device, int retry_count, int timeout)
2176 struct ata_params *ident_buf;
2179 if ((ccb = cam_getccb(device)) == NULL) {
2180 warnx("couldn't allocate CCB");
2184 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2189 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2190 if (ata_read_native_max(device, retry_count, timeout, ccb,
2191 ident_buf, &hpasize) != 0) {
2199 printf("%s%d: ", device->device_name, device->dev_unit_num);
2200 ata_print_ident(ident_buf);
2201 camxferrate(device);
2202 atacapprint(ident_buf);
2203 atahpa_print(ident_buf, hpasize, 0);
2210 #endif /* MINIMALISTIC */
2213 #ifndef MINIMALISTIC
2215 ATA_SECURITY_ACTION_PRINT,
2216 ATA_SECURITY_ACTION_FREEZE,
2217 ATA_SECURITY_ACTION_UNLOCK,
2218 ATA_SECURITY_ACTION_DISABLE,
2219 ATA_SECURITY_ACTION_ERASE,
2220 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2221 ATA_SECURITY_ACTION_SET_PASSWORD
2225 atasecurity_print_time(u_int16_t tw)
2229 printf("unspecified");
2231 printf("> 508 min");
2233 printf("%i min", 2 * tw);
2237 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2241 return 2 * 3600 * 1000; /* default: two hours */
2242 else if (timeout > 255)
2243 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2245 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2250 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2254 bzero(&cmd, sizeof(cmd));
2255 cmd.command = command;
2256 printf("Issuing %s", ata_op_string(&cmd));
2259 char pass[sizeof(pwd->password)+1];
2261 /* pwd->password may not be null terminated */
2262 pass[sizeof(pwd->password)] = '\0';
2263 strncpy(pass, pwd->password, sizeof(pwd->password));
2264 printf(" password='%s', user='%s'",
2266 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2269 if (command == ATA_SECURITY_SET_PASSWORD) {
2270 printf(", mode='%s'",
2271 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2272 "maximum" : "high");
2280 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2281 int retry_count, u_int32_t timeout, int quiet)
2285 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2287 return ata_do_28bit_cmd(device,
2290 /*flags*/CAM_DIR_NONE,
2291 /*protocol*/AP_PROTO_NON_DATA,
2292 /*tag_action*/MSG_SIMPLE_Q_TAG,
2293 /*command*/ATA_SECURITY_FREEZE_LOCK,
2304 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2305 int retry_count, u_int32_t timeout,
2306 struct ata_security_password *pwd, int quiet)
2310 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2312 return ata_do_28bit_cmd(device,
2315 /*flags*/CAM_DIR_OUT,
2316 /*protocol*/AP_PROTO_PIO_OUT,
2317 /*tag_action*/MSG_SIMPLE_Q_TAG,
2318 /*command*/ATA_SECURITY_UNLOCK,
2322 /*data_ptr*/(u_int8_t *)pwd,
2323 /*dxfer_len*/sizeof(*pwd),
2329 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2330 int retry_count, u_int32_t timeout,
2331 struct ata_security_password *pwd, int quiet)
2335 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2336 return ata_do_28bit_cmd(device,
2339 /*flags*/CAM_DIR_OUT,
2340 /*protocol*/AP_PROTO_PIO_OUT,
2341 /*tag_action*/MSG_SIMPLE_Q_TAG,
2342 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2346 /*data_ptr*/(u_int8_t *)pwd,
2347 /*dxfer_len*/sizeof(*pwd),
2354 atasecurity_erase_confirm(struct cam_device *device,
2355 struct ata_params* ident_buf)
2358 printf("\nYou are about to ERASE ALL DATA from the following"
2359 " device:\n%s%d,%s%d: ", device->device_name,
2360 device->dev_unit_num, device->given_dev_name,
2361 device->given_unit_number);
2362 ata_print_ident(ident_buf);
2366 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2368 if (fgets(str, sizeof(str), stdin) != NULL) {
2369 if (strncasecmp(str, "yes", 3) == 0) {
2371 } else if (strncasecmp(str, "no", 2) == 0) {
2374 printf("Please answer \"yes\" or "
2385 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2386 int retry_count, u_int32_t timeout,
2387 u_int32_t erase_timeout,
2388 struct ata_security_password *pwd, int quiet)
2393 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2395 error = ata_do_28bit_cmd(device,
2398 /*flags*/CAM_DIR_NONE,
2399 /*protocol*/AP_PROTO_NON_DATA,
2400 /*tag_action*/MSG_SIMPLE_Q_TAG,
2401 /*command*/ATA_SECURITY_ERASE_PREPARE,
2414 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2416 error = ata_do_28bit_cmd(device,
2419 /*flags*/CAM_DIR_OUT,
2420 /*protocol*/AP_PROTO_PIO_OUT,
2421 /*tag_action*/MSG_SIMPLE_Q_TAG,
2422 /*command*/ATA_SECURITY_ERASE_UNIT,
2426 /*data_ptr*/(u_int8_t *)pwd,
2427 /*dxfer_len*/sizeof(*pwd),
2428 /*timeout*/erase_timeout,
2431 if (error == 0 && quiet == 0)
2432 printf("\nErase Complete\n");
2438 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2439 int retry_count, u_int32_t timeout,
2440 struct ata_security_password *pwd, int quiet)
2444 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2446 return ata_do_28bit_cmd(device,
2449 /*flags*/CAM_DIR_OUT,
2450 /*protocol*/AP_PROTO_PIO_OUT,
2451 /*tag_action*/MSG_SIMPLE_Q_TAG,
2452 /*command*/ATA_SECURITY_SET_PASSWORD,
2456 /*data_ptr*/(u_int8_t *)pwd,
2457 /*dxfer_len*/sizeof(*pwd),
2463 atasecurity_print(struct ata_params *parm)
2466 printf("\nSecurity Option Value\n");
2467 if (arglist & CAM_ARG_VERBOSE) {
2468 printf("status %04x\n",
2469 parm->security_status);
2471 printf("supported %s\n",
2472 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2473 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2475 printf("enabled %s\n",
2476 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2477 printf("drive locked %s\n",
2478 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2479 printf("security config frozen %s\n",
2480 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2481 printf("count expired %s\n",
2482 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2483 printf("security level %s\n",
2484 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2485 printf("enhanced erase supported %s\n",
2486 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2487 printf("erase time ");
2488 atasecurity_print_time(parm->erase_time);
2490 printf("enhanced erase time ");
2491 atasecurity_print_time(parm->enhanced_erase_time);
2493 printf("master password rev %04x%s\n",
2494 parm->master_passwd_revision,
2495 parm->master_passwd_revision == 0x0000 ||
2496 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2500 * Validates and copies the password in optarg to the passed buffer.
2501 * If the password in optarg is the same length as the buffer then
2502 * the data will still be copied but no null termination will occur.
2505 ata_getpwd(u_int8_t *passwd, int max, char opt)
2509 len = strlen(optarg);
2511 warnx("-%c password is too long", opt);
2513 } else if (len == 0) {
2514 warnx("-%c password is missing", opt);
2516 } else if (optarg[0] == '-'){
2517 warnx("-%c password starts with '-' (generic arg?)", opt);
2519 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2520 warnx("-%c password conflicts with existing password from -%c",
2525 /* Callers pass in a buffer which does NOT need to be terminated */
2526 strncpy(passwd, optarg, max);
2533 ATA_HPA_ACTION_PRINT,
2534 ATA_HPA_ACTION_SET_MAX,
2535 ATA_HPA_ACTION_SET_PWD,
2536 ATA_HPA_ACTION_LOCK,
2537 ATA_HPA_ACTION_UNLOCK,
2538 ATA_HPA_ACTION_FREEZE_LOCK
2542 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2543 u_int64_t maxsize, int persist)
2545 printf("\nYou are about to configure HPA to limit the user accessible\n"
2546 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2547 persist ? "persistently" : "temporarily",
2548 device->device_name, device->dev_unit_num,
2549 device->given_dev_name, device->given_unit_number);
2550 ata_print_ident(ident_buf);
2554 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2556 if (NULL != fgets(str, sizeof(str), stdin)) {
2557 if (0 == strncasecmp(str, "yes", 3)) {
2559 } else if (0 == strncasecmp(str, "no", 2)) {
2562 printf("Please answer \"yes\" or "
2573 atahpa(struct cam_device *device, int retry_count, int timeout,
2574 int argc, char **argv, char *combinedopt)
2577 struct ata_params *ident_buf;
2578 struct ccb_getdev cgd;
2579 struct ata_set_max_pwd pwd;
2580 int error, confirm, quiet, c, action, actions, persist;
2581 int security, is48bit, pwdsize;
2582 u_int64_t hpasize, maxsize;
2591 memset(&pwd, 0, sizeof(pwd));
2593 /* default action is to print hpa information */
2594 action = ATA_HPA_ACTION_PRINT;
2595 pwdsize = sizeof(pwd.password);
2597 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2600 action = ATA_HPA_ACTION_SET_MAX;
2601 maxsize = strtoumax(optarg, NULL, 0);
2606 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2608 action = ATA_HPA_ACTION_SET_PWD;
2614 action = ATA_HPA_ACTION_LOCK;
2620 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2622 action = ATA_HPA_ACTION_UNLOCK;
2628 action = ATA_HPA_ACTION_FREEZE_LOCK;
2648 warnx("too many hpa actions specified");
2652 if (get_cgd(device, &cgd) != 0) {
2653 warnx("couldn't get CGD");
2657 ccb = cam_getccb(device);
2659 warnx("couldn't allocate CCB");
2663 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2670 printf("%s%d: ", device->device_name, device->dev_unit_num);
2671 ata_print_ident(ident_buf);
2672 camxferrate(device);
2675 if (action == ATA_HPA_ACTION_PRINT) {
2676 error = ata_read_native_max(device, retry_count, timeout, ccb,
2677 ident_buf, &hpasize);
2679 atahpa_print(ident_buf, hpasize, 1);
2686 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2687 warnx("HPA is not supported by this device");
2693 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2694 warnx("HPA Security is not supported by this device");
2700 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2703 * The ATA spec requires:
2704 * 1. Read native max addr is called directly before set max addr
2705 * 2. Read native max addr is NOT called before any other set max call
2708 case ATA_HPA_ACTION_SET_MAX:
2710 atahpa_set_confirm(device, ident_buf, maxsize,
2717 error = ata_read_native_max(device, retry_count, timeout,
2718 ccb, ident_buf, &hpasize);
2720 error = atahpa_set_max(device, retry_count, timeout,
2721 ccb, is48bit, maxsize, persist);
2723 /* redo identify to get new lba values */
2724 error = ata_do_identify(device, retry_count,
2727 atahpa_print(ident_buf, hpasize, 1);
2732 case ATA_HPA_ACTION_SET_PWD:
2733 error = atahpa_password(device, retry_count, timeout,
2734 ccb, is48bit, &pwd);
2736 printf("HPA password has been set\n");
2739 case ATA_HPA_ACTION_LOCK:
2740 error = atahpa_lock(device, retry_count, timeout,
2743 printf("HPA has been locked\n");
2746 case ATA_HPA_ACTION_UNLOCK:
2747 error = atahpa_unlock(device, retry_count, timeout,
2748 ccb, is48bit, &pwd);
2750 printf("HPA has been unlocked\n");
2753 case ATA_HPA_ACTION_FREEZE_LOCK:
2754 error = atahpa_freeze_lock(device, retry_count, timeout,
2757 printf("HPA has been frozen\n");
2761 errx(1, "Option currently not supported");
2771 atasecurity(struct cam_device *device, int retry_count, int timeout,
2772 int argc, char **argv, char *combinedopt)
2775 struct ata_params *ident_buf;
2776 int error, confirm, quiet, c, action, actions, setpwd;
2777 int security_enabled, erase_timeout, pwdsize;
2778 struct ata_security_password pwd;
2786 memset(&pwd, 0, sizeof(pwd));
2788 /* default action is to print security information */
2789 action = ATA_SECURITY_ACTION_PRINT;
2791 /* user is master by default as its safer that way */
2792 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2793 pwdsize = sizeof(pwd.password);
2795 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2798 action = ATA_SECURITY_ACTION_FREEZE;
2803 if (strcasecmp(optarg, "user") == 0) {
2804 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2805 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2806 } else if (strcasecmp(optarg, "master") == 0) {
2807 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2808 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2810 warnx("-U argument '%s' is invalid (must be "
2811 "'user' or 'master')", optarg);
2817 if (strcasecmp(optarg, "high") == 0) {
2818 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2819 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2820 } else if (strcasecmp(optarg, "maximum") == 0) {
2821 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2822 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2824 warnx("-l argument '%s' is unknown (must be "
2825 "'high' or 'maximum')", optarg);
2831 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2833 action = ATA_SECURITY_ACTION_UNLOCK;
2838 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2840 action = ATA_SECURITY_ACTION_DISABLE;
2845 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2847 action = ATA_SECURITY_ACTION_ERASE;
2852 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2854 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2855 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2860 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2863 if (action == ATA_SECURITY_ACTION_PRINT)
2864 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2866 * Don't increment action as this can be combined
2867 * with other actions.
2880 erase_timeout = atoi(optarg) * 1000;
2886 warnx("too many security actions specified");
2890 if ((ccb = cam_getccb(device)) == NULL) {
2891 warnx("couldn't allocate CCB");
2895 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2902 printf("%s%d: ", device->device_name, device->dev_unit_num);
2903 ata_print_ident(ident_buf);
2904 camxferrate(device);
2907 if (action == ATA_SECURITY_ACTION_PRINT) {
2908 atasecurity_print(ident_buf);
2914 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2915 warnx("Security not supported");
2921 /* default timeout 15 seconds the same as linux hdparm */
2922 timeout = timeout ? timeout : 15 * 1000;
2924 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2926 /* first set the password if requested */
2928 /* confirm we can erase before setting the password if erasing */
2930 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2931 action == ATA_SECURITY_ACTION_ERASE) &&
2932 atasecurity_erase_confirm(device, ident_buf) == 0) {
2938 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2939 pwd.revision = ident_buf->master_passwd_revision;
2940 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2941 --pwd.revision == 0) {
2942 pwd.revision = 0xfffe;
2945 error = atasecurity_set_password(device, ccb, retry_count,
2946 timeout, &pwd, quiet);
2952 security_enabled = 1;
2956 case ATA_SECURITY_ACTION_FREEZE:
2957 error = atasecurity_freeze(device, ccb, retry_count,
2961 case ATA_SECURITY_ACTION_UNLOCK:
2962 if (security_enabled) {
2963 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2964 error = atasecurity_unlock(device, ccb,
2965 retry_count, timeout, &pwd, quiet);
2967 warnx("Can't unlock, drive is not locked");
2971 warnx("Can't unlock, security is disabled");
2976 case ATA_SECURITY_ACTION_DISABLE:
2977 if (security_enabled) {
2978 /* First unlock the drive if its locked */
2979 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2980 error = atasecurity_unlock(device, ccb,
2988 error = atasecurity_disable(device,
2996 warnx("Can't disable security (already disabled)");
3001 case ATA_SECURITY_ACTION_ERASE:
3002 if (security_enabled) {
3003 if (erase_timeout == 0) {
3004 erase_timeout = atasecurity_erase_timeout_msecs(
3005 ident_buf->erase_time);
3008 error = atasecurity_erase(device, ccb, retry_count,
3009 timeout, erase_timeout, &pwd,
3012 warnx("Can't secure erase (security is disabled)");
3017 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3018 if (security_enabled) {
3019 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3020 if (erase_timeout == 0) {
3022 atasecurity_erase_timeout_msecs(
3023 ident_buf->enhanced_erase_time);
3026 error = atasecurity_erase(device, ccb,
3027 retry_count, timeout,
3028 erase_timeout, &pwd,
3031 warnx("Enhanced erase is not supported");
3035 warnx("Can't secure erase (enhanced), "
3036 "(security is disabled)");
3047 #endif /* MINIMALISTIC */
3050 * Parse out a bus, or a bus, target and lun in the following
3056 * Returns the number of parsed components, or 0.
3059 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3060 cam_argmask *arglst)
3065 while (isspace(*tstr) && (*tstr != '\0'))
3068 tmpstr = (char *)strtok(tstr, ":");
3069 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3070 *bus = strtol(tmpstr, NULL, 0);
3071 *arglst |= CAM_ARG_BUS;
3073 tmpstr = (char *)strtok(NULL, ":");
3074 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3075 *target = strtol(tmpstr, NULL, 0);
3076 *arglst |= CAM_ARG_TARGET;
3078 tmpstr = (char *)strtok(NULL, ":");
3079 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3080 *lun = strtol(tmpstr, NULL, 0);
3081 *arglst |= CAM_ARG_LUN;
3091 dorescan_or_reset(int argc, char **argv, int rescan)
3093 static const char must[] =
3094 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3096 path_id_t bus = CAM_BUS_WILDCARD;
3097 target_id_t target = CAM_TARGET_WILDCARD;
3098 lun_id_t lun = CAM_LUN_WILDCARD;
3102 warnx(must, rescan? "rescan" : "reset");
3106 tstr = argv[optind];
3107 while (isspace(*tstr) && (*tstr != '\0'))
3109 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3110 arglist |= CAM_ARG_BUS;
3112 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3113 if (rv != 1 && rv != 3) {
3114 warnx(must, rescan? "rescan" : "reset");
3119 if ((arglist & CAM_ARG_BUS)
3120 && (arglist & CAM_ARG_TARGET)
3121 && (arglist & CAM_ARG_LUN))
3122 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3124 error = rescan_or_reset_bus(bus, rescan);
3130 rescan_or_reset_bus(path_id_t bus, int rescan)
3132 union ccb *ccb = NULL, *matchccb = NULL;
3133 int fd = -1, retval;
3138 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3139 warnx("error opening transport layer device %s", XPT_DEVICE);
3140 warn("%s", XPT_DEVICE);
3144 ccb = malloc(sizeof(*ccb));
3146 warn("failed to allocate CCB");
3150 bzero(ccb, sizeof(*ccb));
3152 if (bus != CAM_BUS_WILDCARD) {
3153 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3154 ccb->ccb_h.path_id = bus;
3155 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3156 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3157 ccb->crcn.flags = CAM_FLAG_NONE;
3159 /* run this at a low priority */
3160 ccb->ccb_h.pinfo.priority = 5;
3162 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3163 warn("CAMIOCOMMAND ioctl failed");
3168 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3169 fprintf(stdout, "%s of bus %d was successful\n",
3170 rescan ? "Re-scan" : "Reset", bus);
3172 fprintf(stdout, "%s of bus %d returned error %#x\n",
3173 rescan ? "Re-scan" : "Reset", bus,
3174 ccb->ccb_h.status & CAM_STATUS_MASK);
3183 * The right way to handle this is to modify the xpt so that it can
3184 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3185 * that isn't implemented, so instead we enumerate the busses and
3186 * send the rescan or reset to those busses in the case where the
3187 * given bus is -1 (wildcard). We don't send a rescan or reset
3188 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3189 * no-op, sending a rescan to the xpt bus would result in a status of
3192 matchccb = malloc(sizeof(*matchccb));
3193 if (matchccb == NULL) {
3194 warn("failed to allocate CCB");
3198 bzero(matchccb, sizeof(*matchccb));
3199 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3200 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3201 bufsize = sizeof(struct dev_match_result) * 20;
3202 matchccb->cdm.match_buf_len = bufsize;
3203 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3204 if (matchccb->cdm.matches == NULL) {
3205 warnx("can't malloc memory for matches");
3209 matchccb->cdm.num_matches = 0;
3211 matchccb->cdm.num_patterns = 1;
3212 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3214 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3215 matchccb->cdm.pattern_buf_len);
3216 if (matchccb->cdm.patterns == NULL) {
3217 warnx("can't malloc memory for patterns");
3221 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3222 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3227 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3228 warn("CAMIOCOMMAND ioctl failed");
3233 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3234 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3235 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3236 warnx("got CAM error %#x, CDM error %d\n",
3237 matchccb->ccb_h.status, matchccb->cdm.status);
3242 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3243 struct bus_match_result *bus_result;
3245 /* This shouldn't happen. */
3246 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3249 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3252 * We don't want to rescan or reset the xpt bus.
3255 if (bus_result->path_id == CAM_XPT_PATH_ID)
3258 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3260 ccb->ccb_h.path_id = bus_result->path_id;
3261 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3262 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3263 ccb->crcn.flags = CAM_FLAG_NONE;
3265 /* run this at a low priority */
3266 ccb->ccb_h.pinfo.priority = 5;
3268 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3269 warn("CAMIOCOMMAND ioctl failed");
3274 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3275 fprintf(stdout, "%s of bus %d was successful\n",
3276 rescan? "Re-scan" : "Reset",
3277 bus_result->path_id);
3280 * Don't bail out just yet, maybe the other
3281 * rescan or reset commands will complete
3284 fprintf(stderr, "%s of bus %d returned error "
3285 "%#x\n", rescan? "Re-scan" : "Reset",
3286 bus_result->path_id,
3287 ccb->ccb_h.status & CAM_STATUS_MASK);
3291 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3292 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3299 if (matchccb != NULL) {
3300 free(matchccb->cdm.patterns);
3301 free(matchccb->cdm.matches);
3310 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3313 struct cam_device *device;
3318 if (bus == CAM_BUS_WILDCARD) {
3319 warnx("invalid bus number %d", bus);
3323 if (target == CAM_TARGET_WILDCARD) {
3324 warnx("invalid target number %d", target);
3328 if (lun == CAM_LUN_WILDCARD) {
3329 warnx("invalid lun number %jx", (uintmax_t)lun);
3335 bzero(&ccb, sizeof(union ccb));
3338 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3339 warnx("error opening transport layer device %s\n",
3341 warn("%s", XPT_DEVICE);
3345 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3346 if (device == NULL) {
3347 warnx("%s", cam_errbuf);
3352 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3353 ccb.ccb_h.path_id = bus;
3354 ccb.ccb_h.target_id = target;
3355 ccb.ccb_h.target_lun = lun;
3356 ccb.ccb_h.timeout = 5000;
3357 ccb.crcn.flags = CAM_FLAG_NONE;
3359 /* run this at a low priority */
3360 ccb.ccb_h.pinfo.priority = 5;
3363 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3364 warn("CAMIOCOMMAND ioctl failed");
3369 if (cam_send_ccb(device, &ccb) < 0) {
3370 warn("error sending XPT_RESET_DEV CCB");
3371 cam_close_device(device);
3379 cam_close_device(device);
3382 * An error code of CAM_BDR_SENT is normal for a BDR request.
3384 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3386 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3387 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3388 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3391 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3392 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3393 ccb.ccb_h.status & CAM_STATUS_MASK);
3398 #ifndef MINIMALISTIC
3400 static struct scsi_nv defect_list_type_map[] = {
3401 { "block", SRDD10_BLOCK_FORMAT },
3402 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3403 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3404 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3405 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3406 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3410 readdefects(struct cam_device *device, int argc, char **argv,
3411 char *combinedopt, int retry_count, int timeout)
3413 union ccb *ccb = NULL;
3414 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3415 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3416 size_t hdr_size = 0, entry_size = 0;
3419 u_int8_t *defect_list = NULL;
3420 u_int8_t list_format = 0;
3421 int list_type_set = 0;
3422 u_int32_t dlist_length = 0;
3423 u_int32_t returned_length = 0, valid_len = 0;
3424 u_int32_t num_returned = 0, num_valid = 0;
3425 u_int32_t max_possible_size = 0, hdr_max = 0;
3426 u_int32_t starting_offset = 0;
3427 u_int8_t returned_format, returned_type;
3429 int summary = 0, quiet = 0;
3431 int lists_specified = 0;
3432 int get_length = 1, first_pass = 1;
3435 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3439 scsi_nv_status status;
3442 status = scsi_get_nv(defect_list_type_map,
3443 sizeof(defect_list_type_map) /
3444 sizeof(defect_list_type_map[0]), optarg,
3445 &entry_num, SCSI_NV_FLAG_IG_CASE);
3447 if (status == SCSI_NV_FOUND) {
3448 list_format = defect_list_type_map[
3452 warnx("%s: %s %s option %s", __func__,
3453 (status == SCSI_NV_AMBIGUOUS) ?
3454 "ambiguous" : "invalid", "defect list type",
3457 goto defect_bailout;
3462 arglist |= CAM_ARG_GLIST;
3465 arglist |= CAM_ARG_PLIST;
3476 starting_offset = strtoul(optarg, &endptr, 0);
3477 if (*endptr != '\0') {
3479 warnx("invalid starting offset %s", optarg);
3480 goto defect_bailout;
3492 if (list_type_set == 0) {
3494 warnx("no defect list format specified");
3495 goto defect_bailout;
3498 if (arglist & CAM_ARG_PLIST) {
3499 list_format |= SRDD10_PLIST;
3503 if (arglist & CAM_ARG_GLIST) {
3504 list_format |= SRDD10_GLIST;
3509 * This implies a summary, and was the previous behavior.
3511 if (lists_specified == 0)
3514 ccb = cam_getccb(device);
3519 * We start off asking for just the header to determine how much
3520 * defect data is available. Some Hitachi drives return an error
3521 * if you ask for more data than the drive has. Once we know the
3522 * length, we retry the command with the returned length.
3524 if (use_12byte == 0)
3525 dlist_length = sizeof(*hdr10);
3527 dlist_length = sizeof(*hdr12);
3530 if (defect_list != NULL) {
3534 defect_list = malloc(dlist_length);
3535 if (defect_list == NULL) {
3536 warnx("can't malloc memory for defect list");
3538 goto defect_bailout;
3542 bzero(defect_list, dlist_length);
3545 * cam_getccb() zeros the CCB header only. So we need to zero the
3546 * payload portion of the ccb.
3548 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3550 scsi_read_defects(&ccb->csio,
3551 /*retries*/ retry_count,
3553 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3554 /*list_format*/ list_format,
3555 /*addr_desc_index*/ starting_offset,
3556 /*data_ptr*/ defect_list,
3557 /*dxfer_len*/ dlist_length,
3558 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3559 /*sense_len*/ SSD_FULL_SIZE,
3560 /*timeout*/ timeout ? timeout : 5000);
3562 /* Disable freezing the device queue */
3563 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3565 if (cam_send_ccb(device, ccb) < 0) {
3566 perror("error reading defect list");
3568 if (arglist & CAM_ARG_VERBOSE) {
3569 cam_error_print(device, ccb, CAM_ESF_ALL,
3570 CAM_EPF_ALL, stderr);
3574 goto defect_bailout;
3577 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3579 if (use_12byte == 0) {
3580 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3581 hdr_size = sizeof(*hdr10);
3582 hdr_max = SRDDH10_MAX_LENGTH;
3584 if (valid_len >= hdr_size) {
3585 returned_length = scsi_2btoul(hdr10->length);
3586 returned_format = hdr10->format;
3588 returned_length = 0;
3589 returned_format = 0;
3592 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3593 hdr_size = sizeof(*hdr12);
3594 hdr_max = SRDDH12_MAX_LENGTH;
3596 if (valid_len >= hdr_size) {
3597 returned_length = scsi_4btoul(hdr12->length);
3598 returned_format = hdr12->format;
3600 returned_length = 0;
3601 returned_format = 0;
3605 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3606 switch (returned_type) {
3607 case SRDD10_BLOCK_FORMAT:
3608 entry_size = sizeof(struct scsi_defect_desc_block);
3610 case SRDD10_LONG_BLOCK_FORMAT:
3611 entry_size = sizeof(struct scsi_defect_desc_long_block);
3613 case SRDD10_EXT_PHYS_FORMAT:
3614 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3615 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3617 case SRDD10_EXT_BFI_FORMAT:
3618 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3619 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3622 warnx("Unknown defect format 0x%x\n", returned_type);
3624 goto defect_bailout;
3628 max_possible_size = (hdr_max / entry_size) * entry_size;
3629 num_returned = returned_length / entry_size;
3630 num_valid = min(returned_length, valid_len - hdr_size);
3631 num_valid /= entry_size;
3633 if (get_length != 0) {
3636 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3637 CAM_SCSI_STATUS_ERROR) {
3638 struct scsi_sense_data *sense;
3639 int error_code, sense_key, asc, ascq;
3641 sense = &ccb->csio.sense_data;
3642 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3643 ccb->csio.sense_resid, &error_code, &sense_key,
3644 &asc, &ascq, /*show_errors*/ 1);
3647 * If the drive is reporting that it just doesn't
3648 * support the defect list format, go ahead and use
3649 * the length it reported. Otherwise, the length
3650 * may not be valid, so use the maximum.
3652 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3653 && (asc == 0x1c) && (ascq == 0x00)
3654 && (returned_length > 0)) {
3655 if ((use_12byte == 0)
3656 && (returned_length >= max_possible_size)) {
3661 dlist_length = returned_length + hdr_size;
3662 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3663 && (asc == 0x1f) && (ascq == 0x00)
3664 && (returned_length > 0)) {
3665 /* Partial defect list transfer */
3667 * Hitachi drives return this error
3668 * along with a partial defect list if they
3669 * have more defects than the 10 byte
3670 * command can support. Retry with the 12
3673 if (use_12byte == 0) {
3678 dlist_length = returned_length + hdr_size;
3679 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3680 && (asc == 0x24) && (ascq == 0x00)) {
3681 /* Invalid field in CDB */
3683 * SBC-3 says that if the drive has more
3684 * defects than can be reported with the
3685 * 10 byte command, it should return this
3686 * error and no data. Retry with the 12
3689 if (use_12byte == 0) {
3694 dlist_length = returned_length + hdr_size;
3697 * If we got a SCSI error and no valid length,
3698 * just use the 10 byte maximum. The 12
3699 * byte maximum is too large.
3701 if (returned_length == 0)
3702 dlist_length = SRDD10_MAX_LENGTH;
3704 if ((use_12byte == 0)
3705 && (returned_length >=
3706 max_possible_size)) {
3711 dlist_length = returned_length +
3715 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3718 warnx("Error reading defect header");
3719 if (arglist & CAM_ARG_VERBOSE)
3720 cam_error_print(device, ccb, CAM_ESF_ALL,
3721 CAM_EPF_ALL, stderr);
3722 goto defect_bailout;
3724 if ((use_12byte == 0)
3725 && (returned_length >= max_possible_size)) {
3730 dlist_length = returned_length + hdr_size;
3733 fprintf(stdout, "%u", num_returned);
3735 fprintf(stdout, " defect%s",
3736 (num_returned != 1) ? "s" : "");
3738 fprintf(stdout, "\n");
3740 goto defect_bailout;
3744 * We always limit the list length to the 10-byte maximum
3745 * length (0xffff). The reason is that some controllers
3746 * can't handle larger I/Os, and we can transfer the entire
3747 * 10 byte list in one shot. For drives that support the 12
3748 * byte read defects command, we'll step through the list
3749 * by specifying a starting offset. For drives that don't
3750 * support the 12 byte command's starting offset, we'll
3751 * just display the first 64K.
3753 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3759 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3760 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3761 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3762 struct scsi_sense_data *sense;
3763 int error_code, sense_key, asc, ascq;
3765 sense = &ccb->csio.sense_data;
3766 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3767 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3768 &ascq, /*show_errors*/ 1);
3771 * According to the SCSI spec, if the disk doesn't support
3772 * the requested format, it will generally return a sense
3773 * key of RECOVERED ERROR, and an additional sense code
3774 * of "DEFECT LIST NOT FOUND". HGST drives also return
3775 * Primary/Grown defect list not found errors. So just
3776 * check for an ASC of 0x1c.
3778 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3780 const char *format_str;
3782 format_str = scsi_nv_to_str(defect_list_type_map,
3783 sizeof(defect_list_type_map) /
3784 sizeof(defect_list_type_map[0]),
3785 list_format & SRDD10_DLIST_FORMAT_MASK);
3786 warnx("requested defect format %s not available",
3787 format_str ? format_str : "unknown");
3789 format_str = scsi_nv_to_str(defect_list_type_map,
3790 sizeof(defect_list_type_map) /
3791 sizeof(defect_list_type_map[0]), returned_type);
3792 if (format_str != NULL) {
3793 warnx("Device returned %s format",
3797 warnx("Device returned unknown defect"
3798 " data format %#x", returned_type);
3799 goto defect_bailout;
3803 warnx("Error returned from read defect data command");
3804 if (arglist & CAM_ARG_VERBOSE)
3805 cam_error_print(device, ccb, CAM_ESF_ALL,
3806 CAM_EPF_ALL, stderr);
3807 goto defect_bailout;
3809 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3811 warnx("Error returned from read defect data command");
3812 if (arglist & CAM_ARG_VERBOSE)
3813 cam_error_print(device, ccb, CAM_ESF_ALL,
3814 CAM_EPF_ALL, stderr);
3815 goto defect_bailout;
3818 if (first_pass != 0) {
3819 fprintf(stderr, "Got %d defect", num_returned);
3821 if ((lists_specified == 0) || (num_returned == 0)) {
3822 fprintf(stderr, "s.\n");
3823 goto defect_bailout;
3824 } else if (num_returned == 1)
3825 fprintf(stderr, ":\n");
3827 fprintf(stderr, "s:\n");
3833 * XXX KDM I should probably clean up the printout format for the
3836 switch (returned_type) {
3837 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3838 case SRDD10_EXT_PHYS_FORMAT:
3840 struct scsi_defect_desc_phys_sector *dlist;
3842 dlist = (struct scsi_defect_desc_phys_sector *)
3843 (defect_list + hdr_size);
3845 for (i = 0; i < num_valid; i++) {
3848 sector = scsi_4btoul(dlist[i].sector);
3849 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3850 mads = (sector & SDD_EXT_PHYS_MADS) ?
3852 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3854 if (hex_format == 0)
3855 fprintf(stdout, "%d:%d:%d%s",
3856 scsi_3btoul(dlist[i].cylinder),
3858 scsi_4btoul(dlist[i].sector),
3859 mads ? " - " : "\n");
3861 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3862 scsi_3btoul(dlist[i].cylinder),
3864 scsi_4btoul(dlist[i].sector),
3865 mads ? " - " : "\n");
3868 if (num_valid < num_returned) {
3869 starting_offset += num_valid;
3874 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3875 case SRDD10_EXT_BFI_FORMAT:
3877 struct scsi_defect_desc_bytes_from_index *dlist;
3879 dlist = (struct scsi_defect_desc_bytes_from_index *)
3880 (defect_list + hdr_size);
3882 for (i = 0; i < num_valid; i++) {
3885 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3886 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3887 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3888 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3890 if (hex_format == 0)
3891 fprintf(stdout, "%d:%d:%d%s",
3892 scsi_3btoul(dlist[i].cylinder),
3894 scsi_4btoul(dlist[i].bytes_from_index),
3895 mads ? " - " : "\n");
3897 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3898 scsi_3btoul(dlist[i].cylinder),
3900 scsi_4btoul(dlist[i].bytes_from_index),
3901 mads ? " - " : "\n");
3905 if (num_valid < num_returned) {
3906 starting_offset += num_valid;
3911 case SRDDH10_BLOCK_FORMAT:
3913 struct scsi_defect_desc_block *dlist;
3915 dlist = (struct scsi_defect_desc_block *)
3916 (defect_list + hdr_size);
3918 for (i = 0; i < num_valid; i++) {
3919 if (hex_format == 0)
3920 fprintf(stdout, "%u\n",
3921 scsi_4btoul(dlist[i].address));
3923 fprintf(stdout, "0x%x\n",
3924 scsi_4btoul(dlist[i].address));
3927 if (num_valid < num_returned) {
3928 starting_offset += num_valid;
3934 case SRDD10_LONG_BLOCK_FORMAT:
3936 struct scsi_defect_desc_long_block *dlist;
3938 dlist = (struct scsi_defect_desc_long_block *)
3939 (defect_list + hdr_size);
3941 for (i = 0; i < num_valid; i++) {
3942 if (hex_format == 0)
3943 fprintf(stdout, "%ju\n",
3944 (uintmax_t)scsi_8btou64(
3947 fprintf(stdout, "0x%jx\n",
3948 (uintmax_t)scsi_8btou64(
3952 if (num_valid < num_returned) {
3953 starting_offset += num_valid;
3959 fprintf(stderr, "Unknown defect format 0x%x\n",
3966 if (defect_list != NULL)
3974 #endif /* MINIMALISTIC */
3978 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3982 ccb = cam_getccb(device);
3988 #ifndef MINIMALISTIC
3990 mode_sense(struct cam_device *device, int mode_page, int page_control,
3991 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3996 ccb = cam_getccb(device);
3999 errx(1, "mode_sense: couldn't allocate CCB");
4001 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4003 scsi_mode_sense(&ccb->csio,
4004 /* retries */ retry_count,
4006 /* tag_action */ MSG_SIMPLE_Q_TAG,
4008 /* page_code */ page_control << 6,
4009 /* page */ mode_page,
4010 /* param_buf */ data,
4011 /* param_len */ datalen,
4012 /* sense_len */ SSD_FULL_SIZE,
4013 /* timeout */ timeout ? timeout : 5000);
4015 if (arglist & CAM_ARG_ERR_RECOVER)
4016 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4018 /* Disable freezing the device queue */
4019 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4021 if (((retval = cam_send_ccb(device, ccb)) < 0)
4022 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4023 if (arglist & CAM_ARG_VERBOSE) {
4024 cam_error_print(device, ccb, CAM_ESF_ALL,
4025 CAM_EPF_ALL, stderr);
4028 cam_close_device(device);
4030 err(1, "error sending mode sense command");
4032 errx(1, "error sending mode sense command");
4039 mode_select(struct cam_device *device, int save_pages, int retry_count,
4040 int timeout, u_int8_t *data, int datalen)
4045 ccb = cam_getccb(device);
4048 errx(1, "mode_select: couldn't allocate CCB");
4050 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4052 scsi_mode_select(&ccb->csio,
4053 /* retries */ retry_count,
4055 /* tag_action */ MSG_SIMPLE_Q_TAG,
4056 /* scsi_page_fmt */ 1,
4057 /* save_pages */ save_pages,
4058 /* param_buf */ data,
4059 /* param_len */ datalen,
4060 /* sense_len */ SSD_FULL_SIZE,
4061 /* timeout */ timeout ? timeout : 5000);
4063 if (arglist & CAM_ARG_ERR_RECOVER)
4064 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4066 /* Disable freezing the device queue */
4067 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4069 if (((retval = cam_send_ccb(device, ccb)) < 0)
4070 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4071 if (arglist & CAM_ARG_VERBOSE) {
4072 cam_error_print(device, ccb, CAM_ESF_ALL,
4073 CAM_EPF_ALL, stderr);
4076 cam_close_device(device);
4079 err(1, "error sending mode select command");
4081 errx(1, "error sending mode select command");
4089 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4090 int retry_count, int timeout)
4092 int c, mode_page = -1, page_control = 0;
4093 int binary = 0, list = 0;
4095 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4101 arglist |= CAM_ARG_DBD;
4104 arglist |= CAM_ARG_MODE_EDIT;
4110 mode_page = strtol(optarg, NULL, 0);
4112 errx(1, "invalid mode page %d", mode_page);
4115 page_control = strtol(optarg, NULL, 0);
4116 if ((page_control < 0) || (page_control > 3))
4117 errx(1, "invalid page control field %d",
4119 arglist |= CAM_ARG_PAGE_CNTL;
4126 if (mode_page == -1 && list == 0)
4127 errx(1, "you must specify a mode page!");
4130 mode_list(device, page_control, arglist & CAM_ARG_DBD,
4131 retry_count, timeout);
4133 mode_edit(device, mode_page, page_control,
4134 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
4135 retry_count, timeout);
4140 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4141 int retry_count, int timeout)
4144 u_int32_t flags = CAM_DIR_NONE;
4145 u_int8_t *data_ptr = NULL;
4147 u_int8_t atacmd[12];
4148 struct get_hook hook;
4149 int c, data_bytes = 0;
4155 char *datastr = NULL, *tstr, *resstr = NULL;
4157 int fd_data = 0, fd_res = 0;
4160 ccb = cam_getccb(device);
4163 warnx("scsicmd: error allocating ccb");
4167 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4169 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4173 while (isspace(*tstr) && (*tstr != '\0'))
4175 hook.argc = argc - optind;
4176 hook.argv = argv + optind;
4178 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4181 * Increment optind by the number of arguments the
4182 * encoding routine processed. After each call to
4183 * getopt(3), optind points to the argument that
4184 * getopt should process _next_. In this case,
4185 * that means it points to the first command string
4186 * argument, if there is one. Once we increment
4187 * this, it should point to either the next command
4188 * line argument, or it should be past the end of
4195 while (isspace(*tstr) && (*tstr != '\0'))
4197 hook.argc = argc - optind;
4198 hook.argv = argv + optind;
4200 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4203 * Increment optind by the number of arguments the
4204 * encoding routine processed. After each call to
4205 * getopt(3), optind points to the argument that
4206 * getopt should process _next_. In this case,
4207 * that means it points to the first command string
4208 * argument, if there is one. Once we increment
4209 * this, it should point to either the next command
4210 * line argument, or it should be past the end of
4222 if (arglist & CAM_ARG_CMD_OUT) {
4223 warnx("command must either be "
4224 "read or write, not both");
4226 goto scsicmd_bailout;
4228 arglist |= CAM_ARG_CMD_IN;
4230 data_bytes = strtol(optarg, NULL, 0);
4231 if (data_bytes <= 0) {
4232 warnx("invalid number of input bytes %d",
4235 goto scsicmd_bailout;
4237 hook.argc = argc - optind;
4238 hook.argv = argv + optind;
4241 datastr = cget(&hook, NULL);
4243 * If the user supplied "-" instead of a format, he
4244 * wants the data to be written to stdout.
4246 if ((datastr != NULL)
4247 && (datastr[0] == '-'))
4250 data_ptr = (u_int8_t *)malloc(data_bytes);
4251 if (data_ptr == NULL) {
4252 warnx("can't malloc memory for data_ptr");
4254 goto scsicmd_bailout;
4258 if (arglist & CAM_ARG_CMD_IN) {
4259 warnx("command must either be "
4260 "read or write, not both");
4262 goto scsicmd_bailout;
4264 arglist |= CAM_ARG_CMD_OUT;
4265 flags = CAM_DIR_OUT;
4266 data_bytes = strtol(optarg, NULL, 0);
4267 if (data_bytes <= 0) {
4268 warnx("invalid number of output bytes %d",
4271 goto scsicmd_bailout;
4273 hook.argc = argc - optind;
4274 hook.argv = argv + optind;
4276 datastr = cget(&hook, NULL);
4277 data_ptr = (u_int8_t *)malloc(data_bytes);
4278 if (data_ptr == NULL) {
4279 warnx("can't malloc memory for data_ptr");
4281 goto scsicmd_bailout;
4283 bzero(data_ptr, data_bytes);
4285 * If the user supplied "-" instead of a format, he
4286 * wants the data to be read from stdin.
4288 if ((datastr != NULL)
4289 && (datastr[0] == '-'))
4292 buff_encode_visit(data_ptr, data_bytes, datastr,
4298 hook.argc = argc - optind;
4299 hook.argv = argv + optind;
4301 resstr = cget(&hook, NULL);
4302 if ((resstr != NULL) && (resstr[0] == '-'))
4312 * If fd_data is set, and we're writing to the device, we need to
4313 * read the data the user wants written from stdin.
4315 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4317 int amt_to_read = data_bytes;
4318 u_int8_t *buf_ptr = data_ptr;
4320 for (amt_read = 0; amt_to_read > 0;
4321 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4322 if (amt_read == -1) {
4323 warn("error reading data from stdin");
4325 goto scsicmd_bailout;
4327 amt_to_read -= amt_read;
4328 buf_ptr += amt_read;
4332 if (arglist & CAM_ARG_ERR_RECOVER)
4333 flags |= CAM_PASS_ERR_RECOVER;
4335 /* Disable freezing the device queue */
4336 flags |= CAM_DEV_QFRZDIS;
4340 * This is taken from the SCSI-3 draft spec.
4341 * (T10/1157D revision 0.3)
4342 * The top 3 bits of an opcode are the group code.
4343 * The next 5 bits are the command code.
4344 * Group 0: six byte commands
4345 * Group 1: ten byte commands
4346 * Group 2: ten byte commands
4348 * Group 4: sixteen byte commands
4349 * Group 5: twelve byte commands
4350 * Group 6: vendor specific
4351 * Group 7: vendor specific
4353 switch((cdb[0] >> 5) & 0x7) {
4364 /* computed by buff_encode_visit */
4375 * We should probably use csio_build_visit or something like that
4376 * here, but it's easier to encode arguments as you go. The
4377 * alternative would be skipping the CDB argument and then encoding
4378 * it here, since we've got the data buffer argument by now.
4380 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4382 cam_fill_csio(&ccb->csio,
4383 /*retries*/ retry_count,
4386 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4387 /*data_ptr*/ data_ptr,
4388 /*dxfer_len*/ data_bytes,
4389 /*sense_len*/ SSD_FULL_SIZE,
4390 /*cdb_len*/ cdb_len,
4391 /*timeout*/ timeout ? timeout : 5000);
4394 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4396 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4398 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4400 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4402 cam_fill_ataio(&ccb->ataio,
4403 /*retries*/ retry_count,
4407 /*data_ptr*/ data_ptr,
4408 /*dxfer_len*/ data_bytes,
4409 /*timeout*/ timeout ? timeout : 5000);
4412 if (((retval = cam_send_ccb(device, ccb)) < 0)
4413 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4414 const char warnstr[] = "error sending command";
4421 if (arglist & CAM_ARG_VERBOSE) {
4422 cam_error_print(device, ccb, CAM_ESF_ALL,
4423 CAM_EPF_ALL, stderr);
4427 goto scsicmd_bailout;
4430 if (atacmd_len && need_res) {
4432 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4434 fprintf(stdout, "\n");
4437 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4438 ccb->ataio.res.status,
4439 ccb->ataio.res.error,
4440 ccb->ataio.res.lba_low,
4441 ccb->ataio.res.lba_mid,
4442 ccb->ataio.res.lba_high,
4443 ccb->ataio.res.device,
4444 ccb->ataio.res.lba_low_exp,
4445 ccb->ataio.res.lba_mid_exp,
4446 ccb->ataio.res.lba_high_exp,
4447 ccb->ataio.res.sector_count,
4448 ccb->ataio.res.sector_count_exp);
4453 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4454 && (arglist & CAM_ARG_CMD_IN)
4455 && (data_bytes > 0)) {
4457 buff_decode_visit(data_ptr, data_bytes, datastr,
4459 fprintf(stdout, "\n");
4461 ssize_t amt_written;
4462 int amt_to_write = data_bytes;
4463 u_int8_t *buf_ptr = data_ptr;
4465 for (amt_written = 0; (amt_to_write > 0) &&
4466 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4467 amt_to_write -= amt_written;
4468 buf_ptr += amt_written;
4470 if (amt_written == -1) {
4471 warn("error writing data to stdout");
4473 goto scsicmd_bailout;
4474 } else if ((amt_written == 0)
4475 && (amt_to_write > 0)) {
4476 warnx("only wrote %u bytes out of %u",
4477 data_bytes - amt_to_write, data_bytes);
4484 if ((data_bytes > 0) && (data_ptr != NULL))
4493 camdebug(int argc, char **argv, char *combinedopt)
4496 path_id_t bus = CAM_BUS_WILDCARD;
4497 target_id_t target = CAM_TARGET_WILDCARD;
4498 lun_id_t lun = CAM_LUN_WILDCARD;
4499 char *tstr, *tmpstr = NULL;
4503 bzero(&ccb, sizeof(union ccb));
4505 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4508 arglist |= CAM_ARG_DEBUG_INFO;
4509 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4512 arglist |= CAM_ARG_DEBUG_PERIPH;
4513 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4516 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4517 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4520 arglist |= CAM_ARG_DEBUG_TRACE;
4521 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4524 arglist |= CAM_ARG_DEBUG_XPT;
4525 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4528 arglist |= CAM_ARG_DEBUG_CDB;
4529 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4532 arglist |= CAM_ARG_DEBUG_PROBE;
4533 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4540 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4541 warnx("error opening transport layer device %s", XPT_DEVICE);
4542 warn("%s", XPT_DEVICE);
4549 warnx("you must specify \"off\", \"all\" or a bus,");
4550 warnx("bus:target, or bus:target:lun");
4557 while (isspace(*tstr) && (*tstr != '\0'))
4560 if (strncmp(tstr, "off", 3) == 0) {
4561 ccb.cdbg.flags = CAM_DEBUG_NONE;
4562 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4563 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4564 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4565 } else if (strncmp(tstr, "all", 3) != 0) {
4566 tmpstr = (char *)strtok(tstr, ":");
4567 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4568 bus = strtol(tmpstr, NULL, 0);
4569 arglist |= CAM_ARG_BUS;
4570 tmpstr = (char *)strtok(NULL, ":");
4571 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4572 target = strtol(tmpstr, NULL, 0);
4573 arglist |= CAM_ARG_TARGET;
4574 tmpstr = (char *)strtok(NULL, ":");
4575 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4576 lun = strtol(tmpstr, NULL, 0);
4577 arglist |= CAM_ARG_LUN;
4582 warnx("you must specify \"all\", \"off\", or a bus,");
4583 warnx("bus:target, or bus:target:lun to debug");
4589 ccb.ccb_h.func_code = XPT_DEBUG;
4590 ccb.ccb_h.path_id = bus;
4591 ccb.ccb_h.target_id = target;
4592 ccb.ccb_h.target_lun = lun;
4594 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4595 warn("CAMIOCOMMAND ioctl failed");
4600 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4601 CAM_FUNC_NOTAVAIL) {
4602 warnx("CAM debugging not available");
4603 warnx("you need to put options CAMDEBUG in"
4604 " your kernel config file!");
4606 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4608 warnx("XPT_DEBUG CCB failed with status %#x",
4612 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4614 "Debugging turned off\n");
4617 "Debugging enabled for "
4619 bus, target, (uintmax_t)lun);
4630 tagcontrol(struct cam_device *device, int argc, char **argv,
4640 ccb = cam_getccb(device);
4643 warnx("tagcontrol: error allocating ccb");
4647 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4650 numtags = strtol(optarg, NULL, 0);
4652 warnx("tag count %d is < 0", numtags);
4654 goto tagcontrol_bailout;
4665 cam_path_string(device, pathstr, sizeof(pathstr));
4668 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4669 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4670 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4671 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4672 ccb->crs.openings = numtags;
4675 if (cam_send_ccb(device, ccb) < 0) {
4676 perror("error sending XPT_REL_SIMQ CCB");
4678 goto tagcontrol_bailout;
4681 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4682 warnx("XPT_REL_SIMQ CCB failed");
4683 cam_error_print(device, ccb, CAM_ESF_ALL,
4684 CAM_EPF_ALL, stderr);
4686 goto tagcontrol_bailout;
4691 fprintf(stdout, "%stagged openings now %d\n",
4692 pathstr, ccb->crs.openings);
4695 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4697 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4699 if (cam_send_ccb(device, ccb) < 0) {
4700 perror("error sending XPT_GDEV_STATS CCB");
4702 goto tagcontrol_bailout;
4705 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4706 warnx("XPT_GDEV_STATS CCB failed");
4707 cam_error_print(device, ccb, CAM_ESF_ALL,
4708 CAM_EPF_ALL, stderr);
4710 goto tagcontrol_bailout;
4713 if (arglist & CAM_ARG_VERBOSE) {
4714 fprintf(stdout, "%s", pathstr);
4715 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4716 fprintf(stdout, "%s", pathstr);
4717 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4718 fprintf(stdout, "%s", pathstr);
4719 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4720 fprintf(stdout, "%s", pathstr);
4721 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4722 fprintf(stdout, "%s", pathstr);
4723 fprintf(stdout, "held %d\n", ccb->cgds.held);
4724 fprintf(stdout, "%s", pathstr);
4725 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4726 fprintf(stdout, "%s", pathstr);
4727 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4730 fprintf(stdout, "%s", pathstr);
4731 fprintf(stdout, "device openings: ");
4733 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4734 ccb->cgds.dev_active);
4744 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4748 cam_path_string(device, pathstr, sizeof(pathstr));
4750 if (cts->transport == XPORT_SPI) {
4751 struct ccb_trans_settings_spi *spi =
4752 &cts->xport_specific.spi;
4754 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4756 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4759 if (spi->sync_offset != 0) {
4762 freq = scsi_calc_syncsrate(spi->sync_period);
4763 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4764 pathstr, freq / 1000, freq % 1000);
4768 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4769 fprintf(stdout, "%soffset: %d\n", pathstr,
4773 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4774 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4775 (0x01 << spi->bus_width) * 8);
4778 if (spi->valid & CTS_SPI_VALID_DISC) {
4779 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4780 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4781 "enabled" : "disabled");
4784 if (cts->transport == XPORT_FC) {
4785 struct ccb_trans_settings_fc *fc =
4786 &cts->xport_specific.fc;
4788 if (fc->valid & CTS_FC_VALID_WWNN)
4789 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4790 (long long) fc->wwnn);
4791 if (fc->valid & CTS_FC_VALID_WWPN)
4792 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4793 (long long) fc->wwpn);
4794 if (fc->valid & CTS_FC_VALID_PORT)
4795 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4796 if (fc->valid & CTS_FC_VALID_SPEED)
4797 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4798 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4800 if (cts->transport == XPORT_SAS) {
4801 struct ccb_trans_settings_sas *sas =
4802 &cts->xport_specific.sas;
4804 if (sas->valid & CTS_SAS_VALID_SPEED)
4805 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4806 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4808 if (cts->transport == XPORT_ATA) {
4809 struct ccb_trans_settings_pata *pata =
4810 &cts->xport_specific.ata;
4812 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4813 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4814 ata_mode2string(pata->mode));
4816 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4817 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4820 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4821 fprintf(stdout, "%sPIO transaction length: %d\n",
4822 pathstr, pata->bytecount);
4825 if (cts->transport == XPORT_SATA) {
4826 struct ccb_trans_settings_sata *sata =
4827 &cts->xport_specific.sata;
4829 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4830 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4833 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4834 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4835 ata_mode2string(sata->mode));
4837 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4838 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4841 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4842 fprintf(stdout, "%sPIO transaction length: %d\n",
4843 pathstr, sata->bytecount);
4845 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4846 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4849 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4850 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4853 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4854 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4858 if (cts->protocol == PROTO_ATA) {
4859 struct ccb_trans_settings_ata *ata=
4860 &cts->proto_specific.ata;
4862 if (ata->valid & CTS_ATA_VALID_TQ) {
4863 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4864 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4865 "enabled" : "disabled");
4868 if (cts->protocol == PROTO_SCSI) {
4869 struct ccb_trans_settings_scsi *scsi=
4870 &cts->proto_specific.scsi;
4872 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4873 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4874 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4875 "enabled" : "disabled");
4882 * Get a path inquiry CCB for the specified device.
4885 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4890 ccb = cam_getccb(device);
4892 warnx("get_cpi: couldn't allocate CCB");
4895 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
4896 ccb->ccb_h.func_code = XPT_PATH_INQ;
4897 if (cam_send_ccb(device, ccb) < 0) {
4898 warn("get_cpi: error sending Path Inquiry CCB");
4899 if (arglist & CAM_ARG_VERBOSE)
4900 cam_error_print(device, ccb, CAM_ESF_ALL,
4901 CAM_EPF_ALL, stderr);
4903 goto get_cpi_bailout;
4905 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4906 if (arglist & CAM_ARG_VERBOSE)
4907 cam_error_print(device, ccb, CAM_ESF_ALL,
4908 CAM_EPF_ALL, stderr);
4910 goto get_cpi_bailout;
4912 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4920 * Get a get device CCB for the specified device.
4923 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4928 ccb = cam_getccb(device);
4930 warnx("get_cgd: couldn't allocate CCB");
4933 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
4934 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4935 if (cam_send_ccb(device, ccb) < 0) {
4936 warn("get_cgd: error sending Path Inquiry CCB");
4937 if (arglist & CAM_ARG_VERBOSE)
4938 cam_error_print(device, ccb, CAM_ESF_ALL,
4939 CAM_EPF_ALL, stderr);
4941 goto get_cgd_bailout;
4943 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4944 if (arglist & CAM_ARG_VERBOSE)
4945 cam_error_print(device, ccb, CAM_ESF_ALL,
4946 CAM_EPF_ALL, stderr);
4948 goto get_cgd_bailout;
4950 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4958 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4962 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4963 int timeout, int verbosemode)
4965 union ccb *ccb = NULL;
4966 struct scsi_vpd_supported_page_list sup_pages;
4970 ccb = cam_getccb(dev);
4972 warn("Unable to allocate CCB");
4977 /* cam_getccb cleans up the header, caller has to zero the payload */
4978 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4980 bzero(&sup_pages, sizeof(sup_pages));
4982 scsi_inquiry(&ccb->csio,
4983 /*retries*/ retry_count,
4985 /* tag_action */ MSG_SIMPLE_Q_TAG,
4986 /* inq_buf */ (u_int8_t *)&sup_pages,
4987 /* inq_len */ sizeof(sup_pages),
4989 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
4990 /* sense_len */ SSD_FULL_SIZE,
4991 /* timeout */ timeout ? timeout : 5000);
4993 /* Disable freezing the device queue */
4994 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4996 if (retry_count != 0)
4997 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4999 if (cam_send_ccb(dev, ccb) < 0) {
5006 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5007 if (verbosemode != 0)
5008 cam_error_print(dev, ccb, CAM_ESF_ALL,
5009 CAM_EPF_ALL, stderr);
5014 for (i = 0; i < sup_pages.length; i++) {
5015 if (sup_pages.list[i] == page_id) {
5028 * devtype is filled in with the type of device.
5029 * Returns 0 for success, non-zero for failure.
5032 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5033 int verbosemode, camcontrol_devtype *devtype)
5035 struct ccb_getdev cgd;
5038 retval = get_cgd(dev, &cgd);
5042 switch (cgd.protocol) {
5048 *devtype = CC_DT_ATA;
5050 break; /*NOTREACHED*/
5052 *devtype = CC_DT_UNKNOWN;
5054 break; /*NOTREACHED*/
5058 * Check for the ATA Information VPD page (0x89). If this is an
5059 * ATA device behind a SCSI to ATA translation layer, this VPD page
5060 * should be present.
5062 * If that VPD page isn't present, or we get an error back from the
5063 * INQUIRY command, we'll just treat it as a normal SCSI device.
5065 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5066 timeout, verbosemode);
5068 *devtype = CC_DT_ATA_BEHIND_SCSI;
5070 *devtype = CC_DT_SCSI;
5079 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5080 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5081 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5082 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5083 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5084 int is48bit, camcontrol_devtype devtype)
5088 if (devtype == CC_DT_ATA) {
5089 cam_fill_ataio(&ccb->ataio,
5090 /*retries*/ retry_count,
5093 /*tag_action*/ tag_action,
5094 /*data_ptr*/ data_ptr,
5095 /*dxfer_len*/ dxfer_len,
5096 /*timeout*/ timeout);
5097 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5098 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5101 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5104 if (auxiliary != 0) {
5105 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5106 ccb->ataio.aux = auxiliary;
5109 if (ata_flags & AP_FLAG_CHK_COND)
5110 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5112 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5113 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5114 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5115 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5117 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5118 protocol |= AP_EXTEND;
5120 retval = scsi_ata_pass(&ccb->csio,
5121 /*retries*/ retry_count,
5124 /*tag_action*/ tag_action,
5125 /*protocol*/ protocol,
5126 /*ata_flags*/ ata_flags,
5127 /*features*/ features,
5128 /*sector_count*/ sector_count,
5130 /*command*/ command,
5133 /*auxiliary*/ auxiliary,
5135 /*data_ptr*/ data_ptr,
5136 /*dxfer_len*/ dxfer_len,
5137 /*cdb_storage*/ cdb_storage,
5138 /*cdb_storage_len*/ cdb_storage_len,
5139 /*minimum_cmd_size*/ 0,
5140 /*sense_len*/ sense_len,
5141 /*timeout*/ timeout);
5148 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5149 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5153 switch (ccb->ccb_h.func_code) {
5156 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5159 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5160 * or 16 byte, and need to see what
5162 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5163 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5165 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5166 if ((opcode != ATA_PASS_12)
5167 && (opcode != ATA_PASS_16)) {
5169 warnx("%s: unsupported opcode %02x", __func__, opcode);
5173 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5175 /* Note: the _ccb() variant returns 0 for an error */
5182 switch (error_code) {
5183 case SSD_DESC_CURRENT_ERROR:
5184 case SSD_DESC_DEFERRED_ERROR: {
5185 struct scsi_sense_data_desc *sense;
5186 struct scsi_sense_ata_ret_desc *desc;
5189 sense = (struct scsi_sense_data_desc *)
5190 &ccb->csio.sense_data;
5192 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5193 ccb->csio.sense_resid, SSD_DESC_ATA);
5194 if (desc_ptr == NULL) {
5195 cam_error_print(dev, ccb, CAM_ESF_ALL,
5196 CAM_EPF_ALL, stderr);
5200 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5202 *error = desc->error;
5203 *count = (desc->count_15_8 << 8) |
5205 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5206 ((uint64_t)desc->lba_39_32 << 32) |
5207 ((uint64_t)desc->lba_31_24 << 24) |
5208 (desc->lba_23_16 << 16) |
5209 (desc->lba_15_8 << 8) |
5211 *device = desc->device;
5212 *status = desc->status;
5215 * If the extend bit isn't set, the result is for a
5216 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5217 * command without the extend bit set. This means
5218 * that the device is supposed to return 28-bit
5219 * status. The count field is only 8 bits, and the
5220 * LBA field is only 8 bits.
5222 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5228 case SSD_CURRENT_ERROR:
5229 case SSD_DEFERRED_ERROR: {
5231 struct scsi_sense_data_fixed *sense;
5234 * XXX KDM need to support fixed sense data.
5236 warnx("%s: Fixed sense data not supported yet",
5240 break; /*NOTREACHED*/
5251 struct ata_res *res;
5254 * In this case, we have an ATA command, and we need to
5255 * fill in the requested values from the result register
5258 res = &ccb->ataio.res;
5259 *error = res->error;
5260 *status = res->status;
5261 *device = res->device;
5262 *count = res->sector_count;
5263 *lba = (res->lba_high << 16) |
5264 (res->lba_mid << 8) |
5266 if (res->flags & CAM_ATAIO_48BIT) {
5267 *count |= (res->sector_count_exp << 8);
5268 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5269 ((uint64_t)res->lba_mid_exp << 32) |
5270 ((uint64_t)res->lba_high_exp << 40);
5272 *lba |= (res->device & 0xf) << 24;
5285 cpi_print(struct ccb_pathinq *cpi)
5287 char adapter_str[1024];
5290 snprintf(adapter_str, sizeof(adapter_str),
5291 "%s%d:", cpi->dev_name, cpi->unit_number);
5293 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5296 for (i = 1; i < 0xff; i = i << 1) {
5299 if ((i & cpi->hba_inquiry) == 0)
5302 fprintf(stdout, "%s supports ", adapter_str);
5306 str = "MDP message";
5309 str = "32 bit wide SCSI";
5312 str = "16 bit wide SCSI";
5315 str = "SDTR message";
5318 str = "linked CDBs";
5321 str = "tag queue messages";
5324 str = "soft reset alternative";
5327 str = "SATA Port Multiplier";
5330 str = "unknown PI bit set";
5333 fprintf(stdout, "%s\n", str);
5336 for (i = 1; i < 0xff; i = i << 1) {
5339 if ((i & cpi->hba_misc) == 0)
5342 fprintf(stdout, "%s ", adapter_str);
5346 str = "bus scans from high ID to low ID";
5349 str = "removable devices not included in scan";
5351 case PIM_NOINITIATOR:
5352 str = "initiator role not supported";
5354 case PIM_NOBUSRESET:
5355 str = "user has disabled initial BUS RESET or"
5356 " controller is in target/mixed mode";
5359 str = "do not send 6-byte commands";
5362 str = "scan bus sequentially";
5365 str = "unknown PIM bit set";
5368 fprintf(stdout, "%s\n", str);
5371 for (i = 1; i < 0xff; i = i << 1) {
5374 if ((i & cpi->target_sprt) == 0)
5377 fprintf(stdout, "%s supports ", adapter_str);
5380 str = "target mode processor mode";
5383 str = "target mode phase cog. mode";
5385 case PIT_DISCONNECT:
5386 str = "disconnects in target mode";
5389 str = "terminate I/O message in target mode";
5392 str = "group 6 commands in target mode";
5395 str = "group 7 commands in target mode";
5398 str = "unknown PIT bit set";
5402 fprintf(stdout, "%s\n", str);
5404 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5406 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5408 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5410 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5411 adapter_str, cpi->hpath_id);
5412 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5414 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5415 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5416 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5417 adapter_str, cpi->hba_vendor);
5418 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5419 adapter_str, cpi->hba_device);
5420 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5421 adapter_str, cpi->hba_subvendor);
5422 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5423 adapter_str, cpi->hba_subdevice);
5424 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5425 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5426 if (cpi->base_transfer_speed > 1000)
5427 fprintf(stdout, "%d.%03dMB/sec\n",
5428 cpi->base_transfer_speed / 1000,
5429 cpi->base_transfer_speed % 1000);
5431 fprintf(stdout, "%dKB/sec\n",
5432 (cpi->base_transfer_speed % 1000) * 1000);
5433 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5434 adapter_str, cpi->maxio);
5438 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5439 struct ccb_trans_settings *cts)
5445 ccb = cam_getccb(device);
5448 warnx("get_print_cts: error allocating ccb");
5452 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5454 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5456 if (user_settings == 0)
5457 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5459 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5461 if (cam_send_ccb(device, ccb) < 0) {
5462 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5463 if (arglist & CAM_ARG_VERBOSE)
5464 cam_error_print(device, ccb, CAM_ESF_ALL,
5465 CAM_EPF_ALL, stderr);
5467 goto get_print_cts_bailout;
5470 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5471 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5472 if (arglist & CAM_ARG_VERBOSE)
5473 cam_error_print(device, ccb, CAM_ESF_ALL,
5474 CAM_EPF_ALL, stderr);
5476 goto get_print_cts_bailout;
5480 cts_print(device, &ccb->cts);
5483 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5485 get_print_cts_bailout:
5493 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5494 int argc, char **argv, char *combinedopt)
5498 int user_settings = 0;
5500 int disc_enable = -1, tag_enable = -1;
5503 double syncrate = -1;
5506 int change_settings = 0, send_tur = 0;
5507 struct ccb_pathinq cpi;
5509 ccb = cam_getccb(device);
5511 warnx("ratecontrol: error allocating ccb");
5514 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5523 if (strncasecmp(optarg, "enable", 6) == 0)
5525 else if (strncasecmp(optarg, "disable", 7) == 0)
5528 warnx("-D argument \"%s\" is unknown", optarg);
5530 goto ratecontrol_bailout;
5532 change_settings = 1;
5535 mode = ata_string2mode(optarg);
5537 warnx("unknown mode '%s'", optarg);
5539 goto ratecontrol_bailout;
5541 change_settings = 1;
5544 offset = strtol(optarg, NULL, 0);
5546 warnx("offset value %d is < 0", offset);
5548 goto ratecontrol_bailout;
5550 change_settings = 1;
5556 syncrate = atof(optarg);
5558 warnx("sync rate %f is < 0", syncrate);
5560 goto ratecontrol_bailout;
5562 change_settings = 1;
5565 if (strncasecmp(optarg, "enable", 6) == 0)
5567 else if (strncasecmp(optarg, "disable", 7) == 0)
5570 warnx("-T argument \"%s\" is unknown", optarg);
5572 goto ratecontrol_bailout;
5574 change_settings = 1;
5580 bus_width = strtol(optarg, NULL, 0);
5581 if (bus_width < 0) {
5582 warnx("bus width %d is < 0", bus_width);
5584 goto ratecontrol_bailout;
5586 change_settings = 1;
5592 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5594 * Grab path inquiry information, so we can determine whether
5595 * or not the initiator is capable of the things that the user
5598 ccb->ccb_h.func_code = XPT_PATH_INQ;
5599 if (cam_send_ccb(device, ccb) < 0) {
5600 perror("error sending XPT_PATH_INQ CCB");
5601 if (arglist & CAM_ARG_VERBOSE) {
5602 cam_error_print(device, ccb, CAM_ESF_ALL,
5603 CAM_EPF_ALL, stderr);
5606 goto ratecontrol_bailout;
5608 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5609 warnx("XPT_PATH_INQ CCB failed");
5610 if (arglist & CAM_ARG_VERBOSE) {
5611 cam_error_print(device, ccb, CAM_ESF_ALL,
5612 CAM_EPF_ALL, stderr);
5615 goto ratecontrol_bailout;
5617 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5618 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5620 fprintf(stdout, "%s parameters:\n",
5621 user_settings ? "User" : "Current");
5623 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5625 goto ratecontrol_bailout;
5627 if (arglist & CAM_ARG_VERBOSE)
5630 if (change_settings) {
5631 int didsettings = 0;
5632 struct ccb_trans_settings_spi *spi = NULL;
5633 struct ccb_trans_settings_pata *pata = NULL;
5634 struct ccb_trans_settings_sata *sata = NULL;
5635 struct ccb_trans_settings_ata *ata = NULL;
5636 struct ccb_trans_settings_scsi *scsi = NULL;
5638 if (ccb->cts.transport == XPORT_SPI)
5639 spi = &ccb->cts.xport_specific.spi;
5640 if (ccb->cts.transport == XPORT_ATA)
5641 pata = &ccb->cts.xport_specific.ata;
5642 if (ccb->cts.transport == XPORT_SATA)
5643 sata = &ccb->cts.xport_specific.sata;
5644 if (ccb->cts.protocol == PROTO_ATA)
5645 ata = &ccb->cts.proto_specific.ata;
5646 if (ccb->cts.protocol == PROTO_SCSI)
5647 scsi = &ccb->cts.proto_specific.scsi;
5648 ccb->cts.xport_specific.valid = 0;
5649 ccb->cts.proto_specific.valid = 0;
5650 if (spi && disc_enable != -1) {
5651 spi->valid |= CTS_SPI_VALID_DISC;
5652 if (disc_enable == 0)
5653 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5655 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5658 if (tag_enable != -1) {
5659 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5660 warnx("HBA does not support tagged queueing, "
5661 "so you cannot modify tag settings");
5663 goto ratecontrol_bailout;
5666 ata->valid |= CTS_SCSI_VALID_TQ;
5667 if (tag_enable == 0)
5668 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5670 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5673 scsi->valid |= CTS_SCSI_VALID_TQ;
5674 if (tag_enable == 0)
5675 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5677 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5681 if (spi && offset != -1) {
5682 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5683 warnx("HBA is not capable of changing offset");
5685 goto ratecontrol_bailout;
5687 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5688 spi->sync_offset = offset;
5691 if (spi && syncrate != -1) {
5692 int prelim_sync_period;
5694 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5695 warnx("HBA is not capable of changing "
5698 goto ratecontrol_bailout;
5700 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5702 * The sync rate the user gives us is in MHz.
5703 * We need to translate it into KHz for this
5708 * Next, we calculate a "preliminary" sync period
5709 * in tenths of a nanosecond.
5712 prelim_sync_period = 0;
5714 prelim_sync_period = 10000000 / syncrate;
5716 scsi_calc_syncparam(prelim_sync_period);
5719 if (sata && syncrate != -1) {
5720 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5721 warnx("HBA is not capable of changing "
5724 goto ratecontrol_bailout;
5726 if (!user_settings) {
5727 warnx("You can modify only user rate "
5728 "settings for SATA");
5730 goto ratecontrol_bailout;
5732 sata->revision = ata_speed2revision(syncrate * 100);
5733 if (sata->revision < 0) {
5734 warnx("Invalid rate %f", syncrate);
5736 goto ratecontrol_bailout;
5738 sata->valid |= CTS_SATA_VALID_REVISION;
5741 if ((pata || sata) && mode != -1) {
5742 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5743 warnx("HBA is not capable of changing "
5746 goto ratecontrol_bailout;
5748 if (!user_settings) {
5749 warnx("You can modify only user mode "
5750 "settings for ATA/SATA");
5752 goto ratecontrol_bailout;
5756 pata->valid |= CTS_ATA_VALID_MODE;
5759 sata->valid |= CTS_SATA_VALID_MODE;
5764 * The bus_width argument goes like this:
5768 * Therefore, if you shift the number of bits given on the
5769 * command line right by 4, you should get the correct
5772 if (spi && bus_width != -1) {
5774 * We might as well validate things here with a
5775 * decipherable error message, rather than what
5776 * will probably be an indecipherable error message
5777 * by the time it gets back to us.
5779 if ((bus_width == 16)
5780 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5781 warnx("HBA does not support 16 bit bus width");
5783 goto ratecontrol_bailout;
5784 } else if ((bus_width == 32)
5785 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5786 warnx("HBA does not support 32 bit bus width");
5788 goto ratecontrol_bailout;
5789 } else if ((bus_width != 8)
5790 && (bus_width != 16)
5791 && (bus_width != 32)) {
5792 warnx("Invalid bus width %d", bus_width);
5794 goto ratecontrol_bailout;
5796 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5797 spi->bus_width = bus_width >> 4;
5800 if (didsettings == 0) {
5801 goto ratecontrol_bailout;
5803 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5804 if (cam_send_ccb(device, ccb) < 0) {
5805 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5806 if (arglist & CAM_ARG_VERBOSE) {
5807 cam_error_print(device, ccb, CAM_ESF_ALL,
5808 CAM_EPF_ALL, stderr);
5811 goto ratecontrol_bailout;
5813 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5814 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5815 if (arglist & CAM_ARG_VERBOSE) {
5816 cam_error_print(device, ccb, CAM_ESF_ALL,
5817 CAM_EPF_ALL, stderr);
5820 goto ratecontrol_bailout;
5824 retval = testunitready(device, retry_count, timeout,
5825 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5827 * If the TUR didn't succeed, just bail.
5831 fprintf(stderr, "Test Unit Ready failed\n");
5832 goto ratecontrol_bailout;
5835 if ((change_settings || send_tur) && !quiet &&
5836 (ccb->cts.transport == XPORT_ATA ||
5837 ccb->cts.transport == XPORT_SATA || send_tur)) {
5838 fprintf(stdout, "New parameters:\n");
5839 retval = get_print_cts(device, user_settings, 0, NULL);
5842 ratecontrol_bailout:
5848 scsiformat(struct cam_device *device, int argc, char **argv,
5849 char *combinedopt, int retry_count, int timeout)
5853 int ycount = 0, quiet = 0;
5854 int error = 0, retval = 0;
5855 int use_timeout = 10800 * 1000;
5857 struct format_defect_list_header fh;
5858 u_int8_t *data_ptr = NULL;
5859 u_int32_t dxfer_len = 0;
5861 int num_warnings = 0;
5864 ccb = cam_getccb(device);
5867 warnx("scsiformat: error allocating ccb");
5871 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5873 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5894 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5895 "following device:\n");
5897 error = scsidoinquiry(device, argc, argv, combinedopt,
5898 retry_count, timeout);
5901 warnx("scsiformat: error sending inquiry");
5902 goto scsiformat_bailout;
5907 if (!get_confirmation()) {
5909 goto scsiformat_bailout;
5914 use_timeout = timeout;
5917 fprintf(stdout, "Current format timeout is %d seconds\n",
5918 use_timeout / 1000);
5922 * If the user hasn't disabled questions and didn't specify a
5923 * timeout on the command line, ask them if they want the current
5927 && (timeout == 0)) {
5929 int new_timeout = 0;
5931 fprintf(stdout, "Enter new timeout in seconds or press\n"
5932 "return to keep the current timeout [%d] ",
5933 use_timeout / 1000);
5935 if (fgets(str, sizeof(str), stdin) != NULL) {
5937 new_timeout = atoi(str);
5940 if (new_timeout != 0) {
5941 use_timeout = new_timeout * 1000;
5942 fprintf(stdout, "Using new timeout value %d\n",
5943 use_timeout / 1000);
5948 * Keep this outside the if block below to silence any unused
5949 * variable warnings.
5951 bzero(&fh, sizeof(fh));
5954 * If we're in immediate mode, we've got to include the format
5957 if (immediate != 0) {
5958 fh.byte2 = FU_DLH_IMMED;
5959 data_ptr = (u_int8_t *)&fh;
5960 dxfer_len = sizeof(fh);
5961 byte2 = FU_FMT_DATA;
5962 } else if (quiet == 0) {
5963 fprintf(stdout, "Formatting...");
5967 scsi_format_unit(&ccb->csio,
5968 /* retries */ retry_count,
5970 /* tag_action */ MSG_SIMPLE_Q_TAG,
5973 /* data_ptr */ data_ptr,
5974 /* dxfer_len */ dxfer_len,
5975 /* sense_len */ SSD_FULL_SIZE,
5976 /* timeout */ use_timeout);
5978 /* Disable freezing the device queue */
5979 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5981 if (arglist & CAM_ARG_ERR_RECOVER)
5982 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5984 if (((retval = cam_send_ccb(device, ccb)) < 0)
5985 || ((immediate == 0)
5986 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5987 const char errstr[] = "error sending format command";
5994 if (arglist & CAM_ARG_VERBOSE) {
5995 cam_error_print(device, ccb, CAM_ESF_ALL,
5996 CAM_EPF_ALL, stderr);
5999 goto scsiformat_bailout;
6003 * If we ran in non-immediate mode, we already checked for errors
6004 * above and printed out any necessary information. If we're in
6005 * immediate mode, we need to loop through and get status
6006 * information periodically.
6008 if (immediate == 0) {
6010 fprintf(stdout, "Format Complete\n");
6012 goto scsiformat_bailout;
6019 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6022 * There's really no need to do error recovery or
6023 * retries here, since we're just going to sit in a
6024 * loop and wait for the device to finish formatting.
6026 scsi_test_unit_ready(&ccb->csio,
6029 /* tag_action */ MSG_SIMPLE_Q_TAG,
6030 /* sense_len */ SSD_FULL_SIZE,
6031 /* timeout */ 5000);
6033 /* Disable freezing the device queue */
6034 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6036 retval = cam_send_ccb(device, ccb);
6039 * If we get an error from the ioctl, bail out. SCSI
6040 * errors are expected.
6043 warn("error sending CAMIOCOMMAND ioctl");
6044 if (arglist & CAM_ARG_VERBOSE) {
6045 cam_error_print(device, ccb, CAM_ESF_ALL,
6046 CAM_EPF_ALL, stderr);
6049 goto scsiformat_bailout;
6052 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6054 if ((status != CAM_REQ_CMP)
6055 && (status == CAM_SCSI_STATUS_ERROR)
6056 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6057 struct scsi_sense_data *sense;
6058 int error_code, sense_key, asc, ascq;
6060 sense = &ccb->csio.sense_data;
6061 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6062 ccb->csio.sense_resid, &error_code, &sense_key,
6063 &asc, &ascq, /*show_errors*/ 1);
6066 * According to the SCSI-2 and SCSI-3 specs, a
6067 * drive that is in the middle of a format should
6068 * return NOT READY with an ASC of "logical unit
6069 * not ready, format in progress". The sense key
6070 * specific bytes will then be a progress indicator.
6072 if ((sense_key == SSD_KEY_NOT_READY)
6073 && (asc == 0x04) && (ascq == 0x04)) {
6076 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6077 ccb->csio.sense_resid, sks) == 0)
6080 u_int64_t percentage;
6082 val = scsi_2btoul(&sks[1]);
6083 percentage = 10000 * val;
6086 "\rFormatting: %ju.%02u %% "
6088 (uintmax_t)(percentage /
6090 (unsigned)((percentage /
6094 } else if ((quiet == 0)
6095 && (++num_warnings <= 1)) {
6096 warnx("Unexpected SCSI Sense Key "
6097 "Specific value returned "
6099 scsi_sense_print(device, &ccb->csio,
6101 warnx("Unable to print status "
6102 "information, but format will "
6104 warnx("will exit when format is "
6109 warnx("Unexpected SCSI error during format");
6110 cam_error_print(device, ccb, CAM_ESF_ALL,
6111 CAM_EPF_ALL, stderr);
6113 goto scsiformat_bailout;
6116 } else if (status != CAM_REQ_CMP) {
6117 warnx("Unexpected CAM status %#x", status);
6118 if (arglist & CAM_ARG_VERBOSE)
6119 cam_error_print(device, ccb, CAM_ESF_ALL,
6120 CAM_EPF_ALL, stderr);
6122 goto scsiformat_bailout;
6125 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6128 fprintf(stdout, "\nFormat Complete\n");
6138 scsisanitize(struct cam_device *device, int argc, char **argv,
6139 char *combinedopt, int retry_count, int timeout)
6142 u_int8_t action = 0;
6144 int ycount = 0, quiet = 0;
6145 int error = 0, retval = 0;
6146 int use_timeout = 10800 * 1000;
6152 const char *pattern = NULL;
6153 u_int8_t *data_ptr = NULL;
6154 u_int32_t dxfer_len = 0;
6156 int num_warnings = 0;
6159 ccb = cam_getccb(device);
6162 warnx("scsisanitize: error allocating ccb");
6166 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6168 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6171 if (strcasecmp(optarg, "overwrite") == 0)
6172 action = SSZ_SERVICE_ACTION_OVERWRITE;
6173 else if (strcasecmp(optarg, "block") == 0)
6174 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6175 else if (strcasecmp(optarg, "crypto") == 0)
6176 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6177 else if (strcasecmp(optarg, "exitfailure") == 0)
6178 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6180 warnx("invalid service operation \"%s\"",
6183 goto scsisanitize_bailout;
6187 passes = strtol(optarg, NULL, 0);
6188 if (passes < 1 || passes > 31) {
6189 warnx("invalid passes value %d", passes);
6191 goto scsisanitize_bailout;
6222 warnx("an action is required");
6224 goto scsisanitize_bailout;
6225 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6226 struct scsi_sanitize_parameter_list *pl;
6230 if (pattern == NULL) {
6231 warnx("overwrite action requires -P argument");
6233 goto scsisanitize_bailout;
6235 fd = open(pattern, O_RDONLY);
6237 warn("cannot open pattern file %s", pattern);
6239 goto scsisanitize_bailout;
6241 if (fstat(fd, &sb) < 0) {
6242 warn("cannot stat pattern file %s", pattern);
6244 goto scsisanitize_bailout;
6247 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6248 warnx("pattern file size exceeds maximum value %d",
6249 SSZPL_MAX_PATTERN_LENGTH);
6251 goto scsisanitize_bailout;
6253 dxfer_len = sizeof(*pl) + sz;
6254 data_ptr = calloc(1, dxfer_len);
6255 if (data_ptr == NULL) {
6256 warnx("cannot allocate parameter list buffer");
6258 goto scsisanitize_bailout;
6261 amt = read(fd, data_ptr + sizeof(*pl), sz);
6263 warn("cannot read pattern file");
6265 goto scsisanitize_bailout;
6266 } else if (amt != sz) {
6267 warnx("short pattern file read");
6269 goto scsisanitize_bailout;
6272 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6278 pl->byte1 |= SSZPL_INVERT;
6279 scsi_ulto2b(sz, pl->length);
6285 else if (invert != 0)
6287 else if (pattern != NULL)
6292 warnx("%s argument only valid with overwrite "
6295 goto scsisanitize_bailout;
6300 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6301 "following device:\n");
6303 error = scsidoinquiry(device, argc, argv, combinedopt,
6304 retry_count, timeout);
6307 warnx("scsisanitize: error sending inquiry");
6308 goto scsisanitize_bailout;
6313 if (!get_confirmation()) {
6315 goto scsisanitize_bailout;
6320 use_timeout = timeout;
6323 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6324 use_timeout / 1000);
6328 * If the user hasn't disabled questions and didn't specify a
6329 * timeout on the command line, ask them if they want the current
6333 && (timeout == 0)) {
6335 int new_timeout = 0;
6337 fprintf(stdout, "Enter new timeout in seconds or press\n"
6338 "return to keep the current timeout [%d] ",
6339 use_timeout / 1000);
6341 if (fgets(str, sizeof(str), stdin) != NULL) {
6343 new_timeout = atoi(str);
6346 if (new_timeout != 0) {
6347 use_timeout = new_timeout * 1000;
6348 fprintf(stdout, "Using new timeout value %d\n",
6349 use_timeout / 1000);
6355 byte2 |= SSZ_UNRESTRICTED_EXIT;
6359 scsi_sanitize(&ccb->csio,
6360 /* retries */ retry_count,
6362 /* tag_action */ MSG_SIMPLE_Q_TAG,
6365 /* data_ptr */ data_ptr,
6366 /* dxfer_len */ dxfer_len,
6367 /* sense_len */ SSD_FULL_SIZE,
6368 /* timeout */ use_timeout);
6370 /* Disable freezing the device queue */
6371 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6373 if (arglist & CAM_ARG_ERR_RECOVER)
6374 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6376 if (cam_send_ccb(device, ccb) < 0) {
6377 warn("error sending sanitize command");
6379 goto scsisanitize_bailout;
6382 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6383 struct scsi_sense_data *sense;
6384 int error_code, sense_key, asc, ascq;
6386 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6387 CAM_SCSI_STATUS_ERROR) {
6388 sense = &ccb->csio.sense_data;
6389 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6390 ccb->csio.sense_resid, &error_code, &sense_key,
6391 &asc, &ascq, /*show_errors*/ 1);
6393 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6394 asc == 0x20 && ascq == 0x00)
6395 warnx("sanitize is not supported by "
6398 warnx("error sanitizing this device");
6400 warnx("error sanitizing this device");
6402 if (arglist & CAM_ARG_VERBOSE) {
6403 cam_error_print(device, ccb, CAM_ESF_ALL,
6404 CAM_EPF_ALL, stderr);
6407 goto scsisanitize_bailout;
6411 * If we ran in non-immediate mode, we already checked for errors
6412 * above and printed out any necessary information. If we're in
6413 * immediate mode, we need to loop through and get status
6414 * information periodically.
6416 if (immediate == 0) {
6418 fprintf(stdout, "Sanitize Complete\n");
6420 goto scsisanitize_bailout;
6427 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6430 * There's really no need to do error recovery or
6431 * retries here, since we're just going to sit in a
6432 * loop and wait for the device to finish sanitizing.
6434 scsi_test_unit_ready(&ccb->csio,
6437 /* tag_action */ MSG_SIMPLE_Q_TAG,
6438 /* sense_len */ SSD_FULL_SIZE,
6439 /* timeout */ 5000);
6441 /* Disable freezing the device queue */
6442 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6444 retval = cam_send_ccb(device, ccb);
6447 * If we get an error from the ioctl, bail out. SCSI
6448 * errors are expected.
6451 warn("error sending CAMIOCOMMAND ioctl");
6452 if (arglist & CAM_ARG_VERBOSE) {
6453 cam_error_print(device, ccb, CAM_ESF_ALL,
6454 CAM_EPF_ALL, stderr);
6457 goto scsisanitize_bailout;
6460 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6462 if ((status != CAM_REQ_CMP)
6463 && (status == CAM_SCSI_STATUS_ERROR)
6464 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6465 struct scsi_sense_data *sense;
6466 int error_code, sense_key, asc, ascq;
6468 sense = &ccb->csio.sense_data;
6469 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6470 ccb->csio.sense_resid, &error_code, &sense_key,
6471 &asc, &ascq, /*show_errors*/ 1);
6474 * According to the SCSI-3 spec, a drive that is in the
6475 * middle of a sanitize should return NOT READY with an
6476 * ASC of "logical unit not ready, sanitize in
6477 * progress". The sense key specific bytes will then
6478 * be a progress indicator.
6480 if ((sense_key == SSD_KEY_NOT_READY)
6481 && (asc == 0x04) && (ascq == 0x1b)) {
6484 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6485 ccb->csio.sense_resid, sks) == 0)
6488 u_int64_t percentage;
6490 val = scsi_2btoul(&sks[1]);
6491 percentage = 10000 * val;
6494 "\rSanitizing: %ju.%02u %% "
6496 (uintmax_t)(percentage /
6498 (unsigned)((percentage /
6502 } else if ((quiet == 0)
6503 && (++num_warnings <= 1)) {
6504 warnx("Unexpected SCSI Sense Key "
6505 "Specific value returned "
6506 "during sanitize:");
6507 scsi_sense_print(device, &ccb->csio,
6509 warnx("Unable to print status "
6510 "information, but sanitze will "
6512 warnx("will exit when sanitize is "
6517 warnx("Unexpected SCSI error during sanitize");
6518 cam_error_print(device, ccb, CAM_ESF_ALL,
6519 CAM_EPF_ALL, stderr);
6521 goto scsisanitize_bailout;
6524 } else if (status != CAM_REQ_CMP) {
6525 warnx("Unexpected CAM status %#x", status);
6526 if (arglist & CAM_ARG_VERBOSE)
6527 cam_error_print(device, ccb, CAM_ESF_ALL,
6528 CAM_EPF_ALL, stderr);
6530 goto scsisanitize_bailout;
6532 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6535 fprintf(stdout, "\nSanitize Complete\n");
6537 scsisanitize_bailout:
6540 if (data_ptr != NULL)
6548 scsireportluns(struct cam_device *device, int argc, char **argv,
6549 char *combinedopt, int retry_count, int timeout)
6552 int c, countonly, lunsonly;
6553 struct scsi_report_luns_data *lundata;
6555 uint8_t report_type;
6556 uint32_t list_len, i, j;
6561 report_type = RPL_REPORT_DEFAULT;
6562 ccb = cam_getccb(device);
6565 warnx("%s: error allocating ccb", __func__);
6569 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6574 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6583 if (strcasecmp(optarg, "default") == 0)
6584 report_type = RPL_REPORT_DEFAULT;
6585 else if (strcasecmp(optarg, "wellknown") == 0)
6586 report_type = RPL_REPORT_WELLKNOWN;
6587 else if (strcasecmp(optarg, "all") == 0)
6588 report_type = RPL_REPORT_ALL;
6590 warnx("%s: invalid report type \"%s\"",
6601 if ((countonly != 0)
6602 && (lunsonly != 0)) {
6603 warnx("%s: you can only specify one of -c or -l", __func__);
6608 * According to SPC-4, the allocation length must be at least 16
6609 * bytes -- enough for the header and one LUN.
6611 alloc_len = sizeof(*lundata) + 8;
6615 lundata = malloc(alloc_len);
6617 if (lundata == NULL) {
6618 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6623 scsi_report_luns(&ccb->csio,
6624 /*retries*/ retry_count,
6626 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6627 /*select_report*/ report_type,
6628 /*rpl_buf*/ lundata,
6629 /*alloc_len*/ alloc_len,
6630 /*sense_len*/ SSD_FULL_SIZE,
6631 /*timeout*/ timeout ? timeout : 5000);
6633 /* Disable freezing the device queue */
6634 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6636 if (arglist & CAM_ARG_ERR_RECOVER)
6637 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6639 if (cam_send_ccb(device, ccb) < 0) {
6640 warn("error sending REPORT LUNS command");
6642 if (arglist & CAM_ARG_VERBOSE)
6643 cam_error_print(device, ccb, CAM_ESF_ALL,
6644 CAM_EPF_ALL, stderr);
6650 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6651 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6657 list_len = scsi_4btoul(lundata->length);
6660 * If we need to list the LUNs, and our allocation
6661 * length was too short, reallocate and retry.
6663 if ((countonly == 0)
6664 && (list_len > (alloc_len - sizeof(*lundata)))) {
6665 alloc_len = list_len + sizeof(*lundata);
6671 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6672 ((list_len / 8) > 1) ? "s" : "");
6677 for (i = 0; i < (list_len / 8); i++) {
6681 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6683 fprintf(stdout, ",");
6684 switch (lundata->luns[i].lundata[j] &
6685 RPL_LUNDATA_ATYP_MASK) {
6686 case RPL_LUNDATA_ATYP_PERIPH:
6687 if ((lundata->luns[i].lundata[j] &
6688 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6689 fprintf(stdout, "%d:",
6690 lundata->luns[i].lundata[j] &
6691 RPL_LUNDATA_PERIPH_BUS_MASK);
6693 && ((lundata->luns[i].lundata[j+2] &
6694 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6697 fprintf(stdout, "%d",
6698 lundata->luns[i].lundata[j+1]);
6700 case RPL_LUNDATA_ATYP_FLAT: {
6702 tmplun[0] = lundata->luns[i].lundata[j] &
6703 RPL_LUNDATA_FLAT_LUN_MASK;
6704 tmplun[1] = lundata->luns[i].lundata[j+1];
6706 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6710 case RPL_LUNDATA_ATYP_LUN:
6711 fprintf(stdout, "%d:%d:%d",
6712 (lundata->luns[i].lundata[j+1] &
6713 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6714 lundata->luns[i].lundata[j] &
6715 RPL_LUNDATA_LUN_TARG_MASK,
6716 lundata->luns[i].lundata[j+1] &
6717 RPL_LUNDATA_LUN_LUN_MASK);
6719 case RPL_LUNDATA_ATYP_EXTLUN: {
6720 int field_len_code, eam_code;
6722 eam_code = lundata->luns[i].lundata[j] &
6723 RPL_LUNDATA_EXT_EAM_MASK;
6724 field_len_code = (lundata->luns[i].lundata[j] &
6725 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6727 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6728 && (field_len_code == 0x00)) {
6729 fprintf(stdout, "%d",
6730 lundata->luns[i].lundata[j+1]);
6731 } else if ((eam_code ==
6732 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6733 && (field_len_code == 0x03)) {
6737 * This format takes up all 8 bytes.
6738 * If we aren't starting at offset 0,
6742 fprintf(stdout, "Invalid "
6745 "specified format", j);
6749 bzero(tmp_lun, sizeof(tmp_lun));
6750 bcopy(&lundata->luns[i].lundata[j+1],
6751 &tmp_lun[1], sizeof(tmp_lun) - 1);
6752 fprintf(stdout, "%#jx",
6753 (intmax_t)scsi_8btou64(tmp_lun));
6756 fprintf(stderr, "Unknown Extended LUN"
6757 "Address method %#x, length "
6758 "code %#x", eam_code,
6765 fprintf(stderr, "Unknown LUN address method "
6766 "%#x\n", lundata->luns[i].lundata[0] &
6767 RPL_LUNDATA_ATYP_MASK);
6771 * For the flat addressing method, there are no
6772 * other levels after it.
6777 fprintf(stdout, "\n");
6790 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6791 char *combinedopt, int retry_count, int timeout)
6794 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6795 struct scsi_read_capacity_data rcap;
6796 struct scsi_read_capacity_data_long rcaplong;
6810 ccb = cam_getccb(device);
6813 warnx("%s: error allocating ccb", __func__);
6817 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6819 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6846 if ((blocksizeonly != 0)
6847 && (numblocks != 0)) {
6848 warnx("%s: you can only specify one of -b or -N", __func__);
6853 if ((blocksizeonly != 0)
6854 && (sizeonly != 0)) {
6855 warnx("%s: you can only specify one of -b or -s", __func__);
6862 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6868 && (blocksizeonly != 0)) {
6869 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6874 scsi_read_capacity(&ccb->csio,
6875 /*retries*/ retry_count,
6877 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6880 /*timeout*/ timeout ? timeout : 5000);
6882 /* Disable freezing the device queue */
6883 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6885 if (arglist & CAM_ARG_ERR_RECOVER)
6886 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6888 if (cam_send_ccb(device, ccb) < 0) {
6889 warn("error sending READ CAPACITY command");
6891 if (arglist & CAM_ARG_VERBOSE)
6892 cam_error_print(device, ccb, CAM_ESF_ALL,
6893 CAM_EPF_ALL, stderr);
6899 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6900 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6905 maxsector = scsi_4btoul(rcap.addr);
6906 block_len = scsi_4btoul(rcap.length);
6909 * A last block of 2^32-1 means that the true capacity is over 2TB,
6910 * and we need to issue the long READ CAPACITY to get the real
6911 * capacity. Otherwise, we're all set.
6913 if (maxsector != 0xffffffff)
6916 scsi_read_capacity_16(&ccb->csio,
6917 /*retries*/ retry_count,
6919 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6923 /*rcap_buf*/ (uint8_t *)&rcaplong,
6924 /*rcap_buf_len*/ sizeof(rcaplong),
6925 /*sense_len*/ SSD_FULL_SIZE,
6926 /*timeout*/ timeout ? timeout : 5000);
6928 /* Disable freezing the device queue */
6929 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6931 if (arglist & CAM_ARG_ERR_RECOVER)
6932 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6934 if (cam_send_ccb(device, ccb) < 0) {
6935 warn("error sending READ CAPACITY (16) command");
6937 if (arglist & CAM_ARG_VERBOSE)
6938 cam_error_print(device, ccb, CAM_ESF_ALL,
6939 CAM_EPF_ALL, stderr);
6945 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6946 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6951 maxsector = scsi_8btou64(rcaplong.addr);
6952 block_len = scsi_4btoul(rcaplong.length);
6955 if (blocksizeonly == 0) {
6957 * Humanize implies !quiet, and also implies numblocks.
6959 if (humanize != 0) {
6964 tmpbytes = (maxsector + 1) * block_len;
6965 ret = humanize_number(tmpstr, sizeof(tmpstr),
6966 tmpbytes, "", HN_AUTOSCALE,
6969 HN_DIVISOR_1000 : 0));
6971 warnx("%s: humanize_number failed!", __func__);
6975 fprintf(stdout, "Device Size: %s%s", tmpstr,
6976 (sizeonly == 0) ? ", " : "\n");
6977 } else if (numblocks != 0) {
6978 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6979 "Blocks: " : "", (uintmax_t)maxsector + 1,
6980 (sizeonly == 0) ? ", " : "\n");
6982 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6983 "Last Block: " : "", (uintmax_t)maxsector,
6984 (sizeonly == 0) ? ", " : "\n");
6988 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6989 "Block Length: " : "", block_len, (quiet == 0) ?
6998 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6999 int retry_count, int timeout)
7003 uint8_t *smp_request = NULL, *smp_response = NULL;
7004 int request_size = 0, response_size = 0;
7005 int fd_request = 0, fd_response = 0;
7006 char *datastr = NULL;
7007 struct get_hook hook;
7012 * Note that at the moment we don't support sending SMP CCBs to
7013 * devices that aren't probed by CAM.
7015 ccb = cam_getccb(device);
7017 warnx("%s: error allocating CCB", __func__);
7021 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7023 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7026 arglist |= CAM_ARG_CMD_IN;
7027 response_size = strtol(optarg, NULL, 0);
7028 if (response_size <= 0) {
7029 warnx("invalid number of response bytes %d",
7032 goto smpcmd_bailout;
7034 hook.argc = argc - optind;
7035 hook.argv = argv + optind;
7038 datastr = cget(&hook, NULL);
7040 * If the user supplied "-" instead of a format, he
7041 * wants the data to be written to stdout.
7043 if ((datastr != NULL)
7044 && (datastr[0] == '-'))
7047 smp_response = (u_int8_t *)malloc(response_size);
7048 if (smp_response == NULL) {
7049 warn("can't malloc memory for SMP response");
7051 goto smpcmd_bailout;
7055 arglist |= CAM_ARG_CMD_OUT;
7056 request_size = strtol(optarg, NULL, 0);
7057 if (request_size <= 0) {
7058 warnx("invalid number of request bytes %d",
7061 goto smpcmd_bailout;
7063 hook.argc = argc - optind;
7064 hook.argv = argv + optind;
7066 datastr = cget(&hook, NULL);
7067 smp_request = (u_int8_t *)malloc(request_size);
7068 if (smp_request == NULL) {
7069 warn("can't malloc memory for SMP request");
7071 goto smpcmd_bailout;
7073 bzero(smp_request, request_size);
7075 * If the user supplied "-" instead of a format, he
7076 * wants the data to be read from stdin.
7078 if ((datastr != NULL)
7079 && (datastr[0] == '-'))
7082 buff_encode_visit(smp_request, request_size,
7093 * If fd_data is set, and we're writing to the device, we need to
7094 * read the data the user wants written from stdin.
7096 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7098 int amt_to_read = request_size;
7099 u_int8_t *buf_ptr = smp_request;
7101 for (amt_read = 0; amt_to_read > 0;
7102 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7103 if (amt_read == -1) {
7104 warn("error reading data from stdin");
7106 goto smpcmd_bailout;
7108 amt_to_read -= amt_read;
7109 buf_ptr += amt_read;
7113 if (((arglist & CAM_ARG_CMD_IN) == 0)
7114 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7115 warnx("%s: need both the request (-r) and response (-R) "
7116 "arguments", __func__);
7118 goto smpcmd_bailout;
7121 flags |= CAM_DEV_QFRZDIS;
7123 cam_fill_smpio(&ccb->smpio,
7124 /*retries*/ retry_count,
7127 /*smp_request*/ smp_request,
7128 /*smp_request_len*/ request_size,
7129 /*smp_response*/ smp_response,
7130 /*smp_response_len*/ response_size,
7131 /*timeout*/ timeout ? timeout : 5000);
7133 ccb->smpio.flags = SMP_FLAG_NONE;
7135 if (((retval = cam_send_ccb(device, ccb)) < 0)
7136 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7137 const char warnstr[] = "error sending command";
7144 if (arglist & CAM_ARG_VERBOSE) {
7145 cam_error_print(device, ccb, CAM_ESF_ALL,
7146 CAM_EPF_ALL, stderr);
7150 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7151 && (response_size > 0)) {
7152 if (fd_response == 0) {
7153 buff_decode_visit(smp_response, response_size,
7154 datastr, arg_put, NULL);
7155 fprintf(stdout, "\n");
7157 ssize_t amt_written;
7158 int amt_to_write = response_size;
7159 u_int8_t *buf_ptr = smp_response;
7161 for (amt_written = 0; (amt_to_write > 0) &&
7162 (amt_written = write(STDOUT_FILENO, buf_ptr,
7163 amt_to_write)) > 0;){
7164 amt_to_write -= amt_written;
7165 buf_ptr += amt_written;
7167 if (amt_written == -1) {
7168 warn("error writing data to stdout");
7170 goto smpcmd_bailout;
7171 } else if ((amt_written == 0)
7172 && (amt_to_write > 0)) {
7173 warnx("only wrote %u bytes out of %u",
7174 response_size - amt_to_write,
7183 if (smp_request != NULL)
7186 if (smp_response != NULL)
7193 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7194 char *combinedopt, int retry_count, int timeout)
7197 struct smp_report_general_request *request = NULL;
7198 struct smp_report_general_response *response = NULL;
7199 struct sbuf *sb = NULL;
7201 int c, long_response = 0;
7205 * Note that at the moment we don't support sending SMP CCBs to
7206 * devices that aren't probed by CAM.
7208 ccb = cam_getccb(device);
7210 warnx("%s: error allocating CCB", __func__);
7214 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7216 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7225 request = malloc(sizeof(*request));
7226 if (request == NULL) {
7227 warn("%s: unable to allocate %zd bytes", __func__,
7233 response = malloc(sizeof(*response));
7234 if (response == NULL) {
7235 warn("%s: unable to allocate %zd bytes", __func__,
7242 smp_report_general(&ccb->smpio,
7246 /*request_len*/ sizeof(*request),
7247 (uint8_t *)response,
7248 /*response_len*/ sizeof(*response),
7249 /*long_response*/ long_response,
7252 if (((retval = cam_send_ccb(device, ccb)) < 0)
7253 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7254 const char warnstr[] = "error sending command";
7261 if (arglist & CAM_ARG_VERBOSE) {
7262 cam_error_print(device, ccb, CAM_ESF_ALL,
7263 CAM_EPF_ALL, stderr);
7270 * If the device supports the long response bit, try again and see
7271 * if we can get all of the data.
7273 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7274 && (long_response == 0)) {
7275 ccb->ccb_h.status = CAM_REQ_INPROG;
7276 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7282 * XXX KDM detect and decode SMP errors here.
7284 sb = sbuf_new_auto();
7286 warnx("%s: error allocating sbuf", __func__);
7290 smp_report_general_sbuf(response, sizeof(*response), sb);
7292 if (sbuf_finish(sb) != 0) {
7293 warnx("%s: sbuf_finish", __func__);
7297 printf("%s", sbuf_data(sb));
7303 if (request != NULL)
7306 if (response != NULL)
7315 static struct camcontrol_opts phy_ops[] = {
7316 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7317 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7318 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7319 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7320 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7321 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7322 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7323 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7324 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7329 smpphycontrol(struct cam_device *device, int argc, char **argv,
7330 char *combinedopt, int retry_count, int timeout)
7333 struct smp_phy_control_request *request = NULL;
7334 struct smp_phy_control_response *response = NULL;
7335 int long_response = 0;
7338 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7340 uint64_t attached_dev_name = 0;
7341 int dev_name_set = 0;
7342 uint32_t min_plr = 0, max_plr = 0;
7343 uint32_t pp_timeout_val = 0;
7344 int slumber_partial = 0;
7345 int set_pp_timeout_val = 0;
7349 * Note that at the moment we don't support sending SMP CCBs to
7350 * devices that aren't probed by CAM.
7352 ccb = cam_getccb(device);
7354 warnx("%s: error allocating CCB", __func__);
7358 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7360 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7368 if (strcasecmp(optarg, "enable") == 0)
7370 else if (strcasecmp(optarg, "disable") == 0)
7373 warnx("%s: Invalid argument %s", __func__,
7380 slumber_partial |= enable <<
7381 SMP_PC_SAS_SLUMBER_SHIFT;
7384 slumber_partial |= enable <<
7385 SMP_PC_SAS_PARTIAL_SHIFT;
7388 slumber_partial |= enable <<
7389 SMP_PC_SATA_SLUMBER_SHIFT;
7392 slumber_partial |= enable <<
7393 SMP_PC_SATA_PARTIAL_SHIFT;
7396 warnx("%s: programmer error", __func__);
7399 break; /*NOTREACHED*/
7404 attached_dev_name = (uintmax_t)strtoumax(optarg,
7413 * We don't do extensive checking here, so this
7414 * will continue to work when new speeds come out.
7416 min_plr = strtoul(optarg, NULL, 0);
7418 || (min_plr > 0xf)) {
7419 warnx("%s: invalid link rate %x",
7427 * We don't do extensive checking here, so this
7428 * will continue to work when new speeds come out.
7430 max_plr = strtoul(optarg, NULL, 0);
7432 || (max_plr > 0xf)) {
7433 warnx("%s: invalid link rate %x",
7440 camcontrol_optret optreturn;
7441 cam_argmask argnums;
7444 if (phy_op_set != 0) {
7445 warnx("%s: only one phy operation argument "
7446 "(-o) allowed", __func__);
7454 * Allow the user to specify the phy operation
7455 * numerically, as well as with a name. This will
7456 * future-proof it a bit, so options that are added
7457 * in future specs can be used.
7459 if (isdigit(optarg[0])) {
7460 phy_operation = strtoul(optarg, NULL, 0);
7461 if ((phy_operation == 0)
7462 || (phy_operation > 0xff)) {
7463 warnx("%s: invalid phy operation %#x",
7464 __func__, phy_operation);
7470 optreturn = getoption(phy_ops, optarg, &phy_operation,
7473 if (optreturn == CC_OR_AMBIGUOUS) {
7474 warnx("%s: ambiguous option %s", __func__,
7479 } else if (optreturn == CC_OR_NOT_FOUND) {
7480 warnx("%s: option %s not found", __func__,
7492 pp_timeout_val = strtoul(optarg, NULL, 0);
7493 if (pp_timeout_val > 15) {
7494 warnx("%s: invalid partial pathway timeout "
7495 "value %u, need a value less than 16",
7496 __func__, pp_timeout_val);
7500 set_pp_timeout_val = 1;
7508 warnx("%s: a PHY (-p phy) argument is required",__func__);
7513 if (((dev_name_set != 0)
7514 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7515 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7516 && (dev_name_set == 0))) {
7517 warnx("%s: -d name and -o setdevname arguments both "
7518 "required to set device name", __func__);
7523 request = malloc(sizeof(*request));
7524 if (request == NULL) {
7525 warn("%s: unable to allocate %zd bytes", __func__,
7531 response = malloc(sizeof(*response));
7532 if (response == NULL) {
7533 warn("%s: unable to allocate %zd bytes", __func__,
7539 smp_phy_control(&ccb->smpio,
7544 (uint8_t *)response,
7547 /*expected_exp_change_count*/ 0,
7550 (set_pp_timeout_val != 0) ? 1 : 0,
7558 if (((retval = cam_send_ccb(device, ccb)) < 0)
7559 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7560 const char warnstr[] = "error sending command";
7567 if (arglist & CAM_ARG_VERBOSE) {
7569 * Use CAM_EPF_NORMAL so we only get one line of
7570 * SMP command decoding.
7572 cam_error_print(device, ccb, CAM_ESF_ALL,
7573 CAM_EPF_NORMAL, stderr);
7579 /* XXX KDM print out something here for success? */
7584 if (request != NULL)
7587 if (response != NULL)
7594 smpmaninfo(struct cam_device *device, int argc, char **argv,
7595 char *combinedopt, int retry_count, int timeout)
7598 struct smp_report_manuf_info_request request;
7599 struct smp_report_manuf_info_response response;
7600 struct sbuf *sb = NULL;
7601 int long_response = 0;
7606 * Note that at the moment we don't support sending SMP CCBs to
7607 * devices that aren't probed by CAM.
7609 ccb = cam_getccb(device);
7611 warnx("%s: error allocating CCB", __func__);
7615 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7617 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7626 bzero(&request, sizeof(request));
7627 bzero(&response, sizeof(response));
7629 smp_report_manuf_info(&ccb->smpio,
7634 (uint8_t *)&response,
7639 if (((retval = cam_send_ccb(device, ccb)) < 0)
7640 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7641 const char warnstr[] = "error sending command";
7648 if (arglist & CAM_ARG_VERBOSE) {
7649 cam_error_print(device, ccb, CAM_ESF_ALL,
7650 CAM_EPF_ALL, stderr);
7656 sb = sbuf_new_auto();
7658 warnx("%s: error allocating sbuf", __func__);
7662 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7664 if (sbuf_finish(sb) != 0) {
7665 warnx("%s: sbuf_finish", __func__);
7669 printf("%s", sbuf_data(sb));
7683 getdevid(struct cam_devitem *item)
7686 union ccb *ccb = NULL;
7688 struct cam_device *dev;
7690 dev = cam_open_btl(item->dev_match.path_id,
7691 item->dev_match.target_id,
7692 item->dev_match.target_lun, O_RDWR, NULL);
7695 warnx("%s", cam_errbuf);
7700 item->device_id_len = 0;
7702 ccb = cam_getccb(dev);
7704 warnx("%s: error allocating CCB", __func__);
7709 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7712 * On the first try, we just probe for the size of the data, and
7713 * then allocate that much memory and try again.
7716 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7717 ccb->ccb_h.flags = CAM_DIR_IN;
7718 ccb->cdai.flags = CDAI_FLAG_NONE;
7719 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7720 ccb->cdai.bufsiz = item->device_id_len;
7721 if (item->device_id_len != 0)
7722 ccb->cdai.buf = (uint8_t *)item->device_id;
7724 if (cam_send_ccb(dev, ccb) < 0) {
7725 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7730 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7731 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7736 if (item->device_id_len == 0) {
7738 * This is our first time through. Allocate the buffer,
7739 * and then go back to get the data.
7741 if (ccb->cdai.provsiz == 0) {
7742 warnx("%s: invalid .provsiz field returned with "
7743 "XPT_GDEV_ADVINFO CCB", __func__);
7747 item->device_id_len = ccb->cdai.provsiz;
7748 item->device_id = malloc(item->device_id_len);
7749 if (item->device_id == NULL) {
7750 warn("%s: unable to allocate %d bytes", __func__,
7751 item->device_id_len);
7755 ccb->ccb_h.status = CAM_REQ_INPROG;
7761 cam_close_device(dev);
7770 * XXX KDM merge this code with getdevtree()?
7773 buildbusdevlist(struct cam_devlist *devlist)
7776 int bufsize, fd = -1;
7777 struct dev_match_pattern *patterns;
7778 struct cam_devitem *item = NULL;
7779 int skip_device = 0;
7782 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7783 warn("couldn't open %s", XPT_DEVICE);
7787 bzero(&ccb, sizeof(union ccb));
7789 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7790 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7791 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7793 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7794 bufsize = sizeof(struct dev_match_result) * 100;
7795 ccb.cdm.match_buf_len = bufsize;
7796 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7797 if (ccb.cdm.matches == NULL) {
7798 warnx("can't malloc memory for matches");
7802 ccb.cdm.num_matches = 0;
7803 ccb.cdm.num_patterns = 2;
7804 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7805 ccb.cdm.num_patterns;
7807 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7808 if (patterns == NULL) {
7809 warnx("can't malloc memory for patterns");
7814 ccb.cdm.patterns = patterns;
7815 bzero(patterns, ccb.cdm.pattern_buf_len);
7817 patterns[0].type = DEV_MATCH_DEVICE;
7818 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7819 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7820 patterns[1].type = DEV_MATCH_PERIPH;
7821 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7822 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7825 * We do the ioctl multiple times if necessary, in case there are
7826 * more than 100 nodes in the EDT.
7831 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7832 warn("error sending CAMIOCOMMAND ioctl");
7837 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7838 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7839 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7840 warnx("got CAM error %#x, CDM error %d\n",
7841 ccb.ccb_h.status, ccb.cdm.status);
7846 for (i = 0; i < ccb.cdm.num_matches; i++) {
7847 switch (ccb.cdm.matches[i].type) {
7848 case DEV_MATCH_DEVICE: {
7849 struct device_match_result *dev_result;
7852 &ccb.cdm.matches[i].result.device_result;
7854 if (dev_result->flags &
7855 DEV_RESULT_UNCONFIGURED) {
7861 item = malloc(sizeof(*item));
7863 warn("%s: unable to allocate %zd bytes",
7864 __func__, sizeof(*item));
7868 bzero(item, sizeof(*item));
7869 bcopy(dev_result, &item->dev_match,
7870 sizeof(*dev_result));
7871 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7874 if (getdevid(item) != 0) {
7880 case DEV_MATCH_PERIPH: {
7881 struct periph_match_result *periph_result;
7884 &ccb.cdm.matches[i].result.periph_result;
7886 if (skip_device != 0)
7888 item->num_periphs++;
7889 item->periph_matches = realloc(
7890 item->periph_matches,
7892 sizeof(struct periph_match_result));
7893 if (item->periph_matches == NULL) {
7894 warn("%s: error allocating periph "
7899 bcopy(periph_result, &item->periph_matches[
7900 item->num_periphs - 1],
7901 sizeof(*periph_result));
7905 fprintf(stderr, "%s: unexpected match "
7906 "type %d\n", __func__,
7907 ccb.cdm.matches[i].type);
7910 break; /*NOTREACHED*/
7913 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7914 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7922 free(ccb.cdm.matches);
7925 freebusdevlist(devlist);
7931 freebusdevlist(struct cam_devlist *devlist)
7933 struct cam_devitem *item, *item2;
7935 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7936 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7938 free(item->device_id);
7939 free(item->periph_matches);
7944 static struct cam_devitem *
7945 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7947 struct cam_devitem *item;
7949 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7950 struct scsi_vpd_id_descriptor *idd;
7953 * XXX KDM look for LUN IDs as well?
7955 idd = scsi_get_devid(item->device_id,
7956 item->device_id_len,
7957 scsi_devid_is_sas_target);
7961 if (scsi_8btou64(idd->identifier) == sasaddr)
7969 smpphylist(struct cam_device *device, int argc, char **argv,
7970 char *combinedopt, int retry_count, int timeout)
7972 struct smp_report_general_request *rgrequest = NULL;
7973 struct smp_report_general_response *rgresponse = NULL;
7974 struct smp_discover_request *disrequest = NULL;
7975 struct smp_discover_response *disresponse = NULL;
7976 struct cam_devlist devlist;
7978 int long_response = 0;
7985 * Note that at the moment we don't support sending SMP CCBs to
7986 * devices that aren't probed by CAM.
7988 ccb = cam_getccb(device);
7990 warnx("%s: error allocating CCB", __func__);
7994 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7995 STAILQ_INIT(&devlist.dev_queue);
7997 rgrequest = malloc(sizeof(*rgrequest));
7998 if (rgrequest == NULL) {
7999 warn("%s: unable to allocate %zd bytes", __func__,
8000 sizeof(*rgrequest));
8005 rgresponse = malloc(sizeof(*rgresponse));
8006 if (rgresponse == NULL) {
8007 warn("%s: unable to allocate %zd bytes", __func__,
8008 sizeof(*rgresponse));
8013 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8026 smp_report_general(&ccb->smpio,
8030 /*request_len*/ sizeof(*rgrequest),
8031 (uint8_t *)rgresponse,
8032 /*response_len*/ sizeof(*rgresponse),
8033 /*long_response*/ long_response,
8036 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8038 if (((retval = cam_send_ccb(device, ccb)) < 0)
8039 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8040 const char warnstr[] = "error sending command";
8047 if (arglist & CAM_ARG_VERBOSE) {
8048 cam_error_print(device, ccb, CAM_ESF_ALL,
8049 CAM_EPF_ALL, stderr);
8055 num_phys = rgresponse->num_phys;
8057 if (num_phys == 0) {
8059 fprintf(stdout, "%s: No Phys reported\n", __func__);
8064 devlist.path_id = device->path_id;
8066 retval = buildbusdevlist(&devlist);
8071 fprintf(stdout, "%d PHYs:\n", num_phys);
8072 fprintf(stdout, "PHY Attached SAS Address\n");
8075 disrequest = malloc(sizeof(*disrequest));
8076 if (disrequest == NULL) {
8077 warn("%s: unable to allocate %zd bytes", __func__,
8078 sizeof(*disrequest));
8083 disresponse = malloc(sizeof(*disresponse));
8084 if (disresponse == NULL) {
8085 warn("%s: unable to allocate %zd bytes", __func__,
8086 sizeof(*disresponse));
8091 for (i = 0; i < num_phys; i++) {
8092 struct cam_devitem *item;
8093 struct device_match_result *dev_match;
8094 char vendor[16], product[48], revision[16];
8098 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8100 ccb->ccb_h.status = CAM_REQ_INPROG;
8101 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8103 smp_discover(&ccb->smpio,
8107 sizeof(*disrequest),
8108 (uint8_t *)disresponse,
8109 sizeof(*disresponse),
8111 /*ignore_zone_group*/ 0,
8115 if (((retval = cam_send_ccb(device, ccb)) < 0)
8116 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8117 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8118 const char warnstr[] = "error sending command";
8125 if (arglist & CAM_ARG_VERBOSE) {
8126 cam_error_print(device, ccb, CAM_ESF_ALL,
8127 CAM_EPF_ALL, stderr);
8133 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8135 fprintf(stdout, "%3d <vacant>\n", i);
8139 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8142 item = findsasdevice(&devlist,
8143 scsi_8btou64(disresponse->attached_sas_address));
8147 || (item != NULL)) {
8148 fprintf(stdout, "%3d 0x%016jx", i,
8149 (uintmax_t)scsi_8btou64(
8150 disresponse->attached_sas_address));
8152 fprintf(stdout, "\n");
8155 } else if (quiet != 0)
8158 dev_match = &item->dev_match;
8160 if (dev_match->protocol == PROTO_SCSI) {
8161 cam_strvis(vendor, dev_match->inq_data.vendor,
8162 sizeof(dev_match->inq_data.vendor),
8164 cam_strvis(product, dev_match->inq_data.product,
8165 sizeof(dev_match->inq_data.product),
8167 cam_strvis(revision, dev_match->inq_data.revision,
8168 sizeof(dev_match->inq_data.revision),
8170 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8172 } else if ((dev_match->protocol == PROTO_ATA)
8173 || (dev_match->protocol == PROTO_SATAPM)) {
8174 cam_strvis(product, dev_match->ident_data.model,
8175 sizeof(dev_match->ident_data.model),
8177 cam_strvis(revision, dev_match->ident_data.revision,
8178 sizeof(dev_match->ident_data.revision),
8180 sprintf(tmpstr, "<%s %s>", product, revision);
8182 sprintf(tmpstr, "<>");
8184 fprintf(stdout, " %-33s ", tmpstr);
8187 * If we have 0 periphs, that's a bug...
8189 if (item->num_periphs == 0) {
8190 fprintf(stdout, "\n");
8194 fprintf(stdout, "(");
8195 for (j = 0; j < item->num_periphs; j++) {
8197 fprintf(stdout, ",");
8199 fprintf(stdout, "%s%d",
8200 item->periph_matches[j].periph_name,
8201 item->periph_matches[j].unit_number);
8204 fprintf(stdout, ")\n");
8218 freebusdevlist(&devlist);
8224 atapm(struct cam_device *device, int argc, char **argv,
8225 char *combinedopt, int retry_count, int timeout)
8233 ccb = cam_getccb(device);
8236 warnx("%s: error allocating ccb", __func__);
8240 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8249 if (strcmp(argv[1], "idle") == 0) {
8251 cmd = ATA_IDLE_IMMEDIATE;
8254 } else if (strcmp(argv[1], "standby") == 0) {
8256 cmd = ATA_STANDBY_IMMEDIATE;
8258 cmd = ATA_STANDBY_CMD;
8266 else if (t <= (240 * 5))
8268 else if (t <= (252 * 5))
8269 /* special encoding for 21 minutes */
8271 else if (t <= (11 * 30 * 60))
8272 sc = (t - 1) / (30 * 60) + 241;
8276 retval = ata_do_28bit_cmd(device,
8278 /*retries*/retry_count,
8279 /*flags*/CAM_DIR_NONE,
8280 /*protocol*/AP_PROTO_NON_DATA,
8281 /*tag_action*/MSG_SIMPLE_Q_TAG,
8288 /*timeout*/timeout ? timeout : 30 * 1000,
8296 ataaxm(struct cam_device *device, int argc, char **argv,
8297 char *combinedopt, int retry_count, int timeout)
8305 ccb = cam_getccb(device);
8308 warnx("%s: error allocating ccb", __func__);
8312 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8322 if (strcmp(argv[1], "apm") == 0) {
8338 retval = ata_do_28bit_cmd(device,
8340 /*retries*/retry_count,
8341 /*flags*/CAM_DIR_NONE,
8342 /*protocol*/AP_PROTO_NON_DATA,
8343 /*tag_action*/MSG_SIMPLE_Q_TAG,
8344 /*command*/ATA_SETFEATURES,
8350 /*timeout*/timeout ? timeout : 30 * 1000,
8358 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8359 int show_sa_errors, int sa_set, int service_action,
8360 int timeout_desc, int retry_count, int timeout, int verbosemode,
8361 uint32_t *fill_len, uint8_t **data_ptr)
8363 union ccb *ccb = NULL;
8364 uint8_t *buf = NULL;
8365 uint32_t alloc_len = 0, num_opcodes;
8366 uint32_t valid_len = 0;
8367 uint32_t avail_len = 0;
8368 struct scsi_report_supported_opcodes_all *all_hdr;
8369 struct scsi_report_supported_opcodes_one *one;
8374 * Make it clear that we haven't yet allocated or filled anything.
8379 ccb = cam_getccb(device);
8381 warnx("couldn't allocate CCB");
8386 /* cam_getccb cleans up the header, caller has to zero the payload */
8387 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8389 if (opcode_set != 0) {
8390 options |= RSO_OPTIONS_OC;
8392 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8395 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8396 sizeof(struct scsi_report_supported_opcodes_descr));
8399 if (timeout_desc != 0) {
8400 options |= RSO_RCTD;
8401 alloc_len += num_opcodes *
8402 sizeof(struct scsi_report_supported_opcodes_timeout);
8406 options |= RSO_OPTIONS_OC_SA;
8407 if (show_sa_errors != 0)
8408 options &= ~RSO_OPTIONS_OC;
8417 buf = malloc(alloc_len);
8419 warn("Unable to allocate %u bytes", alloc_len);
8423 bzero(buf, alloc_len);
8425 scsi_report_supported_opcodes(&ccb->csio,
8426 /*retries*/ retry_count,
8428 /*tag_action*/ MSG_SIMPLE_Q_TAG,
8429 /*options*/ options,
8430 /*req_opcode*/ opcode,
8431 /*req_service_action*/ service_action,
8433 /*dxfer_len*/ alloc_len,
8434 /*sense_len*/ SSD_FULL_SIZE,
8435 /*timeout*/ timeout ? timeout : 10000);
8437 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8439 if (retry_count != 0)
8440 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8442 if (cam_send_ccb(device, ccb) < 0) {
8443 perror("error sending REPORT SUPPORTED OPERATION CODES");
8448 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8449 if (verbosemode != 0)
8450 cam_error_print(device, ccb, CAM_ESF_ALL,
8451 CAM_EPF_ALL, stderr);
8457 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8459 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8460 && (valid_len >= sizeof(*all_hdr))) {
8461 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8462 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8463 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8464 && (valid_len >= sizeof(*one))) {
8465 uint32_t cdb_length;
8467 one = (struct scsi_report_supported_opcodes_one *)buf;
8468 cdb_length = scsi_2btoul(one->cdb_length);
8469 avail_len = sizeof(*one) + cdb_length;
8470 if (one->support & RSO_ONE_CTDP) {
8471 struct scsi_report_supported_opcodes_timeout *td;
8473 td = (struct scsi_report_supported_opcodes_timeout *)
8475 if (valid_len >= (avail_len + sizeof(td->length))) {
8476 avail_len += scsi_2btoul(td->length) +
8479 avail_len += sizeof(*td);
8485 * avail_len could be zero if we didn't get enough data back from
8486 * thet target to determine
8488 if ((avail_len != 0)
8489 && (avail_len > valid_len)) {
8490 alloc_len = avail_len;
8494 *fill_len = valid_len;
8506 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8507 int req_sa, uint8_t *buf, uint32_t valid_len)
8509 struct scsi_report_supported_opcodes_one *one;
8510 struct scsi_report_supported_opcodes_timeout *td;
8511 uint32_t cdb_len = 0, td_len = 0;
8512 const char *op_desc = NULL;
8516 one = (struct scsi_report_supported_opcodes_one *)buf;
8519 * If we don't have the full single opcode descriptor, no point in
8522 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8524 warnx("Only %u bytes returned, not enough to verify support",
8530 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8532 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8535 printf(", SA 0x%x", req_sa);
8538 switch (one->support & RSO_ONE_SUP_MASK) {
8539 case RSO_ONE_SUP_UNAVAIL:
8540 printf("No command support information currently available\n");
8542 case RSO_ONE_SUP_NOT_SUP:
8543 printf("Command not supported\n");
8546 break; /*NOTREACHED*/
8547 case RSO_ONE_SUP_AVAIL:
8548 printf("Command is supported, complies with a SCSI standard\n");
8550 case RSO_ONE_SUP_VENDOR:
8551 printf("Command is supported, vendor-specific "
8552 "implementation\n");
8555 printf("Unknown command support flags 0x%#x\n",
8556 one->support & RSO_ONE_SUP_MASK);
8561 * If we don't have the CDB length, it isn't exactly an error, the
8562 * command probably isn't supported.
8564 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8568 cdb_len = scsi_2btoul(one->cdb_length);
8571 * If our valid data doesn't include the full reported length,
8572 * return. The caller should have detected this and adjusted his
8573 * allocation length to get all of the available data.
8575 if (valid_len < sizeof(*one) + cdb_len) {
8581 * If all we have is the opcode, there is no point in printing out
8589 printf("CDB usage bitmap:");
8590 for (i = 0; i < cdb_len; i++) {
8591 printf(" %02x", one->cdb_usage[i]);
8596 * If we don't have a timeout descriptor, we're done.
8598 if ((one->support & RSO_ONE_CTDP) == 0)
8602 * If we don't have enough valid length to include the timeout
8603 * descriptor length, we're done.
8605 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8608 td = (struct scsi_report_supported_opcodes_timeout *)
8609 &buf[sizeof(*one) + cdb_len];
8610 td_len = scsi_2btoul(td->length);
8611 td_len += sizeof(td->length);
8614 * If we don't have the full timeout descriptor, we're done.
8616 if (td_len < sizeof(*td))
8620 * If we don't have enough valid length to contain the full timeout
8621 * descriptor, we're done.
8623 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8626 printf("Timeout information:\n");
8627 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8628 printf("Nominal timeout: %u seconds\n",
8629 scsi_4btoul(td->nominal_time));
8630 printf("Recommended timeout: %u seconds\n",
8631 scsi_4btoul(td->recommended_time));
8638 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8641 struct scsi_report_supported_opcodes_all *hdr;
8642 struct scsi_report_supported_opcodes_descr *desc;
8643 uint32_t avail_len = 0, used_len = 0;
8647 if (valid_len < sizeof(*hdr)) {
8648 warnx("%s: not enough returned data (%u bytes) opcode list",
8649 __func__, valid_len);
8653 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8654 avail_len = scsi_4btoul(hdr->length);
8655 avail_len += sizeof(hdr->length);
8657 * Take the lesser of the amount of data the drive claims is
8658 * available, and the amount of data the HBA says was returned.
8660 avail_len = MIN(avail_len, valid_len);
8662 used_len = sizeof(hdr->length);
8664 printf("%-6s %4s %8s ",
8665 "Opcode", "SA", "CDB len" );
8668 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8669 printf(" Description\n");
8671 while ((avail_len - used_len) > sizeof(*desc)) {
8672 struct scsi_report_supported_opcodes_timeout *td;
8674 const char *op_desc = NULL;
8676 cur_ptr = &buf[used_len];
8677 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8679 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8680 if (op_desc == NULL)
8681 op_desc = "UNKNOWN";
8683 printf("0x%02x %#4x %8u ", desc->opcode,
8684 scsi_2btoul(desc->service_action),
8685 scsi_2btoul(desc->cdb_length));
8687 used_len += sizeof(*desc);
8689 if ((desc->flags & RSO_CTDP) == 0) {
8690 printf(" %s\n", op_desc);
8695 * If we don't have enough space to fit a timeout
8696 * descriptor, then we're done.
8698 if (avail_len - used_len < sizeof(*td)) {
8699 used_len = avail_len;
8700 printf(" %s\n", op_desc);
8703 cur_ptr = &buf[used_len];
8704 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8705 td_len = scsi_2btoul(td->length);
8706 td_len += sizeof(td->length);
8710 * If the given timeout descriptor length is less than what
8711 * we understand, skip it.
8713 if (td_len < sizeof(*td)) {
8714 printf(" %s\n", op_desc);
8718 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8719 scsi_4btoul(td->nominal_time),
8720 scsi_4btoul(td->recommended_time), op_desc);
8727 scsiopcodes(struct cam_device *device, int argc, char **argv,
8728 char *combinedopt, int retry_count, int timeout, int verbosemode)
8731 uint32_t opcode = 0, service_action = 0;
8732 int td_set = 0, opcode_set = 0, sa_set = 0;
8733 int show_sa_errors = 1;
8734 uint32_t valid_len = 0;
8735 uint8_t *buf = NULL;
8739 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8745 opcode = strtoul(optarg, &endptr, 0);
8746 if (*endptr != '\0') {
8747 warnx("Invalid opcode \"%s\", must be a number",
8752 if (opcode > 0xff) {
8753 warnx("Invalid opcode 0x%#x, must be between"
8754 "0 and 0xff inclusive", opcode);
8761 service_action = strtoul(optarg, &endptr, 0);
8762 if (*endptr != '\0') {
8763 warnx("Invalid service action \"%s\", must "
8764 "be a number", optarg);
8768 if (service_action > 0xffff) {
8769 warnx("Invalid service action 0x%#x, must "
8770 "be between 0 and 0xffff inclusive",
8785 && (opcode_set == 0)) {
8786 warnx("You must specify an opcode with -o if a service "
8791 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8792 sa_set, service_action, td_set, retry_count,
8793 timeout, verbosemode, &valid_len, &buf);
8797 if ((opcode_set != 0)
8799 retval = scsiprintoneopcode(device, opcode, sa_set,
8800 service_action, buf, valid_len);
8802 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8811 #endif /* MINIMALISTIC */
8814 scsireprobe(struct cam_device *device)
8819 ccb = cam_getccb(device);
8822 warnx("%s: error allocating ccb", __func__);
8826 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8828 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8830 if (cam_send_ccb(device, ccb) < 0) {
8831 warn("error sending XPT_REPROBE_LUN CCB");
8836 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8837 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8849 usage(int printlong)
8852 fprintf(printlong ? stdout : stderr,
8853 "usage: camcontrol <command> [device id][generic args][command args]\n"
8854 " camcontrol devlist [-b] [-v]\n"
8855 #ifndef MINIMALISTIC
8856 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8857 " camcontrol tur [dev_id][generic args]\n"
8858 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8859 " camcontrol identify [dev_id][generic args] [-v]\n"
8860 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8861 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8863 " camcontrol start [dev_id][generic args]\n"
8864 " camcontrol stop [dev_id][generic args]\n"
8865 " camcontrol load [dev_id][generic args]\n"
8866 " camcontrol eject [dev_id][generic args]\n"
8867 " camcontrol reprobe [dev_id][generic args]\n"
8868 #endif /* MINIMALISTIC */
8869 " camcontrol rescan <all | bus[:target:lun]>\n"
8870 " camcontrol reset <all | bus[:target:lun]>\n"
8871 #ifndef MINIMALISTIC
8872 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8873 " [-q][-s][-S offset][-X]\n"
8874 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8875 " [-P pagectl][-e | -b][-d]\n"
8876 " camcontrol cmd [dev_id][generic args]\n"
8877 " <-a cmd [args] | -c cmd [args]>\n"
8878 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8879 " camcontrol smpcmd [dev_id][generic args]\n"
8880 " <-r len fmt [args]> <-R len fmt [args]>\n"
8881 " camcontrol smprg [dev_id][generic args][-l]\n"
8882 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8883 " [-o operation][-d name][-m rate][-M rate]\n"
8884 " [-T pp_timeout][-a enable|disable]\n"
8885 " [-A enable|disable][-s enable|disable]\n"
8886 " [-S enable|disable]\n"
8887 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8888 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8889 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8890 " <all|bus[:target[:lun]]|off>\n"
8891 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8892 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8893 " [-D <enable|disable>][-M mode][-O offset]\n"
8894 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8895 " [-U][-W bus_width]\n"
8896 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8897 " camcontrol sanitize [dev_id][generic args]\n"
8898 " [-a overwrite|block|crypto|exitfailure]\n"
8899 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8901 " camcontrol idle [dev_id][generic args][-t time]\n"
8902 " camcontrol standby [dev_id][generic args][-t time]\n"
8903 " camcontrol sleep [dev_id][generic args]\n"
8904 " camcontrol apm [dev_id][generic args][-l level]\n"
8905 " camcontrol aam [dev_id][generic args][-l level]\n"
8906 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8908 " camcontrol security [dev_id][generic args]\n"
8909 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8910 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8911 " [-U <user|master>] [-y]\n"
8912 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8913 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8914 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8915 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8916 " [-s scope][-S][-T type][-U]\n"
8917 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8918 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8919 " [-p part][-s start][-T type][-V vol]\n"
8920 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8922 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
8923 " [-o rep_opts] [-P print_opts]\n"
8924 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
8925 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
8926 " [-S power_src] [-T timer]\n"
8927 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
8928 " <-s <-f format -T time | -U >>\n"
8930 #endif /* MINIMALISTIC */
8931 " camcontrol help\n");
8934 #ifndef MINIMALISTIC
8936 "Specify one of the following options:\n"
8937 "devlist list all CAM devices\n"
8938 "periphlist list all CAM peripheral drivers attached to a device\n"
8939 "tur send a test unit ready to the named device\n"
8940 "inquiry send a SCSI inquiry command to the named device\n"
8941 "identify send a ATA identify command to the named device\n"
8942 "reportluns send a SCSI report luns command to the device\n"
8943 "readcap send a SCSI read capacity command to the device\n"
8944 "start send a Start Unit command to the device\n"
8945 "stop send a Stop Unit command to the device\n"
8946 "load send a Start Unit command to the device with the load bit set\n"
8947 "eject send a Stop Unit command to the device with the eject bit set\n"
8948 "reprobe update capacity information of the given device\n"
8949 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8950 "reset reset all busses, the given bus, or bus:target:lun\n"
8951 "defects read the defect list of the specified device\n"
8952 "modepage display or edit (-e) the given mode page\n"
8953 "cmd send the given SCSI command, may need -i or -o as well\n"
8954 "smpcmd send the given SMP command, requires -o and -i\n"
8955 "smprg send the SMP Report General command\n"
8956 "smppc send the SMP PHY Control command, requires -p\n"
8957 "smpphylist display phys attached to a SAS expander\n"
8958 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8959 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8960 "tags report or set the number of transaction slots for a device\n"
8961 "negotiate report or set device negotiation parameters\n"
8962 "format send the SCSI FORMAT UNIT command to the named device\n"
8963 "sanitize send the SCSI SANITIZE command to the named device\n"
8964 "idle send the ATA IDLE command to the named device\n"
8965 "standby send the ATA STANDBY command to the named device\n"
8966 "sleep send the ATA SLEEP command to the named device\n"
8967 "fwdownload program firmware of the named device with the given image\n"
8968 "security report or send ATA security commands to the named device\n"
8969 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8970 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8971 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8972 "zone manage Zoned Block (Shingled) devices\n"
8973 "epc send ATA Extended Power Conditions commands\n"
8974 "timestamp report or set the device's timestamp\n"
8975 "help this message\n"
8976 "Device Identifiers:\n"
8977 "bus:target specify the bus and target, lun defaults to 0\n"
8978 "bus:target:lun specify the bus, target and lun\n"
8979 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8980 "Generic arguments:\n"
8981 "-v be verbose, print out sense information\n"
8982 "-t timeout command timeout in seconds, overrides default timeout\n"
8983 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8984 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8985 "-E have the kernel attempt to perform SCSI error recovery\n"
8986 "-C count specify the SCSI command retry count (needs -E to work)\n"
8987 "modepage arguments:\n"
8988 "-l list all available mode pages\n"
8989 "-m page specify the mode page to view or edit\n"
8990 "-e edit the specified mode page\n"
8991 "-b force view to binary mode\n"
8992 "-d disable block descriptors for mode sense\n"
8993 "-P pgctl page control field 0-3\n"
8994 "defects arguments:\n"
8995 "-f format specify defect list format (block, bfi or phys)\n"
8996 "-G get the grown defect list\n"
8997 "-P get the permanent defect list\n"
8998 "inquiry arguments:\n"
8999 "-D get the standard inquiry data\n"
9000 "-S get the serial number\n"
9001 "-R get the transfer rate, etc.\n"
9002 "reportluns arguments:\n"
9003 "-c only report a count of available LUNs\n"
9004 "-l only print out luns, and not a count\n"
9005 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9006 "readcap arguments\n"
9007 "-b only report the blocksize\n"
9008 "-h human readable device size, base 2\n"
9009 "-H human readable device size, base 10\n"
9010 "-N print the number of blocks instead of last block\n"
9011 "-q quiet, print numbers only\n"
9012 "-s only report the last block/device size\n"
9014 "-c cdb [args] specify the SCSI CDB\n"
9015 "-i len fmt specify input data and input data format\n"
9016 "-o len fmt [args] specify output data and output data fmt\n"
9017 "smpcmd arguments:\n"
9018 "-r len fmt [args] specify the SMP command to be sent\n"
9019 "-R len fmt [args] specify SMP response format\n"
9020 "smprg arguments:\n"
9021 "-l specify the long response format\n"
9022 "smppc arguments:\n"
9023 "-p phy specify the PHY to operate on\n"
9024 "-l specify the long request/response format\n"
9025 "-o operation specify the phy control operation\n"
9026 "-d name set the attached device name\n"
9027 "-m rate set the minimum physical link rate\n"
9028 "-M rate set the maximum physical link rate\n"
9029 "-T pp_timeout set the partial pathway timeout value\n"
9030 "-a enable|disable enable or disable SATA slumber\n"
9031 "-A enable|disable enable or disable SATA partial phy power\n"
9032 "-s enable|disable enable or disable SAS slumber\n"
9033 "-S enable|disable enable or disable SAS partial phy power\n"
9034 "smpphylist arguments:\n"
9035 "-l specify the long response format\n"
9036 "-q only print phys with attached devices\n"
9037 "smpmaninfo arguments:\n"
9038 "-l specify the long response format\n"
9039 "debug arguments:\n"
9040 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9041 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9042 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9043 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9045 "-N tags specify the number of tags to use for this device\n"
9046 "-q be quiet, don't report the number of tags\n"
9047 "-v report a number of tag-related parameters\n"
9048 "negotiate arguments:\n"
9049 "-a send a test unit ready after negotiation\n"
9050 "-c report/set current negotiation settings\n"
9051 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9052 "-M mode set ATA mode\n"
9053 "-O offset set command delay offset\n"
9054 "-q be quiet, don't report anything\n"
9055 "-R syncrate synchronization rate in MHz\n"
9056 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9057 "-U report/set user negotiation settings\n"
9058 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9059 "-v also print a Path Inquiry CCB for the controller\n"
9060 "format arguments:\n"
9061 "-q be quiet, don't print status messages\n"
9062 "-r run in report only mode\n"
9063 "-w don't send immediate format command\n"
9064 "-y don't ask any questions\n"
9065 "sanitize arguments:\n"
9066 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9067 "-c passes overwrite passes to perform (1 to 31)\n"
9068 "-I invert overwrite pattern after each pass\n"
9069 "-P pattern path to overwrite pattern file\n"
9070 "-q be quiet, don't print status messages\n"
9071 "-r run in report only mode\n"
9072 "-U run operation in unrestricted completion exit mode\n"
9073 "-w don't send immediate sanitize command\n"
9074 "-y don't ask any questions\n"
9075 "idle/standby arguments:\n"
9076 "-t <arg> number of seconds before respective state.\n"
9077 "fwdownload arguments:\n"
9078 "-f fw_image path to firmware image file\n"
9079 "-q don't print informational messages, only errors\n"
9080 "-s run in simulation mode\n"
9081 "-v print info for every firmware segment sent to device\n"
9082 "-y don't ask any questions\n"
9083 "security arguments:\n"
9084 "-d pwd disable security using the given password for the selected\n"
9086 "-e pwd erase the device using the given pwd for the selected user\n"
9087 "-f freeze the security configuration of the specified device\n"
9088 "-h pwd enhanced erase the device using the given pwd for the\n"
9090 "-k pwd unlock the device using the given pwd for the selected\n"
9092 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9093 "-q be quiet, do not print any status messages\n"
9094 "-s pwd password the device (enable security) using the given\n"
9095 " pwd for the selected user\n"
9096 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9097 "-U <user|master> specifies which user to set: user or master\n"
9098 "-y don't ask any questions\n"
9100 "-f freeze the HPA configuration of the device\n"
9101 "-l lock the HPA configuration of the device\n"
9102 "-P make the HPA max sectors persist\n"
9103 "-p pwd Set the HPA configuration password required for unlock\n"
9105 "-q be quiet, do not print any status messages\n"
9106 "-s sectors configures the maximum user accessible sectors of the\n"
9108 "-U pwd unlock the HPA configuration of the device\n"
9109 "-y don't ask any questions\n"
9110 "persist arguments:\n"
9111 "-i action specify read_keys, read_reservation, report_cap, or\n"
9112 " read_full_status\n"
9113 "-o action specify register, register_ignore, reserve, release,\n"
9114 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9115 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9116 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9117 "-k key specify the Reservation Key\n"
9118 "-K sa_key specify the Service Action Reservation Key\n"
9119 "-p set the Activate Persist Through Power Loss bit\n"
9120 "-R rtp specify the Relative Target Port\n"
9121 "-s scope specify the scope: lun, extent, element or a number\n"
9122 "-S specify Transport ID for register, requires -I\n"
9123 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9124 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9125 "-U unregister the current initiator for register_move\n"
9126 "attrib arguments:\n"
9127 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9129 "-w attr specify an attribute to write, one -w argument per attr\n"
9130 "-a attr_num only display this attribute number\n"
9131 "-c get cached attributes\n"
9132 "-e elem_addr request attributes for the given element in a changer\n"
9133 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9134 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9135 " field_none, field_desc, field_num, field_size, field_rw\n"
9136 "-p partition request attributes for the given partition\n"
9137 "-s start_attr request attributes starting at the given number\n"
9138 "-T elem_type specify the element type (used with -e)\n"
9139 "-V logical_vol specify the logical volume ID\n"
9140 "opcodes arguments:\n"
9141 "-o opcode specify the individual opcode to list\n"
9142 "-s service_action specify the service action for the opcode\n"
9143 "-N do not return SCSI error for unsupported SA\n"
9144 "-T request nominal and recommended timeout values\n"
9146 "-c cmd required: rz, open, close, finish, or rwp\n"
9147 "-a apply the action to all zones\n"
9148 "-l LBA specify the zone starting LBA\n"
9149 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9150 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9151 "-P print_opt report zones printing: normal, summary, script\n"
9153 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9154 " source, status, list\n"
9155 "-d disable power mode (timer, state)\n"
9156 "-D delayed entry (goto)\n"
9157 "-e enable power mode (timer, state)\n"
9158 "-H hold power mode (goto)\n"
9159 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9161 "-P only display power mode (status)\n"
9162 "-r rst_src restore settings from: default, saved (restore)\n"
9163 "-s save mode (timer, state, restore)\n"
9164 "-S power_src set power source: battery, nonbattery (source)\n"
9165 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9166 "timestamp arguments:\n"
9167 "-r report the timestamp of the device\n"
9168 "-f format report the timestamp of the device with the given\n"
9169 " strftime(3) format string\n"
9170 "-m report the timestamp of the device as milliseconds since\n"
9171 " January 1st, 1970\n"
9172 "-U report the time with UTC instead of the local time zone\n"
9173 "-s set the timestamp of the device\n"
9174 "-f format the format of the time string passed into strptime(3)\n"
9175 "-T time the time value passed into strptime(3)\n"
9176 "-U set the timestamp of the device to UTC time\n"
9178 #endif /* MINIMALISTIC */
9182 main(int argc, char **argv)
9185 char *device = NULL;
9187 struct cam_device *cam_dev = NULL;
9188 int timeout = 0, retry_count = 1;
9189 camcontrol_optret optreturn;
9191 const char *mainopt = "C:En:t:u:v";
9192 const char *subopt = NULL;
9193 char combinedopt[256];
9194 int error = 0, optstart = 2;
9196 #ifndef MINIMALISTIC
9200 #endif /* MINIMALISTIC */
9202 cmdlist = CAM_CMD_NONE;
9203 arglist = CAM_ARG_NONE;
9211 * Get the base option.
9213 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9215 if (optreturn == CC_OR_AMBIGUOUS) {
9216 warnx("ambiguous option %s", argv[1]);
9219 } else if (optreturn == CC_OR_NOT_FOUND) {
9220 warnx("option %s not found", argv[1]);
9226 * Ahh, getopt(3) is a pain.
9228 * This is a gross hack. There really aren't many other good
9229 * options (excuse the pun) for parsing options in a situation like
9230 * this. getopt is kinda braindead, so you end up having to run
9231 * through the options twice, and give each invocation of getopt
9232 * the option string for the other invocation.
9234 * You would think that you could just have two groups of options.
9235 * The first group would get parsed by the first invocation of
9236 * getopt, and the second group would get parsed by the second
9237 * invocation of getopt. It doesn't quite work out that way. When
9238 * the first invocation of getopt finishes, it leaves optind pointing
9239 * to the argument _after_ the first argument in the second group.
9240 * So when the second invocation of getopt comes around, it doesn't
9241 * recognize the first argument it gets and then bails out.
9243 * A nice alternative would be to have a flag for getopt that says
9244 * "just keep parsing arguments even when you encounter an unknown
9245 * argument", but there isn't one. So there's no real clean way to
9246 * easily parse two sets of arguments without having one invocation
9247 * of getopt know about the other.
9249 * Without this hack, the first invocation of getopt would work as
9250 * long as the generic arguments are first, but the second invocation
9251 * (in the subfunction) would fail in one of two ways. In the case
9252 * where you don't set optreset, it would fail because optind may be
9253 * pointing to the argument after the one it should be pointing at.
9254 * In the case where you do set optreset, and reset optind, it would
9255 * fail because getopt would run into the first set of options, which
9256 * it doesn't understand.
9258 * All of this would "sort of" work if you could somehow figure out
9259 * whether optind had been incremented one option too far. The
9260 * mechanics of that, however, are more daunting than just giving
9261 * both invocations all of the expect options for either invocation.
9263 * Needless to say, I wouldn't mind if someone invented a better
9264 * (non-GPL!) command line parsing interface than getopt. I
9265 * wouldn't mind if someone added more knobs to getopt to make it
9266 * work better. Who knows, I may talk myself into doing it someday,
9267 * if the standards weenies let me. As it is, it just leads to
9268 * hackery like this and causes people to avoid it in some cases.
9270 * KDM, September 8th, 1998
9273 sprintf(combinedopt, "%s%s", mainopt, subopt);
9275 sprintf(combinedopt, "%s", mainopt);
9278 * For these options we do not parse optional device arguments and
9279 * we do not open a passthrough device.
9281 if ((cmdlist == CAM_CMD_RESCAN)
9282 || (cmdlist == CAM_CMD_RESET)
9283 || (cmdlist == CAM_CMD_DEVTREE)
9284 || (cmdlist == CAM_CMD_USAGE)
9285 || (cmdlist == CAM_CMD_DEBUG))
9288 #ifndef MINIMALISTIC
9290 && (argc > 2 && argv[2][0] != '-')) {
9294 if (isdigit(argv[2][0])) {
9295 /* device specified as bus:target[:lun] */
9296 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9298 errx(1, "numeric device specification must "
9299 "be either bus:target, or "
9301 /* default to 0 if lun was not specified */
9302 if ((arglist & CAM_ARG_LUN) == 0) {
9304 arglist |= CAM_ARG_LUN;
9308 if (cam_get_device(argv[2], name, sizeof name, &unit)
9310 errx(1, "%s", cam_errbuf);
9311 device = strdup(name);
9312 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9316 #endif /* MINIMALISTIC */
9318 * Start getopt processing at argv[2/3], since we've already
9319 * accepted argv[1..2] as the command name, and as a possible
9325 * Now we run through the argument list looking for generic
9326 * options, and ignoring options that possibly belong to
9329 while ((c = getopt(argc, argv, combinedopt))!= -1){
9332 retry_count = strtol(optarg, NULL, 0);
9333 if (retry_count < 0)
9334 errx(1, "retry count %d is < 0",
9336 arglist |= CAM_ARG_RETRIES;
9339 arglist |= CAM_ARG_ERR_RECOVER;
9342 arglist |= CAM_ARG_DEVICE;
9344 while (isspace(*tstr) && (*tstr != '\0'))
9346 device = (char *)strdup(tstr);
9349 timeout = strtol(optarg, NULL, 0);
9351 errx(1, "invalid timeout %d", timeout);
9352 /* Convert the timeout from seconds to ms */
9354 arglist |= CAM_ARG_TIMEOUT;
9357 arglist |= CAM_ARG_UNIT;
9358 unit = strtol(optarg, NULL, 0);
9361 arglist |= CAM_ARG_VERBOSE;
9368 #ifndef MINIMALISTIC
9370 * For most commands we'll want to open the passthrough device
9371 * associated with the specified device. In the case of the rescan
9372 * commands, we don't use a passthrough device at all, just the
9373 * transport layer device.
9376 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9377 && (((arglist & CAM_ARG_DEVICE) == 0)
9378 || ((arglist & CAM_ARG_UNIT) == 0))) {
9379 errx(1, "subcommand \"%s\" requires a valid device "
9380 "identifier", argv[1]);
9383 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9384 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9385 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9387 errx(1,"%s", cam_errbuf);
9389 #endif /* MINIMALISTIC */
9392 * Reset optind to 2, and reset getopt, so these routines can parse
9393 * the arguments again.
9399 #ifndef MINIMALISTIC
9400 case CAM_CMD_DEVLIST:
9401 error = getdevlist(cam_dev);
9404 error = atahpa(cam_dev, retry_count, timeout,
9405 argc, argv, combinedopt);
9407 #endif /* MINIMALISTIC */
9408 case CAM_CMD_DEVTREE:
9409 error = getdevtree(argc, argv, combinedopt);
9411 #ifndef MINIMALISTIC
9413 error = testunitready(cam_dev, retry_count, timeout, 0);
9415 case CAM_CMD_INQUIRY:
9416 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9417 retry_count, timeout);
9419 case CAM_CMD_IDENTIFY:
9420 error = ataidentify(cam_dev, retry_count, timeout);
9422 case CAM_CMD_STARTSTOP:
9423 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9424 arglist & CAM_ARG_EJECT, retry_count,
9427 #endif /* MINIMALISTIC */
9428 case CAM_CMD_RESCAN:
9429 error = dorescan_or_reset(argc, argv, 1);
9432 error = dorescan_or_reset(argc, argv, 0);
9434 #ifndef MINIMALISTIC
9435 case CAM_CMD_READ_DEFECTS:
9436 error = readdefects(cam_dev, argc, argv, combinedopt,
9437 retry_count, timeout);
9439 case CAM_CMD_MODE_PAGE:
9440 modepage(cam_dev, argc, argv, combinedopt,
9441 retry_count, timeout);
9443 case CAM_CMD_SCSI_CMD:
9444 error = scsicmd(cam_dev, argc, argv, combinedopt,
9445 retry_count, timeout);
9447 case CAM_CMD_SMP_CMD:
9448 error = smpcmd(cam_dev, argc, argv, combinedopt,
9449 retry_count, timeout);
9451 case CAM_CMD_SMP_RG:
9452 error = smpreportgeneral(cam_dev, argc, argv,
9453 combinedopt, retry_count,
9456 case CAM_CMD_SMP_PC:
9457 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9458 retry_count, timeout);
9460 case CAM_CMD_SMP_PHYLIST:
9461 error = smpphylist(cam_dev, argc, argv, combinedopt,
9462 retry_count, timeout);
9464 case CAM_CMD_SMP_MANINFO:
9465 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9466 retry_count, timeout);
9469 error = camdebug(argc, argv, combinedopt);
9472 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9475 error = ratecontrol(cam_dev, retry_count, timeout,
9476 argc, argv, combinedopt);
9478 case CAM_CMD_FORMAT:
9479 error = scsiformat(cam_dev, argc, argv,
9480 combinedopt, retry_count, timeout);
9482 case CAM_CMD_REPORTLUNS:
9483 error = scsireportluns(cam_dev, argc, argv,
9484 combinedopt, retry_count,
9487 case CAM_CMD_READCAP:
9488 error = scsireadcapacity(cam_dev, argc, argv,
9489 combinedopt, retry_count,
9493 case CAM_CMD_STANDBY:
9495 error = atapm(cam_dev, argc, argv,
9496 combinedopt, retry_count, timeout);
9500 error = ataaxm(cam_dev, argc, argv,
9501 combinedopt, retry_count, timeout);
9503 case CAM_CMD_SECURITY:
9504 error = atasecurity(cam_dev, retry_count, timeout,
9505 argc, argv, combinedopt);
9507 case CAM_CMD_DOWNLOAD_FW:
9508 error = fwdownload(cam_dev, argc, argv, combinedopt,
9509 arglist & CAM_ARG_VERBOSE, retry_count, timeout);
9511 case CAM_CMD_SANITIZE:
9512 error = scsisanitize(cam_dev, argc, argv,
9513 combinedopt, retry_count, timeout);
9515 case CAM_CMD_PERSIST:
9516 error = scsipersist(cam_dev, argc, argv, combinedopt,
9517 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9518 arglist & CAM_ARG_ERR_RECOVER);
9520 case CAM_CMD_ATTRIB:
9521 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9522 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9523 arglist & CAM_ARG_ERR_RECOVER);
9525 case CAM_CMD_OPCODES:
9526 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9527 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9529 case CAM_CMD_REPROBE:
9530 error = scsireprobe(cam_dev);
9533 error = zone(cam_dev, argc, argv, combinedopt,
9534 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9537 error = epc(cam_dev, argc, argv, combinedopt,
9538 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9540 case CAM_CMD_TIMESTAMP:
9541 error = timestamp(cam_dev, argc, argv, combinedopt,
9542 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9544 #endif /* MINIMALISTIC */
9554 if (cam_dev != NULL)
9555 cam_close_device(cam_dev);