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
110 CAM_ARG_NONE = 0x00000000,
111 CAM_ARG_VERBOSE = 0x00000001,
112 CAM_ARG_DEVICE = 0x00000002,
113 CAM_ARG_BUS = 0x00000004,
114 CAM_ARG_TARGET = 0x00000008,
115 CAM_ARG_LUN = 0x00000010,
116 CAM_ARG_EJECT = 0x00000020,
117 CAM_ARG_UNIT = 0x00000040,
118 CAM_ARG_FORMAT_BLOCK = 0x00000080,
119 CAM_ARG_FORMAT_BFI = 0x00000100,
120 CAM_ARG_FORMAT_PHYS = 0x00000200,
121 CAM_ARG_PLIST = 0x00000400,
122 CAM_ARG_GLIST = 0x00000800,
123 CAM_ARG_GET_SERIAL = 0x00001000,
124 CAM_ARG_GET_STDINQ = 0x00002000,
125 CAM_ARG_GET_XFERRATE = 0x00004000,
126 CAM_ARG_INQ_MASK = 0x00007000,
127 CAM_ARG_MODE_EDIT = 0x00008000,
128 CAM_ARG_PAGE_CNTL = 0x00010000,
129 CAM_ARG_TIMEOUT = 0x00020000,
130 CAM_ARG_CMD_IN = 0x00040000,
131 CAM_ARG_CMD_OUT = 0x00080000,
132 CAM_ARG_DBD = 0x00100000,
133 CAM_ARG_ERR_RECOVER = 0x00200000,
134 CAM_ARG_RETRIES = 0x00400000,
135 CAM_ARG_START_UNIT = 0x00800000,
136 CAM_ARG_DEBUG_INFO = 0x01000000,
137 CAM_ARG_DEBUG_TRACE = 0x02000000,
138 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
139 CAM_ARG_DEBUG_CDB = 0x08000000,
140 CAM_ARG_DEBUG_XPT = 0x10000000,
141 CAM_ARG_DEBUG_PERIPH = 0x20000000,
142 CAM_ARG_DEBUG_PROBE = 0x40000000,
145 struct camcontrol_opts {
153 struct ata_res_pass16 {
154 u_int16_t reserved[5];
157 u_int8_t sector_count_exp;
158 u_int8_t sector_count;
159 u_int8_t lba_low_exp;
161 u_int8_t lba_mid_exp;
163 u_int8_t lba_high_exp;
169 struct ata_set_max_pwd
172 u_int8_t password[32];
173 u_int16_t reserved2[239];
176 static const char scsicmd_opts[] = "a:c:dfi:o:r";
177 static const char readdefect_opts[] = "f:GPqsS:X";
178 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
179 static const char smprg_opts[] = "l";
180 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
181 static const char smpphylist_opts[] = "lq";
185 static struct camcontrol_opts option_table[] = {
187 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
188 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
189 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
190 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
191 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
192 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
193 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
194 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
195 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
196 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
197 #endif /* MINIMALISTIC */
198 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
199 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
201 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
202 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
203 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
204 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
205 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
206 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
207 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
208 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
209 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
210 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
211 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
212 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
213 #endif /* MINIMALISTIC */
214 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
216 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
217 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
218 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
219 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
220 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
221 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
222 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
223 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
224 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
225 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
226 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
227 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
228 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
229 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
230 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
231 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
232 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
233 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
234 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
235 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
236 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
237 #endif /* MINIMALISTIC */
238 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
239 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
240 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
245 struct device_match_result dev_match;
247 struct periph_match_result *periph_matches;
248 struct scsi_vpd_device_id *device_id;
250 STAILQ_ENTRY(cam_devitem) links;
254 STAILQ_HEAD(, cam_devitem) dev_queue;
258 static cam_cmdmask cmdlist;
259 static cam_argmask arglist;
261 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
262 uint32_t *cmdnum, cam_argmask *argnum,
263 const char **subopt);
265 static int getdevlist(struct cam_device *device);
266 #endif /* MINIMALISTIC */
267 static int getdevtree(int argc, char **argv, char *combinedopt);
269 static int testunitready(struct cam_device *device, int retry_count,
270 int timeout, int quiet);
271 static int scsistart(struct cam_device *device, int startstop, int loadeject,
272 int retry_count, int timeout);
273 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
274 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
275 #endif /* MINIMALISTIC */
276 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
277 lun_id_t *lun, cam_argmask *arglst);
278 static int dorescan_or_reset(int argc, char **argv, int rescan);
279 static int rescan_or_reset_bus(path_id_t bus, int rescan);
280 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
281 lun_id_t lun, int scan);
283 static int readdefects(struct cam_device *device, int argc, char **argv,
284 char *combinedopt, int retry_count, int timeout);
285 static void modepage(struct cam_device *device, int argc, char **argv,
286 char *combinedopt, int retry_count, int timeout);
287 static int scsicmd(struct cam_device *device, int argc, char **argv,
288 char *combinedopt, int retry_count, int timeout);
289 static int smpcmd(struct cam_device *device, int argc, char **argv,
290 char *combinedopt, int retry_count, int timeout);
291 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
292 char *combinedopt, int retry_count, int timeout);
293 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
294 char *combinedopt, int retry_count, int timeout);
295 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
296 char *combinedopt, int retry_count, int timeout);
297 static int getdevid(struct cam_devitem *item);
298 static int buildbusdevlist(struct cam_devlist *devlist);
299 static void freebusdevlist(struct cam_devlist *devlist);
300 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
302 static int smpphylist(struct cam_device *device, int argc, char **argv,
303 char *combinedopt, int retry_count, int timeout);
304 static int tagcontrol(struct cam_device *device, int argc, char **argv,
306 static void cts_print(struct cam_device *device,
307 struct ccb_trans_settings *cts);
308 static void cpi_print(struct ccb_pathinq *cpi);
309 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
310 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
311 static int get_print_cts(struct cam_device *device, int user_settings,
312 int quiet, struct ccb_trans_settings *cts);
313 static int ratecontrol(struct cam_device *device, int retry_count,
314 int timeout, int argc, char **argv, char *combinedopt);
315 static int scsiformat(struct cam_device *device, int argc, char **argv,
316 char *combinedopt, int retry_count, int timeout);
317 static int scsisanitize(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int scsireportluns(struct cam_device *device, int argc, char **argv,
320 char *combinedopt, int retry_count, int timeout);
321 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
322 char *combinedopt, int retry_count, int timeout);
323 static int atapm(struct cam_device *device, int argc, char **argv,
324 char *combinedopt, int retry_count, int timeout);
325 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
326 int argc, char **argv, char *combinedopt);
327 static int atahpa(struct cam_device *device, int retry_count, int timeout,
328 int argc, char **argv, char *combinedopt);
329 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
330 int sa_set, int req_sa, uint8_t *buf,
332 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
334 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
335 char *combinedopt, int retry_count, int timeout,
337 static int scsireprobe(struct cam_device *device);
339 #endif /* MINIMALISTIC */
341 #define min(a,b) (((a)<(b))?(a):(b))
344 #define max(a,b) (((a)>(b))?(a):(b))
348 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
349 cam_argmask *argnum, const char **subopt)
351 struct camcontrol_opts *opts;
354 for (opts = table; (opts != NULL) && (opts->optname != NULL);
356 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
357 *cmdnum = opts->cmdnum;
358 *argnum = opts->argnum;
359 *subopt = opts->subopt;
360 if (++num_matches > 1)
361 return(CC_OR_AMBIGUOUS);
368 return(CC_OR_NOT_FOUND);
373 getdevlist(struct cam_device *device)
379 ccb = cam_getccb(device);
381 ccb->ccb_h.func_code = XPT_GDEVLIST;
382 ccb->ccb_h.flags = CAM_DIR_NONE;
383 ccb->ccb_h.retry_count = 1;
385 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
386 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
387 if (cam_send_ccb(device, ccb) < 0) {
388 perror("error getting device list");
395 switch (ccb->cgdl.status) {
396 case CAM_GDEVLIST_MORE_DEVS:
397 strcpy(status, "MORE");
399 case CAM_GDEVLIST_LAST_DEVICE:
400 strcpy(status, "LAST");
402 case CAM_GDEVLIST_LIST_CHANGED:
403 strcpy(status, "CHANGED");
405 case CAM_GDEVLIST_ERROR:
406 strcpy(status, "ERROR");
411 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
412 ccb->cgdl.periph_name,
413 ccb->cgdl.unit_number,
414 ccb->cgdl.generation,
419 * If the list has changed, we need to start over from the
422 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
430 #endif /* MINIMALISTIC */
433 getdevtree(int argc, char **argv, char *combinedopt)
444 while ((c = getopt(argc, argv, combinedopt)) != -1) {
447 if ((arglist & CAM_ARG_VERBOSE) == 0)
455 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
456 warn("couldn't open %s", XPT_DEVICE);
460 bzero(&ccb, sizeof(union ccb));
462 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
463 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
464 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
466 ccb.ccb_h.func_code = XPT_DEV_MATCH;
467 bufsize = sizeof(struct dev_match_result) * 100;
468 ccb.cdm.match_buf_len = bufsize;
469 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
470 if (ccb.cdm.matches == NULL) {
471 warnx("can't malloc memory for matches");
475 ccb.cdm.num_matches = 0;
478 * We fetch all nodes, since we display most of them in the default
479 * case, and all in the verbose case.
481 ccb.cdm.num_patterns = 0;
482 ccb.cdm.pattern_buf_len = 0;
485 * We do the ioctl multiple times if necessary, in case there are
486 * more than 100 nodes in the EDT.
489 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
490 warn("error sending CAMIOCOMMAND ioctl");
495 if ((ccb.ccb_h.status != CAM_REQ_CMP)
496 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
497 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
498 warnx("got CAM error %#x, CDM error %d\n",
499 ccb.ccb_h.status, ccb.cdm.status);
504 for (i = 0; i < ccb.cdm.num_matches; i++) {
505 switch (ccb.cdm.matches[i].type) {
506 case DEV_MATCH_BUS: {
507 struct bus_match_result *bus_result;
510 * Only print the bus information if the
511 * user turns on the verbose flag.
513 if ((busonly == 0) &&
514 (arglist & CAM_ARG_VERBOSE) == 0)
518 &ccb.cdm.matches[i].result.bus_result;
521 fprintf(stdout, ")\n");
525 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
527 bus_result->dev_name,
528 bus_result->unit_number,
530 (busonly ? "" : ":"));
533 case DEV_MATCH_DEVICE: {
534 struct device_match_result *dev_result;
535 char vendor[16], product[48], revision[16];
536 char fw[5], tmpstr[256];
542 &ccb.cdm.matches[i].result.device_result;
544 if ((dev_result->flags
545 & DEV_RESULT_UNCONFIGURED)
546 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
552 if (dev_result->protocol == PROTO_SCSI) {
553 cam_strvis(vendor, dev_result->inq_data.vendor,
554 sizeof(dev_result->inq_data.vendor),
557 dev_result->inq_data.product,
558 sizeof(dev_result->inq_data.product),
561 dev_result->inq_data.revision,
562 sizeof(dev_result->inq_data.revision),
564 sprintf(tmpstr, "<%s %s %s>", vendor, product,
566 } else if (dev_result->protocol == PROTO_ATA ||
567 dev_result->protocol == PROTO_SATAPM) {
569 dev_result->ident_data.model,
570 sizeof(dev_result->ident_data.model),
573 dev_result->ident_data.revision,
574 sizeof(dev_result->ident_data.revision),
576 sprintf(tmpstr, "<%s %s>", product,
578 } else if (dev_result->protocol == PROTO_SEMB) {
579 struct sep_identify_data *sid;
581 sid = (struct sep_identify_data *)
582 &dev_result->ident_data;
583 cam_strvis(vendor, sid->vendor_id,
584 sizeof(sid->vendor_id),
586 cam_strvis(product, sid->product_id,
587 sizeof(sid->product_id),
589 cam_strvis(revision, sid->product_rev,
590 sizeof(sid->product_rev),
592 cam_strvis(fw, sid->firmware_rev,
593 sizeof(sid->firmware_rev),
595 sprintf(tmpstr, "<%s %s %s %s>",
596 vendor, product, revision, fw);
598 sprintf(tmpstr, "<>");
601 fprintf(stdout, ")\n");
605 fprintf(stdout, "%-33s at scbus%d "
606 "target %d lun %jx (",
609 dev_result->target_id,
610 (uintmax_t)dev_result->target_lun);
616 case DEV_MATCH_PERIPH: {
617 struct periph_match_result *periph_result;
620 &ccb.cdm.matches[i].result.periph_result;
622 if (busonly || skip_device != 0)
626 fprintf(stdout, ",");
628 fprintf(stdout, "%s%d",
629 periph_result->periph_name,
630 periph_result->unit_number);
636 fprintf(stdout, "unknown match type\n");
641 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
642 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
645 fprintf(stdout, ")\n");
654 testunitready(struct cam_device *device, int retry_count, int timeout,
660 ccb = cam_getccb(device);
662 scsi_test_unit_ready(&ccb->csio,
663 /* retries */ retry_count,
665 /* tag_action */ MSG_SIMPLE_Q_TAG,
666 /* sense_len */ SSD_FULL_SIZE,
667 /* timeout */ timeout ? timeout : 5000);
669 /* Disable freezing the device queue */
670 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
672 if (arglist & CAM_ARG_ERR_RECOVER)
673 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
675 if (cam_send_ccb(device, ccb) < 0) {
677 perror("error sending test unit ready");
679 if (arglist & CAM_ARG_VERBOSE) {
680 cam_error_print(device, ccb, CAM_ESF_ALL,
681 CAM_EPF_ALL, stderr);
688 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
690 fprintf(stdout, "Unit is ready\n");
693 fprintf(stdout, "Unit is not ready\n");
696 if (arglist & CAM_ARG_VERBOSE) {
697 cam_error_print(device, ccb, CAM_ESF_ALL,
698 CAM_EPF_ALL, stderr);
708 scsistart(struct cam_device *device, int startstop, int loadeject,
709 int retry_count, int timeout)
714 ccb = cam_getccb(device);
717 * If we're stopping, send an ordered tag so the drive in question
718 * will finish any previously queued writes before stopping. If
719 * the device isn't capable of tagged queueing, or if tagged
720 * queueing is turned off, the tag action is a no-op.
722 scsi_start_stop(&ccb->csio,
723 /* retries */ retry_count,
725 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
727 /* start/stop */ startstop,
728 /* load_eject */ loadeject,
730 /* sense_len */ SSD_FULL_SIZE,
731 /* timeout */ timeout ? timeout : 120000);
733 /* Disable freezing the device queue */
734 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
736 if (arglist & CAM_ARG_ERR_RECOVER)
737 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
739 if (cam_send_ccb(device, ccb) < 0) {
740 perror("error sending start unit");
742 if (arglist & CAM_ARG_VERBOSE) {
743 cam_error_print(device, ccb, CAM_ESF_ALL,
744 CAM_EPF_ALL, stderr);
751 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
753 fprintf(stdout, "Unit started successfully");
755 fprintf(stdout,", Media loaded\n");
757 fprintf(stdout,"\n");
759 fprintf(stdout, "Unit stopped successfully");
761 fprintf(stdout, ", Media ejected\n");
763 fprintf(stdout, "\n");
769 "Error received from start unit command\n");
772 "Error received from stop unit command\n");
774 if (arglist & CAM_ARG_VERBOSE) {
775 cam_error_print(device, ccb, CAM_ESF_ALL,
776 CAM_EPF_ALL, stderr);
786 scsidoinquiry(struct cam_device *device, int argc, char **argv,
787 char *combinedopt, int retry_count, int timeout)
792 while ((c = getopt(argc, argv, combinedopt)) != -1) {
795 arglist |= CAM_ARG_GET_STDINQ;
798 arglist |= CAM_ARG_GET_XFERRATE;
801 arglist |= CAM_ARG_GET_SERIAL;
809 * If the user didn't specify any inquiry options, he wants all of
812 if ((arglist & CAM_ARG_INQ_MASK) == 0)
813 arglist |= CAM_ARG_INQ_MASK;
815 if (arglist & CAM_ARG_GET_STDINQ)
816 error = scsiinquiry(device, retry_count, timeout);
821 if (arglist & CAM_ARG_GET_SERIAL)
822 scsiserial(device, retry_count, timeout);
824 if (arglist & CAM_ARG_GET_XFERRATE)
825 error = camxferrate(device);
831 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
834 struct scsi_inquiry_data *inq_buf;
837 ccb = cam_getccb(device);
840 warnx("couldn't allocate CCB");
844 /* cam_getccb cleans up the header, caller has to zero the payload */
845 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
847 inq_buf = (struct scsi_inquiry_data *)malloc(
848 sizeof(struct scsi_inquiry_data));
850 if (inq_buf == NULL) {
852 warnx("can't malloc memory for inquiry\n");
855 bzero(inq_buf, sizeof(*inq_buf));
858 * Note that although the size of the inquiry buffer is the full
859 * 256 bytes specified in the SCSI spec, we only tell the device
860 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
861 * two reasons for this:
863 * - The SCSI spec says that when a length field is only 1 byte,
864 * a value of 0 will be interpreted as 256. Therefore
865 * scsi_inquiry() will convert an inq_len (which is passed in as
866 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
867 * to 0. Evidently, very few devices meet the spec in that
868 * regard. Some devices, like many Seagate disks, take the 0 as
869 * 0, and don't return any data. One Pioneer DVD-R drive
870 * returns more data than the command asked for.
872 * So, since there are numerous devices that just don't work
873 * right with the full inquiry size, we don't send the full size.
875 * - The second reason not to use the full inquiry data length is
876 * that we don't need it here. The only reason we issue a
877 * standard inquiry is to get the vendor name, device name,
878 * and revision so scsi_print_inquiry() can print them.
880 * If, at some point in the future, more inquiry data is needed for
881 * some reason, this code should use a procedure similar to the
882 * probe code. i.e., issue a short inquiry, and determine from
883 * the additional length passed back from the device how much
884 * inquiry data the device supports. Once the amount the device
885 * supports is determined, issue an inquiry for that amount and no
890 scsi_inquiry(&ccb->csio,
891 /* retries */ retry_count,
893 /* tag_action */ MSG_SIMPLE_Q_TAG,
894 /* inq_buf */ (u_int8_t *)inq_buf,
895 /* inq_len */ SHORT_INQUIRY_LENGTH,
898 /* sense_len */ SSD_FULL_SIZE,
899 /* timeout */ timeout ? timeout : 5000);
901 /* Disable freezing the device queue */
902 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
904 if (arglist & CAM_ARG_ERR_RECOVER)
905 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
907 if (cam_send_ccb(device, ccb) < 0) {
908 perror("error sending SCSI inquiry");
910 if (arglist & CAM_ARG_VERBOSE) {
911 cam_error_print(device, ccb, CAM_ESF_ALL,
912 CAM_EPF_ALL, stderr);
919 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
922 if (arglist & CAM_ARG_VERBOSE) {
923 cam_error_print(device, ccb, CAM_ESF_ALL,
924 CAM_EPF_ALL, stderr);
935 fprintf(stdout, "%s%d: ", device->device_name,
936 device->dev_unit_num);
937 scsi_print_inquiry(inq_buf);
945 scsiserial(struct cam_device *device, int retry_count, int timeout)
948 struct scsi_vpd_unit_serial_number *serial_buf;
949 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
952 ccb = cam_getccb(device);
955 warnx("couldn't allocate CCB");
959 /* cam_getccb cleans up the header, caller has to zero the payload */
960 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
962 serial_buf = (struct scsi_vpd_unit_serial_number *)
963 malloc(sizeof(*serial_buf));
965 if (serial_buf == NULL) {
967 warnx("can't malloc memory for serial number");
971 scsi_inquiry(&ccb->csio,
972 /*retries*/ retry_count,
974 /* tag_action */ MSG_SIMPLE_Q_TAG,
975 /* inq_buf */ (u_int8_t *)serial_buf,
976 /* inq_len */ sizeof(*serial_buf),
978 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
979 /* sense_len */ SSD_FULL_SIZE,
980 /* timeout */ timeout ? timeout : 5000);
982 /* Disable freezing the device queue */
983 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
985 if (arglist & CAM_ARG_ERR_RECOVER)
986 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
988 if (cam_send_ccb(device, ccb) < 0) {
989 warn("error getting serial number");
991 if (arglist & CAM_ARG_VERBOSE) {
992 cam_error_print(device, ccb, CAM_ESF_ALL,
993 CAM_EPF_ALL, stderr);
1001 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1004 if (arglist & CAM_ARG_VERBOSE) {
1005 cam_error_print(device, ccb, CAM_ESF_ALL,
1006 CAM_EPF_ALL, stderr);
1017 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1018 serial_num[serial_buf->length] = '\0';
1020 if ((arglist & CAM_ARG_GET_STDINQ)
1021 || (arglist & CAM_ARG_GET_XFERRATE))
1022 fprintf(stdout, "%s%d: Serial Number ",
1023 device->device_name, device->dev_unit_num);
1025 fprintf(stdout, "%.60s\n", serial_num);
1033 camxferrate(struct cam_device *device)
1035 struct ccb_pathinq cpi;
1037 u_int32_t speed = 0;
1042 if ((retval = get_cpi(device, &cpi)) != 0)
1045 ccb = cam_getccb(device);
1048 warnx("couldn't allocate CCB");
1052 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1054 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1055 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1057 if (((retval = cam_send_ccb(device, ccb)) < 0)
1058 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1059 const char error_string[] = "error getting transfer settings";
1064 warnx(error_string);
1066 if (arglist & CAM_ARG_VERBOSE)
1067 cam_error_print(device, ccb, CAM_ESF_ALL,
1068 CAM_EPF_ALL, stderr);
1072 goto xferrate_bailout;
1076 speed = cpi.base_transfer_speed;
1078 if (ccb->cts.transport == XPORT_SPI) {
1079 struct ccb_trans_settings_spi *spi =
1080 &ccb->cts.xport_specific.spi;
1082 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1083 freq = scsi_calc_syncsrate(spi->sync_period);
1086 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1087 speed *= (0x01 << spi->bus_width);
1089 } else if (ccb->cts.transport == XPORT_FC) {
1090 struct ccb_trans_settings_fc *fc =
1091 &ccb->cts.xport_specific.fc;
1093 if (fc->valid & CTS_FC_VALID_SPEED)
1094 speed = fc->bitrate;
1095 } else if (ccb->cts.transport == XPORT_SAS) {
1096 struct ccb_trans_settings_sas *sas =
1097 &ccb->cts.xport_specific.sas;
1099 if (sas->valid & CTS_SAS_VALID_SPEED)
1100 speed = sas->bitrate;
1101 } else if (ccb->cts.transport == XPORT_ATA) {
1102 struct ccb_trans_settings_pata *pata =
1103 &ccb->cts.xport_specific.ata;
1105 if (pata->valid & CTS_ATA_VALID_MODE)
1106 speed = ata_mode2speed(pata->mode);
1107 } else if (ccb->cts.transport == XPORT_SATA) {
1108 struct ccb_trans_settings_sata *sata =
1109 &ccb->cts.xport_specific.sata;
1111 if (sata->valid & CTS_SATA_VALID_REVISION)
1112 speed = ata_revision2speed(sata->revision);
1117 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1118 device->device_name, device->dev_unit_num,
1121 fprintf(stdout, "%s%d: %dKB/s transfers",
1122 device->device_name, device->dev_unit_num,
1126 if (ccb->cts.transport == XPORT_SPI) {
1127 struct ccb_trans_settings_spi *spi =
1128 &ccb->cts.xport_specific.spi;
1130 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1131 && (spi->sync_offset != 0))
1132 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1133 freq % 1000, spi->sync_offset);
1135 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1136 && (spi->bus_width > 0)) {
1137 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1138 && (spi->sync_offset != 0)) {
1139 fprintf(stdout, ", ");
1141 fprintf(stdout, " (");
1143 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1144 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1145 && (spi->sync_offset != 0)) {
1146 fprintf(stdout, ")");
1148 } else if (ccb->cts.transport == XPORT_ATA) {
1149 struct ccb_trans_settings_pata *pata =
1150 &ccb->cts.xport_specific.ata;
1153 if (pata->valid & CTS_ATA_VALID_MODE)
1154 printf("%s, ", ata_mode2string(pata->mode));
1155 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1156 printf("ATAPI %dbytes, ", pata->atapi);
1157 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1158 printf("PIO %dbytes", pata->bytecount);
1160 } else if (ccb->cts.transport == XPORT_SATA) {
1161 struct ccb_trans_settings_sata *sata =
1162 &ccb->cts.xport_specific.sata;
1165 if (sata->valid & CTS_SATA_VALID_REVISION)
1166 printf("SATA %d.x, ", sata->revision);
1169 if (sata->valid & CTS_SATA_VALID_MODE)
1170 printf("%s, ", ata_mode2string(sata->mode));
1171 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1172 printf("ATAPI %dbytes, ", sata->atapi);
1173 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1174 printf("PIO %dbytes", sata->bytecount);
1178 if (ccb->cts.protocol == PROTO_SCSI) {
1179 struct ccb_trans_settings_scsi *scsi =
1180 &ccb->cts.proto_specific.scsi;
1181 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1182 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1183 fprintf(stdout, ", Command Queueing Enabled");
1188 fprintf(stdout, "\n");
1198 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1200 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1201 ((u_int32_t)parm->lba_size_2 << 16);
1203 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1204 ((u_int64_t)parm->lba_size48_2 << 16) |
1205 ((u_int64_t)parm->lba_size48_3 << 32) |
1206 ((u_int64_t)parm->lba_size48_4 << 48);
1210 "Support Enabled Value\n");
1213 printf("Host Protected Area (HPA) ");
1214 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1215 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1216 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1219 printf("HPA - Security ");
1220 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1230 atasata(struct ata_params *parm)
1234 if (parm->satacapabilities != 0xffff &&
1235 parm->satacapabilities != 0x0000)
1242 atacapprint(struct ata_params *parm)
1244 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1245 ((u_int32_t)parm->lba_size_2 << 16);
1247 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1248 ((u_int64_t)parm->lba_size48_2 << 16) |
1249 ((u_int64_t)parm->lba_size48_3 << 32) |
1250 ((u_int64_t)parm->lba_size48_4 << 48);
1253 printf("protocol ");
1254 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1255 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1256 if (parm->satacapabilities & ATA_SATA_GEN3)
1257 printf(" SATA 3.x\n");
1258 else if (parm->satacapabilities & ATA_SATA_GEN2)
1259 printf(" SATA 2.x\n");
1260 else if (parm->satacapabilities & ATA_SATA_GEN1)
1261 printf(" SATA 1.x\n");
1267 printf("device model %.40s\n", parm->model);
1268 printf("firmware revision %.8s\n", parm->revision);
1269 printf("serial number %.20s\n", parm->serial);
1270 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1271 printf("WWN %04x%04x%04x%04x\n",
1272 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1274 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1275 printf("media serial number %.30s\n",
1276 parm->media_serial);
1279 printf("cylinders %d\n", parm->cylinders);
1280 printf("heads %d\n", parm->heads);
1281 printf("sectors/track %d\n", parm->sectors);
1282 printf("sector size logical %u, physical %lu, offset %lu\n",
1283 ata_logical_sector_size(parm),
1284 (unsigned long)ata_physical_sector_size(parm),
1285 (unsigned long)ata_logical_sector_offset(parm));
1287 if (parm->config == ATA_PROTO_CFA ||
1288 (parm->support.command2 & ATA_SUPPORT_CFA))
1289 printf("CFA supported\n");
1291 printf("LBA%ssupported ",
1292 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1294 printf("%d sectors\n", lbasize);
1298 printf("LBA48%ssupported ",
1299 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1301 printf("%ju sectors\n", (uintmax_t)lbasize48);
1305 printf("PIO supported PIO");
1306 switch (ata_max_pmode(parm)) {
1322 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1323 printf(" w/o IORDY");
1326 printf("DMA%ssupported ",
1327 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1328 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1329 if (parm->mwdmamodes & 0xff) {
1331 if (parm->mwdmamodes & 0x04)
1333 else if (parm->mwdmamodes & 0x02)
1335 else if (parm->mwdmamodes & 0x01)
1339 if ((parm->atavalid & ATA_FLAG_88) &&
1340 (parm->udmamodes & 0xff)) {
1342 if (parm->udmamodes & 0x40)
1344 else if (parm->udmamodes & 0x20)
1346 else if (parm->udmamodes & 0x10)
1348 else if (parm->udmamodes & 0x08)
1350 else if (parm->udmamodes & 0x04)
1352 else if (parm->udmamodes & 0x02)
1354 else if (parm->udmamodes & 0x01)
1361 if (parm->media_rotation_rate == 1) {
1362 printf("media RPM non-rotating\n");
1363 } else if (parm->media_rotation_rate >= 0x0401 &&
1364 parm->media_rotation_rate <= 0xFFFE) {
1365 printf("media RPM %d\n",
1366 parm->media_rotation_rate);
1370 "Support Enabled Value Vendor\n");
1371 printf("read ahead %s %s\n",
1372 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1373 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1374 printf("write cache %s %s\n",
1375 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1376 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1377 printf("flush cache %s %s\n",
1378 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1379 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1380 printf("overlap %s\n",
1381 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1382 printf("Tagged Command Queuing (TCQ) %s %s",
1383 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1384 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1385 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1386 printf(" %d tags\n",
1387 ATA_QUEUE_LEN(parm->queue) + 1);
1390 printf("Native Command Queuing (NCQ) ");
1391 if (parm->satacapabilities != 0xffff &&
1392 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1393 printf("yes %d tags\n",
1394 ATA_QUEUE_LEN(parm->queue) + 1);
1398 printf("NCQ Queue Management %s\n", atasata(parm) &&
1399 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1401 printf("NCQ Streaming %s\n", atasata(parm) &&
1402 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1404 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1405 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1408 printf("SMART %s %s\n",
1409 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1410 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1411 printf("microcode download %s %s\n",
1412 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1413 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1414 printf("security %s %s\n",
1415 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1416 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1417 printf("power management %s %s\n",
1418 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1419 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1420 printf("advanced power management %s %s",
1421 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1422 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1423 if (parm->support.command2 & ATA_SUPPORT_APM) {
1424 printf(" %d/0x%02X\n",
1425 parm->apm_value & 0xff, parm->apm_value & 0xff);
1428 printf("automatic acoustic management %s %s",
1429 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1430 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1431 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1432 printf(" %d/0x%02X %d/0x%02X\n",
1433 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1434 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1435 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1436 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1439 printf("media status notification %s %s\n",
1440 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1441 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1442 printf("power-up in Standby %s %s\n",
1443 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1444 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1445 printf("write-read-verify %s %s",
1446 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1447 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1448 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1449 printf(" %d/0x%x\n",
1450 parm->wrv_mode, parm->wrv_mode);
1453 printf("unload %s %s\n",
1454 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1455 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1456 printf("general purpose logging %s %s\n",
1457 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1458 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1459 printf("free-fall %s %s\n",
1460 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1461 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1462 printf("Data Set Management (DSM/TRIM) ");
1463 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1465 printf("DSM - max 512byte blocks ");
1466 if (parm->max_dsm_blocks == 0x00)
1467 printf("yes not specified\n");
1470 parm->max_dsm_blocks);
1472 printf("DSM - deterministic read ");
1473 if (parm->support3 & ATA_SUPPORT_DRAT) {
1474 if (parm->support3 & ATA_SUPPORT_RZAT)
1475 printf("yes zeroed\n");
1477 printf("yes any value\n");
1487 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1489 struct ata_pass_16 *ata_pass_16;
1490 struct ata_cmd ata_cmd;
1492 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1493 ata_cmd.command = ata_pass_16->command;
1494 ata_cmd.control = ata_pass_16->control;
1495 ata_cmd.features = ata_pass_16->features;
1497 if (arglist & CAM_ARG_VERBOSE) {
1498 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1499 ata_op_string(&ata_cmd),
1500 ccb->csio.ccb_h.timeout);
1503 /* Disable freezing the device queue */
1504 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1506 if (arglist & CAM_ARG_ERR_RECOVER)
1507 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1509 if (cam_send_ccb(device, ccb) < 0) {
1510 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1511 warn("error sending ATA %s via pass_16",
1512 ata_op_string(&ata_cmd));
1515 if (arglist & CAM_ARG_VERBOSE) {
1516 cam_error_print(device, ccb, CAM_ESF_ALL,
1517 CAM_EPF_ALL, stderr);
1523 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1524 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1525 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1526 warnx("ATA %s via pass_16 failed",
1527 ata_op_string(&ata_cmd));
1529 if (arglist & CAM_ARG_VERBOSE) {
1530 cam_error_print(device, ccb, CAM_ESF_ALL,
1531 CAM_EPF_ALL, stderr);
1542 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1544 if (arglist & CAM_ARG_VERBOSE) {
1545 warnx("sending ATA %s with timeout of %u msecs",
1546 ata_op_string(&(ccb->ataio.cmd)),
1547 ccb->ataio.ccb_h.timeout);
1550 /* Disable freezing the device queue */
1551 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1553 if (arglist & CAM_ARG_ERR_RECOVER)
1554 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1556 if (cam_send_ccb(device, ccb) < 0) {
1557 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1558 warn("error sending ATA %s",
1559 ata_op_string(&(ccb->ataio.cmd)));
1562 if (arglist & CAM_ARG_VERBOSE) {
1563 cam_error_print(device, ccb, CAM_ESF_ALL,
1564 CAM_EPF_ALL, stderr);
1570 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1571 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1572 warnx("ATA %s failed: %d",
1573 ata_op_string(&(ccb->ataio.cmd)), quiet);
1576 if (arglist & CAM_ARG_VERBOSE) {
1577 cam_error_print(device, ccb, CAM_ESF_ALL,
1578 CAM_EPF_ALL, stderr);
1588 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1589 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1590 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1591 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1592 u_int16_t dxfer_len, int timeout, int quiet)
1594 if (data_ptr != NULL) {
1595 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1596 AP_FLAG_TLEN_SECT_CNT;
1597 if (flags & CAM_DIR_OUT)
1598 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1600 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1602 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1605 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1607 scsi_ata_pass_16(&ccb->csio,
1621 /*sense_len*/SSD_FULL_SIZE,
1624 return scsi_cam_pass_16_send(device, ccb, quiet);
1628 ata_try_pass_16(struct cam_device *device)
1630 struct ccb_pathinq cpi;
1632 if (get_cpi(device, &cpi) != 0) {
1633 warnx("couldn't get CPI");
1637 if (cpi.protocol == PROTO_SCSI) {
1638 /* possibly compatible with pass_16 */
1642 /* likely not compatible with pass_16 */
1647 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1648 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1649 u_int8_t command, u_int8_t features, u_int32_t lba,
1650 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1651 int timeout, int quiet)
1655 switch (ata_try_pass_16(device)) {
1659 /* Try using SCSI Passthrough */
1660 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1661 0, tag_action, command, features, lba,
1662 sector_count, data_ptr, dxfer_len,
1666 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1667 cam_fill_ataio(&ccb->ataio,
1676 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1677 return ata_cam_send(device, ccb, quiet);
1681 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1682 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1683 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1684 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1685 u_int16_t dxfer_len, int timeout, int force48bit)
1689 retval = ata_try_pass_16(device);
1696 /* Try using SCSI Passthrough */
1697 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1698 ata_flags, tag_action, command, features,
1699 lba, sector_count, data_ptr, dxfer_len,
1702 if (ata_flags & AP_FLAG_CHK_COND) {
1703 /* Decode ata_res from sense data */
1704 struct ata_res_pass16 *res_pass16;
1705 struct ata_res *res;
1709 /* sense_data is 4 byte aligned */
1710 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1711 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1712 ptr[i] = le16toh(ptr[i]);
1714 /* sense_data is 4 byte aligned */
1715 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1716 &ccb->csio.sense_data;
1717 res = &ccb->ataio.res;
1718 res->flags = res_pass16->flags;
1719 res->status = res_pass16->status;
1720 res->error = res_pass16->error;
1721 res->lba_low = res_pass16->lba_low;
1722 res->lba_mid = res_pass16->lba_mid;
1723 res->lba_high = res_pass16->lba_high;
1724 res->device = res_pass16->device;
1725 res->lba_low_exp = res_pass16->lba_low_exp;
1726 res->lba_mid_exp = res_pass16->lba_mid_exp;
1727 res->lba_high_exp = res_pass16->lba_high_exp;
1728 res->sector_count = res_pass16->sector_count;
1729 res->sector_count_exp = res_pass16->sector_count_exp;
1735 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1736 cam_fill_ataio(&ccb->ataio,
1745 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1746 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1748 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1750 if (ata_flags & AP_FLAG_CHK_COND)
1751 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1753 return ata_cam_send(device, ccb, 0);
1757 dump_data(uint16_t *ptr, uint32_t len)
1761 for (i = 0; i < len / 2; i++) {
1763 printf(" %3d: ", i);
1764 printf("%04hx ", ptr[i]);
1773 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1774 int is48bit, u_int64_t *hpasize)
1776 struct ata_res *res;
1778 res = &ccb->ataio.res;
1779 if (res->status & ATA_STATUS_ERROR) {
1780 if (arglist & CAM_ARG_VERBOSE) {
1781 cam_error_print(device, ccb, CAM_ESF_ALL,
1782 CAM_EPF_ALL, stderr);
1783 printf("error = 0x%02x, sector_count = 0x%04x, "
1784 "device = 0x%02x, status = 0x%02x\n",
1785 res->error, res->sector_count,
1786 res->device, res->status);
1789 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1790 warnx("Max address has already been set since "
1791 "last power-on or hardware reset");
1797 if (arglist & CAM_ARG_VERBOSE) {
1798 fprintf(stdout, "%s%d: Raw native max data:\n",
1799 device->device_name, device->dev_unit_num);
1800 /* res is 4 byte aligned */
1801 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1803 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1804 "status = 0x%02x\n", res->error, res->sector_count,
1805 res->device, res->status);
1808 if (hpasize != NULL) {
1810 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1811 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1812 ((res->lba_high << 16) | (res->lba_mid << 8) |
1815 *hpasize = (((res->device & 0x0f) << 24) |
1816 (res->lba_high << 16) | (res->lba_mid << 8) |
1825 ata_read_native_max(struct cam_device *device, int retry_count,
1826 u_int32_t timeout, union ccb *ccb,
1827 struct ata_params *parm, u_int64_t *hpasize)
1833 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1834 protocol = AP_PROTO_NON_DATA;
1837 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1838 protocol |= AP_EXTEND;
1840 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1843 error = ata_do_cmd(device,
1846 /*flags*/CAM_DIR_NONE,
1847 /*protocol*/protocol,
1848 /*ata_flags*/AP_FLAG_CHK_COND,
1849 /*tag_action*/MSG_SIMPLE_Q_TAG,
1856 timeout ? timeout : 1000,
1862 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1866 atahpa_set_max(struct cam_device *device, int retry_count,
1867 u_int32_t timeout, union ccb *ccb,
1868 int is48bit, u_int64_t maxsize, int persist)
1874 protocol = AP_PROTO_NON_DATA;
1877 cmd = ATA_SET_MAX_ADDRESS48;
1878 protocol |= AP_EXTEND;
1880 cmd = ATA_SET_MAX_ADDRESS;
1883 /* lba's are zero indexed so the max lba is requested max - 1 */
1887 error = ata_do_cmd(device,
1890 /*flags*/CAM_DIR_NONE,
1891 /*protocol*/protocol,
1892 /*ata_flags*/AP_FLAG_CHK_COND,
1893 /*tag_action*/MSG_SIMPLE_Q_TAG,
1895 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1897 /*sector_count*/persist,
1900 timeout ? timeout : 1000,
1906 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1910 atahpa_password(struct cam_device *device, int retry_count,
1911 u_int32_t timeout, union ccb *ccb,
1912 int is48bit, struct ata_set_max_pwd *pwd)
1918 protocol = AP_PROTO_PIO_OUT;
1919 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1921 error = ata_do_cmd(device,
1924 /*flags*/CAM_DIR_OUT,
1925 /*protocol*/protocol,
1926 /*ata_flags*/AP_FLAG_CHK_COND,
1927 /*tag_action*/MSG_SIMPLE_Q_TAG,
1929 /*features*/ATA_HPA_FEAT_SET_PWD,
1932 /*data_ptr*/(u_int8_t*)pwd,
1933 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1934 timeout ? timeout : 1000,
1940 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1944 atahpa_lock(struct cam_device *device, int retry_count,
1945 u_int32_t timeout, union ccb *ccb, int is48bit)
1951 protocol = AP_PROTO_NON_DATA;
1952 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1954 error = ata_do_cmd(device,
1957 /*flags*/CAM_DIR_NONE,
1958 /*protocol*/protocol,
1959 /*ata_flags*/AP_FLAG_CHK_COND,
1960 /*tag_action*/MSG_SIMPLE_Q_TAG,
1962 /*features*/ATA_HPA_FEAT_LOCK,
1967 timeout ? timeout : 1000,
1973 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1977 atahpa_unlock(struct cam_device *device, int retry_count,
1978 u_int32_t timeout, union ccb *ccb,
1979 int is48bit, struct ata_set_max_pwd *pwd)
1985 protocol = AP_PROTO_PIO_OUT;
1986 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1988 error = ata_do_cmd(device,
1991 /*flags*/CAM_DIR_OUT,
1992 /*protocol*/protocol,
1993 /*ata_flags*/AP_FLAG_CHK_COND,
1994 /*tag_action*/MSG_SIMPLE_Q_TAG,
1996 /*features*/ATA_HPA_FEAT_UNLOCK,
1999 /*data_ptr*/(u_int8_t*)pwd,
2000 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2001 timeout ? timeout : 1000,
2007 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2011 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2012 u_int32_t timeout, union ccb *ccb, int is48bit)
2018 protocol = AP_PROTO_NON_DATA;
2019 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2021 error = ata_do_cmd(device,
2024 /*flags*/CAM_DIR_NONE,
2025 /*protocol*/protocol,
2026 /*ata_flags*/AP_FLAG_CHK_COND,
2027 /*tag_action*/MSG_SIMPLE_Q_TAG,
2029 /*features*/ATA_HPA_FEAT_FREEZE,
2034 timeout ? timeout : 1000,
2040 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2045 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2046 union ccb *ccb, struct ata_params** ident_bufp)
2048 struct ata_params *ident_buf;
2049 struct ccb_pathinq cpi;
2050 struct ccb_getdev cgd;
2053 u_int8_t command, retry_command;
2055 if (get_cpi(device, &cpi) != 0) {
2056 warnx("couldn't get CPI");
2060 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2061 if (cpi.protocol == PROTO_ATA) {
2062 if (get_cgd(device, &cgd) != 0) {
2063 warnx("couldn't get CGD");
2067 command = (cgd.protocol == PROTO_ATA) ?
2068 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2071 /* We don't know which for sure so try both */
2072 command = ATA_ATA_IDENTIFY;
2073 retry_command = ATA_ATAPI_IDENTIFY;
2076 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2078 warnx("can't calloc memory for identify\n");
2082 error = ata_do_28bit_cmd(device,
2084 /*retries*/retry_count,
2085 /*flags*/CAM_DIR_IN,
2086 /*protocol*/AP_PROTO_PIO_IN,
2087 /*tag_action*/MSG_SIMPLE_Q_TAG,
2091 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2092 /*data_ptr*/(u_int8_t *)ptr,
2093 /*dxfer_len*/sizeof(struct ata_params),
2094 /*timeout*/timeout ? timeout : 30 * 1000,
2098 if (retry_command == 0) {
2102 error = ata_do_28bit_cmd(device,
2104 /*retries*/retry_count,
2105 /*flags*/CAM_DIR_IN,
2106 /*protocol*/AP_PROTO_PIO_IN,
2107 /*tag_action*/MSG_SIMPLE_Q_TAG,
2108 /*command*/retry_command,
2111 /*sector_count*/(u_int8_t)
2112 sizeof(struct ata_params),
2113 /*data_ptr*/(u_int8_t *)ptr,
2114 /*dxfer_len*/sizeof(struct ata_params),
2115 /*timeout*/timeout ? timeout : 30 * 1000,
2125 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2126 ptr[i] = le16toh(ptr[i]);
2131 if (arglist & CAM_ARG_VERBOSE) {
2132 fprintf(stdout, "%s%d: Raw identify data:\n",
2133 device->device_name, device->dev_unit_num);
2134 dump_data(ptr, sizeof(struct ata_params));
2137 /* check for invalid (all zero) response */
2139 warnx("Invalid identify response detected");
2144 ident_buf = (struct ata_params *)ptr;
2145 if (strncmp(ident_buf->model, "FX", 2) &&
2146 strncmp(ident_buf->model, "NEC", 3) &&
2147 strncmp(ident_buf->model, "Pioneer", 7) &&
2148 strncmp(ident_buf->model, "SHARP", 5)) {
2149 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2150 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2151 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2152 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2154 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2155 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2156 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2157 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2158 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2159 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2160 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2161 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2162 sizeof(ident_buf->media_serial));
2164 *ident_bufp = ident_buf;
2171 ataidentify(struct cam_device *device, int retry_count, int timeout)
2174 struct ata_params *ident_buf;
2177 if ((ccb = cam_getccb(device)) == NULL) {
2178 warnx("couldn't allocate CCB");
2182 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2187 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2188 if (ata_read_native_max(device, retry_count, timeout, ccb,
2189 ident_buf, &hpasize) != 0) {
2197 printf("%s%d: ", device->device_name, device->dev_unit_num);
2198 ata_print_ident(ident_buf);
2199 camxferrate(device);
2200 atacapprint(ident_buf);
2201 atahpa_print(ident_buf, hpasize, 0);
2208 #endif /* MINIMALISTIC */
2211 #ifndef MINIMALISTIC
2213 ATA_SECURITY_ACTION_PRINT,
2214 ATA_SECURITY_ACTION_FREEZE,
2215 ATA_SECURITY_ACTION_UNLOCK,
2216 ATA_SECURITY_ACTION_DISABLE,
2217 ATA_SECURITY_ACTION_ERASE,
2218 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2219 ATA_SECURITY_ACTION_SET_PASSWORD
2223 atasecurity_print_time(u_int16_t tw)
2227 printf("unspecified");
2229 printf("> 508 min");
2231 printf("%i min", 2 * tw);
2235 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2239 return 2 * 3600 * 1000; /* default: two hours */
2240 else if (timeout > 255)
2241 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2243 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2248 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2252 bzero(&cmd, sizeof(cmd));
2253 cmd.command = command;
2254 printf("Issuing %s", ata_op_string(&cmd));
2257 char pass[sizeof(pwd->password)+1];
2259 /* pwd->password may not be null terminated */
2260 pass[sizeof(pwd->password)] = '\0';
2261 strncpy(pass, pwd->password, sizeof(pwd->password));
2262 printf(" password='%s', user='%s'",
2264 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2267 if (command == ATA_SECURITY_SET_PASSWORD) {
2268 printf(", mode='%s'",
2269 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2270 "maximum" : "high");
2278 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2279 int retry_count, u_int32_t timeout, int quiet)
2283 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2285 return ata_do_28bit_cmd(device,
2288 /*flags*/CAM_DIR_NONE,
2289 /*protocol*/AP_PROTO_NON_DATA,
2290 /*tag_action*/MSG_SIMPLE_Q_TAG,
2291 /*command*/ATA_SECURITY_FREEZE_LOCK,
2302 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2303 int retry_count, u_int32_t timeout,
2304 struct ata_security_password *pwd, int quiet)
2308 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2310 return ata_do_28bit_cmd(device,
2313 /*flags*/CAM_DIR_OUT,
2314 /*protocol*/AP_PROTO_PIO_OUT,
2315 /*tag_action*/MSG_SIMPLE_Q_TAG,
2316 /*command*/ATA_SECURITY_UNLOCK,
2320 /*data_ptr*/(u_int8_t *)pwd,
2321 /*dxfer_len*/sizeof(*pwd),
2327 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2328 int retry_count, u_int32_t timeout,
2329 struct ata_security_password *pwd, int quiet)
2333 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2334 return ata_do_28bit_cmd(device,
2337 /*flags*/CAM_DIR_OUT,
2338 /*protocol*/AP_PROTO_PIO_OUT,
2339 /*tag_action*/MSG_SIMPLE_Q_TAG,
2340 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2344 /*data_ptr*/(u_int8_t *)pwd,
2345 /*dxfer_len*/sizeof(*pwd),
2352 atasecurity_erase_confirm(struct cam_device *device,
2353 struct ata_params* ident_buf)
2356 printf("\nYou are about to ERASE ALL DATA from the following"
2357 " device:\n%s%d,%s%d: ", device->device_name,
2358 device->dev_unit_num, device->given_dev_name,
2359 device->given_unit_number);
2360 ata_print_ident(ident_buf);
2364 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2366 if (fgets(str, sizeof(str), stdin) != NULL) {
2367 if (strncasecmp(str, "yes", 3) == 0) {
2369 } else if (strncasecmp(str, "no", 2) == 0) {
2372 printf("Please answer \"yes\" or "
2383 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2384 int retry_count, u_int32_t timeout,
2385 u_int32_t erase_timeout,
2386 struct ata_security_password *pwd, int quiet)
2391 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2393 error = ata_do_28bit_cmd(device,
2396 /*flags*/CAM_DIR_NONE,
2397 /*protocol*/AP_PROTO_NON_DATA,
2398 /*tag_action*/MSG_SIMPLE_Q_TAG,
2399 /*command*/ATA_SECURITY_ERASE_PREPARE,
2412 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2414 error = ata_do_28bit_cmd(device,
2417 /*flags*/CAM_DIR_OUT,
2418 /*protocol*/AP_PROTO_PIO_OUT,
2419 /*tag_action*/MSG_SIMPLE_Q_TAG,
2420 /*command*/ATA_SECURITY_ERASE_UNIT,
2424 /*data_ptr*/(u_int8_t *)pwd,
2425 /*dxfer_len*/sizeof(*pwd),
2426 /*timeout*/erase_timeout,
2429 if (error == 0 && quiet == 0)
2430 printf("\nErase Complete\n");
2436 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2437 int retry_count, u_int32_t timeout,
2438 struct ata_security_password *pwd, int quiet)
2442 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2444 return ata_do_28bit_cmd(device,
2447 /*flags*/CAM_DIR_OUT,
2448 /*protocol*/AP_PROTO_PIO_OUT,
2449 /*tag_action*/MSG_SIMPLE_Q_TAG,
2450 /*command*/ATA_SECURITY_SET_PASSWORD,
2454 /*data_ptr*/(u_int8_t *)pwd,
2455 /*dxfer_len*/sizeof(*pwd),
2461 atasecurity_print(struct ata_params *parm)
2464 printf("\nSecurity Option Value\n");
2465 if (arglist & CAM_ARG_VERBOSE) {
2466 printf("status %04x\n",
2467 parm->security_status);
2469 printf("supported %s\n",
2470 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2471 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2473 printf("enabled %s\n",
2474 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2475 printf("drive locked %s\n",
2476 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2477 printf("security config frozen %s\n",
2478 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2479 printf("count expired %s\n",
2480 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2481 printf("security level %s\n",
2482 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2483 printf("enhanced erase supported %s\n",
2484 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2485 printf("erase time ");
2486 atasecurity_print_time(parm->erase_time);
2488 printf("enhanced erase time ");
2489 atasecurity_print_time(parm->enhanced_erase_time);
2491 printf("master password rev %04x%s\n",
2492 parm->master_passwd_revision,
2493 parm->master_passwd_revision == 0x0000 ||
2494 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2498 * Validates and copies the password in optarg to the passed buffer.
2499 * If the password in optarg is the same length as the buffer then
2500 * the data will still be copied but no null termination will occur.
2503 ata_getpwd(u_int8_t *passwd, int max, char opt)
2507 len = strlen(optarg);
2509 warnx("-%c password is too long", opt);
2511 } else if (len == 0) {
2512 warnx("-%c password is missing", opt);
2514 } else if (optarg[0] == '-'){
2515 warnx("-%c password starts with '-' (generic arg?)", opt);
2517 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2518 warnx("-%c password conflicts with existing password from -%c",
2523 /* Callers pass in a buffer which does NOT need to be terminated */
2524 strncpy(passwd, optarg, max);
2531 ATA_HPA_ACTION_PRINT,
2532 ATA_HPA_ACTION_SET_MAX,
2533 ATA_HPA_ACTION_SET_PWD,
2534 ATA_HPA_ACTION_LOCK,
2535 ATA_HPA_ACTION_UNLOCK,
2536 ATA_HPA_ACTION_FREEZE_LOCK
2540 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2541 u_int64_t maxsize, int persist)
2543 printf("\nYou are about to configure HPA to limit the user accessible\n"
2544 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2545 persist ? "persistently" : "temporarily",
2546 device->device_name, device->dev_unit_num,
2547 device->given_dev_name, device->given_unit_number);
2548 ata_print_ident(ident_buf);
2552 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2554 if (NULL != fgets(str, sizeof(str), stdin)) {
2555 if (0 == strncasecmp(str, "yes", 3)) {
2557 } else if (0 == strncasecmp(str, "no", 2)) {
2560 printf("Please answer \"yes\" or "
2571 atahpa(struct cam_device *device, int retry_count, int timeout,
2572 int argc, char **argv, char *combinedopt)
2575 struct ata_params *ident_buf;
2576 struct ccb_getdev cgd;
2577 struct ata_set_max_pwd pwd;
2578 int error, confirm, quiet, c, action, actions, persist;
2579 int security, is48bit, pwdsize;
2580 u_int64_t hpasize, maxsize;
2589 memset(&pwd, 0, sizeof(pwd));
2591 /* default action is to print hpa information */
2592 action = ATA_HPA_ACTION_PRINT;
2593 pwdsize = sizeof(pwd.password);
2595 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2598 action = ATA_HPA_ACTION_SET_MAX;
2599 maxsize = strtoumax(optarg, NULL, 0);
2604 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2606 action = ATA_HPA_ACTION_SET_PWD;
2612 action = ATA_HPA_ACTION_LOCK;
2618 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2620 action = ATA_HPA_ACTION_UNLOCK;
2626 action = ATA_HPA_ACTION_FREEZE_LOCK;
2646 warnx("too many hpa actions specified");
2650 if (get_cgd(device, &cgd) != 0) {
2651 warnx("couldn't get CGD");
2655 ccb = cam_getccb(device);
2657 warnx("couldn't allocate CCB");
2661 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2668 printf("%s%d: ", device->device_name, device->dev_unit_num);
2669 ata_print_ident(ident_buf);
2670 camxferrate(device);
2673 if (action == ATA_HPA_ACTION_PRINT) {
2674 error = ata_read_native_max(device, retry_count, timeout, ccb,
2675 ident_buf, &hpasize);
2677 atahpa_print(ident_buf, hpasize, 1);
2684 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2685 warnx("HPA is not supported by this device");
2691 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2692 warnx("HPA Security is not supported by this device");
2698 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2701 * The ATA spec requires:
2702 * 1. Read native max addr is called directly before set max addr
2703 * 2. Read native max addr is NOT called before any other set max call
2706 case ATA_HPA_ACTION_SET_MAX:
2708 atahpa_set_confirm(device, ident_buf, maxsize,
2715 error = ata_read_native_max(device, retry_count, timeout,
2716 ccb, ident_buf, &hpasize);
2718 error = atahpa_set_max(device, retry_count, timeout,
2719 ccb, is48bit, maxsize, persist);
2721 /* redo identify to get new lba values */
2722 error = ata_do_identify(device, retry_count,
2725 atahpa_print(ident_buf, hpasize, 1);
2730 case ATA_HPA_ACTION_SET_PWD:
2731 error = atahpa_password(device, retry_count, timeout,
2732 ccb, is48bit, &pwd);
2734 printf("HPA password has been set\n");
2737 case ATA_HPA_ACTION_LOCK:
2738 error = atahpa_lock(device, retry_count, timeout,
2741 printf("HPA has been locked\n");
2744 case ATA_HPA_ACTION_UNLOCK:
2745 error = atahpa_unlock(device, retry_count, timeout,
2746 ccb, is48bit, &pwd);
2748 printf("HPA has been unlocked\n");
2751 case ATA_HPA_ACTION_FREEZE_LOCK:
2752 error = atahpa_freeze_lock(device, retry_count, timeout,
2755 printf("HPA has been frozen\n");
2759 errx(1, "Option currently not supported");
2769 atasecurity(struct cam_device *device, int retry_count, int timeout,
2770 int argc, char **argv, char *combinedopt)
2773 struct ata_params *ident_buf;
2774 int error, confirm, quiet, c, action, actions, setpwd;
2775 int security_enabled, erase_timeout, pwdsize;
2776 struct ata_security_password pwd;
2784 memset(&pwd, 0, sizeof(pwd));
2786 /* default action is to print security information */
2787 action = ATA_SECURITY_ACTION_PRINT;
2789 /* user is master by default as its safer that way */
2790 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2791 pwdsize = sizeof(pwd.password);
2793 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2796 action = ATA_SECURITY_ACTION_FREEZE;
2801 if (strcasecmp(optarg, "user") == 0) {
2802 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2803 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2804 } else if (strcasecmp(optarg, "master") == 0) {
2805 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2806 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2808 warnx("-U argument '%s' is invalid (must be "
2809 "'user' or 'master')", optarg);
2815 if (strcasecmp(optarg, "high") == 0) {
2816 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2817 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2818 } else if (strcasecmp(optarg, "maximum") == 0) {
2819 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2820 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2822 warnx("-l argument '%s' is unknown (must be "
2823 "'high' or 'maximum')", optarg);
2829 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2831 action = ATA_SECURITY_ACTION_UNLOCK;
2836 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2838 action = ATA_SECURITY_ACTION_DISABLE;
2843 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2845 action = ATA_SECURITY_ACTION_ERASE;
2850 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2852 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2853 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2858 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2861 if (action == ATA_SECURITY_ACTION_PRINT)
2862 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2864 * Don't increment action as this can be combined
2865 * with other actions.
2878 erase_timeout = atoi(optarg) * 1000;
2884 warnx("too many security actions specified");
2888 if ((ccb = cam_getccb(device)) == NULL) {
2889 warnx("couldn't allocate CCB");
2893 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2900 printf("%s%d: ", device->device_name, device->dev_unit_num);
2901 ata_print_ident(ident_buf);
2902 camxferrate(device);
2905 if (action == ATA_SECURITY_ACTION_PRINT) {
2906 atasecurity_print(ident_buf);
2912 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2913 warnx("Security not supported");
2919 /* default timeout 15 seconds the same as linux hdparm */
2920 timeout = timeout ? timeout : 15 * 1000;
2922 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2924 /* first set the password if requested */
2926 /* confirm we can erase before setting the password if erasing */
2928 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2929 action == ATA_SECURITY_ACTION_ERASE) &&
2930 atasecurity_erase_confirm(device, ident_buf) == 0) {
2936 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2937 pwd.revision = ident_buf->master_passwd_revision;
2938 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2939 --pwd.revision == 0) {
2940 pwd.revision = 0xfffe;
2943 error = atasecurity_set_password(device, ccb, retry_count,
2944 timeout, &pwd, quiet);
2950 security_enabled = 1;
2954 case ATA_SECURITY_ACTION_FREEZE:
2955 error = atasecurity_freeze(device, ccb, retry_count,
2959 case ATA_SECURITY_ACTION_UNLOCK:
2960 if (security_enabled) {
2961 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2962 error = atasecurity_unlock(device, ccb,
2963 retry_count, timeout, &pwd, quiet);
2965 warnx("Can't unlock, drive is not locked");
2969 warnx("Can't unlock, security is disabled");
2974 case ATA_SECURITY_ACTION_DISABLE:
2975 if (security_enabled) {
2976 /* First unlock the drive if its locked */
2977 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2978 error = atasecurity_unlock(device, ccb,
2986 error = atasecurity_disable(device,
2994 warnx("Can't disable security (already disabled)");
2999 case ATA_SECURITY_ACTION_ERASE:
3000 if (security_enabled) {
3001 if (erase_timeout == 0) {
3002 erase_timeout = atasecurity_erase_timeout_msecs(
3003 ident_buf->erase_time);
3006 error = atasecurity_erase(device, ccb, retry_count,
3007 timeout, erase_timeout, &pwd,
3010 warnx("Can't secure erase (security is disabled)");
3015 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3016 if (security_enabled) {
3017 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3018 if (erase_timeout == 0) {
3020 atasecurity_erase_timeout_msecs(
3021 ident_buf->enhanced_erase_time);
3024 error = atasecurity_erase(device, ccb,
3025 retry_count, timeout,
3026 erase_timeout, &pwd,
3029 warnx("Enhanced erase is not supported");
3033 warnx("Can't secure erase (enhanced), "
3034 "(security is disabled)");
3045 #endif /* MINIMALISTIC */
3048 * Parse out a bus, or a bus, target and lun in the following
3054 * Returns the number of parsed components, or 0.
3057 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3058 cam_argmask *arglst)
3063 while (isspace(*tstr) && (*tstr != '\0'))
3066 tmpstr = (char *)strtok(tstr, ":");
3067 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3068 *bus = strtol(tmpstr, NULL, 0);
3069 *arglst |= CAM_ARG_BUS;
3071 tmpstr = (char *)strtok(NULL, ":");
3072 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3073 *target = strtol(tmpstr, NULL, 0);
3074 *arglst |= CAM_ARG_TARGET;
3076 tmpstr = (char *)strtok(NULL, ":");
3077 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3078 *lun = strtol(tmpstr, NULL, 0);
3079 *arglst |= CAM_ARG_LUN;
3089 dorescan_or_reset(int argc, char **argv, int rescan)
3091 static const char must[] =
3092 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3094 path_id_t bus = CAM_BUS_WILDCARD;
3095 target_id_t target = CAM_TARGET_WILDCARD;
3096 lun_id_t lun = CAM_LUN_WILDCARD;
3100 warnx(must, rescan? "rescan" : "reset");
3104 tstr = argv[optind];
3105 while (isspace(*tstr) && (*tstr != '\0'))
3107 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3108 arglist |= CAM_ARG_BUS;
3110 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3111 if (rv != 1 && rv != 3) {
3112 warnx(must, rescan? "rescan" : "reset");
3117 if ((arglist & CAM_ARG_BUS)
3118 && (arglist & CAM_ARG_TARGET)
3119 && (arglist & CAM_ARG_LUN))
3120 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3122 error = rescan_or_reset_bus(bus, rescan);
3128 rescan_or_reset_bus(path_id_t bus, int rescan)
3130 union ccb ccb, matchccb;
3136 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3137 warnx("error opening transport layer device %s", XPT_DEVICE);
3138 warn("%s", XPT_DEVICE);
3142 if (bus != CAM_BUS_WILDCARD) {
3143 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3144 ccb.ccb_h.path_id = bus;
3145 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3146 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3147 ccb.crcn.flags = CAM_FLAG_NONE;
3149 /* run this at a low priority */
3150 ccb.ccb_h.pinfo.priority = 5;
3152 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3153 warn("CAMIOCOMMAND ioctl failed");
3158 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3159 fprintf(stdout, "%s of bus %d was successful\n",
3160 rescan ? "Re-scan" : "Reset", bus);
3162 fprintf(stdout, "%s of bus %d returned error %#x\n",
3163 rescan ? "Re-scan" : "Reset", bus,
3164 ccb.ccb_h.status & CAM_STATUS_MASK);
3175 * The right way to handle this is to modify the xpt so that it can
3176 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3177 * that isn't implemented, so instead we enumerate the busses and
3178 * send the rescan or reset to those busses in the case where the
3179 * given bus is -1 (wildcard). We don't send a rescan or reset
3180 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3181 * no-op, sending a rescan to the xpt bus would result in a status of
3184 CCB_CLEAR_ALL_EXCEPT_HDR(&matchccb.cdm);
3185 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3186 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3187 bufsize = sizeof(struct dev_match_result) * 20;
3188 matchccb.cdm.match_buf_len = bufsize;
3189 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3190 if (matchccb.cdm.matches == NULL) {
3191 warnx("can't malloc memory for matches");
3195 matchccb.cdm.num_matches = 0;
3197 matchccb.cdm.num_patterns = 1;
3198 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3200 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3201 matchccb.cdm.pattern_buf_len);
3202 if (matchccb.cdm.patterns == NULL) {
3203 warnx("can't malloc memory for patterns");
3207 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3208 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3213 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3214 warn("CAMIOCOMMAND ioctl failed");
3219 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3220 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3221 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3222 warnx("got CAM error %#x, CDM error %d\n",
3223 matchccb.ccb_h.status, matchccb.cdm.status);
3228 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3229 struct bus_match_result *bus_result;
3231 /* This shouldn't happen. */
3232 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3235 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3238 * We don't want to rescan or reset the xpt bus.
3241 if (bus_result->path_id == CAM_XPT_PATH_ID)
3244 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3246 ccb.ccb_h.path_id = bus_result->path_id;
3247 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3248 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3249 ccb.crcn.flags = CAM_FLAG_NONE;
3251 /* run this at a low priority */
3252 ccb.ccb_h.pinfo.priority = 5;
3254 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3255 warn("CAMIOCOMMAND ioctl failed");
3260 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3261 fprintf(stdout, "%s of bus %d was successful\n",
3262 rescan? "Re-scan" : "Reset",
3263 bus_result->path_id);
3266 * Don't bail out just yet, maybe the other
3267 * rescan or reset commands will complete
3270 fprintf(stderr, "%s of bus %d returned error "
3271 "%#x\n", rescan? "Re-scan" : "Reset",
3272 bus_result->path_id,
3273 ccb.ccb_h.status & CAM_STATUS_MASK);
3277 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3278 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3285 if (matchccb.cdm.patterns != NULL)
3286 free(matchccb.cdm.patterns);
3287 if (matchccb.cdm.matches != NULL)
3288 free(matchccb.cdm.matches);
3294 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3297 struct cam_device *device;
3302 if (bus == CAM_BUS_WILDCARD) {
3303 warnx("invalid bus number %d", bus);
3307 if (target == CAM_TARGET_WILDCARD) {
3308 warnx("invalid target number %d", target);
3312 if (lun == CAM_LUN_WILDCARD) {
3313 warnx("invalid lun number %jx", (uintmax_t)lun);
3319 bzero(&ccb, sizeof(union ccb));
3322 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3323 warnx("error opening transport layer device %s\n",
3325 warn("%s", XPT_DEVICE);
3329 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3330 if (device == NULL) {
3331 warnx("%s", cam_errbuf);
3336 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3337 ccb.ccb_h.path_id = bus;
3338 ccb.ccb_h.target_id = target;
3339 ccb.ccb_h.target_lun = lun;
3340 ccb.ccb_h.timeout = 5000;
3341 ccb.crcn.flags = CAM_FLAG_NONE;
3343 /* run this at a low priority */
3344 ccb.ccb_h.pinfo.priority = 5;
3347 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3348 warn("CAMIOCOMMAND ioctl failed");
3353 if (cam_send_ccb(device, &ccb) < 0) {
3354 warn("error sending XPT_RESET_DEV CCB");
3355 cam_close_device(device);
3363 cam_close_device(device);
3366 * An error code of CAM_BDR_SENT is normal for a BDR request.
3368 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3370 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3371 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3372 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3375 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3376 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3377 ccb.ccb_h.status & CAM_STATUS_MASK);
3382 #ifndef MINIMALISTIC
3384 static struct scsi_nv defect_list_type_map[] = {
3385 { "block", SRDD10_BLOCK_FORMAT },
3386 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3387 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3388 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3389 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3390 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3394 readdefects(struct cam_device *device, int argc, char **argv,
3395 char *combinedopt, int retry_count, int timeout)
3397 union ccb *ccb = NULL;
3398 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3399 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3400 size_t hdr_size = 0, entry_size = 0;
3403 u_int8_t *defect_list = NULL;
3404 u_int8_t list_format = 0;
3405 int list_type_set = 0;
3406 u_int32_t dlist_length = 0;
3407 u_int32_t returned_length = 0, valid_len = 0;
3408 u_int32_t num_returned = 0, num_valid = 0;
3409 u_int32_t max_possible_size = 0, hdr_max = 0;
3410 u_int32_t starting_offset = 0;
3411 u_int8_t returned_format, returned_type;
3413 int summary = 0, quiet = 0;
3415 int lists_specified = 0;
3416 int get_length = 1, first_pass = 1;
3419 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3423 scsi_nv_status status;
3426 status = scsi_get_nv(defect_list_type_map,
3427 sizeof(defect_list_type_map) /
3428 sizeof(defect_list_type_map[0]), optarg,
3429 &entry_num, SCSI_NV_FLAG_IG_CASE);
3431 if (status == SCSI_NV_FOUND) {
3432 list_format = defect_list_type_map[
3436 warnx("%s: %s %s option %s", __func__,
3437 (status == SCSI_NV_AMBIGUOUS) ?
3438 "ambiguous" : "invalid", "defect list type",
3441 goto defect_bailout;
3446 arglist |= CAM_ARG_GLIST;
3449 arglist |= CAM_ARG_PLIST;
3460 starting_offset = strtoul(optarg, &endptr, 0);
3461 if (*endptr != '\0') {
3463 warnx("invalid starting offset %s", optarg);
3464 goto defect_bailout;
3476 if (list_type_set == 0) {
3478 warnx("no defect list format specified");
3479 goto defect_bailout;
3482 if (arglist & CAM_ARG_PLIST) {
3483 list_format |= SRDD10_PLIST;
3487 if (arglist & CAM_ARG_GLIST) {
3488 list_format |= SRDD10_GLIST;
3493 * This implies a summary, and was the previous behavior.
3495 if (lists_specified == 0)
3498 ccb = cam_getccb(device);
3503 * We start off asking for just the header to determine how much
3504 * defect data is available. Some Hitachi drives return an error
3505 * if you ask for more data than the drive has. Once we know the
3506 * length, we retry the command with the returned length.
3508 if (use_12byte == 0)
3509 dlist_length = sizeof(*hdr10);
3511 dlist_length = sizeof(*hdr12);
3514 if (defect_list != NULL) {
3518 defect_list = malloc(dlist_length);
3519 if (defect_list == NULL) {
3520 warnx("can't malloc memory for defect list");
3522 goto defect_bailout;
3526 bzero(defect_list, dlist_length);
3529 * cam_getccb() zeros the CCB header only. So we need to zero the
3530 * payload portion of the ccb.
3532 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3534 scsi_read_defects(&ccb->csio,
3535 /*retries*/ retry_count,
3537 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3538 /*list_format*/ list_format,
3539 /*addr_desc_index*/ starting_offset,
3540 /*data_ptr*/ defect_list,
3541 /*dxfer_len*/ dlist_length,
3542 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3543 /*sense_len*/ SSD_FULL_SIZE,
3544 /*timeout*/ timeout ? timeout : 5000);
3546 /* Disable freezing the device queue */
3547 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3549 if (cam_send_ccb(device, ccb) < 0) {
3550 perror("error reading defect list");
3552 if (arglist & CAM_ARG_VERBOSE) {
3553 cam_error_print(device, ccb, CAM_ESF_ALL,
3554 CAM_EPF_ALL, stderr);
3558 goto defect_bailout;
3561 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3563 if (use_12byte == 0) {
3564 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3565 hdr_size = sizeof(*hdr10);
3566 hdr_max = SRDDH10_MAX_LENGTH;
3568 if (valid_len >= hdr_size) {
3569 returned_length = scsi_2btoul(hdr10->length);
3570 returned_format = hdr10->format;
3572 returned_length = 0;
3573 returned_format = 0;
3576 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3577 hdr_size = sizeof(*hdr12);
3578 hdr_max = SRDDH12_MAX_LENGTH;
3580 if (valid_len >= hdr_size) {
3581 returned_length = scsi_4btoul(hdr12->length);
3582 returned_format = hdr12->format;
3584 returned_length = 0;
3585 returned_format = 0;
3589 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3590 switch (returned_type) {
3591 case SRDD10_BLOCK_FORMAT:
3592 entry_size = sizeof(struct scsi_defect_desc_block);
3594 case SRDD10_LONG_BLOCK_FORMAT:
3595 entry_size = sizeof(struct scsi_defect_desc_long_block);
3597 case SRDD10_EXT_PHYS_FORMAT:
3598 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3599 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3601 case SRDD10_EXT_BFI_FORMAT:
3602 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3603 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3606 warnx("Unknown defect format 0x%x\n", returned_type);
3608 goto defect_bailout;
3612 max_possible_size = (hdr_max / entry_size) * entry_size;
3613 num_returned = returned_length / entry_size;
3614 num_valid = min(returned_length, valid_len - hdr_size);
3615 num_valid /= entry_size;
3617 if (get_length != 0) {
3620 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3621 CAM_SCSI_STATUS_ERROR) {
3622 struct scsi_sense_data *sense;
3623 int error_code, sense_key, asc, ascq;
3625 sense = &ccb->csio.sense_data;
3626 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3627 ccb->csio.sense_resid, &error_code, &sense_key,
3628 &asc, &ascq, /*show_errors*/ 1);
3631 * If the drive is reporting that it just doesn't
3632 * support the defect list format, go ahead and use
3633 * the length it reported. Otherwise, the length
3634 * may not be valid, so use the maximum.
3636 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3637 && (asc == 0x1c) && (ascq == 0x00)
3638 && (returned_length > 0)) {
3639 if ((use_12byte == 0)
3640 && (returned_length >= max_possible_size)) {
3645 dlist_length = returned_length + hdr_size;
3646 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3647 && (asc == 0x1f) && (ascq == 0x00)
3648 && (returned_length > 0)) {
3649 /* Partial defect list transfer */
3651 * Hitachi drives return this error
3652 * along with a partial defect list if they
3653 * have more defects than the 10 byte
3654 * command can support. Retry with the 12
3657 if (use_12byte == 0) {
3662 dlist_length = returned_length + hdr_size;
3663 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3664 && (asc == 0x24) && (ascq == 0x00)) {
3665 /* Invalid field in CDB */
3667 * SBC-3 says that if the drive has more
3668 * defects than can be reported with the
3669 * 10 byte command, it should return this
3670 * error and no data. Retry with the 12
3673 if (use_12byte == 0) {
3678 dlist_length = returned_length + hdr_size;
3681 * If we got a SCSI error and no valid length,
3682 * just use the 10 byte maximum. The 12
3683 * byte maximum is too large.
3685 if (returned_length == 0)
3686 dlist_length = SRDD10_MAX_LENGTH;
3688 if ((use_12byte == 0)
3689 && (returned_length >=
3690 max_possible_size)) {
3695 dlist_length = returned_length +
3699 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3702 warnx("Error reading defect header");
3703 if (arglist & CAM_ARG_VERBOSE)
3704 cam_error_print(device, ccb, CAM_ESF_ALL,
3705 CAM_EPF_ALL, stderr);
3706 goto defect_bailout;
3708 if ((use_12byte == 0)
3709 && (returned_length >= max_possible_size)) {
3714 dlist_length = returned_length + hdr_size;
3717 fprintf(stdout, "%u", num_returned);
3719 fprintf(stdout, " defect%s",
3720 (num_returned != 1) ? "s" : "");
3722 fprintf(stdout, "\n");
3724 goto defect_bailout;
3728 * We always limit the list length to the 10-byte maximum
3729 * length (0xffff). The reason is that some controllers
3730 * can't handle larger I/Os, and we can transfer the entire
3731 * 10 byte list in one shot. For drives that support the 12
3732 * byte read defects command, we'll step through the list
3733 * by specifying a starting offset. For drives that don't
3734 * support the 12 byte command's starting offset, we'll
3735 * just display the first 64K.
3737 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3743 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3744 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3745 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3746 struct scsi_sense_data *sense;
3747 int error_code, sense_key, asc, ascq;
3749 sense = &ccb->csio.sense_data;
3750 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3751 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3752 &ascq, /*show_errors*/ 1);
3755 * According to the SCSI spec, if the disk doesn't support
3756 * the requested format, it will generally return a sense
3757 * key of RECOVERED ERROR, and an additional sense code
3758 * of "DEFECT LIST NOT FOUND". HGST drives also return
3759 * Primary/Grown defect list not found errors. So just
3760 * check for an ASC of 0x1c.
3762 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3764 const char *format_str;
3766 format_str = scsi_nv_to_str(defect_list_type_map,
3767 sizeof(defect_list_type_map) /
3768 sizeof(defect_list_type_map[0]),
3769 list_format & SRDD10_DLIST_FORMAT_MASK);
3770 warnx("requested defect format %s not available",
3771 format_str ? format_str : "unknown");
3773 format_str = scsi_nv_to_str(defect_list_type_map,
3774 sizeof(defect_list_type_map) /
3775 sizeof(defect_list_type_map[0]), returned_type);
3776 if (format_str != NULL) {
3777 warnx("Device returned %s format",
3781 warnx("Device returned unknown defect"
3782 " data format %#x", returned_type);
3783 goto defect_bailout;
3787 warnx("Error returned from read defect data command");
3788 if (arglist & CAM_ARG_VERBOSE)
3789 cam_error_print(device, ccb, CAM_ESF_ALL,
3790 CAM_EPF_ALL, stderr);
3791 goto defect_bailout;
3793 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3795 warnx("Error returned from read defect data command");
3796 if (arglist & CAM_ARG_VERBOSE)
3797 cam_error_print(device, ccb, CAM_ESF_ALL,
3798 CAM_EPF_ALL, stderr);
3799 goto defect_bailout;
3802 if (first_pass != 0) {
3803 fprintf(stderr, "Got %d defect", num_returned);
3805 if ((lists_specified == 0) || (num_returned == 0)) {
3806 fprintf(stderr, "s.\n");
3807 goto defect_bailout;
3808 } else if (num_returned == 1)
3809 fprintf(stderr, ":\n");
3811 fprintf(stderr, "s:\n");
3817 * XXX KDM I should probably clean up the printout format for the
3820 switch (returned_type) {
3821 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3822 case SRDD10_EXT_PHYS_FORMAT:
3824 struct scsi_defect_desc_phys_sector *dlist;
3826 dlist = (struct scsi_defect_desc_phys_sector *)
3827 (defect_list + hdr_size);
3829 for (i = 0; i < num_valid; i++) {
3832 sector = scsi_4btoul(dlist[i].sector);
3833 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3834 mads = (sector & SDD_EXT_PHYS_MADS) ?
3836 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3838 if (hex_format == 0)
3839 fprintf(stdout, "%d:%d:%d%s",
3840 scsi_3btoul(dlist[i].cylinder),
3842 scsi_4btoul(dlist[i].sector),
3843 mads ? " - " : "\n");
3845 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3846 scsi_3btoul(dlist[i].cylinder),
3848 scsi_4btoul(dlist[i].sector),
3849 mads ? " - " : "\n");
3852 if (num_valid < num_returned) {
3853 starting_offset += num_valid;
3858 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3859 case SRDD10_EXT_BFI_FORMAT:
3861 struct scsi_defect_desc_bytes_from_index *dlist;
3863 dlist = (struct scsi_defect_desc_bytes_from_index *)
3864 (defect_list + hdr_size);
3866 for (i = 0; i < num_valid; i++) {
3869 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3870 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3871 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3872 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3874 if (hex_format == 0)
3875 fprintf(stdout, "%d:%d:%d%s",
3876 scsi_3btoul(dlist[i].cylinder),
3878 scsi_4btoul(dlist[i].bytes_from_index),
3879 mads ? " - " : "\n");
3881 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3882 scsi_3btoul(dlist[i].cylinder),
3884 scsi_4btoul(dlist[i].bytes_from_index),
3885 mads ? " - " : "\n");
3889 if (num_valid < num_returned) {
3890 starting_offset += num_valid;
3895 case SRDDH10_BLOCK_FORMAT:
3897 struct scsi_defect_desc_block *dlist;
3899 dlist = (struct scsi_defect_desc_block *)
3900 (defect_list + hdr_size);
3902 for (i = 0; i < num_valid; i++) {
3903 if (hex_format == 0)
3904 fprintf(stdout, "%u\n",
3905 scsi_4btoul(dlist[i].address));
3907 fprintf(stdout, "0x%x\n",
3908 scsi_4btoul(dlist[i].address));
3911 if (num_valid < num_returned) {
3912 starting_offset += num_valid;
3918 case SRDD10_LONG_BLOCK_FORMAT:
3920 struct scsi_defect_desc_long_block *dlist;
3922 dlist = (struct scsi_defect_desc_long_block *)
3923 (defect_list + hdr_size);
3925 for (i = 0; i < num_valid; i++) {
3926 if (hex_format == 0)
3927 fprintf(stdout, "%ju\n",
3928 (uintmax_t)scsi_8btou64(
3931 fprintf(stdout, "0x%jx\n",
3932 (uintmax_t)scsi_8btou64(
3936 if (num_valid < num_returned) {
3937 starting_offset += num_valid;
3943 fprintf(stderr, "Unknown defect format 0x%x\n",
3950 if (defect_list != NULL)
3958 #endif /* MINIMALISTIC */
3962 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3966 ccb = cam_getccb(device);
3972 #ifndef MINIMALISTIC
3974 mode_sense(struct cam_device *device, int mode_page, int page_control,
3975 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3980 ccb = cam_getccb(device);
3983 errx(1, "mode_sense: couldn't allocate CCB");
3985 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3987 scsi_mode_sense(&ccb->csio,
3988 /* retries */ retry_count,
3990 /* tag_action */ MSG_SIMPLE_Q_TAG,
3992 /* page_code */ page_control << 6,
3993 /* page */ mode_page,
3994 /* param_buf */ data,
3995 /* param_len */ datalen,
3996 /* sense_len */ SSD_FULL_SIZE,
3997 /* timeout */ timeout ? timeout : 5000);
3999 if (arglist & CAM_ARG_ERR_RECOVER)
4000 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4002 /* Disable freezing the device queue */
4003 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4005 if (((retval = cam_send_ccb(device, ccb)) < 0)
4006 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4007 if (arglist & CAM_ARG_VERBOSE) {
4008 cam_error_print(device, ccb, CAM_ESF_ALL,
4009 CAM_EPF_ALL, stderr);
4012 cam_close_device(device);
4014 err(1, "error sending mode sense command");
4016 errx(1, "error sending mode sense command");
4023 mode_select(struct cam_device *device, int save_pages, int retry_count,
4024 int timeout, u_int8_t *data, int datalen)
4029 ccb = cam_getccb(device);
4032 errx(1, "mode_select: couldn't allocate CCB");
4034 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4036 scsi_mode_select(&ccb->csio,
4037 /* retries */ retry_count,
4039 /* tag_action */ MSG_SIMPLE_Q_TAG,
4040 /* scsi_page_fmt */ 1,
4041 /* save_pages */ save_pages,
4042 /* param_buf */ data,
4043 /* param_len */ datalen,
4044 /* sense_len */ SSD_FULL_SIZE,
4045 /* timeout */ timeout ? timeout : 5000);
4047 if (arglist & CAM_ARG_ERR_RECOVER)
4048 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4050 /* Disable freezing the device queue */
4051 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4053 if (((retval = cam_send_ccb(device, ccb)) < 0)
4054 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4055 if (arglist & CAM_ARG_VERBOSE) {
4056 cam_error_print(device, ccb, CAM_ESF_ALL,
4057 CAM_EPF_ALL, stderr);
4060 cam_close_device(device);
4063 err(1, "error sending mode select command");
4065 errx(1, "error sending mode select command");
4073 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4074 int retry_count, int timeout)
4076 int c, mode_page = -1, page_control = 0;
4077 int binary = 0, list = 0;
4079 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4085 arglist |= CAM_ARG_DBD;
4088 arglist |= CAM_ARG_MODE_EDIT;
4094 mode_page = strtol(optarg, NULL, 0);
4096 errx(1, "invalid mode page %d", mode_page);
4099 page_control = strtol(optarg, NULL, 0);
4100 if ((page_control < 0) || (page_control > 3))
4101 errx(1, "invalid page control field %d",
4103 arglist |= CAM_ARG_PAGE_CNTL;
4110 if (mode_page == -1 && list == 0)
4111 errx(1, "you must specify a mode page!");
4114 mode_list(device, page_control, arglist & CAM_ARG_DBD,
4115 retry_count, timeout);
4117 mode_edit(device, mode_page, page_control,
4118 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
4119 retry_count, timeout);
4124 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4125 int retry_count, int timeout)
4128 u_int32_t flags = CAM_DIR_NONE;
4129 u_int8_t *data_ptr = NULL;
4131 u_int8_t atacmd[12];
4132 struct get_hook hook;
4133 int c, data_bytes = 0;
4139 char *datastr = NULL, *tstr, *resstr = NULL;
4141 int fd_data = 0, fd_res = 0;
4144 ccb = cam_getccb(device);
4147 warnx("scsicmd: error allocating ccb");
4151 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4153 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4157 while (isspace(*tstr) && (*tstr != '\0'))
4159 hook.argc = argc - optind;
4160 hook.argv = argv + optind;
4162 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4165 * Increment optind by the number of arguments the
4166 * encoding routine processed. After each call to
4167 * getopt(3), optind points to the argument that
4168 * getopt should process _next_. In this case,
4169 * that means it points to the first command string
4170 * argument, if there is one. Once we increment
4171 * this, it should point to either the next command
4172 * line argument, or it should be past the end of
4179 while (isspace(*tstr) && (*tstr != '\0'))
4181 hook.argc = argc - optind;
4182 hook.argv = argv + optind;
4184 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4187 * Increment optind by the number of arguments the
4188 * encoding routine processed. After each call to
4189 * getopt(3), optind points to the argument that
4190 * getopt should process _next_. In this case,
4191 * that means it points to the first command string
4192 * argument, if there is one. Once we increment
4193 * this, it should point to either the next command
4194 * line argument, or it should be past the end of
4206 if (arglist & CAM_ARG_CMD_OUT) {
4207 warnx("command must either be "
4208 "read or write, not both");
4210 goto scsicmd_bailout;
4212 arglist |= CAM_ARG_CMD_IN;
4214 data_bytes = strtol(optarg, NULL, 0);
4215 if (data_bytes <= 0) {
4216 warnx("invalid number of input bytes %d",
4219 goto scsicmd_bailout;
4221 hook.argc = argc - optind;
4222 hook.argv = argv + optind;
4225 datastr = cget(&hook, NULL);
4227 * If the user supplied "-" instead of a format, he
4228 * wants the data to be written to stdout.
4230 if ((datastr != NULL)
4231 && (datastr[0] == '-'))
4234 data_ptr = (u_int8_t *)malloc(data_bytes);
4235 if (data_ptr == NULL) {
4236 warnx("can't malloc memory for data_ptr");
4238 goto scsicmd_bailout;
4242 if (arglist & CAM_ARG_CMD_IN) {
4243 warnx("command must either be "
4244 "read or write, not both");
4246 goto scsicmd_bailout;
4248 arglist |= CAM_ARG_CMD_OUT;
4249 flags = CAM_DIR_OUT;
4250 data_bytes = strtol(optarg, NULL, 0);
4251 if (data_bytes <= 0) {
4252 warnx("invalid number of output bytes %d",
4255 goto scsicmd_bailout;
4257 hook.argc = argc - optind;
4258 hook.argv = argv + optind;
4260 datastr = cget(&hook, NULL);
4261 data_ptr = (u_int8_t *)malloc(data_bytes);
4262 if (data_ptr == NULL) {
4263 warnx("can't malloc memory for data_ptr");
4265 goto scsicmd_bailout;
4267 bzero(data_ptr, data_bytes);
4269 * If the user supplied "-" instead of a format, he
4270 * wants the data to be read from stdin.
4272 if ((datastr != NULL)
4273 && (datastr[0] == '-'))
4276 buff_encode_visit(data_ptr, data_bytes, datastr,
4282 hook.argc = argc - optind;
4283 hook.argv = argv + optind;
4285 resstr = cget(&hook, NULL);
4286 if ((resstr != NULL) && (resstr[0] == '-'))
4296 * If fd_data is set, and we're writing to the device, we need to
4297 * read the data the user wants written from stdin.
4299 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4301 int amt_to_read = data_bytes;
4302 u_int8_t *buf_ptr = data_ptr;
4304 for (amt_read = 0; amt_to_read > 0;
4305 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4306 if (amt_read == -1) {
4307 warn("error reading data from stdin");
4309 goto scsicmd_bailout;
4311 amt_to_read -= amt_read;
4312 buf_ptr += amt_read;
4316 if (arglist & CAM_ARG_ERR_RECOVER)
4317 flags |= CAM_PASS_ERR_RECOVER;
4319 /* Disable freezing the device queue */
4320 flags |= CAM_DEV_QFRZDIS;
4324 * This is taken from the SCSI-3 draft spec.
4325 * (T10/1157D revision 0.3)
4326 * The top 3 bits of an opcode are the group code.
4327 * The next 5 bits are the command code.
4328 * Group 0: six byte commands
4329 * Group 1: ten byte commands
4330 * Group 2: ten byte commands
4332 * Group 4: sixteen byte commands
4333 * Group 5: twelve byte commands
4334 * Group 6: vendor specific
4335 * Group 7: vendor specific
4337 switch((cdb[0] >> 5) & 0x7) {
4348 /* computed by buff_encode_visit */
4359 * We should probably use csio_build_visit or something like that
4360 * here, but it's easier to encode arguments as you go. The
4361 * alternative would be skipping the CDB argument and then encoding
4362 * it here, since we've got the data buffer argument by now.
4364 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4366 cam_fill_csio(&ccb->csio,
4367 /*retries*/ retry_count,
4370 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4371 /*data_ptr*/ data_ptr,
4372 /*dxfer_len*/ data_bytes,
4373 /*sense_len*/ SSD_FULL_SIZE,
4374 /*cdb_len*/ cdb_len,
4375 /*timeout*/ timeout ? timeout : 5000);
4378 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4380 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4382 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4384 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4386 cam_fill_ataio(&ccb->ataio,
4387 /*retries*/ retry_count,
4391 /*data_ptr*/ data_ptr,
4392 /*dxfer_len*/ data_bytes,
4393 /*timeout*/ timeout ? timeout : 5000);
4396 if (((retval = cam_send_ccb(device, ccb)) < 0)
4397 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4398 const char warnstr[] = "error sending command";
4405 if (arglist & CAM_ARG_VERBOSE) {
4406 cam_error_print(device, ccb, CAM_ESF_ALL,
4407 CAM_EPF_ALL, stderr);
4411 goto scsicmd_bailout;
4414 if (atacmd_len && need_res) {
4416 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4418 fprintf(stdout, "\n");
4421 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4422 ccb->ataio.res.status,
4423 ccb->ataio.res.error,
4424 ccb->ataio.res.lba_low,
4425 ccb->ataio.res.lba_mid,
4426 ccb->ataio.res.lba_high,
4427 ccb->ataio.res.device,
4428 ccb->ataio.res.lba_low_exp,
4429 ccb->ataio.res.lba_mid_exp,
4430 ccb->ataio.res.lba_high_exp,
4431 ccb->ataio.res.sector_count,
4432 ccb->ataio.res.sector_count_exp);
4437 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4438 && (arglist & CAM_ARG_CMD_IN)
4439 && (data_bytes > 0)) {
4441 buff_decode_visit(data_ptr, data_bytes, datastr,
4443 fprintf(stdout, "\n");
4445 ssize_t amt_written;
4446 int amt_to_write = data_bytes;
4447 u_int8_t *buf_ptr = data_ptr;
4449 for (amt_written = 0; (amt_to_write > 0) &&
4450 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4451 amt_to_write -= amt_written;
4452 buf_ptr += amt_written;
4454 if (amt_written == -1) {
4455 warn("error writing data to stdout");
4457 goto scsicmd_bailout;
4458 } else if ((amt_written == 0)
4459 && (amt_to_write > 0)) {
4460 warnx("only wrote %u bytes out of %u",
4461 data_bytes - amt_to_write, data_bytes);
4468 if ((data_bytes > 0) && (data_ptr != NULL))
4477 camdebug(int argc, char **argv, char *combinedopt)
4480 path_id_t bus = CAM_BUS_WILDCARD;
4481 target_id_t target = CAM_TARGET_WILDCARD;
4482 lun_id_t lun = CAM_LUN_WILDCARD;
4483 char *tstr, *tmpstr = NULL;
4487 bzero(&ccb, sizeof(union ccb));
4489 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4492 arglist |= CAM_ARG_DEBUG_INFO;
4493 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4496 arglist |= CAM_ARG_DEBUG_PERIPH;
4497 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4500 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4501 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4504 arglist |= CAM_ARG_DEBUG_TRACE;
4505 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4508 arglist |= CAM_ARG_DEBUG_XPT;
4509 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4512 arglist |= CAM_ARG_DEBUG_CDB;
4513 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4516 arglist |= CAM_ARG_DEBUG_PROBE;
4517 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4524 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4525 warnx("error opening transport layer device %s", XPT_DEVICE);
4526 warn("%s", XPT_DEVICE);
4533 warnx("you must specify \"off\", \"all\" or a bus,");
4534 warnx("bus:target, or bus:target:lun");
4541 while (isspace(*tstr) && (*tstr != '\0'))
4544 if (strncmp(tstr, "off", 3) == 0) {
4545 ccb.cdbg.flags = CAM_DEBUG_NONE;
4546 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4547 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4548 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4549 } else if (strncmp(tstr, "all", 3) != 0) {
4550 tmpstr = (char *)strtok(tstr, ":");
4551 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4552 bus = strtol(tmpstr, NULL, 0);
4553 arglist |= CAM_ARG_BUS;
4554 tmpstr = (char *)strtok(NULL, ":");
4555 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4556 target = strtol(tmpstr, NULL, 0);
4557 arglist |= CAM_ARG_TARGET;
4558 tmpstr = (char *)strtok(NULL, ":");
4559 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4560 lun = strtol(tmpstr, NULL, 0);
4561 arglist |= CAM_ARG_LUN;
4566 warnx("you must specify \"all\", \"off\", or a bus,");
4567 warnx("bus:target, or bus:target:lun to debug");
4573 ccb.ccb_h.func_code = XPT_DEBUG;
4574 ccb.ccb_h.path_id = bus;
4575 ccb.ccb_h.target_id = target;
4576 ccb.ccb_h.target_lun = lun;
4578 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4579 warn("CAMIOCOMMAND ioctl failed");
4584 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4585 CAM_FUNC_NOTAVAIL) {
4586 warnx("CAM debugging not available");
4587 warnx("you need to put options CAMDEBUG in"
4588 " your kernel config file!");
4590 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4592 warnx("XPT_DEBUG CCB failed with status %#x",
4596 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4598 "Debugging turned off\n");
4601 "Debugging enabled for "
4603 bus, target, (uintmax_t)lun);
4614 tagcontrol(struct cam_device *device, int argc, char **argv,
4624 ccb = cam_getccb(device);
4627 warnx("tagcontrol: error allocating ccb");
4631 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4634 numtags = strtol(optarg, NULL, 0);
4636 warnx("tag count %d is < 0", numtags);
4638 goto tagcontrol_bailout;
4649 cam_path_string(device, pathstr, sizeof(pathstr));
4652 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4653 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4654 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4655 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4656 ccb->crs.openings = numtags;
4659 if (cam_send_ccb(device, ccb) < 0) {
4660 perror("error sending XPT_REL_SIMQ CCB");
4662 goto tagcontrol_bailout;
4665 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4666 warnx("XPT_REL_SIMQ CCB failed");
4667 cam_error_print(device, ccb, CAM_ESF_ALL,
4668 CAM_EPF_ALL, stderr);
4670 goto tagcontrol_bailout;
4675 fprintf(stdout, "%stagged openings now %d\n",
4676 pathstr, ccb->crs.openings);
4679 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4681 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4683 if (cam_send_ccb(device, ccb) < 0) {
4684 perror("error sending XPT_GDEV_STATS CCB");
4686 goto tagcontrol_bailout;
4689 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4690 warnx("XPT_GDEV_STATS CCB failed");
4691 cam_error_print(device, ccb, CAM_ESF_ALL,
4692 CAM_EPF_ALL, stderr);
4694 goto tagcontrol_bailout;
4697 if (arglist & CAM_ARG_VERBOSE) {
4698 fprintf(stdout, "%s", pathstr);
4699 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4700 fprintf(stdout, "%s", pathstr);
4701 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4702 fprintf(stdout, "%s", pathstr);
4703 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4704 fprintf(stdout, "%s", pathstr);
4705 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4706 fprintf(stdout, "%s", pathstr);
4707 fprintf(stdout, "held %d\n", ccb->cgds.held);
4708 fprintf(stdout, "%s", pathstr);
4709 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4710 fprintf(stdout, "%s", pathstr);
4711 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4714 fprintf(stdout, "%s", pathstr);
4715 fprintf(stdout, "device openings: ");
4717 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4718 ccb->cgds.dev_active);
4728 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4732 cam_path_string(device, pathstr, sizeof(pathstr));
4734 if (cts->transport == XPORT_SPI) {
4735 struct ccb_trans_settings_spi *spi =
4736 &cts->xport_specific.spi;
4738 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4740 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4743 if (spi->sync_offset != 0) {
4746 freq = scsi_calc_syncsrate(spi->sync_period);
4747 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4748 pathstr, freq / 1000, freq % 1000);
4752 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4753 fprintf(stdout, "%soffset: %d\n", pathstr,
4757 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4758 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4759 (0x01 << spi->bus_width) * 8);
4762 if (spi->valid & CTS_SPI_VALID_DISC) {
4763 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4764 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4765 "enabled" : "disabled");
4768 if (cts->transport == XPORT_FC) {
4769 struct ccb_trans_settings_fc *fc =
4770 &cts->xport_specific.fc;
4772 if (fc->valid & CTS_FC_VALID_WWNN)
4773 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4774 (long long) fc->wwnn);
4775 if (fc->valid & CTS_FC_VALID_WWPN)
4776 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4777 (long long) fc->wwpn);
4778 if (fc->valid & CTS_FC_VALID_PORT)
4779 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4780 if (fc->valid & CTS_FC_VALID_SPEED)
4781 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4782 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4784 if (cts->transport == XPORT_SAS) {
4785 struct ccb_trans_settings_sas *sas =
4786 &cts->xport_specific.sas;
4788 if (sas->valid & CTS_SAS_VALID_SPEED)
4789 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4790 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4792 if (cts->transport == XPORT_ATA) {
4793 struct ccb_trans_settings_pata *pata =
4794 &cts->xport_specific.ata;
4796 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4797 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4798 ata_mode2string(pata->mode));
4800 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4801 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4804 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4805 fprintf(stdout, "%sPIO transaction length: %d\n",
4806 pathstr, pata->bytecount);
4809 if (cts->transport == XPORT_SATA) {
4810 struct ccb_trans_settings_sata *sata =
4811 &cts->xport_specific.sata;
4813 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4814 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4817 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4818 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4819 ata_mode2string(sata->mode));
4821 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4822 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4825 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4826 fprintf(stdout, "%sPIO transaction length: %d\n",
4827 pathstr, sata->bytecount);
4829 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4830 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4833 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4834 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4837 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4838 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4842 if (cts->protocol == PROTO_ATA) {
4843 struct ccb_trans_settings_ata *ata=
4844 &cts->proto_specific.ata;
4846 if (ata->valid & CTS_ATA_VALID_TQ) {
4847 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4848 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4849 "enabled" : "disabled");
4852 if (cts->protocol == PROTO_SCSI) {
4853 struct ccb_trans_settings_scsi *scsi=
4854 &cts->proto_specific.scsi;
4856 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4857 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4858 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4859 "enabled" : "disabled");
4866 * Get a path inquiry CCB for the specified device.
4869 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4874 ccb = cam_getccb(device);
4876 warnx("get_cpi: couldn't allocate CCB");
4879 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
4880 ccb->ccb_h.func_code = XPT_PATH_INQ;
4881 if (cam_send_ccb(device, ccb) < 0) {
4882 warn("get_cpi: error sending Path Inquiry CCB");
4883 if (arglist & CAM_ARG_VERBOSE)
4884 cam_error_print(device, ccb, CAM_ESF_ALL,
4885 CAM_EPF_ALL, stderr);
4887 goto get_cpi_bailout;
4889 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4890 if (arglist & CAM_ARG_VERBOSE)
4891 cam_error_print(device, ccb, CAM_ESF_ALL,
4892 CAM_EPF_ALL, stderr);
4894 goto get_cpi_bailout;
4896 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4904 * Get a get device CCB for the specified device.
4907 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4912 ccb = cam_getccb(device);
4914 warnx("get_cgd: couldn't allocate CCB");
4917 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
4918 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4919 if (cam_send_ccb(device, ccb) < 0) {
4920 warn("get_cgd: error sending Path Inquiry CCB");
4921 if (arglist & CAM_ARG_VERBOSE)
4922 cam_error_print(device, ccb, CAM_ESF_ALL,
4923 CAM_EPF_ALL, stderr);
4925 goto get_cgd_bailout;
4927 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4928 if (arglist & CAM_ARG_VERBOSE)
4929 cam_error_print(device, ccb, CAM_ESF_ALL,
4930 CAM_EPF_ALL, stderr);
4932 goto get_cgd_bailout;
4934 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4942 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4946 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4947 int timeout, int verbosemode)
4949 union ccb *ccb = NULL;
4950 struct scsi_vpd_supported_page_list sup_pages;
4954 ccb = cam_getccb(dev);
4956 warn("Unable to allocate CCB");
4961 /* cam_getccb cleans up the header, caller has to zero the payload */
4962 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4964 bzero(&sup_pages, sizeof(sup_pages));
4966 scsi_inquiry(&ccb->csio,
4967 /*retries*/ retry_count,
4969 /* tag_action */ MSG_SIMPLE_Q_TAG,
4970 /* inq_buf */ (u_int8_t *)&sup_pages,
4971 /* inq_len */ sizeof(sup_pages),
4973 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
4974 /* sense_len */ SSD_FULL_SIZE,
4975 /* timeout */ timeout ? timeout : 5000);
4977 /* Disable freezing the device queue */
4978 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4980 if (retry_count != 0)
4981 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4983 if (cam_send_ccb(dev, ccb) < 0) {
4990 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4991 if (verbosemode != 0)
4992 cam_error_print(dev, ccb, CAM_ESF_ALL,
4993 CAM_EPF_ALL, stderr);
4998 for (i = 0; i < sup_pages.length; i++) {
4999 if (sup_pages.list[i] == page_id) {
5012 * devtype is filled in with the type of device.
5013 * Returns 0 for success, non-zero for failure.
5016 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5017 int verbosemode, camcontrol_devtype *devtype)
5019 struct ccb_getdev cgd;
5022 retval = get_cgd(dev, &cgd);
5026 switch (cgd.protocol) {
5032 *devtype = CC_DT_ATA;
5034 break; /*NOTREACHED*/
5036 *devtype = CC_DT_UNKNOWN;
5038 break; /*NOTREACHED*/
5042 * Check for the ATA Information VPD page (0x89). If this is an
5043 * ATA device behind a SCSI to ATA translation layer, this VPD page
5044 * should be present.
5046 * If that VPD page isn't present, or we get an error back from the
5047 * INQUIRY command, we'll just treat it as a normal SCSI device.
5049 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5050 timeout, verbosemode);
5052 *devtype = CC_DT_ATA_BEHIND_SCSI;
5054 *devtype = CC_DT_SCSI;
5063 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5064 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5065 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5066 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5067 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5068 int is48bit, camcontrol_devtype devtype)
5072 if (devtype == CC_DT_ATA) {
5073 cam_fill_ataio(&ccb->ataio,
5074 /*retries*/ retry_count,
5077 /*tag_action*/ tag_action,
5078 /*data_ptr*/ data_ptr,
5079 /*dxfer_len*/ dxfer_len,
5080 /*timeout*/ timeout);
5081 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5082 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5085 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5088 if (auxiliary != 0) {
5089 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5090 ccb->ataio.aux = auxiliary;
5093 if (ata_flags & AP_FLAG_CHK_COND)
5094 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5096 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5097 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5098 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5099 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5101 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5102 protocol |= AP_EXTEND;
5104 retval = scsi_ata_pass(&ccb->csio,
5105 /*retries*/ retry_count,
5108 /*tag_action*/ tag_action,
5109 /*protocol*/ protocol,
5110 /*ata_flags*/ ata_flags,
5111 /*features*/ features,
5112 /*sector_count*/ sector_count,
5114 /*command*/ command,
5117 /*auxiliary*/ auxiliary,
5119 /*data_ptr*/ data_ptr,
5120 /*dxfer_len*/ dxfer_len,
5121 /*cdb_storage*/ cdb_storage,
5122 /*cdb_storage_len*/ cdb_storage_len,
5123 /*minimum_cmd_size*/ 0,
5124 /*sense_len*/ sense_len,
5125 /*timeout*/ timeout);
5132 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5133 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5137 switch (ccb->ccb_h.func_code) {
5140 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5143 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5144 * or 16 byte, and need to see what
5146 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5147 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5149 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5150 if ((opcode != ATA_PASS_12)
5151 && (opcode != ATA_PASS_16)) {
5153 warnx("%s: unsupported opcode %02x", __func__, opcode);
5157 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5159 /* Note: the _ccb() variant returns 0 for an error */
5166 switch (error_code) {
5167 case SSD_DESC_CURRENT_ERROR:
5168 case SSD_DESC_DEFERRED_ERROR: {
5169 struct scsi_sense_data_desc *sense;
5170 struct scsi_sense_ata_ret_desc *desc;
5173 sense = (struct scsi_sense_data_desc *)
5174 &ccb->csio.sense_data;
5176 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5177 ccb->csio.sense_resid, SSD_DESC_ATA);
5178 if (desc_ptr == NULL) {
5179 cam_error_print(dev, ccb, CAM_ESF_ALL,
5180 CAM_EPF_ALL, stderr);
5184 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5186 *error = desc->error;
5187 *count = (desc->count_15_8 << 8) |
5189 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5190 ((uint64_t)desc->lba_39_32 << 32) |
5191 ((uint64_t)desc->lba_31_24 << 24) |
5192 (desc->lba_23_16 << 16) |
5193 (desc->lba_15_8 << 8) |
5195 *device = desc->device;
5196 *status = desc->status;
5199 * If the extend bit isn't set, the result is for a
5200 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5201 * command without the extend bit set. This means
5202 * that the device is supposed to return 28-bit
5203 * status. The count field is only 8 bits, and the
5204 * LBA field is only 8 bits.
5206 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5212 case SSD_CURRENT_ERROR:
5213 case SSD_DEFERRED_ERROR: {
5215 struct scsi_sense_data_fixed *sense;
5218 * XXX KDM need to support fixed sense data.
5220 warnx("%s: Fixed sense data not supported yet",
5224 break; /*NOTREACHED*/
5235 struct ata_res *res;
5238 * In this case, we have an ATA command, and we need to
5239 * fill in the requested values from the result register
5242 res = &ccb->ataio.res;
5243 *error = res->error;
5244 *status = res->status;
5245 *device = res->device;
5246 *count = res->sector_count;
5247 *lba = (res->lba_high << 16) |
5248 (res->lba_mid << 8) |
5250 if (res->flags & CAM_ATAIO_48BIT) {
5251 *count |= (res->sector_count_exp << 8);
5252 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5253 ((uint64_t)res->lba_mid_exp << 32) |
5254 ((uint64_t)res->lba_high_exp << 40);
5256 *lba |= (res->device & 0xf) << 24;
5269 cpi_print(struct ccb_pathinq *cpi)
5271 char adapter_str[1024];
5274 snprintf(adapter_str, sizeof(adapter_str),
5275 "%s%d:", cpi->dev_name, cpi->unit_number);
5277 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5280 for (i = 1; i < 0xff; i = i << 1) {
5283 if ((i & cpi->hba_inquiry) == 0)
5286 fprintf(stdout, "%s supports ", adapter_str);
5290 str = "MDP message";
5293 str = "32 bit wide SCSI";
5296 str = "16 bit wide SCSI";
5299 str = "SDTR message";
5302 str = "linked CDBs";
5305 str = "tag queue messages";
5308 str = "soft reset alternative";
5311 str = "SATA Port Multiplier";
5314 str = "unknown PI bit set";
5317 fprintf(stdout, "%s\n", str);
5320 for (i = 1; i < 0xff; i = i << 1) {
5323 if ((i & cpi->hba_misc) == 0)
5326 fprintf(stdout, "%s ", adapter_str);
5330 str = "bus scans from high ID to low ID";
5333 str = "removable devices not included in scan";
5335 case PIM_NOINITIATOR:
5336 str = "initiator role not supported";
5338 case PIM_NOBUSRESET:
5339 str = "user has disabled initial BUS RESET or"
5340 " controller is in target/mixed mode";
5343 str = "do not send 6-byte commands";
5346 str = "scan bus sequentially";
5349 str = "unknown PIM bit set";
5352 fprintf(stdout, "%s\n", str);
5355 for (i = 1; i < 0xff; i = i << 1) {
5358 if ((i & cpi->target_sprt) == 0)
5361 fprintf(stdout, "%s supports ", adapter_str);
5364 str = "target mode processor mode";
5367 str = "target mode phase cog. mode";
5369 case PIT_DISCONNECT:
5370 str = "disconnects in target mode";
5373 str = "terminate I/O message in target mode";
5376 str = "group 6 commands in target mode";
5379 str = "group 7 commands in target mode";
5382 str = "unknown PIT bit set";
5386 fprintf(stdout, "%s\n", str);
5388 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5390 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5392 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5394 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5395 adapter_str, cpi->hpath_id);
5396 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5398 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5399 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5400 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5401 adapter_str, cpi->hba_vendor);
5402 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5403 adapter_str, cpi->hba_device);
5404 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5405 adapter_str, cpi->hba_subvendor);
5406 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5407 adapter_str, cpi->hba_subdevice);
5408 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5409 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5410 if (cpi->base_transfer_speed > 1000)
5411 fprintf(stdout, "%d.%03dMB/sec\n",
5412 cpi->base_transfer_speed / 1000,
5413 cpi->base_transfer_speed % 1000);
5415 fprintf(stdout, "%dKB/sec\n",
5416 (cpi->base_transfer_speed % 1000) * 1000);
5417 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5418 adapter_str, cpi->maxio);
5422 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5423 struct ccb_trans_settings *cts)
5429 ccb = cam_getccb(device);
5432 warnx("get_print_cts: error allocating ccb");
5436 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5438 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5440 if (user_settings == 0)
5441 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5443 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5445 if (cam_send_ccb(device, ccb) < 0) {
5446 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5447 if (arglist & CAM_ARG_VERBOSE)
5448 cam_error_print(device, ccb, CAM_ESF_ALL,
5449 CAM_EPF_ALL, stderr);
5451 goto get_print_cts_bailout;
5454 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5455 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5456 if (arglist & CAM_ARG_VERBOSE)
5457 cam_error_print(device, ccb, CAM_ESF_ALL,
5458 CAM_EPF_ALL, stderr);
5460 goto get_print_cts_bailout;
5464 cts_print(device, &ccb->cts);
5467 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5469 get_print_cts_bailout:
5477 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5478 int argc, char **argv, char *combinedopt)
5482 int user_settings = 0;
5484 int disc_enable = -1, tag_enable = -1;
5487 double syncrate = -1;
5490 int change_settings = 0, send_tur = 0;
5491 struct ccb_pathinq cpi;
5493 ccb = cam_getccb(device);
5495 warnx("ratecontrol: error allocating ccb");
5498 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5507 if (strncasecmp(optarg, "enable", 6) == 0)
5509 else if (strncasecmp(optarg, "disable", 7) == 0)
5512 warnx("-D argument \"%s\" is unknown", optarg);
5514 goto ratecontrol_bailout;
5516 change_settings = 1;
5519 mode = ata_string2mode(optarg);
5521 warnx("unknown mode '%s'", optarg);
5523 goto ratecontrol_bailout;
5525 change_settings = 1;
5528 offset = strtol(optarg, NULL, 0);
5530 warnx("offset value %d is < 0", offset);
5532 goto ratecontrol_bailout;
5534 change_settings = 1;
5540 syncrate = atof(optarg);
5542 warnx("sync rate %f is < 0", syncrate);
5544 goto ratecontrol_bailout;
5546 change_settings = 1;
5549 if (strncasecmp(optarg, "enable", 6) == 0)
5551 else if (strncasecmp(optarg, "disable", 7) == 0)
5554 warnx("-T argument \"%s\" is unknown", optarg);
5556 goto ratecontrol_bailout;
5558 change_settings = 1;
5564 bus_width = strtol(optarg, NULL, 0);
5565 if (bus_width < 0) {
5566 warnx("bus width %d is < 0", bus_width);
5568 goto ratecontrol_bailout;
5570 change_settings = 1;
5576 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5578 * Grab path inquiry information, so we can determine whether
5579 * or not the initiator is capable of the things that the user
5582 ccb->ccb_h.func_code = XPT_PATH_INQ;
5583 if (cam_send_ccb(device, ccb) < 0) {
5584 perror("error sending XPT_PATH_INQ CCB");
5585 if (arglist & CAM_ARG_VERBOSE) {
5586 cam_error_print(device, ccb, CAM_ESF_ALL,
5587 CAM_EPF_ALL, stderr);
5590 goto ratecontrol_bailout;
5592 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5593 warnx("XPT_PATH_INQ CCB failed");
5594 if (arglist & CAM_ARG_VERBOSE) {
5595 cam_error_print(device, ccb, CAM_ESF_ALL,
5596 CAM_EPF_ALL, stderr);
5599 goto ratecontrol_bailout;
5601 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5602 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5604 fprintf(stdout, "%s parameters:\n",
5605 user_settings ? "User" : "Current");
5607 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5609 goto ratecontrol_bailout;
5611 if (arglist & CAM_ARG_VERBOSE)
5614 if (change_settings) {
5615 int didsettings = 0;
5616 struct ccb_trans_settings_spi *spi = NULL;
5617 struct ccb_trans_settings_pata *pata = NULL;
5618 struct ccb_trans_settings_sata *sata = NULL;
5619 struct ccb_trans_settings_ata *ata = NULL;
5620 struct ccb_trans_settings_scsi *scsi = NULL;
5622 if (ccb->cts.transport == XPORT_SPI)
5623 spi = &ccb->cts.xport_specific.spi;
5624 if (ccb->cts.transport == XPORT_ATA)
5625 pata = &ccb->cts.xport_specific.ata;
5626 if (ccb->cts.transport == XPORT_SATA)
5627 sata = &ccb->cts.xport_specific.sata;
5628 if (ccb->cts.protocol == PROTO_ATA)
5629 ata = &ccb->cts.proto_specific.ata;
5630 if (ccb->cts.protocol == PROTO_SCSI)
5631 scsi = &ccb->cts.proto_specific.scsi;
5632 ccb->cts.xport_specific.valid = 0;
5633 ccb->cts.proto_specific.valid = 0;
5634 if (spi && disc_enable != -1) {
5635 spi->valid |= CTS_SPI_VALID_DISC;
5636 if (disc_enable == 0)
5637 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5639 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5642 if (tag_enable != -1) {
5643 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5644 warnx("HBA does not support tagged queueing, "
5645 "so you cannot modify tag settings");
5647 goto ratecontrol_bailout;
5650 ata->valid |= CTS_SCSI_VALID_TQ;
5651 if (tag_enable == 0)
5652 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5654 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5657 scsi->valid |= CTS_SCSI_VALID_TQ;
5658 if (tag_enable == 0)
5659 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5661 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5665 if (spi && offset != -1) {
5666 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5667 warnx("HBA is not capable of changing offset");
5669 goto ratecontrol_bailout;
5671 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5672 spi->sync_offset = offset;
5675 if (spi && syncrate != -1) {
5676 int prelim_sync_period;
5678 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5679 warnx("HBA is not capable of changing "
5682 goto ratecontrol_bailout;
5684 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5686 * The sync rate the user gives us is in MHz.
5687 * We need to translate it into KHz for this
5692 * Next, we calculate a "preliminary" sync period
5693 * in tenths of a nanosecond.
5696 prelim_sync_period = 0;
5698 prelim_sync_period = 10000000 / syncrate;
5700 scsi_calc_syncparam(prelim_sync_period);
5703 if (sata && syncrate != -1) {
5704 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5705 warnx("HBA is not capable of changing "
5708 goto ratecontrol_bailout;
5710 if (!user_settings) {
5711 warnx("You can modify only user rate "
5712 "settings for SATA");
5714 goto ratecontrol_bailout;
5716 sata->revision = ata_speed2revision(syncrate * 100);
5717 if (sata->revision < 0) {
5718 warnx("Invalid rate %f", syncrate);
5720 goto ratecontrol_bailout;
5722 sata->valid |= CTS_SATA_VALID_REVISION;
5725 if ((pata || sata) && mode != -1) {
5726 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5727 warnx("HBA is not capable of changing "
5730 goto ratecontrol_bailout;
5732 if (!user_settings) {
5733 warnx("You can modify only user mode "
5734 "settings for ATA/SATA");
5736 goto ratecontrol_bailout;
5740 pata->valid |= CTS_ATA_VALID_MODE;
5743 sata->valid |= CTS_SATA_VALID_MODE;
5748 * The bus_width argument goes like this:
5752 * Therefore, if you shift the number of bits given on the
5753 * command line right by 4, you should get the correct
5756 if (spi && bus_width != -1) {
5758 * We might as well validate things here with a
5759 * decipherable error message, rather than what
5760 * will probably be an indecipherable error message
5761 * by the time it gets back to us.
5763 if ((bus_width == 16)
5764 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5765 warnx("HBA does not support 16 bit bus width");
5767 goto ratecontrol_bailout;
5768 } else if ((bus_width == 32)
5769 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5770 warnx("HBA does not support 32 bit bus width");
5772 goto ratecontrol_bailout;
5773 } else if ((bus_width != 8)
5774 && (bus_width != 16)
5775 && (bus_width != 32)) {
5776 warnx("Invalid bus width %d", bus_width);
5778 goto ratecontrol_bailout;
5780 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5781 spi->bus_width = bus_width >> 4;
5784 if (didsettings == 0) {
5785 goto ratecontrol_bailout;
5787 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5788 if (cam_send_ccb(device, ccb) < 0) {
5789 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5790 if (arglist & CAM_ARG_VERBOSE) {
5791 cam_error_print(device, ccb, CAM_ESF_ALL,
5792 CAM_EPF_ALL, stderr);
5795 goto ratecontrol_bailout;
5797 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5798 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5799 if (arglist & CAM_ARG_VERBOSE) {
5800 cam_error_print(device, ccb, CAM_ESF_ALL,
5801 CAM_EPF_ALL, stderr);
5804 goto ratecontrol_bailout;
5808 retval = testunitready(device, retry_count, timeout,
5809 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5811 * If the TUR didn't succeed, just bail.
5815 fprintf(stderr, "Test Unit Ready failed\n");
5816 goto ratecontrol_bailout;
5819 if ((change_settings || send_tur) && !quiet &&
5820 (ccb->cts.transport == XPORT_ATA ||
5821 ccb->cts.transport == XPORT_SATA || send_tur)) {
5822 fprintf(stdout, "New parameters:\n");
5823 retval = get_print_cts(device, user_settings, 0, NULL);
5826 ratecontrol_bailout:
5832 scsiformat(struct cam_device *device, int argc, char **argv,
5833 char *combinedopt, int retry_count, int timeout)
5837 int ycount = 0, quiet = 0;
5838 int error = 0, retval = 0;
5839 int use_timeout = 10800 * 1000;
5841 struct format_defect_list_header fh;
5842 u_int8_t *data_ptr = NULL;
5843 u_int32_t dxfer_len = 0;
5845 int num_warnings = 0;
5848 ccb = cam_getccb(device);
5851 warnx("scsiformat: error allocating ccb");
5855 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5857 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5878 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5879 "following device:\n");
5881 error = scsidoinquiry(device, argc, argv, combinedopt,
5882 retry_count, timeout);
5885 warnx("scsiformat: error sending inquiry");
5886 goto scsiformat_bailout;
5891 if (!get_confirmation()) {
5893 goto scsiformat_bailout;
5898 use_timeout = timeout;
5901 fprintf(stdout, "Current format timeout is %d seconds\n",
5902 use_timeout / 1000);
5906 * If the user hasn't disabled questions and didn't specify a
5907 * timeout on the command line, ask them if they want the current
5911 && (timeout == 0)) {
5913 int new_timeout = 0;
5915 fprintf(stdout, "Enter new timeout in seconds or press\n"
5916 "return to keep the current timeout [%d] ",
5917 use_timeout / 1000);
5919 if (fgets(str, sizeof(str), stdin) != NULL) {
5921 new_timeout = atoi(str);
5924 if (new_timeout != 0) {
5925 use_timeout = new_timeout * 1000;
5926 fprintf(stdout, "Using new timeout value %d\n",
5927 use_timeout / 1000);
5932 * Keep this outside the if block below to silence any unused
5933 * variable warnings.
5935 bzero(&fh, sizeof(fh));
5938 * If we're in immediate mode, we've got to include the format
5941 if (immediate != 0) {
5942 fh.byte2 = FU_DLH_IMMED;
5943 data_ptr = (u_int8_t *)&fh;
5944 dxfer_len = sizeof(fh);
5945 byte2 = FU_FMT_DATA;
5946 } else if (quiet == 0) {
5947 fprintf(stdout, "Formatting...");
5951 scsi_format_unit(&ccb->csio,
5952 /* retries */ retry_count,
5954 /* tag_action */ MSG_SIMPLE_Q_TAG,
5957 /* data_ptr */ data_ptr,
5958 /* dxfer_len */ dxfer_len,
5959 /* sense_len */ SSD_FULL_SIZE,
5960 /* timeout */ use_timeout);
5962 /* Disable freezing the device queue */
5963 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5965 if (arglist & CAM_ARG_ERR_RECOVER)
5966 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5968 if (((retval = cam_send_ccb(device, ccb)) < 0)
5969 || ((immediate == 0)
5970 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5971 const char errstr[] = "error sending format command";
5978 if (arglist & CAM_ARG_VERBOSE) {
5979 cam_error_print(device, ccb, CAM_ESF_ALL,
5980 CAM_EPF_ALL, stderr);
5983 goto scsiformat_bailout;
5987 * If we ran in non-immediate mode, we already checked for errors
5988 * above and printed out any necessary information. If we're in
5989 * immediate mode, we need to loop through and get status
5990 * information periodically.
5992 if (immediate == 0) {
5994 fprintf(stdout, "Format Complete\n");
5996 goto scsiformat_bailout;
6003 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6006 * There's really no need to do error recovery or
6007 * retries here, since we're just going to sit in a
6008 * loop and wait for the device to finish formatting.
6010 scsi_test_unit_ready(&ccb->csio,
6013 /* tag_action */ MSG_SIMPLE_Q_TAG,
6014 /* sense_len */ SSD_FULL_SIZE,
6015 /* timeout */ 5000);
6017 /* Disable freezing the device queue */
6018 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6020 retval = cam_send_ccb(device, ccb);
6023 * If we get an error from the ioctl, bail out. SCSI
6024 * errors are expected.
6027 warn("error sending CAMIOCOMMAND ioctl");
6028 if (arglist & CAM_ARG_VERBOSE) {
6029 cam_error_print(device, ccb, CAM_ESF_ALL,
6030 CAM_EPF_ALL, stderr);
6033 goto scsiformat_bailout;
6036 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6038 if ((status != CAM_REQ_CMP)
6039 && (status == CAM_SCSI_STATUS_ERROR)
6040 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6041 struct scsi_sense_data *sense;
6042 int error_code, sense_key, asc, ascq;
6044 sense = &ccb->csio.sense_data;
6045 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6046 ccb->csio.sense_resid, &error_code, &sense_key,
6047 &asc, &ascq, /*show_errors*/ 1);
6050 * According to the SCSI-2 and SCSI-3 specs, a
6051 * drive that is in the middle of a format should
6052 * return NOT READY with an ASC of "logical unit
6053 * not ready, format in progress". The sense key
6054 * specific bytes will then be a progress indicator.
6056 if ((sense_key == SSD_KEY_NOT_READY)
6057 && (asc == 0x04) && (ascq == 0x04)) {
6060 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6061 ccb->csio.sense_resid, sks) == 0)
6064 u_int64_t percentage;
6066 val = scsi_2btoul(&sks[1]);
6067 percentage = 10000 * val;
6070 "\rFormatting: %ju.%02u %% "
6072 (uintmax_t)(percentage /
6074 (unsigned)((percentage /
6078 } else if ((quiet == 0)
6079 && (++num_warnings <= 1)) {
6080 warnx("Unexpected SCSI Sense Key "
6081 "Specific value returned "
6083 scsi_sense_print(device, &ccb->csio,
6085 warnx("Unable to print status "
6086 "information, but format will "
6088 warnx("will exit when format is "
6093 warnx("Unexpected SCSI error during format");
6094 cam_error_print(device, ccb, CAM_ESF_ALL,
6095 CAM_EPF_ALL, stderr);
6097 goto scsiformat_bailout;
6100 } else if (status != CAM_REQ_CMP) {
6101 warnx("Unexpected CAM status %#x", status);
6102 if (arglist & CAM_ARG_VERBOSE)
6103 cam_error_print(device, ccb, CAM_ESF_ALL,
6104 CAM_EPF_ALL, stderr);
6106 goto scsiformat_bailout;
6109 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6112 fprintf(stdout, "\nFormat Complete\n");
6122 scsisanitize(struct cam_device *device, int argc, char **argv,
6123 char *combinedopt, int retry_count, int timeout)
6126 u_int8_t action = 0;
6128 int ycount = 0, quiet = 0;
6129 int error = 0, retval = 0;
6130 int use_timeout = 10800 * 1000;
6136 const char *pattern = NULL;
6137 u_int8_t *data_ptr = NULL;
6138 u_int32_t dxfer_len = 0;
6140 int num_warnings = 0;
6143 ccb = cam_getccb(device);
6146 warnx("scsisanitize: error allocating ccb");
6150 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6152 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6155 if (strcasecmp(optarg, "overwrite") == 0)
6156 action = SSZ_SERVICE_ACTION_OVERWRITE;
6157 else if (strcasecmp(optarg, "block") == 0)
6158 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6159 else if (strcasecmp(optarg, "crypto") == 0)
6160 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6161 else if (strcasecmp(optarg, "exitfailure") == 0)
6162 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6164 warnx("invalid service operation \"%s\"",
6167 goto scsisanitize_bailout;
6171 passes = strtol(optarg, NULL, 0);
6172 if (passes < 1 || passes > 31) {
6173 warnx("invalid passes value %d", passes);
6175 goto scsisanitize_bailout;
6206 warnx("an action is required");
6208 goto scsisanitize_bailout;
6209 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6210 struct scsi_sanitize_parameter_list *pl;
6214 if (pattern == NULL) {
6215 warnx("overwrite action requires -P argument");
6217 goto scsisanitize_bailout;
6219 fd = open(pattern, O_RDONLY);
6221 warn("cannot open pattern file %s", pattern);
6223 goto scsisanitize_bailout;
6225 if (fstat(fd, &sb) < 0) {
6226 warn("cannot stat pattern file %s", pattern);
6228 goto scsisanitize_bailout;
6231 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6232 warnx("pattern file size exceeds maximum value %d",
6233 SSZPL_MAX_PATTERN_LENGTH);
6235 goto scsisanitize_bailout;
6237 dxfer_len = sizeof(*pl) + sz;
6238 data_ptr = calloc(1, dxfer_len);
6239 if (data_ptr == NULL) {
6240 warnx("cannot allocate parameter list buffer");
6242 goto scsisanitize_bailout;
6245 amt = read(fd, data_ptr + sizeof(*pl), sz);
6247 warn("cannot read pattern file");
6249 goto scsisanitize_bailout;
6250 } else if (amt != sz) {
6251 warnx("short pattern file read");
6253 goto scsisanitize_bailout;
6256 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6262 pl->byte1 |= SSZPL_INVERT;
6263 scsi_ulto2b(sz, pl->length);
6269 else if (invert != 0)
6271 else if (pattern != NULL)
6276 warnx("%s argument only valid with overwrite "
6279 goto scsisanitize_bailout;
6284 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6285 "following device:\n");
6287 error = scsidoinquiry(device, argc, argv, combinedopt,
6288 retry_count, timeout);
6291 warnx("scsisanitize: error sending inquiry");
6292 goto scsisanitize_bailout;
6297 if (!get_confirmation()) {
6299 goto scsisanitize_bailout;
6304 use_timeout = timeout;
6307 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6308 use_timeout / 1000);
6312 * If the user hasn't disabled questions and didn't specify a
6313 * timeout on the command line, ask them if they want the current
6317 && (timeout == 0)) {
6319 int new_timeout = 0;
6321 fprintf(stdout, "Enter new timeout in seconds or press\n"
6322 "return to keep the current timeout [%d] ",
6323 use_timeout / 1000);
6325 if (fgets(str, sizeof(str), stdin) != NULL) {
6327 new_timeout = atoi(str);
6330 if (new_timeout != 0) {
6331 use_timeout = new_timeout * 1000;
6332 fprintf(stdout, "Using new timeout value %d\n",
6333 use_timeout / 1000);
6339 byte2 |= SSZ_UNRESTRICTED_EXIT;
6343 scsi_sanitize(&ccb->csio,
6344 /* retries */ retry_count,
6346 /* tag_action */ MSG_SIMPLE_Q_TAG,
6349 /* data_ptr */ data_ptr,
6350 /* dxfer_len */ dxfer_len,
6351 /* sense_len */ SSD_FULL_SIZE,
6352 /* timeout */ use_timeout);
6354 /* Disable freezing the device queue */
6355 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6357 if (arglist & CAM_ARG_ERR_RECOVER)
6358 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6360 if (cam_send_ccb(device, ccb) < 0) {
6361 warn("error sending sanitize command");
6363 goto scsisanitize_bailout;
6366 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6367 struct scsi_sense_data *sense;
6368 int error_code, sense_key, asc, ascq;
6370 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6371 CAM_SCSI_STATUS_ERROR) {
6372 sense = &ccb->csio.sense_data;
6373 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6374 ccb->csio.sense_resid, &error_code, &sense_key,
6375 &asc, &ascq, /*show_errors*/ 1);
6377 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6378 asc == 0x20 && ascq == 0x00)
6379 warnx("sanitize is not supported by "
6382 warnx("error sanitizing this device");
6384 warnx("error sanitizing this device");
6386 if (arglist & CAM_ARG_VERBOSE) {
6387 cam_error_print(device, ccb, CAM_ESF_ALL,
6388 CAM_EPF_ALL, stderr);
6391 goto scsisanitize_bailout;
6395 * If we ran in non-immediate mode, we already checked for errors
6396 * above and printed out any necessary information. If we're in
6397 * immediate mode, we need to loop through and get status
6398 * information periodically.
6400 if (immediate == 0) {
6402 fprintf(stdout, "Sanitize Complete\n");
6404 goto scsisanitize_bailout;
6411 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6414 * There's really no need to do error recovery or
6415 * retries here, since we're just going to sit in a
6416 * loop and wait for the device to finish sanitizing.
6418 scsi_test_unit_ready(&ccb->csio,
6421 /* tag_action */ MSG_SIMPLE_Q_TAG,
6422 /* sense_len */ SSD_FULL_SIZE,
6423 /* timeout */ 5000);
6425 /* Disable freezing the device queue */
6426 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6428 retval = cam_send_ccb(device, ccb);
6431 * If we get an error from the ioctl, bail out. SCSI
6432 * errors are expected.
6435 warn("error sending CAMIOCOMMAND ioctl");
6436 if (arglist & CAM_ARG_VERBOSE) {
6437 cam_error_print(device, ccb, CAM_ESF_ALL,
6438 CAM_EPF_ALL, stderr);
6441 goto scsisanitize_bailout;
6444 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6446 if ((status != CAM_REQ_CMP)
6447 && (status == CAM_SCSI_STATUS_ERROR)
6448 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6449 struct scsi_sense_data *sense;
6450 int error_code, sense_key, asc, ascq;
6452 sense = &ccb->csio.sense_data;
6453 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6454 ccb->csio.sense_resid, &error_code, &sense_key,
6455 &asc, &ascq, /*show_errors*/ 1);
6458 * According to the SCSI-3 spec, a drive that is in the
6459 * middle of a sanitize should return NOT READY with an
6460 * ASC of "logical unit not ready, sanitize in
6461 * progress". The sense key specific bytes will then
6462 * be a progress indicator.
6464 if ((sense_key == SSD_KEY_NOT_READY)
6465 && (asc == 0x04) && (ascq == 0x1b)) {
6468 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6469 ccb->csio.sense_resid, sks) == 0)
6472 u_int64_t percentage;
6474 val = scsi_2btoul(&sks[1]);
6475 percentage = 10000 * val;
6478 "\rSanitizing: %ju.%02u %% "
6480 (uintmax_t)(percentage /
6482 (unsigned)((percentage /
6486 } else if ((quiet == 0)
6487 && (++num_warnings <= 1)) {
6488 warnx("Unexpected SCSI Sense Key "
6489 "Specific value returned "
6490 "during sanitize:");
6491 scsi_sense_print(device, &ccb->csio,
6493 warnx("Unable to print status "
6494 "information, but sanitze will "
6496 warnx("will exit when sanitize is "
6501 warnx("Unexpected SCSI error during sanitize");
6502 cam_error_print(device, ccb, CAM_ESF_ALL,
6503 CAM_EPF_ALL, stderr);
6505 goto scsisanitize_bailout;
6508 } else if (status != CAM_REQ_CMP) {
6509 warnx("Unexpected CAM status %#x", status);
6510 if (arglist & CAM_ARG_VERBOSE)
6511 cam_error_print(device, ccb, CAM_ESF_ALL,
6512 CAM_EPF_ALL, stderr);
6514 goto scsisanitize_bailout;
6516 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6519 fprintf(stdout, "\nSanitize Complete\n");
6521 scsisanitize_bailout:
6524 if (data_ptr != NULL)
6532 scsireportluns(struct cam_device *device, int argc, char **argv,
6533 char *combinedopt, int retry_count, int timeout)
6536 int c, countonly, lunsonly;
6537 struct scsi_report_luns_data *lundata;
6539 uint8_t report_type;
6540 uint32_t list_len, i, j;
6545 report_type = RPL_REPORT_DEFAULT;
6546 ccb = cam_getccb(device);
6549 warnx("%s: error allocating ccb", __func__);
6553 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6558 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6567 if (strcasecmp(optarg, "default") == 0)
6568 report_type = RPL_REPORT_DEFAULT;
6569 else if (strcasecmp(optarg, "wellknown") == 0)
6570 report_type = RPL_REPORT_WELLKNOWN;
6571 else if (strcasecmp(optarg, "all") == 0)
6572 report_type = RPL_REPORT_ALL;
6574 warnx("%s: invalid report type \"%s\"",
6585 if ((countonly != 0)
6586 && (lunsonly != 0)) {
6587 warnx("%s: you can only specify one of -c or -l", __func__);
6592 * According to SPC-4, the allocation length must be at least 16
6593 * bytes -- enough for the header and one LUN.
6595 alloc_len = sizeof(*lundata) + 8;
6599 lundata = malloc(alloc_len);
6601 if (lundata == NULL) {
6602 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6607 scsi_report_luns(&ccb->csio,
6608 /*retries*/ retry_count,
6610 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6611 /*select_report*/ report_type,
6612 /*rpl_buf*/ lundata,
6613 /*alloc_len*/ alloc_len,
6614 /*sense_len*/ SSD_FULL_SIZE,
6615 /*timeout*/ timeout ? timeout : 5000);
6617 /* Disable freezing the device queue */
6618 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6620 if (arglist & CAM_ARG_ERR_RECOVER)
6621 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6623 if (cam_send_ccb(device, ccb) < 0) {
6624 warn("error sending REPORT LUNS command");
6626 if (arglist & CAM_ARG_VERBOSE)
6627 cam_error_print(device, ccb, CAM_ESF_ALL,
6628 CAM_EPF_ALL, stderr);
6634 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6635 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6641 list_len = scsi_4btoul(lundata->length);
6644 * If we need to list the LUNs, and our allocation
6645 * length was too short, reallocate and retry.
6647 if ((countonly == 0)
6648 && (list_len > (alloc_len - sizeof(*lundata)))) {
6649 alloc_len = list_len + sizeof(*lundata);
6655 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6656 ((list_len / 8) > 1) ? "s" : "");
6661 for (i = 0; i < (list_len / 8); i++) {
6665 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6667 fprintf(stdout, ",");
6668 switch (lundata->luns[i].lundata[j] &
6669 RPL_LUNDATA_ATYP_MASK) {
6670 case RPL_LUNDATA_ATYP_PERIPH:
6671 if ((lundata->luns[i].lundata[j] &
6672 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6673 fprintf(stdout, "%d:",
6674 lundata->luns[i].lundata[j] &
6675 RPL_LUNDATA_PERIPH_BUS_MASK);
6677 && ((lundata->luns[i].lundata[j+2] &
6678 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6681 fprintf(stdout, "%d",
6682 lundata->luns[i].lundata[j+1]);
6684 case RPL_LUNDATA_ATYP_FLAT: {
6686 tmplun[0] = lundata->luns[i].lundata[j] &
6687 RPL_LUNDATA_FLAT_LUN_MASK;
6688 tmplun[1] = lundata->luns[i].lundata[j+1];
6690 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6694 case RPL_LUNDATA_ATYP_LUN:
6695 fprintf(stdout, "%d:%d:%d",
6696 (lundata->luns[i].lundata[j+1] &
6697 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6698 lundata->luns[i].lundata[j] &
6699 RPL_LUNDATA_LUN_TARG_MASK,
6700 lundata->luns[i].lundata[j+1] &
6701 RPL_LUNDATA_LUN_LUN_MASK);
6703 case RPL_LUNDATA_ATYP_EXTLUN: {
6704 int field_len_code, eam_code;
6706 eam_code = lundata->luns[i].lundata[j] &
6707 RPL_LUNDATA_EXT_EAM_MASK;
6708 field_len_code = (lundata->luns[i].lundata[j] &
6709 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6711 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6712 && (field_len_code == 0x00)) {
6713 fprintf(stdout, "%d",
6714 lundata->luns[i].lundata[j+1]);
6715 } else if ((eam_code ==
6716 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6717 && (field_len_code == 0x03)) {
6721 * This format takes up all 8 bytes.
6722 * If we aren't starting at offset 0,
6726 fprintf(stdout, "Invalid "
6729 "specified format", j);
6733 bzero(tmp_lun, sizeof(tmp_lun));
6734 bcopy(&lundata->luns[i].lundata[j+1],
6735 &tmp_lun[1], sizeof(tmp_lun) - 1);
6736 fprintf(stdout, "%#jx",
6737 (intmax_t)scsi_8btou64(tmp_lun));
6740 fprintf(stderr, "Unknown Extended LUN"
6741 "Address method %#x, length "
6742 "code %#x", eam_code,
6749 fprintf(stderr, "Unknown LUN address method "
6750 "%#x\n", lundata->luns[i].lundata[0] &
6751 RPL_LUNDATA_ATYP_MASK);
6755 * For the flat addressing method, there are no
6756 * other levels after it.
6761 fprintf(stdout, "\n");
6774 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6775 char *combinedopt, int retry_count, int timeout)
6778 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6779 struct scsi_read_capacity_data rcap;
6780 struct scsi_read_capacity_data_long rcaplong;
6794 ccb = cam_getccb(device);
6797 warnx("%s: error allocating ccb", __func__);
6801 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6803 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6830 if ((blocksizeonly != 0)
6831 && (numblocks != 0)) {
6832 warnx("%s: you can only specify one of -b or -N", __func__);
6837 if ((blocksizeonly != 0)
6838 && (sizeonly != 0)) {
6839 warnx("%s: you can only specify one of -b or -s", __func__);
6846 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6852 && (blocksizeonly != 0)) {
6853 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6858 scsi_read_capacity(&ccb->csio,
6859 /*retries*/ retry_count,
6861 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6864 /*timeout*/ timeout ? timeout : 5000);
6866 /* Disable freezing the device queue */
6867 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6869 if (arglist & CAM_ARG_ERR_RECOVER)
6870 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6872 if (cam_send_ccb(device, ccb) < 0) {
6873 warn("error sending READ CAPACITY command");
6875 if (arglist & CAM_ARG_VERBOSE)
6876 cam_error_print(device, ccb, CAM_ESF_ALL,
6877 CAM_EPF_ALL, stderr);
6883 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6884 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6889 maxsector = scsi_4btoul(rcap.addr);
6890 block_len = scsi_4btoul(rcap.length);
6893 * A last block of 2^32-1 means that the true capacity is over 2TB,
6894 * and we need to issue the long READ CAPACITY to get the real
6895 * capacity. Otherwise, we're all set.
6897 if (maxsector != 0xffffffff)
6900 scsi_read_capacity_16(&ccb->csio,
6901 /*retries*/ retry_count,
6903 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6907 /*rcap_buf*/ (uint8_t *)&rcaplong,
6908 /*rcap_buf_len*/ sizeof(rcaplong),
6909 /*sense_len*/ SSD_FULL_SIZE,
6910 /*timeout*/ timeout ? timeout : 5000);
6912 /* Disable freezing the device queue */
6913 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6915 if (arglist & CAM_ARG_ERR_RECOVER)
6916 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6918 if (cam_send_ccb(device, ccb) < 0) {
6919 warn("error sending READ CAPACITY (16) command");
6921 if (arglist & CAM_ARG_VERBOSE)
6922 cam_error_print(device, ccb, CAM_ESF_ALL,
6923 CAM_EPF_ALL, stderr);
6929 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6930 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6935 maxsector = scsi_8btou64(rcaplong.addr);
6936 block_len = scsi_4btoul(rcaplong.length);
6939 if (blocksizeonly == 0) {
6941 * Humanize implies !quiet, and also implies numblocks.
6943 if (humanize != 0) {
6948 tmpbytes = (maxsector + 1) * block_len;
6949 ret = humanize_number(tmpstr, sizeof(tmpstr),
6950 tmpbytes, "", HN_AUTOSCALE,
6953 HN_DIVISOR_1000 : 0));
6955 warnx("%s: humanize_number failed!", __func__);
6959 fprintf(stdout, "Device Size: %s%s", tmpstr,
6960 (sizeonly == 0) ? ", " : "\n");
6961 } else if (numblocks != 0) {
6962 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6963 "Blocks: " : "", (uintmax_t)maxsector + 1,
6964 (sizeonly == 0) ? ", " : "\n");
6966 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6967 "Last Block: " : "", (uintmax_t)maxsector,
6968 (sizeonly == 0) ? ", " : "\n");
6972 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6973 "Block Length: " : "", block_len, (quiet == 0) ?
6982 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6983 int retry_count, int timeout)
6987 uint8_t *smp_request = NULL, *smp_response = NULL;
6988 int request_size = 0, response_size = 0;
6989 int fd_request = 0, fd_response = 0;
6990 char *datastr = NULL;
6991 struct get_hook hook;
6996 * Note that at the moment we don't support sending SMP CCBs to
6997 * devices that aren't probed by CAM.
6999 ccb = cam_getccb(device);
7001 warnx("%s: error allocating CCB", __func__);
7005 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7007 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7010 arglist |= CAM_ARG_CMD_IN;
7011 response_size = strtol(optarg, NULL, 0);
7012 if (response_size <= 0) {
7013 warnx("invalid number of response bytes %d",
7016 goto smpcmd_bailout;
7018 hook.argc = argc - optind;
7019 hook.argv = argv + optind;
7022 datastr = cget(&hook, NULL);
7024 * If the user supplied "-" instead of a format, he
7025 * wants the data to be written to stdout.
7027 if ((datastr != NULL)
7028 && (datastr[0] == '-'))
7031 smp_response = (u_int8_t *)malloc(response_size);
7032 if (smp_response == NULL) {
7033 warn("can't malloc memory for SMP response");
7035 goto smpcmd_bailout;
7039 arglist |= CAM_ARG_CMD_OUT;
7040 request_size = strtol(optarg, NULL, 0);
7041 if (request_size <= 0) {
7042 warnx("invalid number of request bytes %d",
7045 goto smpcmd_bailout;
7047 hook.argc = argc - optind;
7048 hook.argv = argv + optind;
7050 datastr = cget(&hook, NULL);
7051 smp_request = (u_int8_t *)malloc(request_size);
7052 if (smp_request == NULL) {
7053 warn("can't malloc memory for SMP request");
7055 goto smpcmd_bailout;
7057 bzero(smp_request, request_size);
7059 * If the user supplied "-" instead of a format, he
7060 * wants the data to be read from stdin.
7062 if ((datastr != NULL)
7063 && (datastr[0] == '-'))
7066 buff_encode_visit(smp_request, request_size,
7077 * If fd_data is set, and we're writing to the device, we need to
7078 * read the data the user wants written from stdin.
7080 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7082 int amt_to_read = request_size;
7083 u_int8_t *buf_ptr = smp_request;
7085 for (amt_read = 0; amt_to_read > 0;
7086 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7087 if (amt_read == -1) {
7088 warn("error reading data from stdin");
7090 goto smpcmd_bailout;
7092 amt_to_read -= amt_read;
7093 buf_ptr += amt_read;
7097 if (((arglist & CAM_ARG_CMD_IN) == 0)
7098 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7099 warnx("%s: need both the request (-r) and response (-R) "
7100 "arguments", __func__);
7102 goto smpcmd_bailout;
7105 flags |= CAM_DEV_QFRZDIS;
7107 cam_fill_smpio(&ccb->smpio,
7108 /*retries*/ retry_count,
7111 /*smp_request*/ smp_request,
7112 /*smp_request_len*/ request_size,
7113 /*smp_response*/ smp_response,
7114 /*smp_response_len*/ response_size,
7115 /*timeout*/ timeout ? timeout : 5000);
7117 ccb->smpio.flags = SMP_FLAG_NONE;
7119 if (((retval = cam_send_ccb(device, ccb)) < 0)
7120 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7121 const char warnstr[] = "error sending command";
7128 if (arglist & CAM_ARG_VERBOSE) {
7129 cam_error_print(device, ccb, CAM_ESF_ALL,
7130 CAM_EPF_ALL, stderr);
7134 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7135 && (response_size > 0)) {
7136 if (fd_response == 0) {
7137 buff_decode_visit(smp_response, response_size,
7138 datastr, arg_put, NULL);
7139 fprintf(stdout, "\n");
7141 ssize_t amt_written;
7142 int amt_to_write = response_size;
7143 u_int8_t *buf_ptr = smp_response;
7145 for (amt_written = 0; (amt_to_write > 0) &&
7146 (amt_written = write(STDOUT_FILENO, buf_ptr,
7147 amt_to_write)) > 0;){
7148 amt_to_write -= amt_written;
7149 buf_ptr += amt_written;
7151 if (amt_written == -1) {
7152 warn("error writing data to stdout");
7154 goto smpcmd_bailout;
7155 } else if ((amt_written == 0)
7156 && (amt_to_write > 0)) {
7157 warnx("only wrote %u bytes out of %u",
7158 response_size - amt_to_write,
7167 if (smp_request != NULL)
7170 if (smp_response != NULL)
7177 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7178 char *combinedopt, int retry_count, int timeout)
7181 struct smp_report_general_request *request = NULL;
7182 struct smp_report_general_response *response = NULL;
7183 struct sbuf *sb = NULL;
7185 int c, long_response = 0;
7189 * Note that at the moment we don't support sending SMP CCBs to
7190 * devices that aren't probed by CAM.
7192 ccb = cam_getccb(device);
7194 warnx("%s: error allocating CCB", __func__);
7198 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7200 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7209 request = malloc(sizeof(*request));
7210 if (request == NULL) {
7211 warn("%s: unable to allocate %zd bytes", __func__,
7217 response = malloc(sizeof(*response));
7218 if (response == NULL) {
7219 warn("%s: unable to allocate %zd bytes", __func__,
7226 smp_report_general(&ccb->smpio,
7230 /*request_len*/ sizeof(*request),
7231 (uint8_t *)response,
7232 /*response_len*/ sizeof(*response),
7233 /*long_response*/ long_response,
7236 if (((retval = cam_send_ccb(device, ccb)) < 0)
7237 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7238 const char warnstr[] = "error sending command";
7245 if (arglist & CAM_ARG_VERBOSE) {
7246 cam_error_print(device, ccb, CAM_ESF_ALL,
7247 CAM_EPF_ALL, stderr);
7254 * If the device supports the long response bit, try again and see
7255 * if we can get all of the data.
7257 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7258 && (long_response == 0)) {
7259 ccb->ccb_h.status = CAM_REQ_INPROG;
7260 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7266 * XXX KDM detect and decode SMP errors here.
7268 sb = sbuf_new_auto();
7270 warnx("%s: error allocating sbuf", __func__);
7274 smp_report_general_sbuf(response, sizeof(*response), sb);
7276 if (sbuf_finish(sb) != 0) {
7277 warnx("%s: sbuf_finish", __func__);
7281 printf("%s", sbuf_data(sb));
7287 if (request != NULL)
7290 if (response != NULL)
7299 static struct camcontrol_opts phy_ops[] = {
7300 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7301 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7302 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7303 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7304 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7305 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7306 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7307 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7308 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7313 smpphycontrol(struct cam_device *device, int argc, char **argv,
7314 char *combinedopt, int retry_count, int timeout)
7317 struct smp_phy_control_request *request = NULL;
7318 struct smp_phy_control_response *response = NULL;
7319 int long_response = 0;
7322 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7324 uint64_t attached_dev_name = 0;
7325 int dev_name_set = 0;
7326 uint32_t min_plr = 0, max_plr = 0;
7327 uint32_t pp_timeout_val = 0;
7328 int slumber_partial = 0;
7329 int set_pp_timeout_val = 0;
7333 * Note that at the moment we don't support sending SMP CCBs to
7334 * devices that aren't probed by CAM.
7336 ccb = cam_getccb(device);
7338 warnx("%s: error allocating CCB", __func__);
7342 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7344 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7352 if (strcasecmp(optarg, "enable") == 0)
7354 else if (strcasecmp(optarg, "disable") == 0)
7357 warnx("%s: Invalid argument %s", __func__,
7364 slumber_partial |= enable <<
7365 SMP_PC_SAS_SLUMBER_SHIFT;
7368 slumber_partial |= enable <<
7369 SMP_PC_SAS_PARTIAL_SHIFT;
7372 slumber_partial |= enable <<
7373 SMP_PC_SATA_SLUMBER_SHIFT;
7376 slumber_partial |= enable <<
7377 SMP_PC_SATA_PARTIAL_SHIFT;
7380 warnx("%s: programmer error", __func__);
7383 break; /*NOTREACHED*/
7388 attached_dev_name = (uintmax_t)strtoumax(optarg,
7397 * We don't do extensive checking here, so this
7398 * will continue to work when new speeds come out.
7400 min_plr = strtoul(optarg, NULL, 0);
7402 || (min_plr > 0xf)) {
7403 warnx("%s: invalid link rate %x",
7411 * We don't do extensive checking here, so this
7412 * will continue to work when new speeds come out.
7414 max_plr = strtoul(optarg, NULL, 0);
7416 || (max_plr > 0xf)) {
7417 warnx("%s: invalid link rate %x",
7424 camcontrol_optret optreturn;
7425 cam_argmask argnums;
7428 if (phy_op_set != 0) {
7429 warnx("%s: only one phy operation argument "
7430 "(-o) allowed", __func__);
7438 * Allow the user to specify the phy operation
7439 * numerically, as well as with a name. This will
7440 * future-proof it a bit, so options that are added
7441 * in future specs can be used.
7443 if (isdigit(optarg[0])) {
7444 phy_operation = strtoul(optarg, NULL, 0);
7445 if ((phy_operation == 0)
7446 || (phy_operation > 0xff)) {
7447 warnx("%s: invalid phy operation %#x",
7448 __func__, phy_operation);
7454 optreturn = getoption(phy_ops, optarg, &phy_operation,
7457 if (optreturn == CC_OR_AMBIGUOUS) {
7458 warnx("%s: ambiguous option %s", __func__,
7463 } else if (optreturn == CC_OR_NOT_FOUND) {
7464 warnx("%s: option %s not found", __func__,
7476 pp_timeout_val = strtoul(optarg, NULL, 0);
7477 if (pp_timeout_val > 15) {
7478 warnx("%s: invalid partial pathway timeout "
7479 "value %u, need a value less than 16",
7480 __func__, pp_timeout_val);
7484 set_pp_timeout_val = 1;
7492 warnx("%s: a PHY (-p phy) argument is required",__func__);
7497 if (((dev_name_set != 0)
7498 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7499 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7500 && (dev_name_set == 0))) {
7501 warnx("%s: -d name and -o setdevname arguments both "
7502 "required to set device name", __func__);
7507 request = malloc(sizeof(*request));
7508 if (request == NULL) {
7509 warn("%s: unable to allocate %zd bytes", __func__,
7515 response = malloc(sizeof(*response));
7516 if (response == NULL) {
7517 warn("%s: unable to allocate %zd bytes", __func__,
7523 smp_phy_control(&ccb->smpio,
7528 (uint8_t *)response,
7531 /*expected_exp_change_count*/ 0,
7534 (set_pp_timeout_val != 0) ? 1 : 0,
7542 if (((retval = cam_send_ccb(device, ccb)) < 0)
7543 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7544 const char warnstr[] = "error sending command";
7551 if (arglist & CAM_ARG_VERBOSE) {
7553 * Use CAM_EPF_NORMAL so we only get one line of
7554 * SMP command decoding.
7556 cam_error_print(device, ccb, CAM_ESF_ALL,
7557 CAM_EPF_NORMAL, stderr);
7563 /* XXX KDM print out something here for success? */
7568 if (request != NULL)
7571 if (response != NULL)
7578 smpmaninfo(struct cam_device *device, int argc, char **argv,
7579 char *combinedopt, int retry_count, int timeout)
7582 struct smp_report_manuf_info_request request;
7583 struct smp_report_manuf_info_response response;
7584 struct sbuf *sb = NULL;
7585 int long_response = 0;
7590 * Note that at the moment we don't support sending SMP CCBs to
7591 * devices that aren't probed by CAM.
7593 ccb = cam_getccb(device);
7595 warnx("%s: error allocating CCB", __func__);
7599 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7601 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7610 bzero(&request, sizeof(request));
7611 bzero(&response, sizeof(response));
7613 smp_report_manuf_info(&ccb->smpio,
7618 (uint8_t *)&response,
7623 if (((retval = cam_send_ccb(device, ccb)) < 0)
7624 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7625 const char warnstr[] = "error sending command";
7632 if (arglist & CAM_ARG_VERBOSE) {
7633 cam_error_print(device, ccb, CAM_ESF_ALL,
7634 CAM_EPF_ALL, stderr);
7640 sb = sbuf_new_auto();
7642 warnx("%s: error allocating sbuf", __func__);
7646 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7648 if (sbuf_finish(sb) != 0) {
7649 warnx("%s: sbuf_finish", __func__);
7653 printf("%s", sbuf_data(sb));
7667 getdevid(struct cam_devitem *item)
7670 union ccb *ccb = NULL;
7672 struct cam_device *dev;
7674 dev = cam_open_btl(item->dev_match.path_id,
7675 item->dev_match.target_id,
7676 item->dev_match.target_lun, O_RDWR, NULL);
7679 warnx("%s", cam_errbuf);
7684 item->device_id_len = 0;
7686 ccb = cam_getccb(dev);
7688 warnx("%s: error allocating CCB", __func__);
7693 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7696 * On the first try, we just probe for the size of the data, and
7697 * then allocate that much memory and try again.
7700 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7701 ccb->ccb_h.flags = CAM_DIR_IN;
7702 ccb->cdai.flags = CDAI_FLAG_NONE;
7703 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7704 ccb->cdai.bufsiz = item->device_id_len;
7705 if (item->device_id_len != 0)
7706 ccb->cdai.buf = (uint8_t *)item->device_id;
7708 if (cam_send_ccb(dev, ccb) < 0) {
7709 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7714 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7715 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7720 if (item->device_id_len == 0) {
7722 * This is our first time through. Allocate the buffer,
7723 * and then go back to get the data.
7725 if (ccb->cdai.provsiz == 0) {
7726 warnx("%s: invalid .provsiz field returned with "
7727 "XPT_GDEV_ADVINFO CCB", __func__);
7731 item->device_id_len = ccb->cdai.provsiz;
7732 item->device_id = malloc(item->device_id_len);
7733 if (item->device_id == NULL) {
7734 warn("%s: unable to allocate %d bytes", __func__,
7735 item->device_id_len);
7739 ccb->ccb_h.status = CAM_REQ_INPROG;
7745 cam_close_device(dev);
7754 * XXX KDM merge this code with getdevtree()?
7757 buildbusdevlist(struct cam_devlist *devlist)
7760 int bufsize, fd = -1;
7761 struct dev_match_pattern *patterns;
7762 struct cam_devitem *item = NULL;
7763 int skip_device = 0;
7766 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7767 warn("couldn't open %s", XPT_DEVICE);
7771 bzero(&ccb, sizeof(union ccb));
7773 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7774 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7775 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7777 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7778 bufsize = sizeof(struct dev_match_result) * 100;
7779 ccb.cdm.match_buf_len = bufsize;
7780 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7781 if (ccb.cdm.matches == NULL) {
7782 warnx("can't malloc memory for matches");
7786 ccb.cdm.num_matches = 0;
7787 ccb.cdm.num_patterns = 2;
7788 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7789 ccb.cdm.num_patterns;
7791 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7792 if (patterns == NULL) {
7793 warnx("can't malloc memory for patterns");
7798 ccb.cdm.patterns = patterns;
7799 bzero(patterns, ccb.cdm.pattern_buf_len);
7801 patterns[0].type = DEV_MATCH_DEVICE;
7802 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7803 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7804 patterns[1].type = DEV_MATCH_PERIPH;
7805 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7806 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7809 * We do the ioctl multiple times if necessary, in case there are
7810 * more than 100 nodes in the EDT.
7815 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7816 warn("error sending CAMIOCOMMAND ioctl");
7821 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7822 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7823 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7824 warnx("got CAM error %#x, CDM error %d\n",
7825 ccb.ccb_h.status, ccb.cdm.status);
7830 for (i = 0; i < ccb.cdm.num_matches; i++) {
7831 switch (ccb.cdm.matches[i].type) {
7832 case DEV_MATCH_DEVICE: {
7833 struct device_match_result *dev_result;
7836 &ccb.cdm.matches[i].result.device_result;
7838 if (dev_result->flags &
7839 DEV_RESULT_UNCONFIGURED) {
7845 item = malloc(sizeof(*item));
7847 warn("%s: unable to allocate %zd bytes",
7848 __func__, sizeof(*item));
7852 bzero(item, sizeof(*item));
7853 bcopy(dev_result, &item->dev_match,
7854 sizeof(*dev_result));
7855 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7858 if (getdevid(item) != 0) {
7864 case DEV_MATCH_PERIPH: {
7865 struct periph_match_result *periph_result;
7868 &ccb.cdm.matches[i].result.periph_result;
7870 if (skip_device != 0)
7872 item->num_periphs++;
7873 item->periph_matches = realloc(
7874 item->periph_matches,
7876 sizeof(struct periph_match_result));
7877 if (item->periph_matches == NULL) {
7878 warn("%s: error allocating periph "
7883 bcopy(periph_result, &item->periph_matches[
7884 item->num_periphs - 1],
7885 sizeof(*periph_result));
7889 fprintf(stderr, "%s: unexpected match "
7890 "type %d\n", __func__,
7891 ccb.cdm.matches[i].type);
7894 break; /*NOTREACHED*/
7897 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7898 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7906 free(ccb.cdm.matches);
7909 freebusdevlist(devlist);
7915 freebusdevlist(struct cam_devlist *devlist)
7917 struct cam_devitem *item, *item2;
7919 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7920 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7922 free(item->device_id);
7923 free(item->periph_matches);
7928 static struct cam_devitem *
7929 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7931 struct cam_devitem *item;
7933 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7934 struct scsi_vpd_id_descriptor *idd;
7937 * XXX KDM look for LUN IDs as well?
7939 idd = scsi_get_devid(item->device_id,
7940 item->device_id_len,
7941 scsi_devid_is_sas_target);
7945 if (scsi_8btou64(idd->identifier) == sasaddr)
7953 smpphylist(struct cam_device *device, int argc, char **argv,
7954 char *combinedopt, int retry_count, int timeout)
7956 struct smp_report_general_request *rgrequest = NULL;
7957 struct smp_report_general_response *rgresponse = NULL;
7958 struct smp_discover_request *disrequest = NULL;
7959 struct smp_discover_response *disresponse = NULL;
7960 struct cam_devlist devlist;
7962 int long_response = 0;
7969 * Note that at the moment we don't support sending SMP CCBs to
7970 * devices that aren't probed by CAM.
7972 ccb = cam_getccb(device);
7974 warnx("%s: error allocating CCB", __func__);
7978 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7979 STAILQ_INIT(&devlist.dev_queue);
7981 rgrequest = malloc(sizeof(*rgrequest));
7982 if (rgrequest == NULL) {
7983 warn("%s: unable to allocate %zd bytes", __func__,
7984 sizeof(*rgrequest));
7989 rgresponse = malloc(sizeof(*rgresponse));
7990 if (rgresponse == NULL) {
7991 warn("%s: unable to allocate %zd bytes", __func__,
7992 sizeof(*rgresponse));
7997 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8010 smp_report_general(&ccb->smpio,
8014 /*request_len*/ sizeof(*rgrequest),
8015 (uint8_t *)rgresponse,
8016 /*response_len*/ sizeof(*rgresponse),
8017 /*long_response*/ long_response,
8020 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8022 if (((retval = cam_send_ccb(device, ccb)) < 0)
8023 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8024 const char warnstr[] = "error sending command";
8031 if (arglist & CAM_ARG_VERBOSE) {
8032 cam_error_print(device, ccb, CAM_ESF_ALL,
8033 CAM_EPF_ALL, stderr);
8039 num_phys = rgresponse->num_phys;
8041 if (num_phys == 0) {
8043 fprintf(stdout, "%s: No Phys reported\n", __func__);
8048 devlist.path_id = device->path_id;
8050 retval = buildbusdevlist(&devlist);
8055 fprintf(stdout, "%d PHYs:\n", num_phys);
8056 fprintf(stdout, "PHY Attached SAS Address\n");
8059 disrequest = malloc(sizeof(*disrequest));
8060 if (disrequest == NULL) {
8061 warn("%s: unable to allocate %zd bytes", __func__,
8062 sizeof(*disrequest));
8067 disresponse = malloc(sizeof(*disresponse));
8068 if (disresponse == NULL) {
8069 warn("%s: unable to allocate %zd bytes", __func__,
8070 sizeof(*disresponse));
8075 for (i = 0; i < num_phys; i++) {
8076 struct cam_devitem *item;
8077 struct device_match_result *dev_match;
8078 char vendor[16], product[48], revision[16];
8082 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8084 ccb->ccb_h.status = CAM_REQ_INPROG;
8085 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8087 smp_discover(&ccb->smpio,
8091 sizeof(*disrequest),
8092 (uint8_t *)disresponse,
8093 sizeof(*disresponse),
8095 /*ignore_zone_group*/ 0,
8099 if (((retval = cam_send_ccb(device, ccb)) < 0)
8100 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8101 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8102 const char warnstr[] = "error sending command";
8109 if (arglist & CAM_ARG_VERBOSE) {
8110 cam_error_print(device, ccb, CAM_ESF_ALL,
8111 CAM_EPF_ALL, stderr);
8117 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8119 fprintf(stdout, "%3d <vacant>\n", i);
8123 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8126 item = findsasdevice(&devlist,
8127 scsi_8btou64(disresponse->attached_sas_address));
8131 || (item != NULL)) {
8132 fprintf(stdout, "%3d 0x%016jx", i,
8133 (uintmax_t)scsi_8btou64(
8134 disresponse->attached_sas_address));
8136 fprintf(stdout, "\n");
8139 } else if (quiet != 0)
8142 dev_match = &item->dev_match;
8144 if (dev_match->protocol == PROTO_SCSI) {
8145 cam_strvis(vendor, dev_match->inq_data.vendor,
8146 sizeof(dev_match->inq_data.vendor),
8148 cam_strvis(product, dev_match->inq_data.product,
8149 sizeof(dev_match->inq_data.product),
8151 cam_strvis(revision, dev_match->inq_data.revision,
8152 sizeof(dev_match->inq_data.revision),
8154 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8156 } else if ((dev_match->protocol == PROTO_ATA)
8157 || (dev_match->protocol == PROTO_SATAPM)) {
8158 cam_strvis(product, dev_match->ident_data.model,
8159 sizeof(dev_match->ident_data.model),
8161 cam_strvis(revision, dev_match->ident_data.revision,
8162 sizeof(dev_match->ident_data.revision),
8164 sprintf(tmpstr, "<%s %s>", product, revision);
8166 sprintf(tmpstr, "<>");
8168 fprintf(stdout, " %-33s ", tmpstr);
8171 * If we have 0 periphs, that's a bug...
8173 if (item->num_periphs == 0) {
8174 fprintf(stdout, "\n");
8178 fprintf(stdout, "(");
8179 for (j = 0; j < item->num_periphs; j++) {
8181 fprintf(stdout, ",");
8183 fprintf(stdout, "%s%d",
8184 item->periph_matches[j].periph_name,
8185 item->periph_matches[j].unit_number);
8188 fprintf(stdout, ")\n");
8202 freebusdevlist(&devlist);
8208 atapm(struct cam_device *device, int argc, char **argv,
8209 char *combinedopt, int retry_count, int timeout)
8217 ccb = cam_getccb(device);
8220 warnx("%s: error allocating ccb", __func__);
8224 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8233 if (strcmp(argv[1], "idle") == 0) {
8235 cmd = ATA_IDLE_IMMEDIATE;
8238 } else if (strcmp(argv[1], "standby") == 0) {
8240 cmd = ATA_STANDBY_IMMEDIATE;
8242 cmd = ATA_STANDBY_CMD;
8250 else if (t <= (240 * 5))
8252 else if (t <= (252 * 5))
8253 /* special encoding for 21 minutes */
8255 else if (t <= (11 * 30 * 60))
8256 sc = (t - 1) / (30 * 60) + 241;
8260 retval = ata_do_28bit_cmd(device,
8262 /*retries*/retry_count,
8263 /*flags*/CAM_DIR_NONE,
8264 /*protocol*/AP_PROTO_NON_DATA,
8265 /*tag_action*/MSG_SIMPLE_Q_TAG,
8272 /*timeout*/timeout ? timeout : 30 * 1000,
8280 ataaxm(struct cam_device *device, int argc, char **argv,
8281 char *combinedopt, int retry_count, int timeout)
8289 ccb = cam_getccb(device);
8292 warnx("%s: error allocating ccb", __func__);
8296 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8306 if (strcmp(argv[1], "apm") == 0) {
8322 retval = ata_do_28bit_cmd(device,
8324 /*retries*/retry_count,
8325 /*flags*/CAM_DIR_NONE,
8326 /*protocol*/AP_PROTO_NON_DATA,
8327 /*tag_action*/MSG_SIMPLE_Q_TAG,
8328 /*command*/ATA_SETFEATURES,
8334 /*timeout*/timeout ? timeout : 30 * 1000,
8342 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8343 int show_sa_errors, int sa_set, int service_action,
8344 int timeout_desc, int retry_count, int timeout, int verbosemode,
8345 uint32_t *fill_len, uint8_t **data_ptr)
8347 union ccb *ccb = NULL;
8348 uint8_t *buf = NULL;
8349 uint32_t alloc_len = 0, num_opcodes;
8350 uint32_t valid_len = 0;
8351 uint32_t avail_len = 0;
8352 struct scsi_report_supported_opcodes_all *all_hdr;
8353 struct scsi_report_supported_opcodes_one *one;
8358 * Make it clear that we haven't yet allocated or filled anything.
8363 ccb = cam_getccb(device);
8365 warnx("couldn't allocate CCB");
8370 /* cam_getccb cleans up the header, caller has to zero the payload */
8371 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8373 if (opcode_set != 0) {
8374 options |= RSO_OPTIONS_OC;
8376 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8379 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8380 sizeof(struct scsi_report_supported_opcodes_descr));
8383 if (timeout_desc != 0) {
8384 options |= RSO_RCTD;
8385 alloc_len += num_opcodes *
8386 sizeof(struct scsi_report_supported_opcodes_timeout);
8390 options |= RSO_OPTIONS_OC_SA;
8391 if (show_sa_errors != 0)
8392 options &= ~RSO_OPTIONS_OC;
8401 buf = malloc(alloc_len);
8403 warn("Unable to allocate %u bytes", alloc_len);
8407 bzero(buf, alloc_len);
8409 scsi_report_supported_opcodes(&ccb->csio,
8410 /*retries*/ retry_count,
8412 /*tag_action*/ MSG_SIMPLE_Q_TAG,
8413 /*options*/ options,
8414 /*req_opcode*/ opcode,
8415 /*req_service_action*/ service_action,
8417 /*dxfer_len*/ alloc_len,
8418 /*sense_len*/ SSD_FULL_SIZE,
8419 /*timeout*/ timeout ? timeout : 10000);
8421 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8423 if (retry_count != 0)
8424 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8426 if (cam_send_ccb(device, ccb) < 0) {
8427 perror("error sending REPORT SUPPORTED OPERATION CODES");
8432 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8433 if (verbosemode != 0)
8434 cam_error_print(device, ccb, CAM_ESF_ALL,
8435 CAM_EPF_ALL, stderr);
8441 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8443 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8444 && (valid_len >= sizeof(*all_hdr))) {
8445 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8446 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8447 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8448 && (valid_len >= sizeof(*one))) {
8449 uint32_t cdb_length;
8451 one = (struct scsi_report_supported_opcodes_one *)buf;
8452 cdb_length = scsi_2btoul(one->cdb_length);
8453 avail_len = sizeof(*one) + cdb_length;
8454 if (one->support & RSO_ONE_CTDP) {
8455 struct scsi_report_supported_opcodes_timeout *td;
8457 td = (struct scsi_report_supported_opcodes_timeout *)
8459 if (valid_len >= (avail_len + sizeof(td->length))) {
8460 avail_len += scsi_2btoul(td->length) +
8463 avail_len += sizeof(*td);
8469 * avail_len could be zero if we didn't get enough data back from
8470 * thet target to determine
8472 if ((avail_len != 0)
8473 && (avail_len > valid_len)) {
8474 alloc_len = avail_len;
8478 *fill_len = valid_len;
8490 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8491 int req_sa, uint8_t *buf, uint32_t valid_len)
8493 struct scsi_report_supported_opcodes_one *one;
8494 struct scsi_report_supported_opcodes_timeout *td;
8495 uint32_t cdb_len = 0, td_len = 0;
8496 const char *op_desc = NULL;
8500 one = (struct scsi_report_supported_opcodes_one *)buf;
8503 * If we don't have the full single opcode descriptor, no point in
8506 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8508 warnx("Only %u bytes returned, not enough to verify support",
8514 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8516 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8519 printf(", SA 0x%x", req_sa);
8522 switch (one->support & RSO_ONE_SUP_MASK) {
8523 case RSO_ONE_SUP_UNAVAIL:
8524 printf("No command support information currently available\n");
8526 case RSO_ONE_SUP_NOT_SUP:
8527 printf("Command not supported\n");
8530 break; /*NOTREACHED*/
8531 case RSO_ONE_SUP_AVAIL:
8532 printf("Command is supported, complies with a SCSI standard\n");
8534 case RSO_ONE_SUP_VENDOR:
8535 printf("Command is supported, vendor-specific "
8536 "implementation\n");
8539 printf("Unknown command support flags 0x%#x\n",
8540 one->support & RSO_ONE_SUP_MASK);
8545 * If we don't have the CDB length, it isn't exactly an error, the
8546 * command probably isn't supported.
8548 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8552 cdb_len = scsi_2btoul(one->cdb_length);
8555 * If our valid data doesn't include the full reported length,
8556 * return. The caller should have detected this and adjusted his
8557 * allocation length to get all of the available data.
8559 if (valid_len < sizeof(*one) + cdb_len) {
8565 * If all we have is the opcode, there is no point in printing out
8573 printf("CDB usage bitmap:");
8574 for (i = 0; i < cdb_len; i++) {
8575 printf(" %02x", one->cdb_usage[i]);
8580 * If we don't have a timeout descriptor, we're done.
8582 if ((one->support & RSO_ONE_CTDP) == 0)
8586 * If we don't have enough valid length to include the timeout
8587 * descriptor length, we're done.
8589 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8592 td = (struct scsi_report_supported_opcodes_timeout *)
8593 &buf[sizeof(*one) + cdb_len];
8594 td_len = scsi_2btoul(td->length);
8595 td_len += sizeof(td->length);
8598 * If we don't have the full timeout descriptor, we're done.
8600 if (td_len < sizeof(*td))
8604 * If we don't have enough valid length to contain the full timeout
8605 * descriptor, we're done.
8607 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8610 printf("Timeout information:\n");
8611 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8612 printf("Nominal timeout: %u seconds\n",
8613 scsi_4btoul(td->nominal_time));
8614 printf("Recommended timeout: %u seconds\n",
8615 scsi_4btoul(td->recommended_time));
8622 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8625 struct scsi_report_supported_opcodes_all *hdr;
8626 struct scsi_report_supported_opcodes_descr *desc;
8627 uint32_t avail_len = 0, used_len = 0;
8631 if (valid_len < sizeof(*hdr)) {
8632 warnx("%s: not enough returned data (%u bytes) opcode list",
8633 __func__, valid_len);
8637 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8638 avail_len = scsi_4btoul(hdr->length);
8639 avail_len += sizeof(hdr->length);
8641 * Take the lesser of the amount of data the drive claims is
8642 * available, and the amount of data the HBA says was returned.
8644 avail_len = MIN(avail_len, valid_len);
8646 used_len = sizeof(hdr->length);
8648 printf("%-6s %4s %8s ",
8649 "Opcode", "SA", "CDB len" );
8652 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8653 printf(" Description\n");
8655 while ((avail_len - used_len) > sizeof(*desc)) {
8656 struct scsi_report_supported_opcodes_timeout *td;
8658 const char *op_desc = NULL;
8660 cur_ptr = &buf[used_len];
8661 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8663 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8664 if (op_desc == NULL)
8665 op_desc = "UNKNOWN";
8667 printf("0x%02x %#4x %8u ", desc->opcode,
8668 scsi_2btoul(desc->service_action),
8669 scsi_2btoul(desc->cdb_length));
8671 used_len += sizeof(*desc);
8673 if ((desc->flags & RSO_CTDP) == 0) {
8674 printf(" %s\n", op_desc);
8679 * If we don't have enough space to fit a timeout
8680 * descriptor, then we're done.
8682 if (avail_len - used_len < sizeof(*td)) {
8683 used_len = avail_len;
8684 printf(" %s\n", op_desc);
8687 cur_ptr = &buf[used_len];
8688 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8689 td_len = scsi_2btoul(td->length);
8690 td_len += sizeof(td->length);
8694 * If the given timeout descriptor length is less than what
8695 * we understand, skip it.
8697 if (td_len < sizeof(*td)) {
8698 printf(" %s\n", op_desc);
8702 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8703 scsi_4btoul(td->nominal_time),
8704 scsi_4btoul(td->recommended_time), op_desc);
8711 scsiopcodes(struct cam_device *device, int argc, char **argv,
8712 char *combinedopt, int retry_count, int timeout, int verbosemode)
8715 uint32_t opcode = 0, service_action = 0;
8716 int td_set = 0, opcode_set = 0, sa_set = 0;
8717 int show_sa_errors = 1;
8718 uint32_t valid_len = 0;
8719 uint8_t *buf = NULL;
8723 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8729 opcode = strtoul(optarg, &endptr, 0);
8730 if (*endptr != '\0') {
8731 warnx("Invalid opcode \"%s\", must be a number",
8736 if (opcode > 0xff) {
8737 warnx("Invalid opcode 0x%#x, must be between"
8738 "0 and 0xff inclusive", opcode);
8745 service_action = strtoul(optarg, &endptr, 0);
8746 if (*endptr != '\0') {
8747 warnx("Invalid service action \"%s\", must "
8748 "be a number", optarg);
8752 if (service_action > 0xffff) {
8753 warnx("Invalid service action 0x%#x, must "
8754 "be between 0 and 0xffff inclusive",
8769 && (opcode_set == 0)) {
8770 warnx("You must specify an opcode with -o if a service "
8775 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8776 sa_set, service_action, td_set, retry_count,
8777 timeout, verbosemode, &valid_len, &buf);
8781 if ((opcode_set != 0)
8783 retval = scsiprintoneopcode(device, opcode, sa_set,
8784 service_action, buf, valid_len);
8786 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8795 #endif /* MINIMALISTIC */
8798 scsireprobe(struct cam_device *device)
8803 ccb = cam_getccb(device);
8806 warnx("%s: error allocating ccb", __func__);
8810 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8812 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8814 if (cam_send_ccb(device, ccb) < 0) {
8815 warn("error sending XPT_REPROBE_LUN CCB");
8820 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8821 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8833 usage(int printlong)
8836 fprintf(printlong ? stdout : stderr,
8837 "usage: camcontrol <command> [device id][generic args][command args]\n"
8838 " camcontrol devlist [-b] [-v]\n"
8839 #ifndef MINIMALISTIC
8840 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8841 " camcontrol tur [dev_id][generic args]\n"
8842 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8843 " camcontrol identify [dev_id][generic args] [-v]\n"
8844 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8845 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8847 " camcontrol start [dev_id][generic args]\n"
8848 " camcontrol stop [dev_id][generic args]\n"
8849 " camcontrol load [dev_id][generic args]\n"
8850 " camcontrol eject [dev_id][generic args]\n"
8851 " camcontrol reprobe [dev_id][generic args]\n"
8852 #endif /* MINIMALISTIC */
8853 " camcontrol rescan <all | bus[:target:lun]>\n"
8854 " camcontrol reset <all | bus[:target:lun]>\n"
8855 #ifndef MINIMALISTIC
8856 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8857 " [-q][-s][-S offset][-X]\n"
8858 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8859 " [-P pagectl][-e | -b][-d]\n"
8860 " camcontrol cmd [dev_id][generic args]\n"
8861 " <-a cmd [args] | -c cmd [args]>\n"
8862 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8863 " camcontrol smpcmd [dev_id][generic args]\n"
8864 " <-r len fmt [args]> <-R len fmt [args]>\n"
8865 " camcontrol smprg [dev_id][generic args][-l]\n"
8866 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8867 " [-o operation][-d name][-m rate][-M rate]\n"
8868 " [-T pp_timeout][-a enable|disable]\n"
8869 " [-A enable|disable][-s enable|disable]\n"
8870 " [-S enable|disable]\n"
8871 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8872 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8873 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8874 " <all|bus[:target[:lun]]|off>\n"
8875 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8876 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8877 " [-D <enable|disable>][-M mode][-O offset]\n"
8878 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8879 " [-U][-W bus_width]\n"
8880 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8881 " camcontrol sanitize [dev_id][generic args]\n"
8882 " [-a overwrite|block|crypto|exitfailure]\n"
8883 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8885 " camcontrol idle [dev_id][generic args][-t time]\n"
8886 " camcontrol standby [dev_id][generic args][-t time]\n"
8887 " camcontrol sleep [dev_id][generic args]\n"
8888 " camcontrol apm [dev_id][generic args][-l level]\n"
8889 " camcontrol aam [dev_id][generic args][-l level]\n"
8890 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8892 " camcontrol security [dev_id][generic args]\n"
8893 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8894 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8895 " [-U <user|master>] [-y]\n"
8896 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8897 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8898 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8899 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8900 " [-s scope][-S][-T type][-U]\n"
8901 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8902 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8903 " [-p part][-s start][-T type][-V vol]\n"
8904 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8906 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
8907 " [-o rep_opts] [-P print_opts]\n"
8908 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
8909 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
8910 " [-S power_src] [-T timer]\n"
8911 #endif /* MINIMALISTIC */
8912 " camcontrol help\n");
8915 #ifndef MINIMALISTIC
8917 "Specify one of the following options:\n"
8918 "devlist list all CAM devices\n"
8919 "periphlist list all CAM peripheral drivers attached to a device\n"
8920 "tur send a test unit ready to the named device\n"
8921 "inquiry send a SCSI inquiry command to the named device\n"
8922 "identify send a ATA identify command to the named device\n"
8923 "reportluns send a SCSI report luns command to the device\n"
8924 "readcap send a SCSI read capacity command to the device\n"
8925 "start send a Start Unit command to the device\n"
8926 "stop send a Stop Unit command to the device\n"
8927 "load send a Start Unit command to the device with the load bit set\n"
8928 "eject send a Stop Unit command to the device with the eject bit set\n"
8929 "reprobe update capacity information of the given device\n"
8930 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8931 "reset reset all busses, the given bus, or bus:target:lun\n"
8932 "defects read the defect list of the specified device\n"
8933 "modepage display or edit (-e) the given mode page\n"
8934 "cmd send the given SCSI command, may need -i or -o as well\n"
8935 "smpcmd send the given SMP command, requires -o and -i\n"
8936 "smprg send the SMP Report General command\n"
8937 "smppc send the SMP PHY Control command, requires -p\n"
8938 "smpphylist display phys attached to a SAS expander\n"
8939 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8940 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8941 "tags report or set the number of transaction slots for a device\n"
8942 "negotiate report or set device negotiation parameters\n"
8943 "format send the SCSI FORMAT UNIT command to the named device\n"
8944 "sanitize send the SCSI SANITIZE command to the named device\n"
8945 "idle send the ATA IDLE command to the named device\n"
8946 "standby send the ATA STANDBY command to the named device\n"
8947 "sleep send the ATA SLEEP command to the named device\n"
8948 "fwdownload program firmware of the named device with the given image\n"
8949 "security report or send ATA security commands to the named device\n"
8950 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8951 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8952 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8953 "zone manage Zoned Block (Shingled) devices\n"
8954 "epc send ATA Extended Power Conditions commands\n"
8955 "help this message\n"
8956 "Device Identifiers:\n"
8957 "bus:target specify the bus and target, lun defaults to 0\n"
8958 "bus:target:lun specify the bus, target and lun\n"
8959 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8960 "Generic arguments:\n"
8961 "-v be verbose, print out sense information\n"
8962 "-t timeout command timeout in seconds, overrides default timeout\n"
8963 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8964 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8965 "-E have the kernel attempt to perform SCSI error recovery\n"
8966 "-C count specify the SCSI command retry count (needs -E to work)\n"
8967 "modepage arguments:\n"
8968 "-l list all available mode pages\n"
8969 "-m page specify the mode page to view or edit\n"
8970 "-e edit the specified mode page\n"
8971 "-b force view to binary mode\n"
8972 "-d disable block descriptors for mode sense\n"
8973 "-P pgctl page control field 0-3\n"
8974 "defects arguments:\n"
8975 "-f format specify defect list format (block, bfi or phys)\n"
8976 "-G get the grown defect list\n"
8977 "-P get the permanent defect list\n"
8978 "inquiry arguments:\n"
8979 "-D get the standard inquiry data\n"
8980 "-S get the serial number\n"
8981 "-R get the transfer rate, etc.\n"
8982 "reportluns arguments:\n"
8983 "-c only report a count of available LUNs\n"
8984 "-l only print out luns, and not a count\n"
8985 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
8986 "readcap arguments\n"
8987 "-b only report the blocksize\n"
8988 "-h human readable device size, base 2\n"
8989 "-H human readable device size, base 10\n"
8990 "-N print the number of blocks instead of last block\n"
8991 "-q quiet, print numbers only\n"
8992 "-s only report the last block/device size\n"
8994 "-c cdb [args] specify the SCSI CDB\n"
8995 "-i len fmt specify input data and input data format\n"
8996 "-o len fmt [args] specify output data and output data fmt\n"
8997 "smpcmd arguments:\n"
8998 "-r len fmt [args] specify the SMP command to be sent\n"
8999 "-R len fmt [args] specify SMP response format\n"
9000 "smprg arguments:\n"
9001 "-l specify the long response format\n"
9002 "smppc arguments:\n"
9003 "-p phy specify the PHY to operate on\n"
9004 "-l specify the long request/response format\n"
9005 "-o operation specify the phy control operation\n"
9006 "-d name set the attached device name\n"
9007 "-m rate set the minimum physical link rate\n"
9008 "-M rate set the maximum physical link rate\n"
9009 "-T pp_timeout set the partial pathway timeout value\n"
9010 "-a enable|disable enable or disable SATA slumber\n"
9011 "-A enable|disable enable or disable SATA partial phy power\n"
9012 "-s enable|disable enable or disable SAS slumber\n"
9013 "-S enable|disable enable or disable SAS partial phy power\n"
9014 "smpphylist arguments:\n"
9015 "-l specify the long response format\n"
9016 "-q only print phys with attached devices\n"
9017 "smpmaninfo arguments:\n"
9018 "-l specify the long response format\n"
9019 "debug arguments:\n"
9020 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9021 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9022 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9023 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9025 "-N tags specify the number of tags to use for this device\n"
9026 "-q be quiet, don't report the number of tags\n"
9027 "-v report a number of tag-related parameters\n"
9028 "negotiate arguments:\n"
9029 "-a send a test unit ready after negotiation\n"
9030 "-c report/set current negotiation settings\n"
9031 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9032 "-M mode set ATA mode\n"
9033 "-O offset set command delay offset\n"
9034 "-q be quiet, don't report anything\n"
9035 "-R syncrate synchronization rate in MHz\n"
9036 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9037 "-U report/set user negotiation settings\n"
9038 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9039 "-v also print a Path Inquiry CCB for the controller\n"
9040 "format arguments:\n"
9041 "-q be quiet, don't print status messages\n"
9042 "-r run in report only mode\n"
9043 "-w don't send immediate format command\n"
9044 "-y don't ask any questions\n"
9045 "sanitize arguments:\n"
9046 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9047 "-c passes overwrite passes to perform (1 to 31)\n"
9048 "-I invert overwrite pattern after each pass\n"
9049 "-P pattern path to overwrite pattern file\n"
9050 "-q be quiet, don't print status messages\n"
9051 "-r run in report only mode\n"
9052 "-U run operation in unrestricted completion exit mode\n"
9053 "-w don't send immediate sanitize command\n"
9054 "-y don't ask any questions\n"
9055 "idle/standby arguments:\n"
9056 "-t <arg> number of seconds before respective state.\n"
9057 "fwdownload arguments:\n"
9058 "-f fw_image path to firmware image file\n"
9059 "-q don't print informational messages, only errors\n"
9060 "-s run in simulation mode\n"
9061 "-v print info for every firmware segment sent to device\n"
9062 "-y don't ask any questions\n"
9063 "security arguments:\n"
9064 "-d pwd disable security using the given password for the selected\n"
9066 "-e pwd erase the device using the given pwd for the selected user\n"
9067 "-f freeze the security configuration of the specified device\n"
9068 "-h pwd enhanced erase the device using the given pwd for the\n"
9070 "-k pwd unlock the device using the given pwd for the selected\n"
9072 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9073 "-q be quiet, do not print any status messages\n"
9074 "-s pwd password the device (enable security) using the given\n"
9075 " pwd for the selected user\n"
9076 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9077 "-U <user|master> specifies which user to set: user or master\n"
9078 "-y don't ask any questions\n"
9080 "-f freeze the HPA configuration of the device\n"
9081 "-l lock the HPA configuration of the device\n"
9082 "-P make the HPA max sectors persist\n"
9083 "-p pwd Set the HPA configuration password required for unlock\n"
9085 "-q be quiet, do not print any status messages\n"
9086 "-s sectors configures the maximum user accessible sectors of the\n"
9088 "-U pwd unlock the HPA configuration of the device\n"
9089 "-y don't ask any questions\n"
9090 "persist arguments:\n"
9091 "-i action specify read_keys, read_reservation, report_cap, or\n"
9092 " read_full_status\n"
9093 "-o action specify register, register_ignore, reserve, release,\n"
9094 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9095 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9096 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9097 "-k key specify the Reservation Key\n"
9098 "-K sa_key specify the Service Action Reservation Key\n"
9099 "-p set the Activate Persist Through Power Loss bit\n"
9100 "-R rtp specify the Relative Target Port\n"
9101 "-s scope specify the scope: lun, extent, element or a number\n"
9102 "-S specify Transport ID for register, requires -I\n"
9103 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9104 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9105 "-U unregister the current initiator for register_move\n"
9106 "attrib arguments:\n"
9107 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9109 "-w attr specify an attribute to write, one -w argument per attr\n"
9110 "-a attr_num only display this attribute number\n"
9111 "-c get cached attributes\n"
9112 "-e elem_addr request attributes for the given element in a changer\n"
9113 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9114 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9115 " field_none, field_desc, field_num, field_size, field_rw\n"
9116 "-p partition request attributes for the given partition\n"
9117 "-s start_attr request attributes starting at the given number\n"
9118 "-T elem_type specify the element type (used with -e)\n"
9119 "-V logical_vol specify the logical volume ID\n"
9120 "opcodes arguments:\n"
9121 "-o opcode specify the individual opcode to list\n"
9122 "-s service_action specify the service action for the opcode\n"
9123 "-N do not return SCSI error for unsupported SA\n"
9124 "-T request nominal and recommended timeout values\n"
9126 "-c cmd required: rz, open, close, finish, or rwp\n"
9127 "-a apply the action to all zones\n"
9128 "-l LBA specify the zone starting LBA\n"
9129 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9130 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9131 "-P print_opt report zones printing: normal, summary, script\n"
9133 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9134 " source, status, list\n"
9135 "-d disable power mode (timer, state)\n"
9136 "-D delayed entry (goto)\n"
9137 "-e enable power mode (timer, state)\n"
9138 "-H hold power mode (goto)\n"
9139 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9141 "-P only display power mode (status)\n"
9142 "-r rst_src restore settings from: default, saved (restore)\n"
9143 "-s save mode (timer, state, restore)\n"
9144 "-S power_src set power source: battery, nonbattery (source)\n"
9145 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9147 #endif /* MINIMALISTIC */
9151 main(int argc, char **argv)
9154 char *device = NULL;
9156 struct cam_device *cam_dev = NULL;
9157 int timeout = 0, retry_count = 1;
9158 camcontrol_optret optreturn;
9160 const char *mainopt = "C:En:t:u:v";
9161 const char *subopt = NULL;
9162 char combinedopt[256];
9163 int error = 0, optstart = 2;
9165 #ifndef MINIMALISTIC
9169 #endif /* MINIMALISTIC */
9171 cmdlist = CAM_CMD_NONE;
9172 arglist = CAM_ARG_NONE;
9180 * Get the base option.
9182 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9184 if (optreturn == CC_OR_AMBIGUOUS) {
9185 warnx("ambiguous option %s", argv[1]);
9188 } else if (optreturn == CC_OR_NOT_FOUND) {
9189 warnx("option %s not found", argv[1]);
9195 * Ahh, getopt(3) is a pain.
9197 * This is a gross hack. There really aren't many other good
9198 * options (excuse the pun) for parsing options in a situation like
9199 * this. getopt is kinda braindead, so you end up having to run
9200 * through the options twice, and give each invocation of getopt
9201 * the option string for the other invocation.
9203 * You would think that you could just have two groups of options.
9204 * The first group would get parsed by the first invocation of
9205 * getopt, and the second group would get parsed by the second
9206 * invocation of getopt. It doesn't quite work out that way. When
9207 * the first invocation of getopt finishes, it leaves optind pointing
9208 * to the argument _after_ the first argument in the second group.
9209 * So when the second invocation of getopt comes around, it doesn't
9210 * recognize the first argument it gets and then bails out.
9212 * A nice alternative would be to have a flag for getopt that says
9213 * "just keep parsing arguments even when you encounter an unknown
9214 * argument", but there isn't one. So there's no real clean way to
9215 * easily parse two sets of arguments without having one invocation
9216 * of getopt know about the other.
9218 * Without this hack, the first invocation of getopt would work as
9219 * long as the generic arguments are first, but the second invocation
9220 * (in the subfunction) would fail in one of two ways. In the case
9221 * where you don't set optreset, it would fail because optind may be
9222 * pointing to the argument after the one it should be pointing at.
9223 * In the case where you do set optreset, and reset optind, it would
9224 * fail because getopt would run into the first set of options, which
9225 * it doesn't understand.
9227 * All of this would "sort of" work if you could somehow figure out
9228 * whether optind had been incremented one option too far. The
9229 * mechanics of that, however, are more daunting than just giving
9230 * both invocations all of the expect options for either invocation.
9232 * Needless to say, I wouldn't mind if someone invented a better
9233 * (non-GPL!) command line parsing interface than getopt. I
9234 * wouldn't mind if someone added more knobs to getopt to make it
9235 * work better. Who knows, I may talk myself into doing it someday,
9236 * if the standards weenies let me. As it is, it just leads to
9237 * hackery like this and causes people to avoid it in some cases.
9239 * KDM, September 8th, 1998
9242 sprintf(combinedopt, "%s%s", mainopt, subopt);
9244 sprintf(combinedopt, "%s", mainopt);
9247 * For these options we do not parse optional device arguments and
9248 * we do not open a passthrough device.
9250 if ((cmdlist == CAM_CMD_RESCAN)
9251 || (cmdlist == CAM_CMD_RESET)
9252 || (cmdlist == CAM_CMD_DEVTREE)
9253 || (cmdlist == CAM_CMD_USAGE)
9254 || (cmdlist == CAM_CMD_DEBUG))
9257 #ifndef MINIMALISTIC
9259 && (argc > 2 && argv[2][0] != '-')) {
9263 if (isdigit(argv[2][0])) {
9264 /* device specified as bus:target[:lun] */
9265 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9267 errx(1, "numeric device specification must "
9268 "be either bus:target, or "
9270 /* default to 0 if lun was not specified */
9271 if ((arglist & CAM_ARG_LUN) == 0) {
9273 arglist |= CAM_ARG_LUN;
9277 if (cam_get_device(argv[2], name, sizeof name, &unit)
9279 errx(1, "%s", cam_errbuf);
9280 device = strdup(name);
9281 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9285 #endif /* MINIMALISTIC */
9287 * Start getopt processing at argv[2/3], since we've already
9288 * accepted argv[1..2] as the command name, and as a possible
9294 * Now we run through the argument list looking for generic
9295 * options, and ignoring options that possibly belong to
9298 while ((c = getopt(argc, argv, combinedopt))!= -1){
9301 retry_count = strtol(optarg, NULL, 0);
9302 if (retry_count < 0)
9303 errx(1, "retry count %d is < 0",
9305 arglist |= CAM_ARG_RETRIES;
9308 arglist |= CAM_ARG_ERR_RECOVER;
9311 arglist |= CAM_ARG_DEVICE;
9313 while (isspace(*tstr) && (*tstr != '\0'))
9315 device = (char *)strdup(tstr);
9318 timeout = strtol(optarg, NULL, 0);
9320 errx(1, "invalid timeout %d", timeout);
9321 /* Convert the timeout from seconds to ms */
9323 arglist |= CAM_ARG_TIMEOUT;
9326 arglist |= CAM_ARG_UNIT;
9327 unit = strtol(optarg, NULL, 0);
9330 arglist |= CAM_ARG_VERBOSE;
9337 #ifndef MINIMALISTIC
9339 * For most commands we'll want to open the passthrough device
9340 * associated with the specified device. In the case of the rescan
9341 * commands, we don't use a passthrough device at all, just the
9342 * transport layer device.
9345 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9346 && (((arglist & CAM_ARG_DEVICE) == 0)
9347 || ((arglist & CAM_ARG_UNIT) == 0))) {
9348 errx(1, "subcommand \"%s\" requires a valid device "
9349 "identifier", argv[1]);
9352 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9353 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9354 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9356 errx(1,"%s", cam_errbuf);
9358 #endif /* MINIMALISTIC */
9361 * Reset optind to 2, and reset getopt, so these routines can parse
9362 * the arguments again.
9368 #ifndef MINIMALISTIC
9369 case CAM_CMD_DEVLIST:
9370 error = getdevlist(cam_dev);
9373 error = atahpa(cam_dev, retry_count, timeout,
9374 argc, argv, combinedopt);
9376 #endif /* MINIMALISTIC */
9377 case CAM_CMD_DEVTREE:
9378 error = getdevtree(argc, argv, combinedopt);
9380 #ifndef MINIMALISTIC
9382 error = testunitready(cam_dev, retry_count, timeout, 0);
9384 case CAM_CMD_INQUIRY:
9385 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9386 retry_count, timeout);
9388 case CAM_CMD_IDENTIFY:
9389 error = ataidentify(cam_dev, retry_count, timeout);
9391 case CAM_CMD_STARTSTOP:
9392 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9393 arglist & CAM_ARG_EJECT, retry_count,
9396 #endif /* MINIMALISTIC */
9397 case CAM_CMD_RESCAN:
9398 error = dorescan_or_reset(argc, argv, 1);
9401 error = dorescan_or_reset(argc, argv, 0);
9403 #ifndef MINIMALISTIC
9404 case CAM_CMD_READ_DEFECTS:
9405 error = readdefects(cam_dev, argc, argv, combinedopt,
9406 retry_count, timeout);
9408 case CAM_CMD_MODE_PAGE:
9409 modepage(cam_dev, argc, argv, combinedopt,
9410 retry_count, timeout);
9412 case CAM_CMD_SCSI_CMD:
9413 error = scsicmd(cam_dev, argc, argv, combinedopt,
9414 retry_count, timeout);
9416 case CAM_CMD_SMP_CMD:
9417 error = smpcmd(cam_dev, argc, argv, combinedopt,
9418 retry_count, timeout);
9420 case CAM_CMD_SMP_RG:
9421 error = smpreportgeneral(cam_dev, argc, argv,
9422 combinedopt, retry_count,
9425 case CAM_CMD_SMP_PC:
9426 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9427 retry_count, timeout);
9429 case CAM_CMD_SMP_PHYLIST:
9430 error = smpphylist(cam_dev, argc, argv, combinedopt,
9431 retry_count, timeout);
9433 case CAM_CMD_SMP_MANINFO:
9434 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9435 retry_count, timeout);
9438 error = camdebug(argc, argv, combinedopt);
9441 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9444 error = ratecontrol(cam_dev, retry_count, timeout,
9445 argc, argv, combinedopt);
9447 case CAM_CMD_FORMAT:
9448 error = scsiformat(cam_dev, argc, argv,
9449 combinedopt, retry_count, timeout);
9451 case CAM_CMD_REPORTLUNS:
9452 error = scsireportluns(cam_dev, argc, argv,
9453 combinedopt, retry_count,
9456 case CAM_CMD_READCAP:
9457 error = scsireadcapacity(cam_dev, argc, argv,
9458 combinedopt, retry_count,
9462 case CAM_CMD_STANDBY:
9464 error = atapm(cam_dev, argc, argv,
9465 combinedopt, retry_count, timeout);
9469 error = ataaxm(cam_dev, argc, argv,
9470 combinedopt, retry_count, timeout);
9472 case CAM_CMD_SECURITY:
9473 error = atasecurity(cam_dev, retry_count, timeout,
9474 argc, argv, combinedopt);
9476 case CAM_CMD_DOWNLOAD_FW:
9477 error = fwdownload(cam_dev, argc, argv, combinedopt,
9478 arglist & CAM_ARG_VERBOSE, retry_count, timeout);
9480 case CAM_CMD_SANITIZE:
9481 error = scsisanitize(cam_dev, argc, argv,
9482 combinedopt, retry_count, timeout);
9484 case CAM_CMD_PERSIST:
9485 error = scsipersist(cam_dev, argc, argv, combinedopt,
9486 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9487 arglist & CAM_ARG_ERR_RECOVER);
9489 case CAM_CMD_ATTRIB:
9490 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9491 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9492 arglist & CAM_ARG_ERR_RECOVER);
9494 case CAM_CMD_OPCODES:
9495 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9496 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9498 case CAM_CMD_REPROBE:
9499 error = scsireprobe(cam_dev);
9502 error = zone(cam_dev, argc, argv, combinedopt,
9503 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9506 error = epc(cam_dev, argc, argv, combinedopt,
9507 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9509 #endif /* MINIMALISTIC */
9519 if (cam_dev != NULL)
9520 cam_close_device(cam_dev);