2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
55 #include <cam/cam_debug.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/scsi/scsi_all.h>
58 #include <cam/scsi/scsi_da.h>
59 #include <cam/scsi/scsi_pass.h>
60 #include <cam/scsi/scsi_message.h>
61 #include <cam/scsi/smp_all.h>
62 #include <cam/ata/ata_all.h>
64 #include "camcontrol.h"
67 CAM_CMD_NONE = 0x00000000,
68 CAM_CMD_DEVLIST = 0x00000001,
69 CAM_CMD_TUR = 0x00000002,
70 CAM_CMD_INQUIRY = 0x00000003,
71 CAM_CMD_STARTSTOP = 0x00000004,
72 CAM_CMD_RESCAN = 0x00000005,
73 CAM_CMD_READ_DEFECTS = 0x00000006,
74 CAM_CMD_MODE_PAGE = 0x00000007,
75 CAM_CMD_SCSI_CMD = 0x00000008,
76 CAM_CMD_DEVTREE = 0x00000009,
77 CAM_CMD_USAGE = 0x0000000a,
78 CAM_CMD_DEBUG = 0x0000000b,
79 CAM_CMD_RESET = 0x0000000c,
80 CAM_CMD_FORMAT = 0x0000000d,
81 CAM_CMD_TAG = 0x0000000e,
82 CAM_CMD_RATE = 0x0000000f,
83 CAM_CMD_DETACH = 0x00000010,
84 CAM_CMD_REPORTLUNS = 0x00000011,
85 CAM_CMD_READCAP = 0x00000012,
86 CAM_CMD_IDENTIFY = 0x00000013,
87 CAM_CMD_IDLE = 0x00000014,
88 CAM_CMD_STANDBY = 0x00000015,
89 CAM_CMD_SLEEP = 0x00000016,
90 CAM_CMD_SMP_CMD = 0x00000017,
91 CAM_CMD_SMP_RG = 0x00000018,
92 CAM_CMD_SMP_PC = 0x00000019,
93 CAM_CMD_SMP_PHYLIST = 0x0000001a,
94 CAM_CMD_SMP_MANINFO = 0x0000001b,
95 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
96 CAM_CMD_SECURITY = 0x0000001d,
97 CAM_CMD_HPA = 0x0000001e,
98 CAM_CMD_SANITIZE = 0x0000001f,
99 CAM_CMD_PERSIST = 0x00000020,
100 CAM_CMD_APM = 0x00000021,
101 CAM_CMD_AAM = 0x00000022,
102 CAM_CMD_ATTRIB = 0x00000023,
103 CAM_CMD_OPCODES = 0x00000024,
104 CAM_CMD_REPROBE = 0x00000025,
105 CAM_CMD_ZONE = 0x00000026,
106 CAM_CMD_EPC = 0x00000027,
107 CAM_CMD_TIMESTAMP = 0x00000028
111 CAM_ARG_NONE = 0x00000000,
112 CAM_ARG_VERBOSE = 0x00000001,
113 CAM_ARG_DEVICE = 0x00000002,
114 CAM_ARG_BUS = 0x00000004,
115 CAM_ARG_TARGET = 0x00000008,
116 CAM_ARG_LUN = 0x00000010,
117 CAM_ARG_EJECT = 0x00000020,
118 CAM_ARG_UNIT = 0x00000040,
119 CAM_ARG_FORMAT_BLOCK = 0x00000080,
120 CAM_ARG_FORMAT_BFI = 0x00000100,
121 CAM_ARG_FORMAT_PHYS = 0x00000200,
122 CAM_ARG_PLIST = 0x00000400,
123 CAM_ARG_GLIST = 0x00000800,
124 CAM_ARG_GET_SERIAL = 0x00001000,
125 CAM_ARG_GET_STDINQ = 0x00002000,
126 CAM_ARG_GET_XFERRATE = 0x00004000,
127 CAM_ARG_INQ_MASK = 0x00007000,
128 CAM_ARG_TIMEOUT = 0x00020000,
129 CAM_ARG_CMD_IN = 0x00040000,
130 CAM_ARG_CMD_OUT = 0x00080000,
131 CAM_ARG_ERR_RECOVER = 0x00200000,
132 CAM_ARG_RETRIES = 0x00400000,
133 CAM_ARG_START_UNIT = 0x00800000,
134 CAM_ARG_DEBUG_INFO = 0x01000000,
135 CAM_ARG_DEBUG_TRACE = 0x02000000,
136 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
137 CAM_ARG_DEBUG_CDB = 0x08000000,
138 CAM_ARG_DEBUG_XPT = 0x10000000,
139 CAM_ARG_DEBUG_PERIPH = 0x20000000,
140 CAM_ARG_DEBUG_PROBE = 0x40000000,
143 struct camcontrol_opts {
151 struct ata_res_pass16 {
152 u_int16_t reserved[5];
155 u_int8_t sector_count_exp;
156 u_int8_t sector_count;
157 u_int8_t lba_low_exp;
159 u_int8_t lba_mid_exp;
161 u_int8_t lba_high_exp;
167 struct ata_set_max_pwd
170 u_int8_t password[32];
171 u_int16_t reserved2[239];
174 static const char scsicmd_opts[] = "a:c:dfi:o:r";
175 static const char readdefect_opts[] = "f:GPqsS:X";
176 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
177 static const char smprg_opts[] = "l";
178 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
179 static const char smpphylist_opts[] = "lq";
183 static struct camcontrol_opts option_table[] = {
185 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
186 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
187 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
188 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
189 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
190 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
191 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
192 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
193 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
194 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
195 #endif /* MINIMALISTIC */
196 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
197 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
199 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
200 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
201 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
202 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
203 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
204 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
205 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
206 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
207 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
208 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
209 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
210 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
211 #endif /* MINIMALISTIC */
212 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
214 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
215 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
216 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
217 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
218 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
219 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
220 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
221 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
222 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
223 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
224 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
225 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
226 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
227 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
228 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
229 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
230 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
231 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
232 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
233 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
234 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
235 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
236 #endif /* MINIMALISTIC */
237 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
238 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
239 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
244 struct device_match_result dev_match;
246 struct periph_match_result *periph_matches;
247 struct scsi_vpd_device_id *device_id;
249 STAILQ_ENTRY(cam_devitem) links;
253 STAILQ_HEAD(, cam_devitem) dev_queue;
257 static cam_cmdmask cmdlist;
258 static cam_argmask arglist;
260 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
261 uint32_t *cmdnum, cam_argmask *argnum,
262 const char **subopt);
264 static int getdevlist(struct cam_device *device);
265 #endif /* MINIMALISTIC */
266 static int getdevtree(int argc, char **argv, char *combinedopt);
268 static int testunitready(struct cam_device *device, int retry_count,
269 int timeout, int quiet);
270 static int scsistart(struct cam_device *device, int startstop, int loadeject,
271 int retry_count, int timeout);
272 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
273 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
274 #endif /* MINIMALISTIC */
275 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
276 lun_id_t *lun, cam_argmask *arglst);
277 static int dorescan_or_reset(int argc, char **argv, int rescan);
278 static int rescan_or_reset_bus(path_id_t bus, int rescan);
279 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
280 lun_id_t lun, int scan);
282 static int readdefects(struct cam_device *device, int argc, char **argv,
283 char *combinedopt, int retry_count, int timeout);
284 static void modepage(struct cam_device *device, int argc, char **argv,
285 char *combinedopt, int retry_count, int timeout);
286 static int scsicmd(struct cam_device *device, int argc, char **argv,
287 char *combinedopt, int retry_count, int timeout);
288 static int smpcmd(struct cam_device *device, int argc, char **argv,
289 char *combinedopt, int retry_count, int timeout);
290 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
291 char *combinedopt, int retry_count, int timeout);
292 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
293 char *combinedopt, int retry_count, int timeout);
294 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
295 char *combinedopt, int retry_count, int timeout);
296 static int getdevid(struct cam_devitem *item);
297 static int buildbusdevlist(struct cam_devlist *devlist);
298 static void freebusdevlist(struct cam_devlist *devlist);
299 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
301 static int smpphylist(struct cam_device *device, int argc, char **argv,
302 char *combinedopt, int retry_count, int timeout);
303 static int tagcontrol(struct cam_device *device, int argc, char **argv,
305 static void cts_print(struct cam_device *device,
306 struct ccb_trans_settings *cts);
307 static void cpi_print(struct ccb_pathinq *cpi);
308 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
309 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
310 static int get_print_cts(struct cam_device *device, int user_settings,
311 int quiet, struct ccb_trans_settings *cts);
312 static int ratecontrol(struct cam_device *device, int retry_count,
313 int timeout, int argc, char **argv, char *combinedopt);
314 static int scsiformat(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int retry_count, int timeout);
316 static int scsisanitize(struct cam_device *device, int argc, char **argv,
317 char *combinedopt, int retry_count, int timeout);
318 static int scsireportluns(struct cam_device *device, int argc, char **argv,
319 char *combinedopt, int retry_count, int timeout);
320 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
321 char *combinedopt, int retry_count, int timeout);
322 static int atapm(struct cam_device *device, int argc, char **argv,
323 char *combinedopt, int retry_count, int timeout);
324 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
325 int argc, char **argv, char *combinedopt);
326 static int atahpa(struct cam_device *device, int retry_count, int timeout,
327 int argc, char **argv, char *combinedopt);
328 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
329 int sa_set, int req_sa, uint8_t *buf,
331 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
333 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
334 char *combinedopt, int retry_count, int timeout,
336 static int scsireprobe(struct cam_device *device);
338 #endif /* MINIMALISTIC */
340 #define min(a,b) (((a)<(b))?(a):(b))
343 #define max(a,b) (((a)>(b))?(a):(b))
347 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
348 cam_argmask *argnum, const char **subopt)
350 struct camcontrol_opts *opts;
353 for (opts = table; (opts != NULL) && (opts->optname != NULL);
355 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
356 *cmdnum = opts->cmdnum;
357 *argnum = opts->argnum;
358 *subopt = opts->subopt;
359 if (++num_matches > 1)
360 return(CC_OR_AMBIGUOUS);
367 return(CC_OR_NOT_FOUND);
372 getdevlist(struct cam_device *device)
378 ccb = cam_getccb(device);
380 ccb->ccb_h.func_code = XPT_GDEVLIST;
381 ccb->ccb_h.flags = CAM_DIR_NONE;
382 ccb->ccb_h.retry_count = 1;
384 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
385 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
386 if (cam_send_ccb(device, ccb) < 0) {
387 perror("error getting device list");
394 switch (ccb->cgdl.status) {
395 case CAM_GDEVLIST_MORE_DEVS:
396 strcpy(status, "MORE");
398 case CAM_GDEVLIST_LAST_DEVICE:
399 strcpy(status, "LAST");
401 case CAM_GDEVLIST_LIST_CHANGED:
402 strcpy(status, "CHANGED");
404 case CAM_GDEVLIST_ERROR:
405 strcpy(status, "ERROR");
410 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
411 ccb->cgdl.periph_name,
412 ccb->cgdl.unit_number,
413 ccb->cgdl.generation,
418 * If the list has changed, we need to start over from the
421 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
429 #endif /* MINIMALISTIC */
432 getdevtree(int argc, char **argv, char *combinedopt)
443 while ((c = getopt(argc, argv, combinedopt)) != -1) {
446 if ((arglist & CAM_ARG_VERBOSE) == 0)
454 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
455 warn("couldn't open %s", XPT_DEVICE);
459 bzero(&ccb, sizeof(union ccb));
461 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
462 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
463 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
465 ccb.ccb_h.func_code = XPT_DEV_MATCH;
466 bufsize = sizeof(struct dev_match_result) * 100;
467 ccb.cdm.match_buf_len = bufsize;
468 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
469 if (ccb.cdm.matches == NULL) {
470 warnx("can't malloc memory for matches");
474 ccb.cdm.num_matches = 0;
477 * We fetch all nodes, since we display most of them in the default
478 * case, and all in the verbose case.
480 ccb.cdm.num_patterns = 0;
481 ccb.cdm.pattern_buf_len = 0;
484 * We do the ioctl multiple times if necessary, in case there are
485 * more than 100 nodes in the EDT.
488 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
489 warn("error sending CAMIOCOMMAND ioctl");
494 if ((ccb.ccb_h.status != CAM_REQ_CMP)
495 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
496 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
497 warnx("got CAM error %#x, CDM error %d\n",
498 ccb.ccb_h.status, ccb.cdm.status);
503 for (i = 0; i < ccb.cdm.num_matches; i++) {
504 switch (ccb.cdm.matches[i].type) {
505 case DEV_MATCH_BUS: {
506 struct bus_match_result *bus_result;
509 * Only print the bus information if the
510 * user turns on the verbose flag.
512 if ((busonly == 0) &&
513 (arglist & CAM_ARG_VERBOSE) == 0)
517 &ccb.cdm.matches[i].result.bus_result;
520 fprintf(stdout, ")\n");
524 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
526 bus_result->dev_name,
527 bus_result->unit_number,
529 (busonly ? "" : ":"));
532 case DEV_MATCH_DEVICE: {
533 struct device_match_result *dev_result;
534 char vendor[16], product[48], revision[16];
535 char fw[5], tmpstr[256];
541 &ccb.cdm.matches[i].result.device_result;
543 if ((dev_result->flags
544 & DEV_RESULT_UNCONFIGURED)
545 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
551 if (dev_result->protocol == PROTO_SCSI) {
552 cam_strvis(vendor, dev_result->inq_data.vendor,
553 sizeof(dev_result->inq_data.vendor),
556 dev_result->inq_data.product,
557 sizeof(dev_result->inq_data.product),
560 dev_result->inq_data.revision,
561 sizeof(dev_result->inq_data.revision),
563 sprintf(tmpstr, "<%s %s %s>", vendor, product,
565 } else if (dev_result->protocol == PROTO_ATA ||
566 dev_result->protocol == PROTO_SATAPM) {
568 dev_result->ident_data.model,
569 sizeof(dev_result->ident_data.model),
572 dev_result->ident_data.revision,
573 sizeof(dev_result->ident_data.revision),
575 sprintf(tmpstr, "<%s %s>", product,
577 } else if (dev_result->protocol == PROTO_SEMB) {
578 struct sep_identify_data *sid;
580 sid = (struct sep_identify_data *)
581 &dev_result->ident_data;
582 cam_strvis(vendor, sid->vendor_id,
583 sizeof(sid->vendor_id),
585 cam_strvis(product, sid->product_id,
586 sizeof(sid->product_id),
588 cam_strvis(revision, sid->product_rev,
589 sizeof(sid->product_rev),
591 cam_strvis(fw, sid->firmware_rev,
592 sizeof(sid->firmware_rev),
594 sprintf(tmpstr, "<%s %s %s %s>",
595 vendor, product, revision, fw);
597 sprintf(tmpstr, "<>");
600 fprintf(stdout, ")\n");
604 fprintf(stdout, "%-33s at scbus%d "
605 "target %d lun %jx (",
608 dev_result->target_id,
609 (uintmax_t)dev_result->target_lun);
615 case DEV_MATCH_PERIPH: {
616 struct periph_match_result *periph_result;
619 &ccb.cdm.matches[i].result.periph_result;
621 if (busonly || skip_device != 0)
625 fprintf(stdout, ",");
627 fprintf(stdout, "%s%d",
628 periph_result->periph_name,
629 periph_result->unit_number);
635 fprintf(stdout, "unknown match type\n");
640 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
641 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
644 fprintf(stdout, ")\n");
653 testunitready(struct cam_device *device, int retry_count, int timeout,
659 ccb = cam_getccb(device);
661 scsi_test_unit_ready(&ccb->csio,
662 /* retries */ retry_count,
664 /* tag_action */ MSG_SIMPLE_Q_TAG,
665 /* sense_len */ SSD_FULL_SIZE,
666 /* timeout */ timeout ? timeout : 5000);
668 /* Disable freezing the device queue */
669 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
671 if (arglist & CAM_ARG_ERR_RECOVER)
672 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
674 if (cam_send_ccb(device, ccb) < 0) {
676 perror("error sending test unit ready");
678 if (arglist & CAM_ARG_VERBOSE) {
679 cam_error_print(device, ccb, CAM_ESF_ALL,
680 CAM_EPF_ALL, stderr);
687 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
689 fprintf(stdout, "Unit is ready\n");
692 fprintf(stdout, "Unit is not ready\n");
695 if (arglist & CAM_ARG_VERBOSE) {
696 cam_error_print(device, ccb, CAM_ESF_ALL,
697 CAM_EPF_ALL, stderr);
707 scsistart(struct cam_device *device, int startstop, int loadeject,
708 int retry_count, int timeout)
713 ccb = cam_getccb(device);
716 * If we're stopping, send an ordered tag so the drive in question
717 * will finish any previously queued writes before stopping. If
718 * the device isn't capable of tagged queueing, or if tagged
719 * queueing is turned off, the tag action is a no-op.
721 scsi_start_stop(&ccb->csio,
722 /* retries */ retry_count,
724 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
726 /* start/stop */ startstop,
727 /* load_eject */ loadeject,
729 /* sense_len */ SSD_FULL_SIZE,
730 /* timeout */ timeout ? timeout : 120000);
732 /* Disable freezing the device queue */
733 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
735 if (arglist & CAM_ARG_ERR_RECOVER)
736 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
738 if (cam_send_ccb(device, ccb) < 0) {
739 perror("error sending start unit");
741 if (arglist & CAM_ARG_VERBOSE) {
742 cam_error_print(device, ccb, CAM_ESF_ALL,
743 CAM_EPF_ALL, stderr);
750 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
752 fprintf(stdout, "Unit started successfully");
754 fprintf(stdout,", Media loaded\n");
756 fprintf(stdout,"\n");
758 fprintf(stdout, "Unit stopped successfully");
760 fprintf(stdout, ", Media ejected\n");
762 fprintf(stdout, "\n");
768 "Error received from start unit command\n");
771 "Error received from stop unit command\n");
773 if (arglist & CAM_ARG_VERBOSE) {
774 cam_error_print(device, ccb, CAM_ESF_ALL,
775 CAM_EPF_ALL, stderr);
785 scsidoinquiry(struct cam_device *device, int argc, char **argv,
786 char *combinedopt, int retry_count, int timeout)
791 while ((c = getopt(argc, argv, combinedopt)) != -1) {
794 arglist |= CAM_ARG_GET_STDINQ;
797 arglist |= CAM_ARG_GET_XFERRATE;
800 arglist |= CAM_ARG_GET_SERIAL;
808 * If the user didn't specify any inquiry options, he wants all of
811 if ((arglist & CAM_ARG_INQ_MASK) == 0)
812 arglist |= CAM_ARG_INQ_MASK;
814 if (arglist & CAM_ARG_GET_STDINQ)
815 error = scsiinquiry(device, retry_count, timeout);
820 if (arglist & CAM_ARG_GET_SERIAL)
821 scsiserial(device, retry_count, timeout);
823 if (arglist & CAM_ARG_GET_XFERRATE)
824 error = camxferrate(device);
830 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
833 struct scsi_inquiry_data *inq_buf;
836 ccb = cam_getccb(device);
839 warnx("couldn't allocate CCB");
843 /* cam_getccb cleans up the header, caller has to zero the payload */
844 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
846 inq_buf = (struct scsi_inquiry_data *)malloc(
847 sizeof(struct scsi_inquiry_data));
849 if (inq_buf == NULL) {
851 warnx("can't malloc memory for inquiry\n");
854 bzero(inq_buf, sizeof(*inq_buf));
857 * Note that although the size of the inquiry buffer is the full
858 * 256 bytes specified in the SCSI spec, we only tell the device
859 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
860 * two reasons for this:
862 * - The SCSI spec says that when a length field is only 1 byte,
863 * a value of 0 will be interpreted as 256. Therefore
864 * scsi_inquiry() will convert an inq_len (which is passed in as
865 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
866 * to 0. Evidently, very few devices meet the spec in that
867 * regard. Some devices, like many Seagate disks, take the 0 as
868 * 0, and don't return any data. One Pioneer DVD-R drive
869 * returns more data than the command asked for.
871 * So, since there are numerous devices that just don't work
872 * right with the full inquiry size, we don't send the full size.
874 * - The second reason not to use the full inquiry data length is
875 * that we don't need it here. The only reason we issue a
876 * standard inquiry is to get the vendor name, device name,
877 * and revision so scsi_print_inquiry() can print them.
879 * If, at some point in the future, more inquiry data is needed for
880 * some reason, this code should use a procedure similar to the
881 * probe code. i.e., issue a short inquiry, and determine from
882 * the additional length passed back from the device how much
883 * inquiry data the device supports. Once the amount the device
884 * supports is determined, issue an inquiry for that amount and no
889 scsi_inquiry(&ccb->csio,
890 /* retries */ retry_count,
892 /* tag_action */ MSG_SIMPLE_Q_TAG,
893 /* inq_buf */ (u_int8_t *)inq_buf,
894 /* inq_len */ SHORT_INQUIRY_LENGTH,
897 /* sense_len */ SSD_FULL_SIZE,
898 /* timeout */ timeout ? timeout : 5000);
900 /* Disable freezing the device queue */
901 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
903 if (arglist & CAM_ARG_ERR_RECOVER)
904 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
906 if (cam_send_ccb(device, ccb) < 0) {
907 perror("error sending SCSI inquiry");
909 if (arglist & CAM_ARG_VERBOSE) {
910 cam_error_print(device, ccb, CAM_ESF_ALL,
911 CAM_EPF_ALL, stderr);
918 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
921 if (arglist & CAM_ARG_VERBOSE) {
922 cam_error_print(device, ccb, CAM_ESF_ALL,
923 CAM_EPF_ALL, stderr);
934 fprintf(stdout, "%s%d: ", device->device_name,
935 device->dev_unit_num);
936 scsi_print_inquiry(inq_buf);
944 scsiserial(struct cam_device *device, int retry_count, int timeout)
947 struct scsi_vpd_unit_serial_number *serial_buf;
948 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
951 ccb = cam_getccb(device);
954 warnx("couldn't allocate CCB");
958 /* cam_getccb cleans up the header, caller has to zero the payload */
959 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
961 serial_buf = (struct scsi_vpd_unit_serial_number *)
962 malloc(sizeof(*serial_buf));
964 if (serial_buf == NULL) {
966 warnx("can't malloc memory for serial number");
970 scsi_inquiry(&ccb->csio,
971 /*retries*/ retry_count,
973 /* tag_action */ MSG_SIMPLE_Q_TAG,
974 /* inq_buf */ (u_int8_t *)serial_buf,
975 /* inq_len */ sizeof(*serial_buf),
977 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
978 /* sense_len */ SSD_FULL_SIZE,
979 /* timeout */ timeout ? timeout : 5000);
981 /* Disable freezing the device queue */
982 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
984 if (arglist & CAM_ARG_ERR_RECOVER)
985 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
987 if (cam_send_ccb(device, ccb) < 0) {
988 warn("error getting serial number");
990 if (arglist & CAM_ARG_VERBOSE) {
991 cam_error_print(device, ccb, CAM_ESF_ALL,
992 CAM_EPF_ALL, stderr);
1000 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1003 if (arglist & CAM_ARG_VERBOSE) {
1004 cam_error_print(device, ccb, CAM_ESF_ALL,
1005 CAM_EPF_ALL, stderr);
1016 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1017 serial_num[serial_buf->length] = '\0';
1019 if ((arglist & CAM_ARG_GET_STDINQ)
1020 || (arglist & CAM_ARG_GET_XFERRATE))
1021 fprintf(stdout, "%s%d: Serial Number ",
1022 device->device_name, device->dev_unit_num);
1024 fprintf(stdout, "%.60s\n", serial_num);
1032 camxferrate(struct cam_device *device)
1034 struct ccb_pathinq cpi;
1036 u_int32_t speed = 0;
1041 if ((retval = get_cpi(device, &cpi)) != 0)
1044 ccb = cam_getccb(device);
1047 warnx("couldn't allocate CCB");
1051 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1053 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1054 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1056 if (((retval = cam_send_ccb(device, ccb)) < 0)
1057 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1058 const char error_string[] = "error getting transfer settings";
1063 warnx(error_string);
1065 if (arglist & CAM_ARG_VERBOSE)
1066 cam_error_print(device, ccb, CAM_ESF_ALL,
1067 CAM_EPF_ALL, stderr);
1071 goto xferrate_bailout;
1075 speed = cpi.base_transfer_speed;
1077 if (ccb->cts.transport == XPORT_SPI) {
1078 struct ccb_trans_settings_spi *spi =
1079 &ccb->cts.xport_specific.spi;
1081 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1082 freq = scsi_calc_syncsrate(spi->sync_period);
1085 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1086 speed *= (0x01 << spi->bus_width);
1088 } else if (ccb->cts.transport == XPORT_FC) {
1089 struct ccb_trans_settings_fc *fc =
1090 &ccb->cts.xport_specific.fc;
1092 if (fc->valid & CTS_FC_VALID_SPEED)
1093 speed = fc->bitrate;
1094 } else if (ccb->cts.transport == XPORT_SAS) {
1095 struct ccb_trans_settings_sas *sas =
1096 &ccb->cts.xport_specific.sas;
1098 if (sas->valid & CTS_SAS_VALID_SPEED)
1099 speed = sas->bitrate;
1100 } else if (ccb->cts.transport == XPORT_ATA) {
1101 struct ccb_trans_settings_pata *pata =
1102 &ccb->cts.xport_specific.ata;
1104 if (pata->valid & CTS_ATA_VALID_MODE)
1105 speed = ata_mode2speed(pata->mode);
1106 } else if (ccb->cts.transport == XPORT_SATA) {
1107 struct ccb_trans_settings_sata *sata =
1108 &ccb->cts.xport_specific.sata;
1110 if (sata->valid & CTS_SATA_VALID_REVISION)
1111 speed = ata_revision2speed(sata->revision);
1116 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1117 device->device_name, device->dev_unit_num,
1120 fprintf(stdout, "%s%d: %dKB/s transfers",
1121 device->device_name, device->dev_unit_num,
1125 if (ccb->cts.transport == XPORT_SPI) {
1126 struct ccb_trans_settings_spi *spi =
1127 &ccb->cts.xport_specific.spi;
1129 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1130 && (spi->sync_offset != 0))
1131 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1132 freq % 1000, spi->sync_offset);
1134 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1135 && (spi->bus_width > 0)) {
1136 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1137 && (spi->sync_offset != 0)) {
1138 fprintf(stdout, ", ");
1140 fprintf(stdout, " (");
1142 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1143 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1144 && (spi->sync_offset != 0)) {
1145 fprintf(stdout, ")");
1147 } else if (ccb->cts.transport == XPORT_ATA) {
1148 struct ccb_trans_settings_pata *pata =
1149 &ccb->cts.xport_specific.ata;
1152 if (pata->valid & CTS_ATA_VALID_MODE)
1153 printf("%s, ", ata_mode2string(pata->mode));
1154 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1155 printf("ATAPI %dbytes, ", pata->atapi);
1156 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1157 printf("PIO %dbytes", pata->bytecount);
1159 } else if (ccb->cts.transport == XPORT_SATA) {
1160 struct ccb_trans_settings_sata *sata =
1161 &ccb->cts.xport_specific.sata;
1164 if (sata->valid & CTS_SATA_VALID_REVISION)
1165 printf("SATA %d.x, ", sata->revision);
1168 if (sata->valid & CTS_SATA_VALID_MODE)
1169 printf("%s, ", ata_mode2string(sata->mode));
1170 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1171 printf("ATAPI %dbytes, ", sata->atapi);
1172 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1173 printf("PIO %dbytes", sata->bytecount);
1177 if (ccb->cts.protocol == PROTO_SCSI) {
1178 struct ccb_trans_settings_scsi *scsi =
1179 &ccb->cts.proto_specific.scsi;
1180 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1181 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1182 fprintf(stdout, ", Command Queueing Enabled");
1187 fprintf(stdout, "\n");
1197 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1199 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1200 ((u_int32_t)parm->lba_size_2 << 16);
1202 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1203 ((u_int64_t)parm->lba_size48_2 << 16) |
1204 ((u_int64_t)parm->lba_size48_3 << 32) |
1205 ((u_int64_t)parm->lba_size48_4 << 48);
1209 "Support Enabled Value\n");
1212 printf("Host Protected Area (HPA) ");
1213 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1214 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1215 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1218 printf("HPA - Security ");
1219 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1229 atasata(struct ata_params *parm)
1233 if (parm->satacapabilities != 0xffff &&
1234 parm->satacapabilities != 0x0000)
1241 atacapprint(struct ata_params *parm)
1243 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1244 ((u_int32_t)parm->lba_size_2 << 16);
1246 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1247 ((u_int64_t)parm->lba_size48_2 << 16) |
1248 ((u_int64_t)parm->lba_size48_3 << 32) |
1249 ((u_int64_t)parm->lba_size48_4 << 48);
1252 printf("protocol ");
1253 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1254 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1255 if (parm->satacapabilities & ATA_SATA_GEN3)
1256 printf(" SATA 3.x\n");
1257 else if (parm->satacapabilities & ATA_SATA_GEN2)
1258 printf(" SATA 2.x\n");
1259 else if (parm->satacapabilities & ATA_SATA_GEN1)
1260 printf(" SATA 1.x\n");
1266 printf("device model %.40s\n", parm->model);
1267 printf("firmware revision %.8s\n", parm->revision);
1268 printf("serial number %.20s\n", parm->serial);
1269 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1270 printf("WWN %04x%04x%04x%04x\n",
1271 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1273 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1274 printf("media serial number %.30s\n",
1275 parm->media_serial);
1278 printf("cylinders %d\n", parm->cylinders);
1279 printf("heads %d\n", parm->heads);
1280 printf("sectors/track %d\n", parm->sectors);
1281 printf("sector size logical %u, physical %lu, offset %lu\n",
1282 ata_logical_sector_size(parm),
1283 (unsigned long)ata_physical_sector_size(parm),
1284 (unsigned long)ata_logical_sector_offset(parm));
1286 if (parm->config == ATA_PROTO_CFA ||
1287 (parm->support.command2 & ATA_SUPPORT_CFA))
1288 printf("CFA supported\n");
1290 printf("LBA%ssupported ",
1291 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1293 printf("%d sectors\n", lbasize);
1297 printf("LBA48%ssupported ",
1298 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1300 printf("%ju sectors\n", (uintmax_t)lbasize48);
1304 printf("PIO supported PIO");
1305 switch (ata_max_pmode(parm)) {
1321 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1322 printf(" w/o IORDY");
1325 printf("DMA%ssupported ",
1326 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1327 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1328 if (parm->mwdmamodes & 0xff) {
1330 if (parm->mwdmamodes & 0x04)
1332 else if (parm->mwdmamodes & 0x02)
1334 else if (parm->mwdmamodes & 0x01)
1338 if ((parm->atavalid & ATA_FLAG_88) &&
1339 (parm->udmamodes & 0xff)) {
1341 if (parm->udmamodes & 0x40)
1343 else if (parm->udmamodes & 0x20)
1345 else if (parm->udmamodes & 0x10)
1347 else if (parm->udmamodes & 0x08)
1349 else if (parm->udmamodes & 0x04)
1351 else if (parm->udmamodes & 0x02)
1353 else if (parm->udmamodes & 0x01)
1360 if (parm->media_rotation_rate == 1) {
1361 printf("media RPM non-rotating\n");
1362 } else if (parm->media_rotation_rate >= 0x0401 &&
1363 parm->media_rotation_rate <= 0xFFFE) {
1364 printf("media RPM %d\n",
1365 parm->media_rotation_rate);
1369 "Support Enabled Value Vendor\n");
1370 printf("read ahead %s %s\n",
1371 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1372 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1373 printf("write cache %s %s\n",
1374 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1375 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1376 printf("flush cache %s %s\n",
1377 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1378 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1379 printf("overlap %s\n",
1380 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1381 printf("Tagged Command Queuing (TCQ) %s %s",
1382 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1383 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1384 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1385 printf(" %d tags\n",
1386 ATA_QUEUE_LEN(parm->queue) + 1);
1389 printf("Native Command Queuing (NCQ) ");
1390 if (parm->satacapabilities != 0xffff &&
1391 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1392 printf("yes %d tags\n",
1393 ATA_QUEUE_LEN(parm->queue) + 1);
1397 printf("NCQ Queue Management %s\n", atasata(parm) &&
1398 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1400 printf("NCQ Streaming %s\n", atasata(parm) &&
1401 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1403 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1404 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1407 printf("SMART %s %s\n",
1408 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1409 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1410 printf("microcode download %s %s\n",
1411 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1412 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1413 printf("security %s %s\n",
1414 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1415 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1416 printf("power management %s %s\n",
1417 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1418 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1419 printf("advanced power management %s %s",
1420 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1421 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1422 if (parm->support.command2 & ATA_SUPPORT_APM) {
1423 printf(" %d/0x%02X\n",
1424 parm->apm_value & 0xff, parm->apm_value & 0xff);
1427 printf("automatic acoustic management %s %s",
1428 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1429 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1430 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1431 printf(" %d/0x%02X %d/0x%02X\n",
1432 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1433 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1434 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1435 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1438 printf("media status notification %s %s\n",
1439 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1440 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1441 printf("power-up in Standby %s %s\n",
1442 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1443 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1444 printf("write-read-verify %s %s",
1445 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1446 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1447 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1448 printf(" %d/0x%x\n",
1449 parm->wrv_mode, parm->wrv_mode);
1452 printf("unload %s %s\n",
1453 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1454 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1455 printf("general purpose logging %s %s\n",
1456 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1457 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1458 printf("free-fall %s %s\n",
1459 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1460 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1461 printf("Data Set Management (DSM/TRIM) ");
1462 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1464 printf("DSM - max 512byte blocks ");
1465 if (parm->max_dsm_blocks == 0x00)
1466 printf("yes not specified\n");
1469 parm->max_dsm_blocks);
1471 printf("DSM - deterministic read ");
1472 if (parm->support3 & ATA_SUPPORT_DRAT) {
1473 if (parm->support3 & ATA_SUPPORT_RZAT)
1474 printf("yes zeroed\n");
1476 printf("yes any value\n");
1486 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1488 struct ata_pass_16 *ata_pass_16;
1489 struct ata_cmd ata_cmd;
1491 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1492 ata_cmd.command = ata_pass_16->command;
1493 ata_cmd.control = ata_pass_16->control;
1494 ata_cmd.features = ata_pass_16->features;
1496 if (arglist & CAM_ARG_VERBOSE) {
1497 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1498 ata_op_string(&ata_cmd),
1499 ccb->csio.ccb_h.timeout);
1502 /* Disable freezing the device queue */
1503 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1505 if (arglist & CAM_ARG_ERR_RECOVER)
1506 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1508 if (cam_send_ccb(device, ccb) < 0) {
1509 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1510 warn("error sending ATA %s via pass_16",
1511 ata_op_string(&ata_cmd));
1514 if (arglist & CAM_ARG_VERBOSE) {
1515 cam_error_print(device, ccb, CAM_ESF_ALL,
1516 CAM_EPF_ALL, stderr);
1522 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1523 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1524 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1525 warnx("ATA %s via pass_16 failed",
1526 ata_op_string(&ata_cmd));
1528 if (arglist & CAM_ARG_VERBOSE) {
1529 cam_error_print(device, ccb, CAM_ESF_ALL,
1530 CAM_EPF_ALL, stderr);
1541 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1543 if (arglist & CAM_ARG_VERBOSE) {
1544 warnx("sending ATA %s with timeout of %u msecs",
1545 ata_op_string(&(ccb->ataio.cmd)),
1546 ccb->ataio.ccb_h.timeout);
1549 /* Disable freezing the device queue */
1550 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1552 if (arglist & CAM_ARG_ERR_RECOVER)
1553 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1555 if (cam_send_ccb(device, ccb) < 0) {
1556 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1557 warn("error sending ATA %s",
1558 ata_op_string(&(ccb->ataio.cmd)));
1561 if (arglist & CAM_ARG_VERBOSE) {
1562 cam_error_print(device, ccb, CAM_ESF_ALL,
1563 CAM_EPF_ALL, stderr);
1569 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1570 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1571 warnx("ATA %s failed: %d",
1572 ata_op_string(&(ccb->ataio.cmd)), quiet);
1575 if (arglist & CAM_ARG_VERBOSE) {
1576 cam_error_print(device, ccb, CAM_ESF_ALL,
1577 CAM_EPF_ALL, stderr);
1587 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1588 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1589 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1590 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1591 u_int16_t dxfer_len, int timeout, int quiet)
1593 if (data_ptr != NULL) {
1594 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1595 AP_FLAG_TLEN_SECT_CNT;
1596 if (flags & CAM_DIR_OUT)
1597 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1599 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1601 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1604 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1606 scsi_ata_pass_16(&ccb->csio,
1620 /*sense_len*/SSD_FULL_SIZE,
1623 return scsi_cam_pass_16_send(device, ccb, quiet);
1627 ata_try_pass_16(struct cam_device *device)
1629 struct ccb_pathinq cpi;
1631 if (get_cpi(device, &cpi) != 0) {
1632 warnx("couldn't get CPI");
1636 if (cpi.protocol == PROTO_SCSI) {
1637 /* possibly compatible with pass_16 */
1641 /* likely not compatible with pass_16 */
1646 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1647 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1648 u_int8_t command, u_int8_t features, u_int32_t lba,
1649 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1650 int timeout, int quiet)
1654 switch (ata_try_pass_16(device)) {
1658 /* Try using SCSI Passthrough */
1659 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1660 0, tag_action, command, features, lba,
1661 sector_count, data_ptr, dxfer_len,
1665 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1666 cam_fill_ataio(&ccb->ataio,
1675 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1676 return ata_cam_send(device, ccb, quiet);
1680 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1681 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1682 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1683 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1684 u_int16_t dxfer_len, int timeout, int force48bit)
1688 retval = ata_try_pass_16(device);
1695 /* Try using SCSI Passthrough */
1696 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1697 ata_flags, tag_action, command, features,
1698 lba, sector_count, data_ptr, dxfer_len,
1701 if (ata_flags & AP_FLAG_CHK_COND) {
1702 /* Decode ata_res from sense data */
1703 struct ata_res_pass16 *res_pass16;
1704 struct ata_res *res;
1708 /* sense_data is 4 byte aligned */
1709 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1710 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1711 ptr[i] = le16toh(ptr[i]);
1713 /* sense_data is 4 byte aligned */
1714 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1715 &ccb->csio.sense_data;
1716 res = &ccb->ataio.res;
1717 res->flags = res_pass16->flags;
1718 res->status = res_pass16->status;
1719 res->error = res_pass16->error;
1720 res->lba_low = res_pass16->lba_low;
1721 res->lba_mid = res_pass16->lba_mid;
1722 res->lba_high = res_pass16->lba_high;
1723 res->device = res_pass16->device;
1724 res->lba_low_exp = res_pass16->lba_low_exp;
1725 res->lba_mid_exp = res_pass16->lba_mid_exp;
1726 res->lba_high_exp = res_pass16->lba_high_exp;
1727 res->sector_count = res_pass16->sector_count;
1728 res->sector_count_exp = res_pass16->sector_count_exp;
1734 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1735 cam_fill_ataio(&ccb->ataio,
1744 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1745 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1747 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1749 if (ata_flags & AP_FLAG_CHK_COND)
1750 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1752 return ata_cam_send(device, ccb, 0);
1756 dump_data(uint16_t *ptr, uint32_t len)
1760 for (i = 0; i < len / 2; i++) {
1762 printf(" %3d: ", i);
1763 printf("%04hx ", ptr[i]);
1772 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1773 int is48bit, u_int64_t *hpasize)
1775 struct ata_res *res;
1777 res = &ccb->ataio.res;
1778 if (res->status & ATA_STATUS_ERROR) {
1779 if (arglist & CAM_ARG_VERBOSE) {
1780 cam_error_print(device, ccb, CAM_ESF_ALL,
1781 CAM_EPF_ALL, stderr);
1782 printf("error = 0x%02x, sector_count = 0x%04x, "
1783 "device = 0x%02x, status = 0x%02x\n",
1784 res->error, res->sector_count,
1785 res->device, res->status);
1788 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1789 warnx("Max address has already been set since "
1790 "last power-on or hardware reset");
1796 if (arglist & CAM_ARG_VERBOSE) {
1797 fprintf(stdout, "%s%d: Raw native max data:\n",
1798 device->device_name, device->dev_unit_num);
1799 /* res is 4 byte aligned */
1800 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1802 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1803 "status = 0x%02x\n", res->error, res->sector_count,
1804 res->device, res->status);
1807 if (hpasize != NULL) {
1809 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1810 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1811 ((res->lba_high << 16) | (res->lba_mid << 8) |
1814 *hpasize = (((res->device & 0x0f) << 24) |
1815 (res->lba_high << 16) | (res->lba_mid << 8) |
1824 ata_read_native_max(struct cam_device *device, int retry_count,
1825 u_int32_t timeout, union ccb *ccb,
1826 struct ata_params *parm, u_int64_t *hpasize)
1832 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1833 protocol = AP_PROTO_NON_DATA;
1836 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1837 protocol |= AP_EXTEND;
1839 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1842 error = ata_do_cmd(device,
1845 /*flags*/CAM_DIR_NONE,
1846 /*protocol*/protocol,
1847 /*ata_flags*/AP_FLAG_CHK_COND,
1848 /*tag_action*/MSG_SIMPLE_Q_TAG,
1855 timeout ? timeout : 1000,
1861 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1865 atahpa_set_max(struct cam_device *device, int retry_count,
1866 u_int32_t timeout, union ccb *ccb,
1867 int is48bit, u_int64_t maxsize, int persist)
1873 protocol = AP_PROTO_NON_DATA;
1876 cmd = ATA_SET_MAX_ADDRESS48;
1877 protocol |= AP_EXTEND;
1879 cmd = ATA_SET_MAX_ADDRESS;
1882 /* lba's are zero indexed so the max lba is requested max - 1 */
1886 error = ata_do_cmd(device,
1889 /*flags*/CAM_DIR_NONE,
1890 /*protocol*/protocol,
1891 /*ata_flags*/AP_FLAG_CHK_COND,
1892 /*tag_action*/MSG_SIMPLE_Q_TAG,
1894 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1896 /*sector_count*/persist,
1899 timeout ? timeout : 1000,
1905 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1909 atahpa_password(struct cam_device *device, int retry_count,
1910 u_int32_t timeout, union ccb *ccb,
1911 int is48bit, struct ata_set_max_pwd *pwd)
1917 protocol = AP_PROTO_PIO_OUT;
1918 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1920 error = ata_do_cmd(device,
1923 /*flags*/CAM_DIR_OUT,
1924 /*protocol*/protocol,
1925 /*ata_flags*/AP_FLAG_CHK_COND,
1926 /*tag_action*/MSG_SIMPLE_Q_TAG,
1928 /*features*/ATA_HPA_FEAT_SET_PWD,
1931 /*data_ptr*/(u_int8_t*)pwd,
1932 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1933 timeout ? timeout : 1000,
1939 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1943 atahpa_lock(struct cam_device *device, int retry_count,
1944 u_int32_t timeout, union ccb *ccb, int is48bit)
1950 protocol = AP_PROTO_NON_DATA;
1951 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1953 error = ata_do_cmd(device,
1956 /*flags*/CAM_DIR_NONE,
1957 /*protocol*/protocol,
1958 /*ata_flags*/AP_FLAG_CHK_COND,
1959 /*tag_action*/MSG_SIMPLE_Q_TAG,
1961 /*features*/ATA_HPA_FEAT_LOCK,
1966 timeout ? timeout : 1000,
1972 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1976 atahpa_unlock(struct cam_device *device, int retry_count,
1977 u_int32_t timeout, union ccb *ccb,
1978 int is48bit, struct ata_set_max_pwd *pwd)
1984 protocol = AP_PROTO_PIO_OUT;
1985 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1987 error = ata_do_cmd(device,
1990 /*flags*/CAM_DIR_OUT,
1991 /*protocol*/protocol,
1992 /*ata_flags*/AP_FLAG_CHK_COND,
1993 /*tag_action*/MSG_SIMPLE_Q_TAG,
1995 /*features*/ATA_HPA_FEAT_UNLOCK,
1998 /*data_ptr*/(u_int8_t*)pwd,
1999 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2000 timeout ? timeout : 1000,
2006 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2010 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2011 u_int32_t timeout, union ccb *ccb, int is48bit)
2017 protocol = AP_PROTO_NON_DATA;
2018 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2020 error = ata_do_cmd(device,
2023 /*flags*/CAM_DIR_NONE,
2024 /*protocol*/protocol,
2025 /*ata_flags*/AP_FLAG_CHK_COND,
2026 /*tag_action*/MSG_SIMPLE_Q_TAG,
2028 /*features*/ATA_HPA_FEAT_FREEZE,
2033 timeout ? timeout : 1000,
2039 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2044 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2045 union ccb *ccb, struct ata_params** ident_bufp)
2047 struct ata_params *ident_buf;
2048 struct ccb_pathinq cpi;
2049 struct ccb_getdev cgd;
2052 u_int8_t command, retry_command;
2054 if (get_cpi(device, &cpi) != 0) {
2055 warnx("couldn't get CPI");
2059 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2060 if (cpi.protocol == PROTO_ATA) {
2061 if (get_cgd(device, &cgd) != 0) {
2062 warnx("couldn't get CGD");
2066 command = (cgd.protocol == PROTO_ATA) ?
2067 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2070 /* We don't know which for sure so try both */
2071 command = ATA_ATA_IDENTIFY;
2072 retry_command = ATA_ATAPI_IDENTIFY;
2075 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2077 warnx("can't calloc memory for identify\n");
2081 error = ata_do_28bit_cmd(device,
2083 /*retries*/retry_count,
2084 /*flags*/CAM_DIR_IN,
2085 /*protocol*/AP_PROTO_PIO_IN,
2086 /*tag_action*/MSG_SIMPLE_Q_TAG,
2090 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2091 /*data_ptr*/(u_int8_t *)ptr,
2092 /*dxfer_len*/sizeof(struct ata_params),
2093 /*timeout*/timeout ? timeout : 30 * 1000,
2097 if (retry_command == 0) {
2101 error = ata_do_28bit_cmd(device,
2103 /*retries*/retry_count,
2104 /*flags*/CAM_DIR_IN,
2105 /*protocol*/AP_PROTO_PIO_IN,
2106 /*tag_action*/MSG_SIMPLE_Q_TAG,
2107 /*command*/retry_command,
2110 /*sector_count*/(u_int8_t)
2111 sizeof(struct ata_params),
2112 /*data_ptr*/(u_int8_t *)ptr,
2113 /*dxfer_len*/sizeof(struct ata_params),
2114 /*timeout*/timeout ? timeout : 30 * 1000,
2124 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2125 ptr[i] = le16toh(ptr[i]);
2130 if (arglist & CAM_ARG_VERBOSE) {
2131 fprintf(stdout, "%s%d: Raw identify data:\n",
2132 device->device_name, device->dev_unit_num);
2133 dump_data(ptr, sizeof(struct ata_params));
2136 /* check for invalid (all zero) response */
2138 warnx("Invalid identify response detected");
2143 ident_buf = (struct ata_params *)ptr;
2144 if (strncmp(ident_buf->model, "FX", 2) &&
2145 strncmp(ident_buf->model, "NEC", 3) &&
2146 strncmp(ident_buf->model, "Pioneer", 7) &&
2147 strncmp(ident_buf->model, "SHARP", 5)) {
2148 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2149 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2150 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2151 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2153 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2154 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2155 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2156 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2157 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2158 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2159 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2160 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2161 sizeof(ident_buf->media_serial));
2163 *ident_bufp = ident_buf;
2170 ataidentify(struct cam_device *device, int retry_count, int timeout)
2173 struct ata_params *ident_buf;
2176 if ((ccb = cam_getccb(device)) == NULL) {
2177 warnx("couldn't allocate CCB");
2181 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2186 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2187 if (ata_read_native_max(device, retry_count, timeout, ccb,
2188 ident_buf, &hpasize) != 0) {
2196 printf("%s%d: ", device->device_name, device->dev_unit_num);
2197 ata_print_ident(ident_buf);
2198 camxferrate(device);
2199 atacapprint(ident_buf);
2200 atahpa_print(ident_buf, hpasize, 0);
2207 #endif /* MINIMALISTIC */
2210 #ifndef MINIMALISTIC
2212 ATA_SECURITY_ACTION_PRINT,
2213 ATA_SECURITY_ACTION_FREEZE,
2214 ATA_SECURITY_ACTION_UNLOCK,
2215 ATA_SECURITY_ACTION_DISABLE,
2216 ATA_SECURITY_ACTION_ERASE,
2217 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2218 ATA_SECURITY_ACTION_SET_PASSWORD
2222 atasecurity_print_time(u_int16_t tw)
2226 printf("unspecified");
2228 printf("> 508 min");
2230 printf("%i min", 2 * tw);
2234 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2238 return 2 * 3600 * 1000; /* default: two hours */
2239 else if (timeout > 255)
2240 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2242 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2247 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2251 bzero(&cmd, sizeof(cmd));
2252 cmd.command = command;
2253 printf("Issuing %s", ata_op_string(&cmd));
2256 char pass[sizeof(pwd->password)+1];
2258 /* pwd->password may not be null terminated */
2259 pass[sizeof(pwd->password)] = '\0';
2260 strncpy(pass, pwd->password, sizeof(pwd->password));
2261 printf(" password='%s', user='%s'",
2263 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2266 if (command == ATA_SECURITY_SET_PASSWORD) {
2267 printf(", mode='%s'",
2268 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2269 "maximum" : "high");
2277 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2278 int retry_count, u_int32_t timeout, int quiet)
2282 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2284 return ata_do_28bit_cmd(device,
2287 /*flags*/CAM_DIR_NONE,
2288 /*protocol*/AP_PROTO_NON_DATA,
2289 /*tag_action*/MSG_SIMPLE_Q_TAG,
2290 /*command*/ATA_SECURITY_FREEZE_LOCK,
2301 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2302 int retry_count, u_int32_t timeout,
2303 struct ata_security_password *pwd, int quiet)
2307 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2309 return ata_do_28bit_cmd(device,
2312 /*flags*/CAM_DIR_OUT,
2313 /*protocol*/AP_PROTO_PIO_OUT,
2314 /*tag_action*/MSG_SIMPLE_Q_TAG,
2315 /*command*/ATA_SECURITY_UNLOCK,
2319 /*data_ptr*/(u_int8_t *)pwd,
2320 /*dxfer_len*/sizeof(*pwd),
2326 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2327 int retry_count, u_int32_t timeout,
2328 struct ata_security_password *pwd, int quiet)
2332 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2333 return ata_do_28bit_cmd(device,
2336 /*flags*/CAM_DIR_OUT,
2337 /*protocol*/AP_PROTO_PIO_OUT,
2338 /*tag_action*/MSG_SIMPLE_Q_TAG,
2339 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2343 /*data_ptr*/(u_int8_t *)pwd,
2344 /*dxfer_len*/sizeof(*pwd),
2351 atasecurity_erase_confirm(struct cam_device *device,
2352 struct ata_params* ident_buf)
2355 printf("\nYou are about to ERASE ALL DATA from the following"
2356 " device:\n%s%d,%s%d: ", device->device_name,
2357 device->dev_unit_num, device->given_dev_name,
2358 device->given_unit_number);
2359 ata_print_ident(ident_buf);
2363 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2365 if (fgets(str, sizeof(str), stdin) != NULL) {
2366 if (strncasecmp(str, "yes", 3) == 0) {
2368 } else if (strncasecmp(str, "no", 2) == 0) {
2371 printf("Please answer \"yes\" or "
2382 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2383 int retry_count, u_int32_t timeout,
2384 u_int32_t erase_timeout,
2385 struct ata_security_password *pwd, int quiet)
2390 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2392 error = ata_do_28bit_cmd(device,
2395 /*flags*/CAM_DIR_NONE,
2396 /*protocol*/AP_PROTO_NON_DATA,
2397 /*tag_action*/MSG_SIMPLE_Q_TAG,
2398 /*command*/ATA_SECURITY_ERASE_PREPARE,
2411 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2413 error = ata_do_28bit_cmd(device,
2416 /*flags*/CAM_DIR_OUT,
2417 /*protocol*/AP_PROTO_PIO_OUT,
2418 /*tag_action*/MSG_SIMPLE_Q_TAG,
2419 /*command*/ATA_SECURITY_ERASE_UNIT,
2423 /*data_ptr*/(u_int8_t *)pwd,
2424 /*dxfer_len*/sizeof(*pwd),
2425 /*timeout*/erase_timeout,
2428 if (error == 0 && quiet == 0)
2429 printf("\nErase Complete\n");
2435 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2436 int retry_count, u_int32_t timeout,
2437 struct ata_security_password *pwd, int quiet)
2441 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2443 return ata_do_28bit_cmd(device,
2446 /*flags*/CAM_DIR_OUT,
2447 /*protocol*/AP_PROTO_PIO_OUT,
2448 /*tag_action*/MSG_SIMPLE_Q_TAG,
2449 /*command*/ATA_SECURITY_SET_PASSWORD,
2453 /*data_ptr*/(u_int8_t *)pwd,
2454 /*dxfer_len*/sizeof(*pwd),
2460 atasecurity_print(struct ata_params *parm)
2463 printf("\nSecurity Option Value\n");
2464 if (arglist & CAM_ARG_VERBOSE) {
2465 printf("status %04x\n",
2466 parm->security_status);
2468 printf("supported %s\n",
2469 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2470 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2472 printf("enabled %s\n",
2473 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2474 printf("drive locked %s\n",
2475 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2476 printf("security config frozen %s\n",
2477 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2478 printf("count expired %s\n",
2479 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2480 printf("security level %s\n",
2481 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2482 printf("enhanced erase supported %s\n",
2483 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2484 printf("erase time ");
2485 atasecurity_print_time(parm->erase_time);
2487 printf("enhanced erase time ");
2488 atasecurity_print_time(parm->enhanced_erase_time);
2490 printf("master password rev %04x%s\n",
2491 parm->master_passwd_revision,
2492 parm->master_passwd_revision == 0x0000 ||
2493 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2497 * Validates and copies the password in optarg to the passed buffer.
2498 * If the password in optarg is the same length as the buffer then
2499 * the data will still be copied but no null termination will occur.
2502 ata_getpwd(u_int8_t *passwd, int max, char opt)
2506 len = strlen(optarg);
2508 warnx("-%c password is too long", opt);
2510 } else if (len == 0) {
2511 warnx("-%c password is missing", opt);
2513 } else if (optarg[0] == '-'){
2514 warnx("-%c password starts with '-' (generic arg?)", opt);
2516 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2517 warnx("-%c password conflicts with existing password from -%c",
2522 /* Callers pass in a buffer which does NOT need to be terminated */
2523 strncpy(passwd, optarg, max);
2530 ATA_HPA_ACTION_PRINT,
2531 ATA_HPA_ACTION_SET_MAX,
2532 ATA_HPA_ACTION_SET_PWD,
2533 ATA_HPA_ACTION_LOCK,
2534 ATA_HPA_ACTION_UNLOCK,
2535 ATA_HPA_ACTION_FREEZE_LOCK
2539 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2540 u_int64_t maxsize, int persist)
2542 printf("\nYou are about to configure HPA to limit the user accessible\n"
2543 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2544 persist ? "persistently" : "temporarily",
2545 device->device_name, device->dev_unit_num,
2546 device->given_dev_name, device->given_unit_number);
2547 ata_print_ident(ident_buf);
2551 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2553 if (NULL != fgets(str, sizeof(str), stdin)) {
2554 if (0 == strncasecmp(str, "yes", 3)) {
2556 } else if (0 == strncasecmp(str, "no", 2)) {
2559 printf("Please answer \"yes\" or "
2570 atahpa(struct cam_device *device, int retry_count, int timeout,
2571 int argc, char **argv, char *combinedopt)
2574 struct ata_params *ident_buf;
2575 struct ccb_getdev cgd;
2576 struct ata_set_max_pwd pwd;
2577 int error, confirm, quiet, c, action, actions, persist;
2578 int security, is48bit, pwdsize;
2579 u_int64_t hpasize, maxsize;
2588 memset(&pwd, 0, sizeof(pwd));
2590 /* default action is to print hpa information */
2591 action = ATA_HPA_ACTION_PRINT;
2592 pwdsize = sizeof(pwd.password);
2594 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2597 action = ATA_HPA_ACTION_SET_MAX;
2598 maxsize = strtoumax(optarg, NULL, 0);
2603 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2605 action = ATA_HPA_ACTION_SET_PWD;
2611 action = ATA_HPA_ACTION_LOCK;
2617 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2619 action = ATA_HPA_ACTION_UNLOCK;
2625 action = ATA_HPA_ACTION_FREEZE_LOCK;
2645 warnx("too many hpa actions specified");
2649 if (get_cgd(device, &cgd) != 0) {
2650 warnx("couldn't get CGD");
2654 ccb = cam_getccb(device);
2656 warnx("couldn't allocate CCB");
2660 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2667 printf("%s%d: ", device->device_name, device->dev_unit_num);
2668 ata_print_ident(ident_buf);
2669 camxferrate(device);
2672 if (action == ATA_HPA_ACTION_PRINT) {
2673 error = ata_read_native_max(device, retry_count, timeout, ccb,
2674 ident_buf, &hpasize);
2676 atahpa_print(ident_buf, hpasize, 1);
2683 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2684 warnx("HPA is not supported by this device");
2690 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2691 warnx("HPA Security is not supported by this device");
2697 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2700 * The ATA spec requires:
2701 * 1. Read native max addr is called directly before set max addr
2702 * 2. Read native max addr is NOT called before any other set max call
2705 case ATA_HPA_ACTION_SET_MAX:
2707 atahpa_set_confirm(device, ident_buf, maxsize,
2714 error = ata_read_native_max(device, retry_count, timeout,
2715 ccb, ident_buf, &hpasize);
2717 error = atahpa_set_max(device, retry_count, timeout,
2718 ccb, is48bit, maxsize, persist);
2720 /* redo identify to get new lba values */
2721 error = ata_do_identify(device, retry_count,
2724 atahpa_print(ident_buf, hpasize, 1);
2729 case ATA_HPA_ACTION_SET_PWD:
2730 error = atahpa_password(device, retry_count, timeout,
2731 ccb, is48bit, &pwd);
2733 printf("HPA password has been set\n");
2736 case ATA_HPA_ACTION_LOCK:
2737 error = atahpa_lock(device, retry_count, timeout,
2740 printf("HPA has been locked\n");
2743 case ATA_HPA_ACTION_UNLOCK:
2744 error = atahpa_unlock(device, retry_count, timeout,
2745 ccb, is48bit, &pwd);
2747 printf("HPA has been unlocked\n");
2750 case ATA_HPA_ACTION_FREEZE_LOCK:
2751 error = atahpa_freeze_lock(device, retry_count, timeout,
2754 printf("HPA has been frozen\n");
2758 errx(1, "Option currently not supported");
2768 atasecurity(struct cam_device *device, int retry_count, int timeout,
2769 int argc, char **argv, char *combinedopt)
2772 struct ata_params *ident_buf;
2773 int error, confirm, quiet, c, action, actions, setpwd;
2774 int security_enabled, erase_timeout, pwdsize;
2775 struct ata_security_password pwd;
2783 memset(&pwd, 0, sizeof(pwd));
2785 /* default action is to print security information */
2786 action = ATA_SECURITY_ACTION_PRINT;
2788 /* user is master by default as its safer that way */
2789 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2790 pwdsize = sizeof(pwd.password);
2792 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2795 action = ATA_SECURITY_ACTION_FREEZE;
2800 if (strcasecmp(optarg, "user") == 0) {
2801 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2802 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2803 } else if (strcasecmp(optarg, "master") == 0) {
2804 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2805 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2807 warnx("-U argument '%s' is invalid (must be "
2808 "'user' or 'master')", optarg);
2814 if (strcasecmp(optarg, "high") == 0) {
2815 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2816 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2817 } else if (strcasecmp(optarg, "maximum") == 0) {
2818 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2819 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2821 warnx("-l argument '%s' is unknown (must be "
2822 "'high' or 'maximum')", optarg);
2828 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2830 action = ATA_SECURITY_ACTION_UNLOCK;
2835 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2837 action = ATA_SECURITY_ACTION_DISABLE;
2842 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2844 action = ATA_SECURITY_ACTION_ERASE;
2849 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2851 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2852 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2857 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2860 if (action == ATA_SECURITY_ACTION_PRINT)
2861 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2863 * Don't increment action as this can be combined
2864 * with other actions.
2877 erase_timeout = atoi(optarg) * 1000;
2883 warnx("too many security actions specified");
2887 if ((ccb = cam_getccb(device)) == NULL) {
2888 warnx("couldn't allocate CCB");
2892 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2899 printf("%s%d: ", device->device_name, device->dev_unit_num);
2900 ata_print_ident(ident_buf);
2901 camxferrate(device);
2904 if (action == ATA_SECURITY_ACTION_PRINT) {
2905 atasecurity_print(ident_buf);
2911 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2912 warnx("Security not supported");
2918 /* default timeout 15 seconds the same as linux hdparm */
2919 timeout = timeout ? timeout : 15 * 1000;
2921 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2923 /* first set the password if requested */
2925 /* confirm we can erase before setting the password if erasing */
2927 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2928 action == ATA_SECURITY_ACTION_ERASE) &&
2929 atasecurity_erase_confirm(device, ident_buf) == 0) {
2935 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2936 pwd.revision = ident_buf->master_passwd_revision;
2937 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2938 --pwd.revision == 0) {
2939 pwd.revision = 0xfffe;
2942 error = atasecurity_set_password(device, ccb, retry_count,
2943 timeout, &pwd, quiet);
2949 security_enabled = 1;
2953 case ATA_SECURITY_ACTION_FREEZE:
2954 error = atasecurity_freeze(device, ccb, retry_count,
2958 case ATA_SECURITY_ACTION_UNLOCK:
2959 if (security_enabled) {
2960 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2961 error = atasecurity_unlock(device, ccb,
2962 retry_count, timeout, &pwd, quiet);
2964 warnx("Can't unlock, drive is not locked");
2968 warnx("Can't unlock, security is disabled");
2973 case ATA_SECURITY_ACTION_DISABLE:
2974 if (security_enabled) {
2975 /* First unlock the drive if its locked */
2976 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2977 error = atasecurity_unlock(device, ccb,
2985 error = atasecurity_disable(device,
2993 warnx("Can't disable security (already disabled)");
2998 case ATA_SECURITY_ACTION_ERASE:
2999 if (security_enabled) {
3000 if (erase_timeout == 0) {
3001 erase_timeout = atasecurity_erase_timeout_msecs(
3002 ident_buf->erase_time);
3005 error = atasecurity_erase(device, ccb, retry_count,
3006 timeout, erase_timeout, &pwd,
3009 warnx("Can't secure erase (security is disabled)");
3014 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3015 if (security_enabled) {
3016 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3017 if (erase_timeout == 0) {
3019 atasecurity_erase_timeout_msecs(
3020 ident_buf->enhanced_erase_time);
3023 error = atasecurity_erase(device, ccb,
3024 retry_count, timeout,
3025 erase_timeout, &pwd,
3028 warnx("Enhanced erase is not supported");
3032 warnx("Can't secure erase (enhanced), "
3033 "(security is disabled)");
3044 #endif /* MINIMALISTIC */
3047 * Parse out a bus, or a bus, target and lun in the following
3053 * Returns the number of parsed components, or 0.
3056 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3057 cam_argmask *arglst)
3062 while (isspace(*tstr) && (*tstr != '\0'))
3065 tmpstr = (char *)strtok(tstr, ":");
3066 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3067 *bus = strtol(tmpstr, NULL, 0);
3068 *arglst |= CAM_ARG_BUS;
3070 tmpstr = (char *)strtok(NULL, ":");
3071 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3072 *target = strtol(tmpstr, NULL, 0);
3073 *arglst |= CAM_ARG_TARGET;
3075 tmpstr = (char *)strtok(NULL, ":");
3076 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3077 *lun = strtol(tmpstr, NULL, 0);
3078 *arglst |= CAM_ARG_LUN;
3088 dorescan_or_reset(int argc, char **argv, int rescan)
3090 static const char must[] =
3091 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3093 path_id_t bus = CAM_BUS_WILDCARD;
3094 target_id_t target = CAM_TARGET_WILDCARD;
3095 lun_id_t lun = CAM_LUN_WILDCARD;
3099 warnx(must, rescan? "rescan" : "reset");
3103 tstr = argv[optind];
3104 while (isspace(*tstr) && (*tstr != '\0'))
3106 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3107 arglist |= CAM_ARG_BUS;
3109 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3110 if (rv != 1 && rv != 3) {
3111 warnx(must, rescan? "rescan" : "reset");
3116 if ((arglist & CAM_ARG_BUS)
3117 && (arglist & CAM_ARG_TARGET)
3118 && (arglist & CAM_ARG_LUN))
3119 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3121 error = rescan_or_reset_bus(bus, rescan);
3127 rescan_or_reset_bus(path_id_t bus, int rescan)
3129 union ccb *ccb = NULL, *matchccb = NULL;
3130 int fd = -1, retval;
3135 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3136 warnx("error opening transport layer device %s", XPT_DEVICE);
3137 warn("%s", XPT_DEVICE);
3141 ccb = malloc(sizeof(*ccb));
3143 warn("failed to allocate CCB");
3147 bzero(ccb, sizeof(*ccb));
3149 if (bus != CAM_BUS_WILDCARD) {
3150 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3151 ccb->ccb_h.path_id = bus;
3152 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3153 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3154 ccb->crcn.flags = CAM_FLAG_NONE;
3156 /* run this at a low priority */
3157 ccb->ccb_h.pinfo.priority = 5;
3159 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3160 warn("CAMIOCOMMAND ioctl failed");
3165 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3166 fprintf(stdout, "%s of bus %d was successful\n",
3167 rescan ? "Re-scan" : "Reset", bus);
3169 fprintf(stdout, "%s of bus %d returned error %#x\n",
3170 rescan ? "Re-scan" : "Reset", bus,
3171 ccb->ccb_h.status & CAM_STATUS_MASK);
3180 * The right way to handle this is to modify the xpt so that it can
3181 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3182 * that isn't implemented, so instead we enumerate the busses and
3183 * send the rescan or reset to those busses in the case where the
3184 * given bus is -1 (wildcard). We don't send a rescan or reset
3185 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3186 * no-op, sending a rescan to the xpt bus would result in a status of
3189 matchccb = malloc(sizeof(*matchccb));
3190 if (matchccb == NULL) {
3191 warn("failed to allocate CCB");
3195 bzero(matchccb, sizeof(*matchccb));
3196 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3197 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3198 bufsize = sizeof(struct dev_match_result) * 20;
3199 matchccb->cdm.match_buf_len = bufsize;
3200 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3201 if (matchccb->cdm.matches == NULL) {
3202 warnx("can't malloc memory for matches");
3206 matchccb->cdm.num_matches = 0;
3208 matchccb->cdm.num_patterns = 1;
3209 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3211 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3212 matchccb->cdm.pattern_buf_len);
3213 if (matchccb->cdm.patterns == NULL) {
3214 warnx("can't malloc memory for patterns");
3218 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3219 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3224 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3225 warn("CAMIOCOMMAND ioctl failed");
3230 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3231 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3232 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3233 warnx("got CAM error %#x, CDM error %d\n",
3234 matchccb->ccb_h.status, matchccb->cdm.status);
3239 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3240 struct bus_match_result *bus_result;
3242 /* This shouldn't happen. */
3243 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3246 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3249 * We don't want to rescan or reset the xpt bus.
3252 if (bus_result->path_id == CAM_XPT_PATH_ID)
3255 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3257 ccb->ccb_h.path_id = bus_result->path_id;
3258 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3259 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3260 ccb->crcn.flags = CAM_FLAG_NONE;
3262 /* run this at a low priority */
3263 ccb->ccb_h.pinfo.priority = 5;
3265 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3266 warn("CAMIOCOMMAND ioctl failed");
3271 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3272 fprintf(stdout, "%s of bus %d was successful\n",
3273 rescan? "Re-scan" : "Reset",
3274 bus_result->path_id);
3277 * Don't bail out just yet, maybe the other
3278 * rescan or reset commands will complete
3281 fprintf(stderr, "%s of bus %d returned error "
3282 "%#x\n", rescan? "Re-scan" : "Reset",
3283 bus_result->path_id,
3284 ccb->ccb_h.status & CAM_STATUS_MASK);
3288 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3289 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3296 if (matchccb != NULL) {
3297 free(matchccb->cdm.patterns);
3298 free(matchccb->cdm.matches);
3307 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3310 struct cam_device *device;
3315 if (bus == CAM_BUS_WILDCARD) {
3316 warnx("invalid bus number %d", bus);
3320 if (target == CAM_TARGET_WILDCARD) {
3321 warnx("invalid target number %d", target);
3325 if (lun == CAM_LUN_WILDCARD) {
3326 warnx("invalid lun number %jx", (uintmax_t)lun);
3332 bzero(&ccb, sizeof(union ccb));
3335 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3336 warnx("error opening transport layer device %s\n",
3338 warn("%s", XPT_DEVICE);
3342 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3343 if (device == NULL) {
3344 warnx("%s", cam_errbuf);
3349 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3350 ccb.ccb_h.path_id = bus;
3351 ccb.ccb_h.target_id = target;
3352 ccb.ccb_h.target_lun = lun;
3353 ccb.ccb_h.timeout = 5000;
3354 ccb.crcn.flags = CAM_FLAG_NONE;
3356 /* run this at a low priority */
3357 ccb.ccb_h.pinfo.priority = 5;
3360 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3361 warn("CAMIOCOMMAND ioctl failed");
3366 if (cam_send_ccb(device, &ccb) < 0) {
3367 warn("error sending XPT_RESET_DEV CCB");
3368 cam_close_device(device);
3376 cam_close_device(device);
3379 * An error code of CAM_BDR_SENT is normal for a BDR request.
3381 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3383 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3384 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3385 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3388 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3389 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3390 ccb.ccb_h.status & CAM_STATUS_MASK);
3395 #ifndef MINIMALISTIC
3397 static struct scsi_nv defect_list_type_map[] = {
3398 { "block", SRDD10_BLOCK_FORMAT },
3399 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3400 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3401 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3402 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3403 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3407 readdefects(struct cam_device *device, int argc, char **argv,
3408 char *combinedopt, int retry_count, int timeout)
3410 union ccb *ccb = NULL;
3411 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3412 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3413 size_t hdr_size = 0, entry_size = 0;
3416 u_int8_t *defect_list = NULL;
3417 u_int8_t list_format = 0;
3418 int list_type_set = 0;
3419 u_int32_t dlist_length = 0;
3420 u_int32_t returned_length = 0, valid_len = 0;
3421 u_int32_t num_returned = 0, num_valid = 0;
3422 u_int32_t max_possible_size = 0, hdr_max = 0;
3423 u_int32_t starting_offset = 0;
3424 u_int8_t returned_format, returned_type;
3426 int summary = 0, quiet = 0;
3428 int lists_specified = 0;
3429 int get_length = 1, first_pass = 1;
3432 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3436 scsi_nv_status status;
3439 status = scsi_get_nv(defect_list_type_map,
3440 sizeof(defect_list_type_map) /
3441 sizeof(defect_list_type_map[0]), optarg,
3442 &entry_num, SCSI_NV_FLAG_IG_CASE);
3444 if (status == SCSI_NV_FOUND) {
3445 list_format = defect_list_type_map[
3449 warnx("%s: %s %s option %s", __func__,
3450 (status == SCSI_NV_AMBIGUOUS) ?
3451 "ambiguous" : "invalid", "defect list type",
3454 goto defect_bailout;
3459 arglist |= CAM_ARG_GLIST;
3462 arglist |= CAM_ARG_PLIST;
3473 starting_offset = strtoul(optarg, &endptr, 0);
3474 if (*endptr != '\0') {
3476 warnx("invalid starting offset %s", optarg);
3477 goto defect_bailout;
3489 if (list_type_set == 0) {
3491 warnx("no defect list format specified");
3492 goto defect_bailout;
3495 if (arglist & CAM_ARG_PLIST) {
3496 list_format |= SRDD10_PLIST;
3500 if (arglist & CAM_ARG_GLIST) {
3501 list_format |= SRDD10_GLIST;
3506 * This implies a summary, and was the previous behavior.
3508 if (lists_specified == 0)
3511 ccb = cam_getccb(device);
3516 * We start off asking for just the header to determine how much
3517 * defect data is available. Some Hitachi drives return an error
3518 * if you ask for more data than the drive has. Once we know the
3519 * length, we retry the command with the returned length.
3521 if (use_12byte == 0)
3522 dlist_length = sizeof(*hdr10);
3524 dlist_length = sizeof(*hdr12);
3527 if (defect_list != NULL) {
3531 defect_list = malloc(dlist_length);
3532 if (defect_list == NULL) {
3533 warnx("can't malloc memory for defect list");
3535 goto defect_bailout;
3539 bzero(defect_list, dlist_length);
3542 * cam_getccb() zeros the CCB header only. So we need to zero the
3543 * payload portion of the ccb.
3545 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3547 scsi_read_defects(&ccb->csio,
3548 /*retries*/ retry_count,
3550 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3551 /*list_format*/ list_format,
3552 /*addr_desc_index*/ starting_offset,
3553 /*data_ptr*/ defect_list,
3554 /*dxfer_len*/ dlist_length,
3555 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3556 /*sense_len*/ SSD_FULL_SIZE,
3557 /*timeout*/ timeout ? timeout : 5000);
3559 /* Disable freezing the device queue */
3560 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3562 if (cam_send_ccb(device, ccb) < 0) {
3563 perror("error reading defect list");
3565 if (arglist & CAM_ARG_VERBOSE) {
3566 cam_error_print(device, ccb, CAM_ESF_ALL,
3567 CAM_EPF_ALL, stderr);
3571 goto defect_bailout;
3574 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3576 if (use_12byte == 0) {
3577 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3578 hdr_size = sizeof(*hdr10);
3579 hdr_max = SRDDH10_MAX_LENGTH;
3581 if (valid_len >= hdr_size) {
3582 returned_length = scsi_2btoul(hdr10->length);
3583 returned_format = hdr10->format;
3585 returned_length = 0;
3586 returned_format = 0;
3589 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3590 hdr_size = sizeof(*hdr12);
3591 hdr_max = SRDDH12_MAX_LENGTH;
3593 if (valid_len >= hdr_size) {
3594 returned_length = scsi_4btoul(hdr12->length);
3595 returned_format = hdr12->format;
3597 returned_length = 0;
3598 returned_format = 0;
3602 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3603 switch (returned_type) {
3604 case SRDD10_BLOCK_FORMAT:
3605 entry_size = sizeof(struct scsi_defect_desc_block);
3607 case SRDD10_LONG_BLOCK_FORMAT:
3608 entry_size = sizeof(struct scsi_defect_desc_long_block);
3610 case SRDD10_EXT_PHYS_FORMAT:
3611 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3612 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3614 case SRDD10_EXT_BFI_FORMAT:
3615 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3616 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3619 warnx("Unknown defect format 0x%x\n", returned_type);
3621 goto defect_bailout;
3625 max_possible_size = (hdr_max / entry_size) * entry_size;
3626 num_returned = returned_length / entry_size;
3627 num_valid = min(returned_length, valid_len - hdr_size);
3628 num_valid /= entry_size;
3630 if (get_length != 0) {
3633 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3634 CAM_SCSI_STATUS_ERROR) {
3635 struct scsi_sense_data *sense;
3636 int error_code, sense_key, asc, ascq;
3638 sense = &ccb->csio.sense_data;
3639 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3640 ccb->csio.sense_resid, &error_code, &sense_key,
3641 &asc, &ascq, /*show_errors*/ 1);
3644 * If the drive is reporting that it just doesn't
3645 * support the defect list format, go ahead and use
3646 * the length it reported. Otherwise, the length
3647 * may not be valid, so use the maximum.
3649 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3650 && (asc == 0x1c) && (ascq == 0x00)
3651 && (returned_length > 0)) {
3652 if ((use_12byte == 0)
3653 && (returned_length >= max_possible_size)) {
3658 dlist_length = returned_length + hdr_size;
3659 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3660 && (asc == 0x1f) && (ascq == 0x00)
3661 && (returned_length > 0)) {
3662 /* Partial defect list transfer */
3664 * Hitachi drives return this error
3665 * along with a partial defect list if they
3666 * have more defects than the 10 byte
3667 * command can support. Retry with the 12
3670 if (use_12byte == 0) {
3675 dlist_length = returned_length + hdr_size;
3676 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3677 && (asc == 0x24) && (ascq == 0x00)) {
3678 /* Invalid field in CDB */
3680 * SBC-3 says that if the drive has more
3681 * defects than can be reported with the
3682 * 10 byte command, it should return this
3683 * error and no data. Retry with the 12
3686 if (use_12byte == 0) {
3691 dlist_length = returned_length + hdr_size;
3694 * If we got a SCSI error and no valid length,
3695 * just use the 10 byte maximum. The 12
3696 * byte maximum is too large.
3698 if (returned_length == 0)
3699 dlist_length = SRDD10_MAX_LENGTH;
3701 if ((use_12byte == 0)
3702 && (returned_length >=
3703 max_possible_size)) {
3708 dlist_length = returned_length +
3712 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3715 warnx("Error reading defect header");
3716 if (arglist & CAM_ARG_VERBOSE)
3717 cam_error_print(device, ccb, CAM_ESF_ALL,
3718 CAM_EPF_ALL, stderr);
3719 goto defect_bailout;
3721 if ((use_12byte == 0)
3722 && (returned_length >= max_possible_size)) {
3727 dlist_length = returned_length + hdr_size;
3730 fprintf(stdout, "%u", num_returned);
3732 fprintf(stdout, " defect%s",
3733 (num_returned != 1) ? "s" : "");
3735 fprintf(stdout, "\n");
3737 goto defect_bailout;
3741 * We always limit the list length to the 10-byte maximum
3742 * length (0xffff). The reason is that some controllers
3743 * can't handle larger I/Os, and we can transfer the entire
3744 * 10 byte list in one shot. For drives that support the 12
3745 * byte read defects command, we'll step through the list
3746 * by specifying a starting offset. For drives that don't
3747 * support the 12 byte command's starting offset, we'll
3748 * just display the first 64K.
3750 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3756 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3757 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3758 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3759 struct scsi_sense_data *sense;
3760 int error_code, sense_key, asc, ascq;
3762 sense = &ccb->csio.sense_data;
3763 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3764 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3765 &ascq, /*show_errors*/ 1);
3768 * According to the SCSI spec, if the disk doesn't support
3769 * the requested format, it will generally return a sense
3770 * key of RECOVERED ERROR, and an additional sense code
3771 * of "DEFECT LIST NOT FOUND". HGST drives also return
3772 * Primary/Grown defect list not found errors. So just
3773 * check for an ASC of 0x1c.
3775 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3777 const char *format_str;
3779 format_str = scsi_nv_to_str(defect_list_type_map,
3780 sizeof(defect_list_type_map) /
3781 sizeof(defect_list_type_map[0]),
3782 list_format & SRDD10_DLIST_FORMAT_MASK);
3783 warnx("requested defect format %s not available",
3784 format_str ? format_str : "unknown");
3786 format_str = scsi_nv_to_str(defect_list_type_map,
3787 sizeof(defect_list_type_map) /
3788 sizeof(defect_list_type_map[0]), returned_type);
3789 if (format_str != NULL) {
3790 warnx("Device returned %s format",
3794 warnx("Device returned unknown defect"
3795 " data format %#x", returned_type);
3796 goto defect_bailout;
3800 warnx("Error returned from read defect data command");
3801 if (arglist & CAM_ARG_VERBOSE)
3802 cam_error_print(device, ccb, CAM_ESF_ALL,
3803 CAM_EPF_ALL, stderr);
3804 goto defect_bailout;
3806 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3808 warnx("Error returned from read defect data command");
3809 if (arglist & CAM_ARG_VERBOSE)
3810 cam_error_print(device, ccb, CAM_ESF_ALL,
3811 CAM_EPF_ALL, stderr);
3812 goto defect_bailout;
3815 if (first_pass != 0) {
3816 fprintf(stderr, "Got %d defect", num_returned);
3818 if ((lists_specified == 0) || (num_returned == 0)) {
3819 fprintf(stderr, "s.\n");
3820 goto defect_bailout;
3821 } else if (num_returned == 1)
3822 fprintf(stderr, ":\n");
3824 fprintf(stderr, "s:\n");
3830 * XXX KDM I should probably clean up the printout format for the
3833 switch (returned_type) {
3834 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3835 case SRDD10_EXT_PHYS_FORMAT:
3837 struct scsi_defect_desc_phys_sector *dlist;
3839 dlist = (struct scsi_defect_desc_phys_sector *)
3840 (defect_list + hdr_size);
3842 for (i = 0; i < num_valid; i++) {
3845 sector = scsi_4btoul(dlist[i].sector);
3846 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3847 mads = (sector & SDD_EXT_PHYS_MADS) ?
3849 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3851 if (hex_format == 0)
3852 fprintf(stdout, "%d:%d:%d%s",
3853 scsi_3btoul(dlist[i].cylinder),
3855 scsi_4btoul(dlist[i].sector),
3856 mads ? " - " : "\n");
3858 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3859 scsi_3btoul(dlist[i].cylinder),
3861 scsi_4btoul(dlist[i].sector),
3862 mads ? " - " : "\n");
3865 if (num_valid < num_returned) {
3866 starting_offset += num_valid;
3871 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3872 case SRDD10_EXT_BFI_FORMAT:
3874 struct scsi_defect_desc_bytes_from_index *dlist;
3876 dlist = (struct scsi_defect_desc_bytes_from_index *)
3877 (defect_list + hdr_size);
3879 for (i = 0; i < num_valid; i++) {
3882 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3883 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3884 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3885 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3887 if (hex_format == 0)
3888 fprintf(stdout, "%d:%d:%d%s",
3889 scsi_3btoul(dlist[i].cylinder),
3891 scsi_4btoul(dlist[i].bytes_from_index),
3892 mads ? " - " : "\n");
3894 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3895 scsi_3btoul(dlist[i].cylinder),
3897 scsi_4btoul(dlist[i].bytes_from_index),
3898 mads ? " - " : "\n");
3902 if (num_valid < num_returned) {
3903 starting_offset += num_valid;
3908 case SRDDH10_BLOCK_FORMAT:
3910 struct scsi_defect_desc_block *dlist;
3912 dlist = (struct scsi_defect_desc_block *)
3913 (defect_list + hdr_size);
3915 for (i = 0; i < num_valid; i++) {
3916 if (hex_format == 0)
3917 fprintf(stdout, "%u\n",
3918 scsi_4btoul(dlist[i].address));
3920 fprintf(stdout, "0x%x\n",
3921 scsi_4btoul(dlist[i].address));
3924 if (num_valid < num_returned) {
3925 starting_offset += num_valid;
3931 case SRDD10_LONG_BLOCK_FORMAT:
3933 struct scsi_defect_desc_long_block *dlist;
3935 dlist = (struct scsi_defect_desc_long_block *)
3936 (defect_list + hdr_size);
3938 for (i = 0; i < num_valid; i++) {
3939 if (hex_format == 0)
3940 fprintf(stdout, "%ju\n",
3941 (uintmax_t)scsi_8btou64(
3944 fprintf(stdout, "0x%jx\n",
3945 (uintmax_t)scsi_8btou64(
3949 if (num_valid < num_returned) {
3950 starting_offset += num_valid;
3956 fprintf(stderr, "Unknown defect format 0x%x\n",
3963 if (defect_list != NULL)
3971 #endif /* MINIMALISTIC */
3975 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3979 ccb = cam_getccb(device);
3985 #ifndef MINIMALISTIC
3987 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
3988 int retry_count, int timeout, u_int8_t *data, int datalen)
3993 ccb = cam_getccb(device);
3996 errx(1, "mode_sense: couldn't allocate CCB");
3998 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4000 scsi_mode_sense_subpage(&ccb->csio,
4001 /* retries */ retry_count,
4003 /* tag_action */ MSG_SIMPLE_Q_TAG,
4007 /* subpage */ subpage,
4008 /* param_buf */ data,
4009 /* param_len */ datalen,
4010 /* minimum_cmd_size */ 0,
4011 /* sense_len */ SSD_FULL_SIZE,
4012 /* timeout */ timeout ? timeout : 5000);
4014 if (arglist & CAM_ARG_ERR_RECOVER)
4015 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4017 /* Disable freezing the device queue */
4018 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4020 if (((retval = cam_send_ccb(device, ccb)) < 0)
4021 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4022 if (arglist & CAM_ARG_VERBOSE) {
4023 cam_error_print(device, ccb, CAM_ESF_ALL,
4024 CAM_EPF_ALL, stderr);
4027 cam_close_device(device);
4029 err(1, "error sending mode sense command");
4031 errx(1, "error sending mode sense command");
4038 mode_select(struct cam_device *device, int save_pages, int retry_count,
4039 int timeout, u_int8_t *data, int datalen)
4044 ccb = cam_getccb(device);
4047 errx(1, "mode_select: couldn't allocate CCB");
4049 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4051 scsi_mode_select(&ccb->csio,
4052 /* retries */ retry_count,
4054 /* tag_action */ MSG_SIMPLE_Q_TAG,
4055 /* scsi_page_fmt */ 1,
4056 /* save_pages */ save_pages,
4057 /* param_buf */ data,
4058 /* param_len */ datalen,
4059 /* sense_len */ SSD_FULL_SIZE,
4060 /* timeout */ timeout ? timeout : 5000);
4062 if (arglist & CAM_ARG_ERR_RECOVER)
4063 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4065 /* Disable freezing the device queue */
4066 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4068 if (((retval = cam_send_ccb(device, ccb)) < 0)
4069 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4070 if (arglist & CAM_ARG_VERBOSE) {
4071 cam_error_print(device, ccb, CAM_ESF_ALL,
4072 CAM_EPF_ALL, stderr);
4075 cam_close_device(device);
4078 err(1, "error sending mode select command");
4080 errx(1, "error sending mode select command");
4088 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4089 int retry_count, int timeout)
4092 int c, page = -1, subpage = -1, pc = 0;
4093 int binary = 0, dbd = 0, edit = 0, list = 0;
4095 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4110 str_subpage = optarg;
4111 strsep(&str_subpage, ",");
4112 page = strtol(optarg, NULL, 0);
4114 subpage = strtol(str_subpage, NULL, 0);
4118 errx(1, "invalid mode page %d", page);
4120 errx(1, "invalid mode subpage %d", subpage);
4123 pc = strtol(optarg, NULL, 0);
4124 if ((pc < 0) || (pc > 3))
4125 errx(1, "invalid page control field %d", pc);
4132 if (page == -1 && list == 0)
4133 errx(1, "you must specify a mode page!");
4136 mode_list(device, dbd, pc, list > 1, retry_count, timeout);
4138 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4139 retry_count, timeout);
4144 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4145 int retry_count, int timeout)
4148 u_int32_t flags = CAM_DIR_NONE;
4149 u_int8_t *data_ptr = NULL;
4151 u_int8_t atacmd[12];
4152 struct get_hook hook;
4153 int c, data_bytes = 0;
4159 char *datastr = NULL, *tstr, *resstr = NULL;
4161 int fd_data = 0, fd_res = 0;
4164 ccb = cam_getccb(device);
4167 warnx("scsicmd: error allocating ccb");
4171 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4173 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4177 while (isspace(*tstr) && (*tstr != '\0'))
4179 hook.argc = argc - optind;
4180 hook.argv = argv + optind;
4182 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4185 * Increment optind by the number of arguments the
4186 * encoding routine processed. After each call to
4187 * getopt(3), optind points to the argument that
4188 * getopt should process _next_. In this case,
4189 * that means it points to the first command string
4190 * argument, if there is one. Once we increment
4191 * this, it should point to either the next command
4192 * line argument, or it should be past the end of
4199 while (isspace(*tstr) && (*tstr != '\0'))
4201 hook.argc = argc - optind;
4202 hook.argv = argv + optind;
4204 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4207 * Increment optind by the number of arguments the
4208 * encoding routine processed. After each call to
4209 * getopt(3), optind points to the argument that
4210 * getopt should process _next_. In this case,
4211 * that means it points to the first command string
4212 * argument, if there is one. Once we increment
4213 * this, it should point to either the next command
4214 * line argument, or it should be past the end of
4226 if (arglist & CAM_ARG_CMD_OUT) {
4227 warnx("command must either be "
4228 "read or write, not both");
4230 goto scsicmd_bailout;
4232 arglist |= CAM_ARG_CMD_IN;
4234 data_bytes = strtol(optarg, NULL, 0);
4235 if (data_bytes <= 0) {
4236 warnx("invalid number of input bytes %d",
4239 goto scsicmd_bailout;
4241 hook.argc = argc - optind;
4242 hook.argv = argv + optind;
4245 datastr = cget(&hook, NULL);
4247 * If the user supplied "-" instead of a format, he
4248 * wants the data to be written to stdout.
4250 if ((datastr != NULL)
4251 && (datastr[0] == '-'))
4254 data_ptr = (u_int8_t *)malloc(data_bytes);
4255 if (data_ptr == NULL) {
4256 warnx("can't malloc memory for data_ptr");
4258 goto scsicmd_bailout;
4262 if (arglist & CAM_ARG_CMD_IN) {
4263 warnx("command must either be "
4264 "read or write, not both");
4266 goto scsicmd_bailout;
4268 arglist |= CAM_ARG_CMD_OUT;
4269 flags = CAM_DIR_OUT;
4270 data_bytes = strtol(optarg, NULL, 0);
4271 if (data_bytes <= 0) {
4272 warnx("invalid number of output bytes %d",
4275 goto scsicmd_bailout;
4277 hook.argc = argc - optind;
4278 hook.argv = argv + optind;
4280 datastr = cget(&hook, NULL);
4281 data_ptr = (u_int8_t *)malloc(data_bytes);
4282 if (data_ptr == NULL) {
4283 warnx("can't malloc memory for data_ptr");
4285 goto scsicmd_bailout;
4287 bzero(data_ptr, data_bytes);
4289 * If the user supplied "-" instead of a format, he
4290 * wants the data to be read from stdin.
4292 if ((datastr != NULL)
4293 && (datastr[0] == '-'))
4296 buff_encode_visit(data_ptr, data_bytes, datastr,
4302 hook.argc = argc - optind;
4303 hook.argv = argv + optind;
4305 resstr = cget(&hook, NULL);
4306 if ((resstr != NULL) && (resstr[0] == '-'))
4316 * If fd_data is set, and we're writing to the device, we need to
4317 * read the data the user wants written from stdin.
4319 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4321 int amt_to_read = data_bytes;
4322 u_int8_t *buf_ptr = data_ptr;
4324 for (amt_read = 0; amt_to_read > 0;
4325 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4326 if (amt_read == -1) {
4327 warn("error reading data from stdin");
4329 goto scsicmd_bailout;
4331 amt_to_read -= amt_read;
4332 buf_ptr += amt_read;
4336 if (arglist & CAM_ARG_ERR_RECOVER)
4337 flags |= CAM_PASS_ERR_RECOVER;
4339 /* Disable freezing the device queue */
4340 flags |= CAM_DEV_QFRZDIS;
4344 * This is taken from the SCSI-3 draft spec.
4345 * (T10/1157D revision 0.3)
4346 * The top 3 bits of an opcode are the group code.
4347 * The next 5 bits are the command code.
4348 * Group 0: six byte commands
4349 * Group 1: ten byte commands
4350 * Group 2: ten byte commands
4352 * Group 4: sixteen byte commands
4353 * Group 5: twelve byte commands
4354 * Group 6: vendor specific
4355 * Group 7: vendor specific
4357 switch((cdb[0] >> 5) & 0x7) {
4368 /* computed by buff_encode_visit */
4379 * We should probably use csio_build_visit or something like that
4380 * here, but it's easier to encode arguments as you go. The
4381 * alternative would be skipping the CDB argument and then encoding
4382 * it here, since we've got the data buffer argument by now.
4384 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4386 cam_fill_csio(&ccb->csio,
4387 /*retries*/ retry_count,
4390 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4391 /*data_ptr*/ data_ptr,
4392 /*dxfer_len*/ data_bytes,
4393 /*sense_len*/ SSD_FULL_SIZE,
4394 /*cdb_len*/ cdb_len,
4395 /*timeout*/ timeout ? timeout : 5000);
4398 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4400 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4402 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4404 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4406 cam_fill_ataio(&ccb->ataio,
4407 /*retries*/ retry_count,
4411 /*data_ptr*/ data_ptr,
4412 /*dxfer_len*/ data_bytes,
4413 /*timeout*/ timeout ? timeout : 5000);
4416 if (((retval = cam_send_ccb(device, ccb)) < 0)
4417 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4418 const char warnstr[] = "error sending command";
4425 if (arglist & CAM_ARG_VERBOSE) {
4426 cam_error_print(device, ccb, CAM_ESF_ALL,
4427 CAM_EPF_ALL, stderr);
4431 goto scsicmd_bailout;
4434 if (atacmd_len && need_res) {
4436 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4438 fprintf(stdout, "\n");
4441 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4442 ccb->ataio.res.status,
4443 ccb->ataio.res.error,
4444 ccb->ataio.res.lba_low,
4445 ccb->ataio.res.lba_mid,
4446 ccb->ataio.res.lba_high,
4447 ccb->ataio.res.device,
4448 ccb->ataio.res.lba_low_exp,
4449 ccb->ataio.res.lba_mid_exp,
4450 ccb->ataio.res.lba_high_exp,
4451 ccb->ataio.res.sector_count,
4452 ccb->ataio.res.sector_count_exp);
4457 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4458 && (arglist & CAM_ARG_CMD_IN)
4459 && (data_bytes > 0)) {
4461 buff_decode_visit(data_ptr, data_bytes, datastr,
4463 fprintf(stdout, "\n");
4465 ssize_t amt_written;
4466 int amt_to_write = data_bytes;
4467 u_int8_t *buf_ptr = data_ptr;
4469 for (amt_written = 0; (amt_to_write > 0) &&
4470 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4471 amt_to_write -= amt_written;
4472 buf_ptr += amt_written;
4474 if (amt_written == -1) {
4475 warn("error writing data to stdout");
4477 goto scsicmd_bailout;
4478 } else if ((amt_written == 0)
4479 && (amt_to_write > 0)) {
4480 warnx("only wrote %u bytes out of %u",
4481 data_bytes - amt_to_write, data_bytes);
4488 if ((data_bytes > 0) && (data_ptr != NULL))
4497 camdebug(int argc, char **argv, char *combinedopt)
4500 path_id_t bus = CAM_BUS_WILDCARD;
4501 target_id_t target = CAM_TARGET_WILDCARD;
4502 lun_id_t lun = CAM_LUN_WILDCARD;
4503 char *tstr, *tmpstr = NULL;
4507 bzero(&ccb, sizeof(union ccb));
4509 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4512 arglist |= CAM_ARG_DEBUG_INFO;
4513 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4516 arglist |= CAM_ARG_DEBUG_PERIPH;
4517 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4520 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4521 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4524 arglist |= CAM_ARG_DEBUG_TRACE;
4525 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4528 arglist |= CAM_ARG_DEBUG_XPT;
4529 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4532 arglist |= CAM_ARG_DEBUG_CDB;
4533 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4536 arglist |= CAM_ARG_DEBUG_PROBE;
4537 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4544 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4545 warnx("error opening transport layer device %s", XPT_DEVICE);
4546 warn("%s", XPT_DEVICE);
4553 warnx("you must specify \"off\", \"all\" or a bus,");
4554 warnx("bus:target, or bus:target:lun");
4561 while (isspace(*tstr) && (*tstr != '\0'))
4564 if (strncmp(tstr, "off", 3) == 0) {
4565 ccb.cdbg.flags = CAM_DEBUG_NONE;
4566 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4567 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4568 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4569 } else if (strncmp(tstr, "all", 3) != 0) {
4570 tmpstr = (char *)strtok(tstr, ":");
4571 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4572 bus = strtol(tmpstr, NULL, 0);
4573 arglist |= CAM_ARG_BUS;
4574 tmpstr = (char *)strtok(NULL, ":");
4575 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4576 target = strtol(tmpstr, NULL, 0);
4577 arglist |= CAM_ARG_TARGET;
4578 tmpstr = (char *)strtok(NULL, ":");
4579 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4580 lun = strtol(tmpstr, NULL, 0);
4581 arglist |= CAM_ARG_LUN;
4586 warnx("you must specify \"all\", \"off\", or a bus,");
4587 warnx("bus:target, or bus:target:lun to debug");
4593 ccb.ccb_h.func_code = XPT_DEBUG;
4594 ccb.ccb_h.path_id = bus;
4595 ccb.ccb_h.target_id = target;
4596 ccb.ccb_h.target_lun = lun;
4598 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4599 warn("CAMIOCOMMAND ioctl failed");
4604 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4605 CAM_FUNC_NOTAVAIL) {
4606 warnx("CAM debugging not available");
4607 warnx("you need to put options CAMDEBUG in"
4608 " your kernel config file!");
4610 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4612 warnx("XPT_DEBUG CCB failed with status %#x",
4616 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4618 "Debugging turned off\n");
4621 "Debugging enabled for "
4623 bus, target, (uintmax_t)lun);
4634 tagcontrol(struct cam_device *device, int argc, char **argv,
4644 ccb = cam_getccb(device);
4647 warnx("tagcontrol: error allocating ccb");
4651 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4654 numtags = strtol(optarg, NULL, 0);
4656 warnx("tag count %d is < 0", numtags);
4658 goto tagcontrol_bailout;
4669 cam_path_string(device, pathstr, sizeof(pathstr));
4672 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4673 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4674 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4675 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4676 ccb->crs.openings = numtags;
4679 if (cam_send_ccb(device, ccb) < 0) {
4680 perror("error sending XPT_REL_SIMQ CCB");
4682 goto tagcontrol_bailout;
4685 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4686 warnx("XPT_REL_SIMQ CCB failed");
4687 cam_error_print(device, ccb, CAM_ESF_ALL,
4688 CAM_EPF_ALL, stderr);
4690 goto tagcontrol_bailout;
4695 fprintf(stdout, "%stagged openings now %d\n",
4696 pathstr, ccb->crs.openings);
4699 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4701 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4703 if (cam_send_ccb(device, ccb) < 0) {
4704 perror("error sending XPT_GDEV_STATS CCB");
4706 goto tagcontrol_bailout;
4709 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4710 warnx("XPT_GDEV_STATS CCB failed");
4711 cam_error_print(device, ccb, CAM_ESF_ALL,
4712 CAM_EPF_ALL, stderr);
4714 goto tagcontrol_bailout;
4717 if (arglist & CAM_ARG_VERBOSE) {
4718 fprintf(stdout, "%s", pathstr);
4719 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4720 fprintf(stdout, "%s", pathstr);
4721 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4722 fprintf(stdout, "%s", pathstr);
4723 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4724 fprintf(stdout, "%s", pathstr);
4725 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4726 fprintf(stdout, "%s", pathstr);
4727 fprintf(stdout, "held %d\n", ccb->cgds.held);
4728 fprintf(stdout, "%s", pathstr);
4729 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4730 fprintf(stdout, "%s", pathstr);
4731 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4734 fprintf(stdout, "%s", pathstr);
4735 fprintf(stdout, "device openings: ");
4737 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4738 ccb->cgds.dev_active);
4748 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4752 cam_path_string(device, pathstr, sizeof(pathstr));
4754 if (cts->transport == XPORT_SPI) {
4755 struct ccb_trans_settings_spi *spi =
4756 &cts->xport_specific.spi;
4758 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4760 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4763 if (spi->sync_offset != 0) {
4766 freq = scsi_calc_syncsrate(spi->sync_period);
4767 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4768 pathstr, freq / 1000, freq % 1000);
4772 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4773 fprintf(stdout, "%soffset: %d\n", pathstr,
4777 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4778 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4779 (0x01 << spi->bus_width) * 8);
4782 if (spi->valid & CTS_SPI_VALID_DISC) {
4783 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4784 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4785 "enabled" : "disabled");
4788 if (cts->transport == XPORT_FC) {
4789 struct ccb_trans_settings_fc *fc =
4790 &cts->xport_specific.fc;
4792 if (fc->valid & CTS_FC_VALID_WWNN)
4793 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4794 (long long) fc->wwnn);
4795 if (fc->valid & CTS_FC_VALID_WWPN)
4796 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4797 (long long) fc->wwpn);
4798 if (fc->valid & CTS_FC_VALID_PORT)
4799 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4800 if (fc->valid & CTS_FC_VALID_SPEED)
4801 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4802 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4804 if (cts->transport == XPORT_SAS) {
4805 struct ccb_trans_settings_sas *sas =
4806 &cts->xport_specific.sas;
4808 if (sas->valid & CTS_SAS_VALID_SPEED)
4809 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4810 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4812 if (cts->transport == XPORT_ATA) {
4813 struct ccb_trans_settings_pata *pata =
4814 &cts->xport_specific.ata;
4816 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4817 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4818 ata_mode2string(pata->mode));
4820 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4821 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4824 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4825 fprintf(stdout, "%sPIO transaction length: %d\n",
4826 pathstr, pata->bytecount);
4829 if (cts->transport == XPORT_SATA) {
4830 struct ccb_trans_settings_sata *sata =
4831 &cts->xport_specific.sata;
4833 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4834 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4837 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4838 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4839 ata_mode2string(sata->mode));
4841 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4842 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4845 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4846 fprintf(stdout, "%sPIO transaction length: %d\n",
4847 pathstr, sata->bytecount);
4849 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4850 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4853 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4854 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4857 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4858 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4862 if (cts->protocol == PROTO_ATA) {
4863 struct ccb_trans_settings_ata *ata=
4864 &cts->proto_specific.ata;
4866 if (ata->valid & CTS_ATA_VALID_TQ) {
4867 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4868 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4869 "enabled" : "disabled");
4872 if (cts->protocol == PROTO_SCSI) {
4873 struct ccb_trans_settings_scsi *scsi=
4874 &cts->proto_specific.scsi;
4876 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4877 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4878 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4879 "enabled" : "disabled");
4886 * Get a path inquiry CCB for the specified device.
4889 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4894 ccb = cam_getccb(device);
4896 warnx("get_cpi: couldn't allocate CCB");
4899 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
4900 ccb->ccb_h.func_code = XPT_PATH_INQ;
4901 if (cam_send_ccb(device, ccb) < 0) {
4902 warn("get_cpi: error sending Path Inquiry CCB");
4903 if (arglist & CAM_ARG_VERBOSE)
4904 cam_error_print(device, ccb, CAM_ESF_ALL,
4905 CAM_EPF_ALL, stderr);
4907 goto get_cpi_bailout;
4909 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4910 if (arglist & CAM_ARG_VERBOSE)
4911 cam_error_print(device, ccb, CAM_ESF_ALL,
4912 CAM_EPF_ALL, stderr);
4914 goto get_cpi_bailout;
4916 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4924 * Get a get device CCB for the specified device.
4927 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4932 ccb = cam_getccb(device);
4934 warnx("get_cgd: couldn't allocate CCB");
4937 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
4938 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4939 if (cam_send_ccb(device, ccb) < 0) {
4940 warn("get_cgd: error sending Path Inquiry CCB");
4941 if (arglist & CAM_ARG_VERBOSE)
4942 cam_error_print(device, ccb, CAM_ESF_ALL,
4943 CAM_EPF_ALL, stderr);
4945 goto get_cgd_bailout;
4947 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4948 if (arglist & CAM_ARG_VERBOSE)
4949 cam_error_print(device, ccb, CAM_ESF_ALL,
4950 CAM_EPF_ALL, stderr);
4952 goto get_cgd_bailout;
4954 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4962 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4966 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4967 int timeout, int verbosemode)
4969 union ccb *ccb = NULL;
4970 struct scsi_vpd_supported_page_list sup_pages;
4974 ccb = cam_getccb(dev);
4976 warn("Unable to allocate CCB");
4981 /* cam_getccb cleans up the header, caller has to zero the payload */
4982 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4984 bzero(&sup_pages, sizeof(sup_pages));
4986 scsi_inquiry(&ccb->csio,
4987 /*retries*/ retry_count,
4989 /* tag_action */ MSG_SIMPLE_Q_TAG,
4990 /* inq_buf */ (u_int8_t *)&sup_pages,
4991 /* inq_len */ sizeof(sup_pages),
4993 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
4994 /* sense_len */ SSD_FULL_SIZE,
4995 /* timeout */ timeout ? timeout : 5000);
4997 /* Disable freezing the device queue */
4998 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5000 if (retry_count != 0)
5001 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5003 if (cam_send_ccb(dev, ccb) < 0) {
5010 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5011 if (verbosemode != 0)
5012 cam_error_print(dev, ccb, CAM_ESF_ALL,
5013 CAM_EPF_ALL, stderr);
5018 for (i = 0; i < sup_pages.length; i++) {
5019 if (sup_pages.list[i] == page_id) {
5032 * devtype is filled in with the type of device.
5033 * Returns 0 for success, non-zero for failure.
5036 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5037 int verbosemode, camcontrol_devtype *devtype)
5039 struct ccb_getdev cgd;
5042 retval = get_cgd(dev, &cgd);
5046 switch (cgd.protocol) {
5052 *devtype = CC_DT_ATA;
5054 break; /*NOTREACHED*/
5056 *devtype = CC_DT_UNKNOWN;
5058 break; /*NOTREACHED*/
5062 * Check for the ATA Information VPD page (0x89). If this is an
5063 * ATA device behind a SCSI to ATA translation layer, this VPD page
5064 * should be present.
5066 * If that VPD page isn't present, or we get an error back from the
5067 * INQUIRY command, we'll just treat it as a normal SCSI device.
5069 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5070 timeout, verbosemode);
5072 *devtype = CC_DT_ATA_BEHIND_SCSI;
5074 *devtype = CC_DT_SCSI;
5083 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5084 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5085 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5086 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5087 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5088 int is48bit, camcontrol_devtype devtype)
5092 if (devtype == CC_DT_ATA) {
5093 cam_fill_ataio(&ccb->ataio,
5094 /*retries*/ retry_count,
5097 /*tag_action*/ tag_action,
5098 /*data_ptr*/ data_ptr,
5099 /*dxfer_len*/ dxfer_len,
5100 /*timeout*/ timeout);
5101 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5102 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5105 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5108 if (auxiliary != 0) {
5109 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5110 ccb->ataio.aux = auxiliary;
5113 if (ata_flags & AP_FLAG_CHK_COND)
5114 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5116 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5117 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5118 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5119 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5121 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5122 protocol |= AP_EXTEND;
5124 retval = scsi_ata_pass(&ccb->csio,
5125 /*retries*/ retry_count,
5128 /*tag_action*/ tag_action,
5129 /*protocol*/ protocol,
5130 /*ata_flags*/ ata_flags,
5131 /*features*/ features,
5132 /*sector_count*/ sector_count,
5134 /*command*/ command,
5137 /*auxiliary*/ auxiliary,
5139 /*data_ptr*/ data_ptr,
5140 /*dxfer_len*/ dxfer_len,
5141 /*cdb_storage*/ cdb_storage,
5142 /*cdb_storage_len*/ cdb_storage_len,
5143 /*minimum_cmd_size*/ 0,
5144 /*sense_len*/ sense_len,
5145 /*timeout*/ timeout);
5152 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5153 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5157 switch (ccb->ccb_h.func_code) {
5160 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5163 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5164 * or 16 byte, and need to see what
5166 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5167 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5169 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5170 if ((opcode != ATA_PASS_12)
5171 && (opcode != ATA_PASS_16)) {
5173 warnx("%s: unsupported opcode %02x", __func__, opcode);
5177 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5179 /* Note: the _ccb() variant returns 0 for an error */
5186 switch (error_code) {
5187 case SSD_DESC_CURRENT_ERROR:
5188 case SSD_DESC_DEFERRED_ERROR: {
5189 struct scsi_sense_data_desc *sense;
5190 struct scsi_sense_ata_ret_desc *desc;
5193 sense = (struct scsi_sense_data_desc *)
5194 &ccb->csio.sense_data;
5196 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5197 ccb->csio.sense_resid, SSD_DESC_ATA);
5198 if (desc_ptr == NULL) {
5199 cam_error_print(dev, ccb, CAM_ESF_ALL,
5200 CAM_EPF_ALL, stderr);
5204 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5206 *error = desc->error;
5207 *count = (desc->count_15_8 << 8) |
5209 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5210 ((uint64_t)desc->lba_39_32 << 32) |
5211 ((uint64_t)desc->lba_31_24 << 24) |
5212 (desc->lba_23_16 << 16) |
5213 (desc->lba_15_8 << 8) |
5215 *device = desc->device;
5216 *status = desc->status;
5219 * If the extend bit isn't set, the result is for a
5220 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5221 * command without the extend bit set. This means
5222 * that the device is supposed to return 28-bit
5223 * status. The count field is only 8 bits, and the
5224 * LBA field is only 8 bits.
5226 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5232 case SSD_CURRENT_ERROR:
5233 case SSD_DEFERRED_ERROR: {
5235 struct scsi_sense_data_fixed *sense;
5238 * XXX KDM need to support fixed sense data.
5240 warnx("%s: Fixed sense data not supported yet",
5244 break; /*NOTREACHED*/
5255 struct ata_res *res;
5258 * In this case, we have an ATA command, and we need to
5259 * fill in the requested values from the result register
5262 res = &ccb->ataio.res;
5263 *error = res->error;
5264 *status = res->status;
5265 *device = res->device;
5266 *count = res->sector_count;
5267 *lba = (res->lba_high << 16) |
5268 (res->lba_mid << 8) |
5270 if (res->flags & CAM_ATAIO_48BIT) {
5271 *count |= (res->sector_count_exp << 8);
5272 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5273 ((uint64_t)res->lba_mid_exp << 32) |
5274 ((uint64_t)res->lba_high_exp << 40);
5276 *lba |= (res->device & 0xf) << 24;
5289 cpi_print(struct ccb_pathinq *cpi)
5291 char adapter_str[1024];
5294 snprintf(adapter_str, sizeof(adapter_str),
5295 "%s%d:", cpi->dev_name, cpi->unit_number);
5297 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5300 for (i = 1; i < 0xff; i = i << 1) {
5303 if ((i & cpi->hba_inquiry) == 0)
5306 fprintf(stdout, "%s supports ", adapter_str);
5310 str = "MDP message";
5313 str = "32 bit wide SCSI";
5316 str = "16 bit wide SCSI";
5319 str = "SDTR message";
5322 str = "linked CDBs";
5325 str = "tag queue messages";
5328 str = "soft reset alternative";
5331 str = "SATA Port Multiplier";
5334 str = "unknown PI bit set";
5337 fprintf(stdout, "%s\n", str);
5340 for (i = 1; i < 0xff; i = i << 1) {
5343 if ((i & cpi->hba_misc) == 0)
5346 fprintf(stdout, "%s ", adapter_str);
5350 str = "bus scans from high ID to low ID";
5353 str = "removable devices not included in scan";
5355 case PIM_NOINITIATOR:
5356 str = "initiator role not supported";
5358 case PIM_NOBUSRESET:
5359 str = "user has disabled initial BUS RESET or"
5360 " controller is in target/mixed mode";
5363 str = "do not send 6-byte commands";
5366 str = "scan bus sequentially";
5369 str = "unknown PIM bit set";
5372 fprintf(stdout, "%s\n", str);
5375 for (i = 1; i < 0xff; i = i << 1) {
5378 if ((i & cpi->target_sprt) == 0)
5381 fprintf(stdout, "%s supports ", adapter_str);
5384 str = "target mode processor mode";
5387 str = "target mode phase cog. mode";
5389 case PIT_DISCONNECT:
5390 str = "disconnects in target mode";
5393 str = "terminate I/O message in target mode";
5396 str = "group 6 commands in target mode";
5399 str = "group 7 commands in target mode";
5402 str = "unknown PIT bit set";
5406 fprintf(stdout, "%s\n", str);
5408 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5410 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5412 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5414 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5415 adapter_str, cpi->hpath_id);
5416 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5418 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5419 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5420 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5421 adapter_str, cpi->hba_vendor);
5422 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5423 adapter_str, cpi->hba_device);
5424 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5425 adapter_str, cpi->hba_subvendor);
5426 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5427 adapter_str, cpi->hba_subdevice);
5428 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5429 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5430 if (cpi->base_transfer_speed > 1000)
5431 fprintf(stdout, "%d.%03dMB/sec\n",
5432 cpi->base_transfer_speed / 1000,
5433 cpi->base_transfer_speed % 1000);
5435 fprintf(stdout, "%dKB/sec\n",
5436 (cpi->base_transfer_speed % 1000) * 1000);
5437 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5438 adapter_str, cpi->maxio);
5442 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5443 struct ccb_trans_settings *cts)
5449 ccb = cam_getccb(device);
5452 warnx("get_print_cts: error allocating ccb");
5456 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5458 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5460 if (user_settings == 0)
5461 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5463 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5465 if (cam_send_ccb(device, ccb) < 0) {
5466 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5467 if (arglist & CAM_ARG_VERBOSE)
5468 cam_error_print(device, ccb, CAM_ESF_ALL,
5469 CAM_EPF_ALL, stderr);
5471 goto get_print_cts_bailout;
5474 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5475 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5476 if (arglist & CAM_ARG_VERBOSE)
5477 cam_error_print(device, ccb, CAM_ESF_ALL,
5478 CAM_EPF_ALL, stderr);
5480 goto get_print_cts_bailout;
5484 cts_print(device, &ccb->cts);
5487 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5489 get_print_cts_bailout:
5497 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5498 int argc, char **argv, char *combinedopt)
5502 int user_settings = 0;
5504 int disc_enable = -1, tag_enable = -1;
5507 double syncrate = -1;
5510 int change_settings = 0, send_tur = 0;
5511 struct ccb_pathinq cpi;
5513 ccb = cam_getccb(device);
5515 warnx("ratecontrol: error allocating ccb");
5518 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5527 if (strncasecmp(optarg, "enable", 6) == 0)
5529 else if (strncasecmp(optarg, "disable", 7) == 0)
5532 warnx("-D argument \"%s\" is unknown", optarg);
5534 goto ratecontrol_bailout;
5536 change_settings = 1;
5539 mode = ata_string2mode(optarg);
5541 warnx("unknown mode '%s'", optarg);
5543 goto ratecontrol_bailout;
5545 change_settings = 1;
5548 offset = strtol(optarg, NULL, 0);
5550 warnx("offset value %d is < 0", offset);
5552 goto ratecontrol_bailout;
5554 change_settings = 1;
5560 syncrate = atof(optarg);
5562 warnx("sync rate %f is < 0", syncrate);
5564 goto ratecontrol_bailout;
5566 change_settings = 1;
5569 if (strncasecmp(optarg, "enable", 6) == 0)
5571 else if (strncasecmp(optarg, "disable", 7) == 0)
5574 warnx("-T argument \"%s\" is unknown", optarg);
5576 goto ratecontrol_bailout;
5578 change_settings = 1;
5584 bus_width = strtol(optarg, NULL, 0);
5585 if (bus_width < 0) {
5586 warnx("bus width %d is < 0", bus_width);
5588 goto ratecontrol_bailout;
5590 change_settings = 1;
5596 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5598 * Grab path inquiry information, so we can determine whether
5599 * or not the initiator is capable of the things that the user
5602 ccb->ccb_h.func_code = XPT_PATH_INQ;
5603 if (cam_send_ccb(device, ccb) < 0) {
5604 perror("error sending XPT_PATH_INQ CCB");
5605 if (arglist & CAM_ARG_VERBOSE) {
5606 cam_error_print(device, ccb, CAM_ESF_ALL,
5607 CAM_EPF_ALL, stderr);
5610 goto ratecontrol_bailout;
5612 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5613 warnx("XPT_PATH_INQ CCB failed");
5614 if (arglist & CAM_ARG_VERBOSE) {
5615 cam_error_print(device, ccb, CAM_ESF_ALL,
5616 CAM_EPF_ALL, stderr);
5619 goto ratecontrol_bailout;
5621 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5622 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5624 fprintf(stdout, "%s parameters:\n",
5625 user_settings ? "User" : "Current");
5627 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5629 goto ratecontrol_bailout;
5631 if (arglist & CAM_ARG_VERBOSE)
5634 if (change_settings) {
5635 int didsettings = 0;
5636 struct ccb_trans_settings_spi *spi = NULL;
5637 struct ccb_trans_settings_pata *pata = NULL;
5638 struct ccb_trans_settings_sata *sata = NULL;
5639 struct ccb_trans_settings_ata *ata = NULL;
5640 struct ccb_trans_settings_scsi *scsi = NULL;
5642 if (ccb->cts.transport == XPORT_SPI)
5643 spi = &ccb->cts.xport_specific.spi;
5644 if (ccb->cts.transport == XPORT_ATA)
5645 pata = &ccb->cts.xport_specific.ata;
5646 if (ccb->cts.transport == XPORT_SATA)
5647 sata = &ccb->cts.xport_specific.sata;
5648 if (ccb->cts.protocol == PROTO_ATA)
5649 ata = &ccb->cts.proto_specific.ata;
5650 if (ccb->cts.protocol == PROTO_SCSI)
5651 scsi = &ccb->cts.proto_specific.scsi;
5652 ccb->cts.xport_specific.valid = 0;
5653 ccb->cts.proto_specific.valid = 0;
5654 if (spi && disc_enable != -1) {
5655 spi->valid |= CTS_SPI_VALID_DISC;
5656 if (disc_enable == 0)
5657 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5659 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5662 if (tag_enable != -1) {
5663 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5664 warnx("HBA does not support tagged queueing, "
5665 "so you cannot modify tag settings");
5667 goto ratecontrol_bailout;
5670 ata->valid |= CTS_SCSI_VALID_TQ;
5671 if (tag_enable == 0)
5672 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5674 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5677 scsi->valid |= CTS_SCSI_VALID_TQ;
5678 if (tag_enable == 0)
5679 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5681 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5685 if (spi && offset != -1) {
5686 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5687 warnx("HBA is not capable of changing offset");
5689 goto ratecontrol_bailout;
5691 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5692 spi->sync_offset = offset;
5695 if (spi && syncrate != -1) {
5696 int prelim_sync_period;
5698 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5699 warnx("HBA is not capable of changing "
5702 goto ratecontrol_bailout;
5704 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5706 * The sync rate the user gives us is in MHz.
5707 * We need to translate it into KHz for this
5712 * Next, we calculate a "preliminary" sync period
5713 * in tenths of a nanosecond.
5716 prelim_sync_period = 0;
5718 prelim_sync_period = 10000000 / syncrate;
5720 scsi_calc_syncparam(prelim_sync_period);
5723 if (sata && syncrate != -1) {
5724 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5725 warnx("HBA is not capable of changing "
5728 goto ratecontrol_bailout;
5730 if (!user_settings) {
5731 warnx("You can modify only user rate "
5732 "settings for SATA");
5734 goto ratecontrol_bailout;
5736 sata->revision = ata_speed2revision(syncrate * 100);
5737 if (sata->revision < 0) {
5738 warnx("Invalid rate %f", syncrate);
5740 goto ratecontrol_bailout;
5742 sata->valid |= CTS_SATA_VALID_REVISION;
5745 if ((pata || sata) && mode != -1) {
5746 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5747 warnx("HBA is not capable of changing "
5750 goto ratecontrol_bailout;
5752 if (!user_settings) {
5753 warnx("You can modify only user mode "
5754 "settings for ATA/SATA");
5756 goto ratecontrol_bailout;
5760 pata->valid |= CTS_ATA_VALID_MODE;
5763 sata->valid |= CTS_SATA_VALID_MODE;
5768 * The bus_width argument goes like this:
5772 * Therefore, if you shift the number of bits given on the
5773 * command line right by 4, you should get the correct
5776 if (spi && bus_width != -1) {
5778 * We might as well validate things here with a
5779 * decipherable error message, rather than what
5780 * will probably be an indecipherable error message
5781 * by the time it gets back to us.
5783 if ((bus_width == 16)
5784 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5785 warnx("HBA does not support 16 bit bus width");
5787 goto ratecontrol_bailout;
5788 } else if ((bus_width == 32)
5789 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5790 warnx("HBA does not support 32 bit bus width");
5792 goto ratecontrol_bailout;
5793 } else if ((bus_width != 8)
5794 && (bus_width != 16)
5795 && (bus_width != 32)) {
5796 warnx("Invalid bus width %d", bus_width);
5798 goto ratecontrol_bailout;
5800 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5801 spi->bus_width = bus_width >> 4;
5804 if (didsettings == 0) {
5805 goto ratecontrol_bailout;
5807 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5808 if (cam_send_ccb(device, ccb) < 0) {
5809 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5810 if (arglist & CAM_ARG_VERBOSE) {
5811 cam_error_print(device, ccb, CAM_ESF_ALL,
5812 CAM_EPF_ALL, stderr);
5815 goto ratecontrol_bailout;
5817 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5818 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5819 if (arglist & CAM_ARG_VERBOSE) {
5820 cam_error_print(device, ccb, CAM_ESF_ALL,
5821 CAM_EPF_ALL, stderr);
5824 goto ratecontrol_bailout;
5828 retval = testunitready(device, retry_count, timeout,
5829 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5831 * If the TUR didn't succeed, just bail.
5835 fprintf(stderr, "Test Unit Ready failed\n");
5836 goto ratecontrol_bailout;
5839 if ((change_settings || send_tur) && !quiet &&
5840 (ccb->cts.transport == XPORT_ATA ||
5841 ccb->cts.transport == XPORT_SATA || send_tur)) {
5842 fprintf(stdout, "New parameters:\n");
5843 retval = get_print_cts(device, user_settings, 0, NULL);
5846 ratecontrol_bailout:
5852 scsiformat(struct cam_device *device, int argc, char **argv,
5853 char *combinedopt, int retry_count, int timeout)
5857 int ycount = 0, quiet = 0;
5858 int error = 0, retval = 0;
5859 int use_timeout = 10800 * 1000;
5861 struct format_defect_list_header fh;
5862 u_int8_t *data_ptr = NULL;
5863 u_int32_t dxfer_len = 0;
5865 int num_warnings = 0;
5868 ccb = cam_getccb(device);
5871 warnx("scsiformat: error allocating ccb");
5875 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5877 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5898 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5899 "following device:\n");
5901 error = scsidoinquiry(device, argc, argv, combinedopt,
5902 retry_count, timeout);
5905 warnx("scsiformat: error sending inquiry");
5906 goto scsiformat_bailout;
5911 if (!get_confirmation()) {
5913 goto scsiformat_bailout;
5918 use_timeout = timeout;
5921 fprintf(stdout, "Current format timeout is %d seconds\n",
5922 use_timeout / 1000);
5926 * If the user hasn't disabled questions and didn't specify a
5927 * timeout on the command line, ask them if they want the current
5931 && (timeout == 0)) {
5933 int new_timeout = 0;
5935 fprintf(stdout, "Enter new timeout in seconds or press\n"
5936 "return to keep the current timeout [%d] ",
5937 use_timeout / 1000);
5939 if (fgets(str, sizeof(str), stdin) != NULL) {
5941 new_timeout = atoi(str);
5944 if (new_timeout != 0) {
5945 use_timeout = new_timeout * 1000;
5946 fprintf(stdout, "Using new timeout value %d\n",
5947 use_timeout / 1000);
5952 * Keep this outside the if block below to silence any unused
5953 * variable warnings.
5955 bzero(&fh, sizeof(fh));
5958 * If we're in immediate mode, we've got to include the format
5961 if (immediate != 0) {
5962 fh.byte2 = FU_DLH_IMMED;
5963 data_ptr = (u_int8_t *)&fh;
5964 dxfer_len = sizeof(fh);
5965 byte2 = FU_FMT_DATA;
5966 } else if (quiet == 0) {
5967 fprintf(stdout, "Formatting...");
5971 scsi_format_unit(&ccb->csio,
5972 /* retries */ retry_count,
5974 /* tag_action */ MSG_SIMPLE_Q_TAG,
5977 /* data_ptr */ data_ptr,
5978 /* dxfer_len */ dxfer_len,
5979 /* sense_len */ SSD_FULL_SIZE,
5980 /* timeout */ use_timeout);
5982 /* Disable freezing the device queue */
5983 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5985 if (arglist & CAM_ARG_ERR_RECOVER)
5986 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5988 if (((retval = cam_send_ccb(device, ccb)) < 0)
5989 || ((immediate == 0)
5990 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5991 const char errstr[] = "error sending format command";
5998 if (arglist & CAM_ARG_VERBOSE) {
5999 cam_error_print(device, ccb, CAM_ESF_ALL,
6000 CAM_EPF_ALL, stderr);
6003 goto scsiformat_bailout;
6007 * If we ran in non-immediate mode, we already checked for errors
6008 * above and printed out any necessary information. If we're in
6009 * immediate mode, we need to loop through and get status
6010 * information periodically.
6012 if (immediate == 0) {
6014 fprintf(stdout, "Format Complete\n");
6016 goto scsiformat_bailout;
6023 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6026 * There's really no need to do error recovery or
6027 * retries here, since we're just going to sit in a
6028 * loop and wait for the device to finish formatting.
6030 scsi_test_unit_ready(&ccb->csio,
6033 /* tag_action */ MSG_SIMPLE_Q_TAG,
6034 /* sense_len */ SSD_FULL_SIZE,
6035 /* timeout */ 5000);
6037 /* Disable freezing the device queue */
6038 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6040 retval = cam_send_ccb(device, ccb);
6043 * If we get an error from the ioctl, bail out. SCSI
6044 * errors are expected.
6047 warn("error sending CAMIOCOMMAND ioctl");
6048 if (arglist & CAM_ARG_VERBOSE) {
6049 cam_error_print(device, ccb, CAM_ESF_ALL,
6050 CAM_EPF_ALL, stderr);
6053 goto scsiformat_bailout;
6056 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6058 if ((status != CAM_REQ_CMP)
6059 && (status == CAM_SCSI_STATUS_ERROR)
6060 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6061 struct scsi_sense_data *sense;
6062 int error_code, sense_key, asc, ascq;
6064 sense = &ccb->csio.sense_data;
6065 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6066 ccb->csio.sense_resid, &error_code, &sense_key,
6067 &asc, &ascq, /*show_errors*/ 1);
6070 * According to the SCSI-2 and SCSI-3 specs, a
6071 * drive that is in the middle of a format should
6072 * return NOT READY with an ASC of "logical unit
6073 * not ready, format in progress". The sense key
6074 * specific bytes will then be a progress indicator.
6076 if ((sense_key == SSD_KEY_NOT_READY)
6077 && (asc == 0x04) && (ascq == 0x04)) {
6080 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6081 ccb->csio.sense_resid, sks) == 0)
6084 u_int64_t percentage;
6086 val = scsi_2btoul(&sks[1]);
6087 percentage = 10000 * val;
6090 "\rFormatting: %ju.%02u %% "
6092 (uintmax_t)(percentage /
6094 (unsigned)((percentage /
6098 } else if ((quiet == 0)
6099 && (++num_warnings <= 1)) {
6100 warnx("Unexpected SCSI Sense Key "
6101 "Specific value returned "
6103 scsi_sense_print(device, &ccb->csio,
6105 warnx("Unable to print status "
6106 "information, but format will "
6108 warnx("will exit when format is "
6113 warnx("Unexpected SCSI error during format");
6114 cam_error_print(device, ccb, CAM_ESF_ALL,
6115 CAM_EPF_ALL, stderr);
6117 goto scsiformat_bailout;
6120 } else if (status != CAM_REQ_CMP) {
6121 warnx("Unexpected CAM status %#x", status);
6122 if (arglist & CAM_ARG_VERBOSE)
6123 cam_error_print(device, ccb, CAM_ESF_ALL,
6124 CAM_EPF_ALL, stderr);
6126 goto scsiformat_bailout;
6129 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6132 fprintf(stdout, "\nFormat Complete\n");
6142 scsisanitize(struct cam_device *device, int argc, char **argv,
6143 char *combinedopt, int retry_count, int timeout)
6146 u_int8_t action = 0;
6148 int ycount = 0, quiet = 0;
6149 int error = 0, retval = 0;
6150 int use_timeout = 10800 * 1000;
6156 const char *pattern = NULL;
6157 u_int8_t *data_ptr = NULL;
6158 u_int32_t dxfer_len = 0;
6160 int num_warnings = 0;
6163 ccb = cam_getccb(device);
6166 warnx("scsisanitize: error allocating ccb");
6170 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6172 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6175 if (strcasecmp(optarg, "overwrite") == 0)
6176 action = SSZ_SERVICE_ACTION_OVERWRITE;
6177 else if (strcasecmp(optarg, "block") == 0)
6178 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6179 else if (strcasecmp(optarg, "crypto") == 0)
6180 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6181 else if (strcasecmp(optarg, "exitfailure") == 0)
6182 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6184 warnx("invalid service operation \"%s\"",
6187 goto scsisanitize_bailout;
6191 passes = strtol(optarg, NULL, 0);
6192 if (passes < 1 || passes > 31) {
6193 warnx("invalid passes value %d", passes);
6195 goto scsisanitize_bailout;
6226 warnx("an action is required");
6228 goto scsisanitize_bailout;
6229 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6230 struct scsi_sanitize_parameter_list *pl;
6234 if (pattern == NULL) {
6235 warnx("overwrite action requires -P argument");
6237 goto scsisanitize_bailout;
6239 fd = open(pattern, O_RDONLY);
6241 warn("cannot open pattern file %s", pattern);
6243 goto scsisanitize_bailout;
6245 if (fstat(fd, &sb) < 0) {
6246 warn("cannot stat pattern file %s", pattern);
6248 goto scsisanitize_bailout;
6251 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6252 warnx("pattern file size exceeds maximum value %d",
6253 SSZPL_MAX_PATTERN_LENGTH);
6255 goto scsisanitize_bailout;
6257 dxfer_len = sizeof(*pl) + sz;
6258 data_ptr = calloc(1, dxfer_len);
6259 if (data_ptr == NULL) {
6260 warnx("cannot allocate parameter list buffer");
6262 goto scsisanitize_bailout;
6265 amt = read(fd, data_ptr + sizeof(*pl), sz);
6267 warn("cannot read pattern file");
6269 goto scsisanitize_bailout;
6270 } else if (amt != sz) {
6271 warnx("short pattern file read");
6273 goto scsisanitize_bailout;
6276 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6282 pl->byte1 |= SSZPL_INVERT;
6283 scsi_ulto2b(sz, pl->length);
6289 else if (invert != 0)
6291 else if (pattern != NULL)
6296 warnx("%s argument only valid with overwrite "
6299 goto scsisanitize_bailout;
6304 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6305 "following device:\n");
6307 error = scsidoinquiry(device, argc, argv, combinedopt,
6308 retry_count, timeout);
6311 warnx("scsisanitize: error sending inquiry");
6312 goto scsisanitize_bailout;
6317 if (!get_confirmation()) {
6319 goto scsisanitize_bailout;
6324 use_timeout = timeout;
6327 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6328 use_timeout / 1000);
6332 * If the user hasn't disabled questions and didn't specify a
6333 * timeout on the command line, ask them if they want the current
6337 && (timeout == 0)) {
6339 int new_timeout = 0;
6341 fprintf(stdout, "Enter new timeout in seconds or press\n"
6342 "return to keep the current timeout [%d] ",
6343 use_timeout / 1000);
6345 if (fgets(str, sizeof(str), stdin) != NULL) {
6347 new_timeout = atoi(str);
6350 if (new_timeout != 0) {
6351 use_timeout = new_timeout * 1000;
6352 fprintf(stdout, "Using new timeout value %d\n",
6353 use_timeout / 1000);
6359 byte2 |= SSZ_UNRESTRICTED_EXIT;
6363 scsi_sanitize(&ccb->csio,
6364 /* retries */ retry_count,
6366 /* tag_action */ MSG_SIMPLE_Q_TAG,
6369 /* data_ptr */ data_ptr,
6370 /* dxfer_len */ dxfer_len,
6371 /* sense_len */ SSD_FULL_SIZE,
6372 /* timeout */ use_timeout);
6374 /* Disable freezing the device queue */
6375 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6377 if (arglist & CAM_ARG_ERR_RECOVER)
6378 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6380 if (cam_send_ccb(device, ccb) < 0) {
6381 warn("error sending sanitize command");
6383 goto scsisanitize_bailout;
6386 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6387 struct scsi_sense_data *sense;
6388 int error_code, sense_key, asc, ascq;
6390 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6391 CAM_SCSI_STATUS_ERROR) {
6392 sense = &ccb->csio.sense_data;
6393 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6394 ccb->csio.sense_resid, &error_code, &sense_key,
6395 &asc, &ascq, /*show_errors*/ 1);
6397 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6398 asc == 0x20 && ascq == 0x00)
6399 warnx("sanitize is not supported by "
6402 warnx("error sanitizing this device");
6404 warnx("error sanitizing this device");
6406 if (arglist & CAM_ARG_VERBOSE) {
6407 cam_error_print(device, ccb, CAM_ESF_ALL,
6408 CAM_EPF_ALL, stderr);
6411 goto scsisanitize_bailout;
6415 * If we ran in non-immediate mode, we already checked for errors
6416 * above and printed out any necessary information. If we're in
6417 * immediate mode, we need to loop through and get status
6418 * information periodically.
6420 if (immediate == 0) {
6422 fprintf(stdout, "Sanitize Complete\n");
6424 goto scsisanitize_bailout;
6431 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6434 * There's really no need to do error recovery or
6435 * retries here, since we're just going to sit in a
6436 * loop and wait for the device to finish sanitizing.
6438 scsi_test_unit_ready(&ccb->csio,
6441 /* tag_action */ MSG_SIMPLE_Q_TAG,
6442 /* sense_len */ SSD_FULL_SIZE,
6443 /* timeout */ 5000);
6445 /* Disable freezing the device queue */
6446 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6448 retval = cam_send_ccb(device, ccb);
6451 * If we get an error from the ioctl, bail out. SCSI
6452 * errors are expected.
6455 warn("error sending CAMIOCOMMAND ioctl");
6456 if (arglist & CAM_ARG_VERBOSE) {
6457 cam_error_print(device, ccb, CAM_ESF_ALL,
6458 CAM_EPF_ALL, stderr);
6461 goto scsisanitize_bailout;
6464 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6466 if ((status != CAM_REQ_CMP)
6467 && (status == CAM_SCSI_STATUS_ERROR)
6468 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6469 struct scsi_sense_data *sense;
6470 int error_code, sense_key, asc, ascq;
6472 sense = &ccb->csio.sense_data;
6473 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6474 ccb->csio.sense_resid, &error_code, &sense_key,
6475 &asc, &ascq, /*show_errors*/ 1);
6478 * According to the SCSI-3 spec, a drive that is in the
6479 * middle of a sanitize should return NOT READY with an
6480 * ASC of "logical unit not ready, sanitize in
6481 * progress". The sense key specific bytes will then
6482 * be a progress indicator.
6484 if ((sense_key == SSD_KEY_NOT_READY)
6485 && (asc == 0x04) && (ascq == 0x1b)) {
6488 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6489 ccb->csio.sense_resid, sks) == 0)
6492 u_int64_t percentage;
6494 val = scsi_2btoul(&sks[1]);
6495 percentage = 10000 * val;
6498 "\rSanitizing: %ju.%02u %% "
6500 (uintmax_t)(percentage /
6502 (unsigned)((percentage /
6506 } else if ((quiet == 0)
6507 && (++num_warnings <= 1)) {
6508 warnx("Unexpected SCSI Sense Key "
6509 "Specific value returned "
6510 "during sanitize:");
6511 scsi_sense_print(device, &ccb->csio,
6513 warnx("Unable to print status "
6514 "information, but sanitze will "
6516 warnx("will exit when sanitize is "
6521 warnx("Unexpected SCSI error during sanitize");
6522 cam_error_print(device, ccb, CAM_ESF_ALL,
6523 CAM_EPF_ALL, stderr);
6525 goto scsisanitize_bailout;
6528 } else if (status != CAM_REQ_CMP) {
6529 warnx("Unexpected CAM status %#x", status);
6530 if (arglist & CAM_ARG_VERBOSE)
6531 cam_error_print(device, ccb, CAM_ESF_ALL,
6532 CAM_EPF_ALL, stderr);
6534 goto scsisanitize_bailout;
6536 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6539 fprintf(stdout, "\nSanitize Complete\n");
6541 scsisanitize_bailout:
6544 if (data_ptr != NULL)
6552 scsireportluns(struct cam_device *device, int argc, char **argv,
6553 char *combinedopt, int retry_count, int timeout)
6556 int c, countonly, lunsonly;
6557 struct scsi_report_luns_data *lundata;
6559 uint8_t report_type;
6560 uint32_t list_len, i, j;
6565 report_type = RPL_REPORT_DEFAULT;
6566 ccb = cam_getccb(device);
6569 warnx("%s: error allocating ccb", __func__);
6573 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6578 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6587 if (strcasecmp(optarg, "default") == 0)
6588 report_type = RPL_REPORT_DEFAULT;
6589 else if (strcasecmp(optarg, "wellknown") == 0)
6590 report_type = RPL_REPORT_WELLKNOWN;
6591 else if (strcasecmp(optarg, "all") == 0)
6592 report_type = RPL_REPORT_ALL;
6594 warnx("%s: invalid report type \"%s\"",
6605 if ((countonly != 0)
6606 && (lunsonly != 0)) {
6607 warnx("%s: you can only specify one of -c or -l", __func__);
6612 * According to SPC-4, the allocation length must be at least 16
6613 * bytes -- enough for the header and one LUN.
6615 alloc_len = sizeof(*lundata) + 8;
6619 lundata = malloc(alloc_len);
6621 if (lundata == NULL) {
6622 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6627 scsi_report_luns(&ccb->csio,
6628 /*retries*/ retry_count,
6630 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6631 /*select_report*/ report_type,
6632 /*rpl_buf*/ lundata,
6633 /*alloc_len*/ alloc_len,
6634 /*sense_len*/ SSD_FULL_SIZE,
6635 /*timeout*/ timeout ? timeout : 5000);
6637 /* Disable freezing the device queue */
6638 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6640 if (arglist & CAM_ARG_ERR_RECOVER)
6641 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6643 if (cam_send_ccb(device, ccb) < 0) {
6644 warn("error sending REPORT LUNS command");
6646 if (arglist & CAM_ARG_VERBOSE)
6647 cam_error_print(device, ccb, CAM_ESF_ALL,
6648 CAM_EPF_ALL, stderr);
6654 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6655 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6661 list_len = scsi_4btoul(lundata->length);
6664 * If we need to list the LUNs, and our allocation
6665 * length was too short, reallocate and retry.
6667 if ((countonly == 0)
6668 && (list_len > (alloc_len - sizeof(*lundata)))) {
6669 alloc_len = list_len + sizeof(*lundata);
6675 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6676 ((list_len / 8) > 1) ? "s" : "");
6681 for (i = 0; i < (list_len / 8); i++) {
6685 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6687 fprintf(stdout, ",");
6688 switch (lundata->luns[i].lundata[j] &
6689 RPL_LUNDATA_ATYP_MASK) {
6690 case RPL_LUNDATA_ATYP_PERIPH:
6691 if ((lundata->luns[i].lundata[j] &
6692 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6693 fprintf(stdout, "%d:",
6694 lundata->luns[i].lundata[j] &
6695 RPL_LUNDATA_PERIPH_BUS_MASK);
6697 && ((lundata->luns[i].lundata[j+2] &
6698 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6701 fprintf(stdout, "%d",
6702 lundata->luns[i].lundata[j+1]);
6704 case RPL_LUNDATA_ATYP_FLAT: {
6706 tmplun[0] = lundata->luns[i].lundata[j] &
6707 RPL_LUNDATA_FLAT_LUN_MASK;
6708 tmplun[1] = lundata->luns[i].lundata[j+1];
6710 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6714 case RPL_LUNDATA_ATYP_LUN:
6715 fprintf(stdout, "%d:%d:%d",
6716 (lundata->luns[i].lundata[j+1] &
6717 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6718 lundata->luns[i].lundata[j] &
6719 RPL_LUNDATA_LUN_TARG_MASK,
6720 lundata->luns[i].lundata[j+1] &
6721 RPL_LUNDATA_LUN_LUN_MASK);
6723 case RPL_LUNDATA_ATYP_EXTLUN: {
6724 int field_len_code, eam_code;
6726 eam_code = lundata->luns[i].lundata[j] &
6727 RPL_LUNDATA_EXT_EAM_MASK;
6728 field_len_code = (lundata->luns[i].lundata[j] &
6729 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6731 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6732 && (field_len_code == 0x00)) {
6733 fprintf(stdout, "%d",
6734 lundata->luns[i].lundata[j+1]);
6735 } else if ((eam_code ==
6736 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6737 && (field_len_code == 0x03)) {
6741 * This format takes up all 8 bytes.
6742 * If we aren't starting at offset 0,
6746 fprintf(stdout, "Invalid "
6749 "specified format", j);
6753 bzero(tmp_lun, sizeof(tmp_lun));
6754 bcopy(&lundata->luns[i].lundata[j+1],
6755 &tmp_lun[1], sizeof(tmp_lun) - 1);
6756 fprintf(stdout, "%#jx",
6757 (intmax_t)scsi_8btou64(tmp_lun));
6760 fprintf(stderr, "Unknown Extended LUN"
6761 "Address method %#x, length "
6762 "code %#x", eam_code,
6769 fprintf(stderr, "Unknown LUN address method "
6770 "%#x\n", lundata->luns[i].lundata[0] &
6771 RPL_LUNDATA_ATYP_MASK);
6775 * For the flat addressing method, there are no
6776 * other levels after it.
6781 fprintf(stdout, "\n");
6794 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6795 char *combinedopt, int retry_count, int timeout)
6798 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6799 struct scsi_read_capacity_data rcap;
6800 struct scsi_read_capacity_data_long rcaplong;
6814 ccb = cam_getccb(device);
6817 warnx("%s: error allocating ccb", __func__);
6821 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6823 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6850 if ((blocksizeonly != 0)
6851 && (numblocks != 0)) {
6852 warnx("%s: you can only specify one of -b or -N", __func__);
6857 if ((blocksizeonly != 0)
6858 && (sizeonly != 0)) {
6859 warnx("%s: you can only specify one of -b or -s", __func__);
6866 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6872 && (blocksizeonly != 0)) {
6873 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6878 scsi_read_capacity(&ccb->csio,
6879 /*retries*/ retry_count,
6881 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6884 /*timeout*/ timeout ? timeout : 5000);
6886 /* Disable freezing the device queue */
6887 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6889 if (arglist & CAM_ARG_ERR_RECOVER)
6890 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6892 if (cam_send_ccb(device, ccb) < 0) {
6893 warn("error sending READ CAPACITY command");
6895 if (arglist & CAM_ARG_VERBOSE)
6896 cam_error_print(device, ccb, CAM_ESF_ALL,
6897 CAM_EPF_ALL, stderr);
6903 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6904 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6909 maxsector = scsi_4btoul(rcap.addr);
6910 block_len = scsi_4btoul(rcap.length);
6913 * A last block of 2^32-1 means that the true capacity is over 2TB,
6914 * and we need to issue the long READ CAPACITY to get the real
6915 * capacity. Otherwise, we're all set.
6917 if (maxsector != 0xffffffff)
6920 scsi_read_capacity_16(&ccb->csio,
6921 /*retries*/ retry_count,
6923 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6927 /*rcap_buf*/ (uint8_t *)&rcaplong,
6928 /*rcap_buf_len*/ sizeof(rcaplong),
6929 /*sense_len*/ SSD_FULL_SIZE,
6930 /*timeout*/ timeout ? timeout : 5000);
6932 /* Disable freezing the device queue */
6933 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6935 if (arglist & CAM_ARG_ERR_RECOVER)
6936 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6938 if (cam_send_ccb(device, ccb) < 0) {
6939 warn("error sending READ CAPACITY (16) command");
6941 if (arglist & CAM_ARG_VERBOSE)
6942 cam_error_print(device, ccb, CAM_ESF_ALL,
6943 CAM_EPF_ALL, stderr);
6949 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6950 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6955 maxsector = scsi_8btou64(rcaplong.addr);
6956 block_len = scsi_4btoul(rcaplong.length);
6959 if (blocksizeonly == 0) {
6961 * Humanize implies !quiet, and also implies numblocks.
6963 if (humanize != 0) {
6968 tmpbytes = (maxsector + 1) * block_len;
6969 ret = humanize_number(tmpstr, sizeof(tmpstr),
6970 tmpbytes, "", HN_AUTOSCALE,
6973 HN_DIVISOR_1000 : 0));
6975 warnx("%s: humanize_number failed!", __func__);
6979 fprintf(stdout, "Device Size: %s%s", tmpstr,
6980 (sizeonly == 0) ? ", " : "\n");
6981 } else if (numblocks != 0) {
6982 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6983 "Blocks: " : "", (uintmax_t)maxsector + 1,
6984 (sizeonly == 0) ? ", " : "\n");
6986 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6987 "Last Block: " : "", (uintmax_t)maxsector,
6988 (sizeonly == 0) ? ", " : "\n");
6992 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6993 "Block Length: " : "", block_len, (quiet == 0) ?
7002 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7003 int retry_count, int timeout)
7007 uint8_t *smp_request = NULL, *smp_response = NULL;
7008 int request_size = 0, response_size = 0;
7009 int fd_request = 0, fd_response = 0;
7010 char *datastr = NULL;
7011 struct get_hook hook;
7016 * Note that at the moment we don't support sending SMP CCBs to
7017 * devices that aren't probed by CAM.
7019 ccb = cam_getccb(device);
7021 warnx("%s: error allocating CCB", __func__);
7025 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7027 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7030 arglist |= CAM_ARG_CMD_IN;
7031 response_size = strtol(optarg, NULL, 0);
7032 if (response_size <= 0) {
7033 warnx("invalid number of response bytes %d",
7036 goto smpcmd_bailout;
7038 hook.argc = argc - optind;
7039 hook.argv = argv + optind;
7042 datastr = cget(&hook, NULL);
7044 * If the user supplied "-" instead of a format, he
7045 * wants the data to be written to stdout.
7047 if ((datastr != NULL)
7048 && (datastr[0] == '-'))
7051 smp_response = (u_int8_t *)malloc(response_size);
7052 if (smp_response == NULL) {
7053 warn("can't malloc memory for SMP response");
7055 goto smpcmd_bailout;
7059 arglist |= CAM_ARG_CMD_OUT;
7060 request_size = strtol(optarg, NULL, 0);
7061 if (request_size <= 0) {
7062 warnx("invalid number of request bytes %d",
7065 goto smpcmd_bailout;
7067 hook.argc = argc - optind;
7068 hook.argv = argv + optind;
7070 datastr = cget(&hook, NULL);
7071 smp_request = (u_int8_t *)malloc(request_size);
7072 if (smp_request == NULL) {
7073 warn("can't malloc memory for SMP request");
7075 goto smpcmd_bailout;
7077 bzero(smp_request, request_size);
7079 * If the user supplied "-" instead of a format, he
7080 * wants the data to be read from stdin.
7082 if ((datastr != NULL)
7083 && (datastr[0] == '-'))
7086 buff_encode_visit(smp_request, request_size,
7097 * If fd_data is set, and we're writing to the device, we need to
7098 * read the data the user wants written from stdin.
7100 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7102 int amt_to_read = request_size;
7103 u_int8_t *buf_ptr = smp_request;
7105 for (amt_read = 0; amt_to_read > 0;
7106 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7107 if (amt_read == -1) {
7108 warn("error reading data from stdin");
7110 goto smpcmd_bailout;
7112 amt_to_read -= amt_read;
7113 buf_ptr += amt_read;
7117 if (((arglist & CAM_ARG_CMD_IN) == 0)
7118 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7119 warnx("%s: need both the request (-r) and response (-R) "
7120 "arguments", __func__);
7122 goto smpcmd_bailout;
7125 flags |= CAM_DEV_QFRZDIS;
7127 cam_fill_smpio(&ccb->smpio,
7128 /*retries*/ retry_count,
7131 /*smp_request*/ smp_request,
7132 /*smp_request_len*/ request_size,
7133 /*smp_response*/ smp_response,
7134 /*smp_response_len*/ response_size,
7135 /*timeout*/ timeout ? timeout : 5000);
7137 ccb->smpio.flags = SMP_FLAG_NONE;
7139 if (((retval = cam_send_ccb(device, ccb)) < 0)
7140 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7141 const char warnstr[] = "error sending command";
7148 if (arglist & CAM_ARG_VERBOSE) {
7149 cam_error_print(device, ccb, CAM_ESF_ALL,
7150 CAM_EPF_ALL, stderr);
7154 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7155 && (response_size > 0)) {
7156 if (fd_response == 0) {
7157 buff_decode_visit(smp_response, response_size,
7158 datastr, arg_put, NULL);
7159 fprintf(stdout, "\n");
7161 ssize_t amt_written;
7162 int amt_to_write = response_size;
7163 u_int8_t *buf_ptr = smp_response;
7165 for (amt_written = 0; (amt_to_write > 0) &&
7166 (amt_written = write(STDOUT_FILENO, buf_ptr,
7167 amt_to_write)) > 0;){
7168 amt_to_write -= amt_written;
7169 buf_ptr += amt_written;
7171 if (amt_written == -1) {
7172 warn("error writing data to stdout");
7174 goto smpcmd_bailout;
7175 } else if ((amt_written == 0)
7176 && (amt_to_write > 0)) {
7177 warnx("only wrote %u bytes out of %u",
7178 response_size - amt_to_write,
7187 if (smp_request != NULL)
7190 if (smp_response != NULL)
7197 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7198 char *combinedopt, int retry_count, int timeout)
7201 struct smp_report_general_request *request = NULL;
7202 struct smp_report_general_response *response = NULL;
7203 struct sbuf *sb = NULL;
7205 int c, long_response = 0;
7209 * Note that at the moment we don't support sending SMP CCBs to
7210 * devices that aren't probed by CAM.
7212 ccb = cam_getccb(device);
7214 warnx("%s: error allocating CCB", __func__);
7218 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7220 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7229 request = malloc(sizeof(*request));
7230 if (request == NULL) {
7231 warn("%s: unable to allocate %zd bytes", __func__,
7237 response = malloc(sizeof(*response));
7238 if (response == NULL) {
7239 warn("%s: unable to allocate %zd bytes", __func__,
7246 smp_report_general(&ccb->smpio,
7250 /*request_len*/ sizeof(*request),
7251 (uint8_t *)response,
7252 /*response_len*/ sizeof(*response),
7253 /*long_response*/ long_response,
7256 if (((retval = cam_send_ccb(device, ccb)) < 0)
7257 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7258 const char warnstr[] = "error sending command";
7265 if (arglist & CAM_ARG_VERBOSE) {
7266 cam_error_print(device, ccb, CAM_ESF_ALL,
7267 CAM_EPF_ALL, stderr);
7274 * If the device supports the long response bit, try again and see
7275 * if we can get all of the data.
7277 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7278 && (long_response == 0)) {
7279 ccb->ccb_h.status = CAM_REQ_INPROG;
7280 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7286 * XXX KDM detect and decode SMP errors here.
7288 sb = sbuf_new_auto();
7290 warnx("%s: error allocating sbuf", __func__);
7294 smp_report_general_sbuf(response, sizeof(*response), sb);
7296 if (sbuf_finish(sb) != 0) {
7297 warnx("%s: sbuf_finish", __func__);
7301 printf("%s", sbuf_data(sb));
7307 if (request != NULL)
7310 if (response != NULL)
7319 static struct camcontrol_opts phy_ops[] = {
7320 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7321 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7322 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7323 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7324 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7325 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7326 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7327 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7328 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7333 smpphycontrol(struct cam_device *device, int argc, char **argv,
7334 char *combinedopt, int retry_count, int timeout)
7337 struct smp_phy_control_request *request = NULL;
7338 struct smp_phy_control_response *response = NULL;
7339 int long_response = 0;
7342 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7344 uint64_t attached_dev_name = 0;
7345 int dev_name_set = 0;
7346 uint32_t min_plr = 0, max_plr = 0;
7347 uint32_t pp_timeout_val = 0;
7348 int slumber_partial = 0;
7349 int set_pp_timeout_val = 0;
7353 * Note that at the moment we don't support sending SMP CCBs to
7354 * devices that aren't probed by CAM.
7356 ccb = cam_getccb(device);
7358 warnx("%s: error allocating CCB", __func__);
7362 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7364 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7372 if (strcasecmp(optarg, "enable") == 0)
7374 else if (strcasecmp(optarg, "disable") == 0)
7377 warnx("%s: Invalid argument %s", __func__,
7384 slumber_partial |= enable <<
7385 SMP_PC_SAS_SLUMBER_SHIFT;
7388 slumber_partial |= enable <<
7389 SMP_PC_SAS_PARTIAL_SHIFT;
7392 slumber_partial |= enable <<
7393 SMP_PC_SATA_SLUMBER_SHIFT;
7396 slumber_partial |= enable <<
7397 SMP_PC_SATA_PARTIAL_SHIFT;
7400 warnx("%s: programmer error", __func__);
7403 break; /*NOTREACHED*/
7408 attached_dev_name = (uintmax_t)strtoumax(optarg,
7417 * We don't do extensive checking here, so this
7418 * will continue to work when new speeds come out.
7420 min_plr = strtoul(optarg, NULL, 0);
7422 || (min_plr > 0xf)) {
7423 warnx("%s: invalid link rate %x",
7431 * We don't do extensive checking here, so this
7432 * will continue to work when new speeds come out.
7434 max_plr = strtoul(optarg, NULL, 0);
7436 || (max_plr > 0xf)) {
7437 warnx("%s: invalid link rate %x",
7444 camcontrol_optret optreturn;
7445 cam_argmask argnums;
7448 if (phy_op_set != 0) {
7449 warnx("%s: only one phy operation argument "
7450 "(-o) allowed", __func__);
7458 * Allow the user to specify the phy operation
7459 * numerically, as well as with a name. This will
7460 * future-proof it a bit, so options that are added
7461 * in future specs can be used.
7463 if (isdigit(optarg[0])) {
7464 phy_operation = strtoul(optarg, NULL, 0);
7465 if ((phy_operation == 0)
7466 || (phy_operation > 0xff)) {
7467 warnx("%s: invalid phy operation %#x",
7468 __func__, phy_operation);
7474 optreturn = getoption(phy_ops, optarg, &phy_operation,
7477 if (optreturn == CC_OR_AMBIGUOUS) {
7478 warnx("%s: ambiguous option %s", __func__,
7483 } else if (optreturn == CC_OR_NOT_FOUND) {
7484 warnx("%s: option %s not found", __func__,
7496 pp_timeout_val = strtoul(optarg, NULL, 0);
7497 if (pp_timeout_val > 15) {
7498 warnx("%s: invalid partial pathway timeout "
7499 "value %u, need a value less than 16",
7500 __func__, pp_timeout_val);
7504 set_pp_timeout_val = 1;
7512 warnx("%s: a PHY (-p phy) argument is required",__func__);
7517 if (((dev_name_set != 0)
7518 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7519 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7520 && (dev_name_set == 0))) {
7521 warnx("%s: -d name and -o setdevname arguments both "
7522 "required to set device name", __func__);
7527 request = malloc(sizeof(*request));
7528 if (request == NULL) {
7529 warn("%s: unable to allocate %zd bytes", __func__,
7535 response = malloc(sizeof(*response));
7536 if (response == NULL) {
7537 warn("%s: unable to allocate %zd bytes", __func__,
7543 smp_phy_control(&ccb->smpio,
7548 (uint8_t *)response,
7551 /*expected_exp_change_count*/ 0,
7554 (set_pp_timeout_val != 0) ? 1 : 0,
7562 if (((retval = cam_send_ccb(device, ccb)) < 0)
7563 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7564 const char warnstr[] = "error sending command";
7571 if (arglist & CAM_ARG_VERBOSE) {
7573 * Use CAM_EPF_NORMAL so we only get one line of
7574 * SMP command decoding.
7576 cam_error_print(device, ccb, CAM_ESF_ALL,
7577 CAM_EPF_NORMAL, stderr);
7583 /* XXX KDM print out something here for success? */
7588 if (request != NULL)
7591 if (response != NULL)
7598 smpmaninfo(struct cam_device *device, int argc, char **argv,
7599 char *combinedopt, int retry_count, int timeout)
7602 struct smp_report_manuf_info_request request;
7603 struct smp_report_manuf_info_response response;
7604 struct sbuf *sb = NULL;
7605 int long_response = 0;
7610 * Note that at the moment we don't support sending SMP CCBs to
7611 * devices that aren't probed by CAM.
7613 ccb = cam_getccb(device);
7615 warnx("%s: error allocating CCB", __func__);
7619 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7621 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7630 bzero(&request, sizeof(request));
7631 bzero(&response, sizeof(response));
7633 smp_report_manuf_info(&ccb->smpio,
7638 (uint8_t *)&response,
7643 if (((retval = cam_send_ccb(device, ccb)) < 0)
7644 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7645 const char warnstr[] = "error sending command";
7652 if (arglist & CAM_ARG_VERBOSE) {
7653 cam_error_print(device, ccb, CAM_ESF_ALL,
7654 CAM_EPF_ALL, stderr);
7660 sb = sbuf_new_auto();
7662 warnx("%s: error allocating sbuf", __func__);
7666 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7668 if (sbuf_finish(sb) != 0) {
7669 warnx("%s: sbuf_finish", __func__);
7673 printf("%s", sbuf_data(sb));
7687 getdevid(struct cam_devitem *item)
7690 union ccb *ccb = NULL;
7692 struct cam_device *dev;
7694 dev = cam_open_btl(item->dev_match.path_id,
7695 item->dev_match.target_id,
7696 item->dev_match.target_lun, O_RDWR, NULL);
7699 warnx("%s", cam_errbuf);
7704 item->device_id_len = 0;
7706 ccb = cam_getccb(dev);
7708 warnx("%s: error allocating CCB", __func__);
7713 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7716 * On the first try, we just probe for the size of the data, and
7717 * then allocate that much memory and try again.
7720 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7721 ccb->ccb_h.flags = CAM_DIR_IN;
7722 ccb->cdai.flags = CDAI_FLAG_NONE;
7723 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7724 ccb->cdai.bufsiz = item->device_id_len;
7725 if (item->device_id_len != 0)
7726 ccb->cdai.buf = (uint8_t *)item->device_id;
7728 if (cam_send_ccb(dev, ccb) < 0) {
7729 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7734 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7735 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7740 if (item->device_id_len == 0) {
7742 * This is our first time through. Allocate the buffer,
7743 * and then go back to get the data.
7745 if (ccb->cdai.provsiz == 0) {
7746 warnx("%s: invalid .provsiz field returned with "
7747 "XPT_GDEV_ADVINFO CCB", __func__);
7751 item->device_id_len = ccb->cdai.provsiz;
7752 item->device_id = malloc(item->device_id_len);
7753 if (item->device_id == NULL) {
7754 warn("%s: unable to allocate %d bytes", __func__,
7755 item->device_id_len);
7759 ccb->ccb_h.status = CAM_REQ_INPROG;
7765 cam_close_device(dev);
7774 * XXX KDM merge this code with getdevtree()?
7777 buildbusdevlist(struct cam_devlist *devlist)
7780 int bufsize, fd = -1;
7781 struct dev_match_pattern *patterns;
7782 struct cam_devitem *item = NULL;
7783 int skip_device = 0;
7786 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7787 warn("couldn't open %s", XPT_DEVICE);
7791 bzero(&ccb, sizeof(union ccb));
7793 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7794 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7795 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7797 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7798 bufsize = sizeof(struct dev_match_result) * 100;
7799 ccb.cdm.match_buf_len = bufsize;
7800 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7801 if (ccb.cdm.matches == NULL) {
7802 warnx("can't malloc memory for matches");
7806 ccb.cdm.num_matches = 0;
7807 ccb.cdm.num_patterns = 2;
7808 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7809 ccb.cdm.num_patterns;
7811 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7812 if (patterns == NULL) {
7813 warnx("can't malloc memory for patterns");
7818 ccb.cdm.patterns = patterns;
7819 bzero(patterns, ccb.cdm.pattern_buf_len);
7821 patterns[0].type = DEV_MATCH_DEVICE;
7822 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7823 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7824 patterns[1].type = DEV_MATCH_PERIPH;
7825 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7826 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7829 * We do the ioctl multiple times if necessary, in case there are
7830 * more than 100 nodes in the EDT.
7835 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7836 warn("error sending CAMIOCOMMAND ioctl");
7841 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7842 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7843 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7844 warnx("got CAM error %#x, CDM error %d\n",
7845 ccb.ccb_h.status, ccb.cdm.status);
7850 for (i = 0; i < ccb.cdm.num_matches; i++) {
7851 switch (ccb.cdm.matches[i].type) {
7852 case DEV_MATCH_DEVICE: {
7853 struct device_match_result *dev_result;
7856 &ccb.cdm.matches[i].result.device_result;
7858 if (dev_result->flags &
7859 DEV_RESULT_UNCONFIGURED) {
7865 item = malloc(sizeof(*item));
7867 warn("%s: unable to allocate %zd bytes",
7868 __func__, sizeof(*item));
7872 bzero(item, sizeof(*item));
7873 bcopy(dev_result, &item->dev_match,
7874 sizeof(*dev_result));
7875 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7878 if (getdevid(item) != 0) {
7884 case DEV_MATCH_PERIPH: {
7885 struct periph_match_result *periph_result;
7888 &ccb.cdm.matches[i].result.periph_result;
7890 if (skip_device != 0)
7892 item->num_periphs++;
7893 item->periph_matches = realloc(
7894 item->periph_matches,
7896 sizeof(struct periph_match_result));
7897 if (item->periph_matches == NULL) {
7898 warn("%s: error allocating periph "
7903 bcopy(periph_result, &item->periph_matches[
7904 item->num_periphs - 1],
7905 sizeof(*periph_result));
7909 fprintf(stderr, "%s: unexpected match "
7910 "type %d\n", __func__,
7911 ccb.cdm.matches[i].type);
7914 break; /*NOTREACHED*/
7917 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7918 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7926 free(ccb.cdm.matches);
7929 freebusdevlist(devlist);
7935 freebusdevlist(struct cam_devlist *devlist)
7937 struct cam_devitem *item, *item2;
7939 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7940 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7942 free(item->device_id);
7943 free(item->periph_matches);
7948 static struct cam_devitem *
7949 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7951 struct cam_devitem *item;
7953 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7954 struct scsi_vpd_id_descriptor *idd;
7957 * XXX KDM look for LUN IDs as well?
7959 idd = scsi_get_devid(item->device_id,
7960 item->device_id_len,
7961 scsi_devid_is_sas_target);
7965 if (scsi_8btou64(idd->identifier) == sasaddr)
7973 smpphylist(struct cam_device *device, int argc, char **argv,
7974 char *combinedopt, int retry_count, int timeout)
7976 struct smp_report_general_request *rgrequest = NULL;
7977 struct smp_report_general_response *rgresponse = NULL;
7978 struct smp_discover_request *disrequest = NULL;
7979 struct smp_discover_response *disresponse = NULL;
7980 struct cam_devlist devlist;
7982 int long_response = 0;
7989 * Note that at the moment we don't support sending SMP CCBs to
7990 * devices that aren't probed by CAM.
7992 ccb = cam_getccb(device);
7994 warnx("%s: error allocating CCB", __func__);
7998 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7999 STAILQ_INIT(&devlist.dev_queue);
8001 rgrequest = malloc(sizeof(*rgrequest));
8002 if (rgrequest == NULL) {
8003 warn("%s: unable to allocate %zd bytes", __func__,
8004 sizeof(*rgrequest));
8009 rgresponse = malloc(sizeof(*rgresponse));
8010 if (rgresponse == NULL) {
8011 warn("%s: unable to allocate %zd bytes", __func__,
8012 sizeof(*rgresponse));
8017 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8030 smp_report_general(&ccb->smpio,
8034 /*request_len*/ sizeof(*rgrequest),
8035 (uint8_t *)rgresponse,
8036 /*response_len*/ sizeof(*rgresponse),
8037 /*long_response*/ long_response,
8040 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8042 if (((retval = cam_send_ccb(device, ccb)) < 0)
8043 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8044 const char warnstr[] = "error sending command";
8051 if (arglist & CAM_ARG_VERBOSE) {
8052 cam_error_print(device, ccb, CAM_ESF_ALL,
8053 CAM_EPF_ALL, stderr);
8059 num_phys = rgresponse->num_phys;
8061 if (num_phys == 0) {
8063 fprintf(stdout, "%s: No Phys reported\n", __func__);
8068 devlist.path_id = device->path_id;
8070 retval = buildbusdevlist(&devlist);
8075 fprintf(stdout, "%d PHYs:\n", num_phys);
8076 fprintf(stdout, "PHY Attached SAS Address\n");
8079 disrequest = malloc(sizeof(*disrequest));
8080 if (disrequest == NULL) {
8081 warn("%s: unable to allocate %zd bytes", __func__,
8082 sizeof(*disrequest));
8087 disresponse = malloc(sizeof(*disresponse));
8088 if (disresponse == NULL) {
8089 warn("%s: unable to allocate %zd bytes", __func__,
8090 sizeof(*disresponse));
8095 for (i = 0; i < num_phys; i++) {
8096 struct cam_devitem *item;
8097 struct device_match_result *dev_match;
8098 char vendor[16], product[48], revision[16];
8102 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8104 ccb->ccb_h.status = CAM_REQ_INPROG;
8105 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8107 smp_discover(&ccb->smpio,
8111 sizeof(*disrequest),
8112 (uint8_t *)disresponse,
8113 sizeof(*disresponse),
8115 /*ignore_zone_group*/ 0,
8119 if (((retval = cam_send_ccb(device, ccb)) < 0)
8120 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8121 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8122 const char warnstr[] = "error sending command";
8129 if (arglist & CAM_ARG_VERBOSE) {
8130 cam_error_print(device, ccb, CAM_ESF_ALL,
8131 CAM_EPF_ALL, stderr);
8137 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8139 fprintf(stdout, "%3d <vacant>\n", i);
8143 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8146 item = findsasdevice(&devlist,
8147 scsi_8btou64(disresponse->attached_sas_address));
8151 || (item != NULL)) {
8152 fprintf(stdout, "%3d 0x%016jx", i,
8153 (uintmax_t)scsi_8btou64(
8154 disresponse->attached_sas_address));
8156 fprintf(stdout, "\n");
8159 } else if (quiet != 0)
8162 dev_match = &item->dev_match;
8164 if (dev_match->protocol == PROTO_SCSI) {
8165 cam_strvis(vendor, dev_match->inq_data.vendor,
8166 sizeof(dev_match->inq_data.vendor),
8168 cam_strvis(product, dev_match->inq_data.product,
8169 sizeof(dev_match->inq_data.product),
8171 cam_strvis(revision, dev_match->inq_data.revision,
8172 sizeof(dev_match->inq_data.revision),
8174 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8176 } else if ((dev_match->protocol == PROTO_ATA)
8177 || (dev_match->protocol == PROTO_SATAPM)) {
8178 cam_strvis(product, dev_match->ident_data.model,
8179 sizeof(dev_match->ident_data.model),
8181 cam_strvis(revision, dev_match->ident_data.revision,
8182 sizeof(dev_match->ident_data.revision),
8184 sprintf(tmpstr, "<%s %s>", product, revision);
8186 sprintf(tmpstr, "<>");
8188 fprintf(stdout, " %-33s ", tmpstr);
8191 * If we have 0 periphs, that's a bug...
8193 if (item->num_periphs == 0) {
8194 fprintf(stdout, "\n");
8198 fprintf(stdout, "(");
8199 for (j = 0; j < item->num_periphs; j++) {
8201 fprintf(stdout, ",");
8203 fprintf(stdout, "%s%d",
8204 item->periph_matches[j].periph_name,
8205 item->periph_matches[j].unit_number);
8208 fprintf(stdout, ")\n");
8222 freebusdevlist(&devlist);
8228 atapm(struct cam_device *device, int argc, char **argv,
8229 char *combinedopt, int retry_count, int timeout)
8237 ccb = cam_getccb(device);
8240 warnx("%s: error allocating ccb", __func__);
8244 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8253 if (strcmp(argv[1], "idle") == 0) {
8255 cmd = ATA_IDLE_IMMEDIATE;
8258 } else if (strcmp(argv[1], "standby") == 0) {
8260 cmd = ATA_STANDBY_IMMEDIATE;
8262 cmd = ATA_STANDBY_CMD;
8270 else if (t <= (240 * 5))
8272 else if (t <= (252 * 5))
8273 /* special encoding for 21 minutes */
8275 else if (t <= (11 * 30 * 60))
8276 sc = (t - 1) / (30 * 60) + 241;
8280 retval = ata_do_28bit_cmd(device,
8282 /*retries*/retry_count,
8283 /*flags*/CAM_DIR_NONE,
8284 /*protocol*/AP_PROTO_NON_DATA,
8285 /*tag_action*/MSG_SIMPLE_Q_TAG,
8292 /*timeout*/timeout ? timeout : 30 * 1000,
8300 ataaxm(struct cam_device *device, int argc, char **argv,
8301 char *combinedopt, int retry_count, int timeout)
8309 ccb = cam_getccb(device);
8312 warnx("%s: error allocating ccb", __func__);
8316 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8326 if (strcmp(argv[1], "apm") == 0) {
8342 retval = ata_do_28bit_cmd(device,
8344 /*retries*/retry_count,
8345 /*flags*/CAM_DIR_NONE,
8346 /*protocol*/AP_PROTO_NON_DATA,
8347 /*tag_action*/MSG_SIMPLE_Q_TAG,
8348 /*command*/ATA_SETFEATURES,
8354 /*timeout*/timeout ? timeout : 30 * 1000,
8362 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8363 int show_sa_errors, int sa_set, int service_action,
8364 int timeout_desc, int retry_count, int timeout, int verbosemode,
8365 uint32_t *fill_len, uint8_t **data_ptr)
8367 union ccb *ccb = NULL;
8368 uint8_t *buf = NULL;
8369 uint32_t alloc_len = 0, num_opcodes;
8370 uint32_t valid_len = 0;
8371 uint32_t avail_len = 0;
8372 struct scsi_report_supported_opcodes_all *all_hdr;
8373 struct scsi_report_supported_opcodes_one *one;
8378 * Make it clear that we haven't yet allocated or filled anything.
8383 ccb = cam_getccb(device);
8385 warnx("couldn't allocate CCB");
8390 /* cam_getccb cleans up the header, caller has to zero the payload */
8391 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8393 if (opcode_set != 0) {
8394 options |= RSO_OPTIONS_OC;
8396 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8399 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8400 sizeof(struct scsi_report_supported_opcodes_descr));
8403 if (timeout_desc != 0) {
8404 options |= RSO_RCTD;
8405 alloc_len += num_opcodes *
8406 sizeof(struct scsi_report_supported_opcodes_timeout);
8410 options |= RSO_OPTIONS_OC_SA;
8411 if (show_sa_errors != 0)
8412 options &= ~RSO_OPTIONS_OC;
8421 buf = malloc(alloc_len);
8423 warn("Unable to allocate %u bytes", alloc_len);
8427 bzero(buf, alloc_len);
8429 scsi_report_supported_opcodes(&ccb->csio,
8430 /*retries*/ retry_count,
8432 /*tag_action*/ MSG_SIMPLE_Q_TAG,
8433 /*options*/ options,
8434 /*req_opcode*/ opcode,
8435 /*req_service_action*/ service_action,
8437 /*dxfer_len*/ alloc_len,
8438 /*sense_len*/ SSD_FULL_SIZE,
8439 /*timeout*/ timeout ? timeout : 10000);
8441 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8443 if (retry_count != 0)
8444 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8446 if (cam_send_ccb(device, ccb) < 0) {
8447 perror("error sending REPORT SUPPORTED OPERATION CODES");
8452 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8453 if (verbosemode != 0)
8454 cam_error_print(device, ccb, CAM_ESF_ALL,
8455 CAM_EPF_ALL, stderr);
8461 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8463 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8464 && (valid_len >= sizeof(*all_hdr))) {
8465 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8466 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8467 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8468 && (valid_len >= sizeof(*one))) {
8469 uint32_t cdb_length;
8471 one = (struct scsi_report_supported_opcodes_one *)buf;
8472 cdb_length = scsi_2btoul(one->cdb_length);
8473 avail_len = sizeof(*one) + cdb_length;
8474 if (one->support & RSO_ONE_CTDP) {
8475 struct scsi_report_supported_opcodes_timeout *td;
8477 td = (struct scsi_report_supported_opcodes_timeout *)
8479 if (valid_len >= (avail_len + sizeof(td->length))) {
8480 avail_len += scsi_2btoul(td->length) +
8483 avail_len += sizeof(*td);
8489 * avail_len could be zero if we didn't get enough data back from
8490 * thet target to determine
8492 if ((avail_len != 0)
8493 && (avail_len > valid_len)) {
8494 alloc_len = avail_len;
8498 *fill_len = valid_len;
8510 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8511 int req_sa, uint8_t *buf, uint32_t valid_len)
8513 struct scsi_report_supported_opcodes_one *one;
8514 struct scsi_report_supported_opcodes_timeout *td;
8515 uint32_t cdb_len = 0, td_len = 0;
8516 const char *op_desc = NULL;
8520 one = (struct scsi_report_supported_opcodes_one *)buf;
8523 * If we don't have the full single opcode descriptor, no point in
8526 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8528 warnx("Only %u bytes returned, not enough to verify support",
8534 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8536 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8539 printf(", SA 0x%x", req_sa);
8542 switch (one->support & RSO_ONE_SUP_MASK) {
8543 case RSO_ONE_SUP_UNAVAIL:
8544 printf("No command support information currently available\n");
8546 case RSO_ONE_SUP_NOT_SUP:
8547 printf("Command not supported\n");
8550 break; /*NOTREACHED*/
8551 case RSO_ONE_SUP_AVAIL:
8552 printf("Command is supported, complies with a SCSI standard\n");
8554 case RSO_ONE_SUP_VENDOR:
8555 printf("Command is supported, vendor-specific "
8556 "implementation\n");
8559 printf("Unknown command support flags 0x%#x\n",
8560 one->support & RSO_ONE_SUP_MASK);
8565 * If we don't have the CDB length, it isn't exactly an error, the
8566 * command probably isn't supported.
8568 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8572 cdb_len = scsi_2btoul(one->cdb_length);
8575 * If our valid data doesn't include the full reported length,
8576 * return. The caller should have detected this and adjusted his
8577 * allocation length to get all of the available data.
8579 if (valid_len < sizeof(*one) + cdb_len) {
8585 * If all we have is the opcode, there is no point in printing out
8593 printf("CDB usage bitmap:");
8594 for (i = 0; i < cdb_len; i++) {
8595 printf(" %02x", one->cdb_usage[i]);
8600 * If we don't have a timeout descriptor, we're done.
8602 if ((one->support & RSO_ONE_CTDP) == 0)
8606 * If we don't have enough valid length to include the timeout
8607 * descriptor length, we're done.
8609 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8612 td = (struct scsi_report_supported_opcodes_timeout *)
8613 &buf[sizeof(*one) + cdb_len];
8614 td_len = scsi_2btoul(td->length);
8615 td_len += sizeof(td->length);
8618 * If we don't have the full timeout descriptor, we're done.
8620 if (td_len < sizeof(*td))
8624 * If we don't have enough valid length to contain the full timeout
8625 * descriptor, we're done.
8627 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8630 printf("Timeout information:\n");
8631 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8632 printf("Nominal timeout: %u seconds\n",
8633 scsi_4btoul(td->nominal_time));
8634 printf("Recommended timeout: %u seconds\n",
8635 scsi_4btoul(td->recommended_time));
8642 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8645 struct scsi_report_supported_opcodes_all *hdr;
8646 struct scsi_report_supported_opcodes_descr *desc;
8647 uint32_t avail_len = 0, used_len = 0;
8651 if (valid_len < sizeof(*hdr)) {
8652 warnx("%s: not enough returned data (%u bytes) opcode list",
8653 __func__, valid_len);
8657 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8658 avail_len = scsi_4btoul(hdr->length);
8659 avail_len += sizeof(hdr->length);
8661 * Take the lesser of the amount of data the drive claims is
8662 * available, and the amount of data the HBA says was returned.
8664 avail_len = MIN(avail_len, valid_len);
8666 used_len = sizeof(hdr->length);
8668 printf("%-6s %4s %8s ",
8669 "Opcode", "SA", "CDB len" );
8672 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8673 printf(" Description\n");
8675 while ((avail_len - used_len) > sizeof(*desc)) {
8676 struct scsi_report_supported_opcodes_timeout *td;
8678 const char *op_desc = NULL;
8680 cur_ptr = &buf[used_len];
8681 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8683 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8684 if (op_desc == NULL)
8685 op_desc = "UNKNOWN";
8687 printf("0x%02x %#4x %8u ", desc->opcode,
8688 scsi_2btoul(desc->service_action),
8689 scsi_2btoul(desc->cdb_length));
8691 used_len += sizeof(*desc);
8693 if ((desc->flags & RSO_CTDP) == 0) {
8694 printf(" %s\n", op_desc);
8699 * If we don't have enough space to fit a timeout
8700 * descriptor, then we're done.
8702 if (avail_len - used_len < sizeof(*td)) {
8703 used_len = avail_len;
8704 printf(" %s\n", op_desc);
8707 cur_ptr = &buf[used_len];
8708 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8709 td_len = scsi_2btoul(td->length);
8710 td_len += sizeof(td->length);
8714 * If the given timeout descriptor length is less than what
8715 * we understand, skip it.
8717 if (td_len < sizeof(*td)) {
8718 printf(" %s\n", op_desc);
8722 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8723 scsi_4btoul(td->nominal_time),
8724 scsi_4btoul(td->recommended_time), op_desc);
8731 scsiopcodes(struct cam_device *device, int argc, char **argv,
8732 char *combinedopt, int retry_count, int timeout, int verbosemode)
8735 uint32_t opcode = 0, service_action = 0;
8736 int td_set = 0, opcode_set = 0, sa_set = 0;
8737 int show_sa_errors = 1;
8738 uint32_t valid_len = 0;
8739 uint8_t *buf = NULL;
8743 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8749 opcode = strtoul(optarg, &endptr, 0);
8750 if (*endptr != '\0') {
8751 warnx("Invalid opcode \"%s\", must be a number",
8756 if (opcode > 0xff) {
8757 warnx("Invalid opcode 0x%#x, must be between"
8758 "0 and 0xff inclusive", opcode);
8765 service_action = strtoul(optarg, &endptr, 0);
8766 if (*endptr != '\0') {
8767 warnx("Invalid service action \"%s\", must "
8768 "be a number", optarg);
8772 if (service_action > 0xffff) {
8773 warnx("Invalid service action 0x%#x, must "
8774 "be between 0 and 0xffff inclusive",
8789 && (opcode_set == 0)) {
8790 warnx("You must specify an opcode with -o if a service "
8795 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8796 sa_set, service_action, td_set, retry_count,
8797 timeout, verbosemode, &valid_len, &buf);
8801 if ((opcode_set != 0)
8803 retval = scsiprintoneopcode(device, opcode, sa_set,
8804 service_action, buf, valid_len);
8806 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8815 #endif /* MINIMALISTIC */
8818 scsireprobe(struct cam_device *device)
8823 ccb = cam_getccb(device);
8826 warnx("%s: error allocating ccb", __func__);
8830 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8832 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8834 if (cam_send_ccb(device, ccb) < 0) {
8835 warn("error sending XPT_REPROBE_LUN CCB");
8840 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8841 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8853 usage(int printlong)
8856 fprintf(printlong ? stdout : stderr,
8857 "usage: camcontrol <command> [device id][generic args][command args]\n"
8858 " camcontrol devlist [-b] [-v]\n"
8859 #ifndef MINIMALISTIC
8860 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8861 " camcontrol tur [dev_id][generic args]\n"
8862 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8863 " camcontrol identify [dev_id][generic args] [-v]\n"
8864 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8865 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8867 " camcontrol start [dev_id][generic args]\n"
8868 " camcontrol stop [dev_id][generic args]\n"
8869 " camcontrol load [dev_id][generic args]\n"
8870 " camcontrol eject [dev_id][generic args]\n"
8871 " camcontrol reprobe [dev_id][generic args]\n"
8872 #endif /* MINIMALISTIC */
8873 " camcontrol rescan <all | bus[:target:lun]>\n"
8874 " camcontrol reset <all | bus[:target:lun]>\n"
8875 #ifndef MINIMALISTIC
8876 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8877 " [-q][-s][-S offset][-X]\n"
8878 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8879 " [-P pagectl][-e | -b][-d]\n"
8880 " camcontrol cmd [dev_id][generic args]\n"
8881 " <-a cmd [args] | -c cmd [args]>\n"
8882 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8883 " camcontrol smpcmd [dev_id][generic args]\n"
8884 " <-r len fmt [args]> <-R len fmt [args]>\n"
8885 " camcontrol smprg [dev_id][generic args][-l]\n"
8886 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8887 " [-o operation][-d name][-m rate][-M rate]\n"
8888 " [-T pp_timeout][-a enable|disable]\n"
8889 " [-A enable|disable][-s enable|disable]\n"
8890 " [-S enable|disable]\n"
8891 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8892 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8893 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8894 " <all|bus[:target[:lun]]|off>\n"
8895 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8896 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8897 " [-D <enable|disable>][-M mode][-O offset]\n"
8898 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8899 " [-U][-W bus_width]\n"
8900 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8901 " camcontrol sanitize [dev_id][generic args]\n"
8902 " [-a overwrite|block|crypto|exitfailure]\n"
8903 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8905 " camcontrol idle [dev_id][generic args][-t time]\n"
8906 " camcontrol standby [dev_id][generic args][-t time]\n"
8907 " camcontrol sleep [dev_id][generic args]\n"
8908 " camcontrol apm [dev_id][generic args][-l level]\n"
8909 " camcontrol aam [dev_id][generic args][-l level]\n"
8910 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8912 " camcontrol security [dev_id][generic args]\n"
8913 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8914 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8915 " [-U <user|master>] [-y]\n"
8916 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8917 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8918 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8919 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8920 " [-s scope][-S][-T type][-U]\n"
8921 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8922 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8923 " [-p part][-s start][-T type][-V vol]\n"
8924 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8926 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
8927 " [-o rep_opts] [-P print_opts]\n"
8928 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
8929 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
8930 " [-S power_src] [-T timer]\n"
8931 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
8932 " <-s <-f format -T time | -U >>\n"
8934 #endif /* MINIMALISTIC */
8935 " camcontrol help\n");
8938 #ifndef MINIMALISTIC
8940 "Specify one of the following options:\n"
8941 "devlist list all CAM devices\n"
8942 "periphlist list all CAM peripheral drivers attached to a device\n"
8943 "tur send a test unit ready to the named device\n"
8944 "inquiry send a SCSI inquiry command to the named device\n"
8945 "identify send a ATA identify command to the named device\n"
8946 "reportluns send a SCSI report luns command to the device\n"
8947 "readcap send a SCSI read capacity command to the device\n"
8948 "start send a Start Unit command to the device\n"
8949 "stop send a Stop Unit command to the device\n"
8950 "load send a Start Unit command to the device with the load bit set\n"
8951 "eject send a Stop Unit command to the device with the eject bit set\n"
8952 "reprobe update capacity information of the given device\n"
8953 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8954 "reset reset all busses, the given bus, or bus:target:lun\n"
8955 "defects read the defect list of the specified device\n"
8956 "modepage display or edit (-e) the given mode page\n"
8957 "cmd send the given SCSI command, may need -i or -o as well\n"
8958 "smpcmd send the given SMP command, requires -o and -i\n"
8959 "smprg send the SMP Report General command\n"
8960 "smppc send the SMP PHY Control command, requires -p\n"
8961 "smpphylist display phys attached to a SAS expander\n"
8962 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8963 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8964 "tags report or set the number of transaction slots for a device\n"
8965 "negotiate report or set device negotiation parameters\n"
8966 "format send the SCSI FORMAT UNIT command to the named device\n"
8967 "sanitize send the SCSI SANITIZE command to the named device\n"
8968 "idle send the ATA IDLE command to the named device\n"
8969 "standby send the ATA STANDBY command to the named device\n"
8970 "sleep send the ATA SLEEP command to the named device\n"
8971 "fwdownload program firmware of the named device with the given image\n"
8972 "security report or send ATA security commands to the named device\n"
8973 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8974 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8975 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8976 "zone manage Zoned Block (Shingled) devices\n"
8977 "epc send ATA Extended Power Conditions commands\n"
8978 "timestamp report or set the device's timestamp\n"
8979 "help this message\n"
8980 "Device Identifiers:\n"
8981 "bus:target specify the bus and target, lun defaults to 0\n"
8982 "bus:target:lun specify the bus, target and lun\n"
8983 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8984 "Generic arguments:\n"
8985 "-v be verbose, print out sense information\n"
8986 "-t timeout command timeout in seconds, overrides default timeout\n"
8987 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8988 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8989 "-E have the kernel attempt to perform SCSI error recovery\n"
8990 "-C count specify the SCSI command retry count (needs -E to work)\n"
8991 "modepage arguments:\n"
8992 "-l list all available mode pages\n"
8993 "-m page specify the mode page to view or edit\n"
8994 "-e edit the specified mode page\n"
8995 "-b force view to binary mode\n"
8996 "-d disable block descriptors for mode sense\n"
8997 "-P pgctl page control field 0-3\n"
8998 "defects arguments:\n"
8999 "-f format specify defect list format (block, bfi or phys)\n"
9000 "-G get the grown defect list\n"
9001 "-P get the permanent defect list\n"
9002 "inquiry arguments:\n"
9003 "-D get the standard inquiry data\n"
9004 "-S get the serial number\n"
9005 "-R get the transfer rate, etc.\n"
9006 "reportluns arguments:\n"
9007 "-c only report a count of available LUNs\n"
9008 "-l only print out luns, and not a count\n"
9009 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9010 "readcap arguments\n"
9011 "-b only report the blocksize\n"
9012 "-h human readable device size, base 2\n"
9013 "-H human readable device size, base 10\n"
9014 "-N print the number of blocks instead of last block\n"
9015 "-q quiet, print numbers only\n"
9016 "-s only report the last block/device size\n"
9018 "-c cdb [args] specify the SCSI CDB\n"
9019 "-i len fmt specify input data and input data format\n"
9020 "-o len fmt [args] specify output data and output data fmt\n"
9021 "smpcmd arguments:\n"
9022 "-r len fmt [args] specify the SMP command to be sent\n"
9023 "-R len fmt [args] specify SMP response format\n"
9024 "smprg arguments:\n"
9025 "-l specify the long response format\n"
9026 "smppc arguments:\n"
9027 "-p phy specify the PHY to operate on\n"
9028 "-l specify the long request/response format\n"
9029 "-o operation specify the phy control operation\n"
9030 "-d name set the attached device name\n"
9031 "-m rate set the minimum physical link rate\n"
9032 "-M rate set the maximum physical link rate\n"
9033 "-T pp_timeout set the partial pathway timeout value\n"
9034 "-a enable|disable enable or disable SATA slumber\n"
9035 "-A enable|disable enable or disable SATA partial phy power\n"
9036 "-s enable|disable enable or disable SAS slumber\n"
9037 "-S enable|disable enable or disable SAS partial phy power\n"
9038 "smpphylist arguments:\n"
9039 "-l specify the long response format\n"
9040 "-q only print phys with attached devices\n"
9041 "smpmaninfo arguments:\n"
9042 "-l specify the long response format\n"
9043 "debug arguments:\n"
9044 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9045 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9046 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9047 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9049 "-N tags specify the number of tags to use for this device\n"
9050 "-q be quiet, don't report the number of tags\n"
9051 "-v report a number of tag-related parameters\n"
9052 "negotiate arguments:\n"
9053 "-a send a test unit ready after negotiation\n"
9054 "-c report/set current negotiation settings\n"
9055 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9056 "-M mode set ATA mode\n"
9057 "-O offset set command delay offset\n"
9058 "-q be quiet, don't report anything\n"
9059 "-R syncrate synchronization rate in MHz\n"
9060 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9061 "-U report/set user negotiation settings\n"
9062 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9063 "-v also print a Path Inquiry CCB for the controller\n"
9064 "format arguments:\n"
9065 "-q be quiet, don't print status messages\n"
9066 "-r run in report only mode\n"
9067 "-w don't send immediate format command\n"
9068 "-y don't ask any questions\n"
9069 "sanitize arguments:\n"
9070 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9071 "-c passes overwrite passes to perform (1 to 31)\n"
9072 "-I invert overwrite pattern after each pass\n"
9073 "-P pattern path to overwrite pattern file\n"
9074 "-q be quiet, don't print status messages\n"
9075 "-r run in report only mode\n"
9076 "-U run operation in unrestricted completion exit mode\n"
9077 "-w don't send immediate sanitize command\n"
9078 "-y don't ask any questions\n"
9079 "idle/standby arguments:\n"
9080 "-t <arg> number of seconds before respective state.\n"
9081 "fwdownload arguments:\n"
9082 "-f fw_image path to firmware image file\n"
9083 "-q don't print informational messages, only errors\n"
9084 "-s run in simulation mode\n"
9085 "-v print info for every firmware segment sent to device\n"
9086 "-y don't ask any questions\n"
9087 "security arguments:\n"
9088 "-d pwd disable security using the given password for the selected\n"
9090 "-e pwd erase the device using the given pwd for the selected user\n"
9091 "-f freeze the security configuration of the specified device\n"
9092 "-h pwd enhanced erase the device using the given pwd for the\n"
9094 "-k pwd unlock the device using the given pwd for the selected\n"
9096 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9097 "-q be quiet, do not print any status messages\n"
9098 "-s pwd password the device (enable security) using the given\n"
9099 " pwd for the selected user\n"
9100 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9101 "-U <user|master> specifies which user to set: user or master\n"
9102 "-y don't ask any questions\n"
9104 "-f freeze the HPA configuration of the device\n"
9105 "-l lock the HPA configuration of the device\n"
9106 "-P make the HPA max sectors persist\n"
9107 "-p pwd Set the HPA configuration password required for unlock\n"
9109 "-q be quiet, do not print any status messages\n"
9110 "-s sectors configures the maximum user accessible sectors of the\n"
9112 "-U pwd unlock the HPA configuration of the device\n"
9113 "-y don't ask any questions\n"
9114 "persist arguments:\n"
9115 "-i action specify read_keys, read_reservation, report_cap, or\n"
9116 " read_full_status\n"
9117 "-o action specify register, register_ignore, reserve, release,\n"
9118 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9119 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9120 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9121 "-k key specify the Reservation Key\n"
9122 "-K sa_key specify the Service Action Reservation Key\n"
9123 "-p set the Activate Persist Through Power Loss bit\n"
9124 "-R rtp specify the Relative Target Port\n"
9125 "-s scope specify the scope: lun, extent, element or a number\n"
9126 "-S specify Transport ID for register, requires -I\n"
9127 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9128 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9129 "-U unregister the current initiator for register_move\n"
9130 "attrib arguments:\n"
9131 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9133 "-w attr specify an attribute to write, one -w argument per attr\n"
9134 "-a attr_num only display this attribute number\n"
9135 "-c get cached attributes\n"
9136 "-e elem_addr request attributes for the given element in a changer\n"
9137 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9138 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9139 " field_none, field_desc, field_num, field_size, field_rw\n"
9140 "-p partition request attributes for the given partition\n"
9141 "-s start_attr request attributes starting at the given number\n"
9142 "-T elem_type specify the element type (used with -e)\n"
9143 "-V logical_vol specify the logical volume ID\n"
9144 "opcodes arguments:\n"
9145 "-o opcode specify the individual opcode to list\n"
9146 "-s service_action specify the service action for the opcode\n"
9147 "-N do not return SCSI error for unsupported SA\n"
9148 "-T request nominal and recommended timeout values\n"
9150 "-c cmd required: rz, open, close, finish, or rwp\n"
9151 "-a apply the action to all zones\n"
9152 "-l LBA specify the zone starting LBA\n"
9153 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9154 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9155 "-P print_opt report zones printing: normal, summary, script\n"
9157 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9158 " source, status, list\n"
9159 "-d disable power mode (timer, state)\n"
9160 "-D delayed entry (goto)\n"
9161 "-e enable power mode (timer, state)\n"
9162 "-H hold power mode (goto)\n"
9163 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9165 "-P only display power mode (status)\n"
9166 "-r rst_src restore settings from: default, saved (restore)\n"
9167 "-s save mode (timer, state, restore)\n"
9168 "-S power_src set power source: battery, nonbattery (source)\n"
9169 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9170 "timestamp arguments:\n"
9171 "-r report the timestamp of the device\n"
9172 "-f format report the timestamp of the device with the given\n"
9173 " strftime(3) format string\n"
9174 "-m report the timestamp of the device as milliseconds since\n"
9175 " January 1st, 1970\n"
9176 "-U report the time with UTC instead of the local time zone\n"
9177 "-s set the timestamp of the device\n"
9178 "-f format the format of the time string passed into strptime(3)\n"
9179 "-T time the time value passed into strptime(3)\n"
9180 "-U set the timestamp of the device to UTC time\n"
9182 #endif /* MINIMALISTIC */
9186 main(int argc, char **argv)
9189 char *device = NULL;
9191 struct cam_device *cam_dev = NULL;
9192 int timeout = 0, retry_count = 1;
9193 camcontrol_optret optreturn;
9195 const char *mainopt = "C:En:t:u:v";
9196 const char *subopt = NULL;
9197 char combinedopt[256];
9198 int error = 0, optstart = 2;
9200 #ifndef MINIMALISTIC
9204 #endif /* MINIMALISTIC */
9206 cmdlist = CAM_CMD_NONE;
9207 arglist = CAM_ARG_NONE;
9215 * Get the base option.
9217 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9219 if (optreturn == CC_OR_AMBIGUOUS) {
9220 warnx("ambiguous option %s", argv[1]);
9223 } else if (optreturn == CC_OR_NOT_FOUND) {
9224 warnx("option %s not found", argv[1]);
9230 * Ahh, getopt(3) is a pain.
9232 * This is a gross hack. There really aren't many other good
9233 * options (excuse the pun) for parsing options in a situation like
9234 * this. getopt is kinda braindead, so you end up having to run
9235 * through the options twice, and give each invocation of getopt
9236 * the option string for the other invocation.
9238 * You would think that you could just have two groups of options.
9239 * The first group would get parsed by the first invocation of
9240 * getopt, and the second group would get parsed by the second
9241 * invocation of getopt. It doesn't quite work out that way. When
9242 * the first invocation of getopt finishes, it leaves optind pointing
9243 * to the argument _after_ the first argument in the second group.
9244 * So when the second invocation of getopt comes around, it doesn't
9245 * recognize the first argument it gets and then bails out.
9247 * A nice alternative would be to have a flag for getopt that says
9248 * "just keep parsing arguments even when you encounter an unknown
9249 * argument", but there isn't one. So there's no real clean way to
9250 * easily parse two sets of arguments without having one invocation
9251 * of getopt know about the other.
9253 * Without this hack, the first invocation of getopt would work as
9254 * long as the generic arguments are first, but the second invocation
9255 * (in the subfunction) would fail in one of two ways. In the case
9256 * where you don't set optreset, it would fail because optind may be
9257 * pointing to the argument after the one it should be pointing at.
9258 * In the case where you do set optreset, and reset optind, it would
9259 * fail because getopt would run into the first set of options, which
9260 * it doesn't understand.
9262 * All of this would "sort of" work if you could somehow figure out
9263 * whether optind had been incremented one option too far. The
9264 * mechanics of that, however, are more daunting than just giving
9265 * both invocations all of the expect options for either invocation.
9267 * Needless to say, I wouldn't mind if someone invented a better
9268 * (non-GPL!) command line parsing interface than getopt. I
9269 * wouldn't mind if someone added more knobs to getopt to make it
9270 * work better. Who knows, I may talk myself into doing it someday,
9271 * if the standards weenies let me. As it is, it just leads to
9272 * hackery like this and causes people to avoid it in some cases.
9274 * KDM, September 8th, 1998
9277 sprintf(combinedopt, "%s%s", mainopt, subopt);
9279 sprintf(combinedopt, "%s", mainopt);
9282 * For these options we do not parse optional device arguments and
9283 * we do not open a passthrough device.
9285 if ((cmdlist == CAM_CMD_RESCAN)
9286 || (cmdlist == CAM_CMD_RESET)
9287 || (cmdlist == CAM_CMD_DEVTREE)
9288 || (cmdlist == CAM_CMD_USAGE)
9289 || (cmdlist == CAM_CMD_DEBUG))
9292 #ifndef MINIMALISTIC
9294 && (argc > 2 && argv[2][0] != '-')) {
9298 if (isdigit(argv[2][0])) {
9299 /* device specified as bus:target[:lun] */
9300 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9302 errx(1, "numeric device specification must "
9303 "be either bus:target, or "
9305 /* default to 0 if lun was not specified */
9306 if ((arglist & CAM_ARG_LUN) == 0) {
9308 arglist |= CAM_ARG_LUN;
9312 if (cam_get_device(argv[2], name, sizeof name, &unit)
9314 errx(1, "%s", cam_errbuf);
9315 device = strdup(name);
9316 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9320 #endif /* MINIMALISTIC */
9322 * Start getopt processing at argv[2/3], since we've already
9323 * accepted argv[1..2] as the command name, and as a possible
9329 * Now we run through the argument list looking for generic
9330 * options, and ignoring options that possibly belong to
9333 while ((c = getopt(argc, argv, combinedopt))!= -1){
9336 retry_count = strtol(optarg, NULL, 0);
9337 if (retry_count < 0)
9338 errx(1, "retry count %d is < 0",
9340 arglist |= CAM_ARG_RETRIES;
9343 arglist |= CAM_ARG_ERR_RECOVER;
9346 arglist |= CAM_ARG_DEVICE;
9348 while (isspace(*tstr) && (*tstr != '\0'))
9350 device = (char *)strdup(tstr);
9353 timeout = strtol(optarg, NULL, 0);
9355 errx(1, "invalid timeout %d", timeout);
9356 /* Convert the timeout from seconds to ms */
9358 arglist |= CAM_ARG_TIMEOUT;
9361 arglist |= CAM_ARG_UNIT;
9362 unit = strtol(optarg, NULL, 0);
9365 arglist |= CAM_ARG_VERBOSE;
9372 #ifndef MINIMALISTIC
9374 * For most commands we'll want to open the passthrough device
9375 * associated with the specified device. In the case of the rescan
9376 * commands, we don't use a passthrough device at all, just the
9377 * transport layer device.
9380 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9381 && (((arglist & CAM_ARG_DEVICE) == 0)
9382 || ((arglist & CAM_ARG_UNIT) == 0))) {
9383 errx(1, "subcommand \"%s\" requires a valid device "
9384 "identifier", argv[1]);
9387 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9388 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9389 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9391 errx(1,"%s", cam_errbuf);
9393 #endif /* MINIMALISTIC */
9396 * Reset optind to 2, and reset getopt, so these routines can parse
9397 * the arguments again.
9403 #ifndef MINIMALISTIC
9404 case CAM_CMD_DEVLIST:
9405 error = getdevlist(cam_dev);
9408 error = atahpa(cam_dev, retry_count, timeout,
9409 argc, argv, combinedopt);
9411 #endif /* MINIMALISTIC */
9412 case CAM_CMD_DEVTREE:
9413 error = getdevtree(argc, argv, combinedopt);
9415 #ifndef MINIMALISTIC
9417 error = testunitready(cam_dev, retry_count, timeout, 0);
9419 case CAM_CMD_INQUIRY:
9420 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9421 retry_count, timeout);
9423 case CAM_CMD_IDENTIFY:
9424 error = ataidentify(cam_dev, retry_count, timeout);
9426 case CAM_CMD_STARTSTOP:
9427 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9428 arglist & CAM_ARG_EJECT, retry_count,
9431 #endif /* MINIMALISTIC */
9432 case CAM_CMD_RESCAN:
9433 error = dorescan_or_reset(argc, argv, 1);
9436 error = dorescan_or_reset(argc, argv, 0);
9438 #ifndef MINIMALISTIC
9439 case CAM_CMD_READ_DEFECTS:
9440 error = readdefects(cam_dev, argc, argv, combinedopt,
9441 retry_count, timeout);
9443 case CAM_CMD_MODE_PAGE:
9444 modepage(cam_dev, argc, argv, combinedopt,
9445 retry_count, timeout);
9447 case CAM_CMD_SCSI_CMD:
9448 error = scsicmd(cam_dev, argc, argv, combinedopt,
9449 retry_count, timeout);
9451 case CAM_CMD_SMP_CMD:
9452 error = smpcmd(cam_dev, argc, argv, combinedopt,
9453 retry_count, timeout);
9455 case CAM_CMD_SMP_RG:
9456 error = smpreportgeneral(cam_dev, argc, argv,
9457 combinedopt, retry_count,
9460 case CAM_CMD_SMP_PC:
9461 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9462 retry_count, timeout);
9464 case CAM_CMD_SMP_PHYLIST:
9465 error = smpphylist(cam_dev, argc, argv, combinedopt,
9466 retry_count, timeout);
9468 case CAM_CMD_SMP_MANINFO:
9469 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9470 retry_count, timeout);
9473 error = camdebug(argc, argv, combinedopt);
9476 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9479 error = ratecontrol(cam_dev, retry_count, timeout,
9480 argc, argv, combinedopt);
9482 case CAM_CMD_FORMAT:
9483 error = scsiformat(cam_dev, argc, argv,
9484 combinedopt, retry_count, timeout);
9486 case CAM_CMD_REPORTLUNS:
9487 error = scsireportluns(cam_dev, argc, argv,
9488 combinedopt, retry_count,
9491 case CAM_CMD_READCAP:
9492 error = scsireadcapacity(cam_dev, argc, argv,
9493 combinedopt, retry_count,
9497 case CAM_CMD_STANDBY:
9499 error = atapm(cam_dev, argc, argv,
9500 combinedopt, retry_count, timeout);
9504 error = ataaxm(cam_dev, argc, argv,
9505 combinedopt, retry_count, timeout);
9507 case CAM_CMD_SECURITY:
9508 error = atasecurity(cam_dev, retry_count, timeout,
9509 argc, argv, combinedopt);
9511 case CAM_CMD_DOWNLOAD_FW:
9512 error = fwdownload(cam_dev, argc, argv, combinedopt,
9513 arglist & CAM_ARG_VERBOSE, retry_count, timeout);
9515 case CAM_CMD_SANITIZE:
9516 error = scsisanitize(cam_dev, argc, argv,
9517 combinedopt, retry_count, timeout);
9519 case CAM_CMD_PERSIST:
9520 error = scsipersist(cam_dev, argc, argv, combinedopt,
9521 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9522 arglist & CAM_ARG_ERR_RECOVER);
9524 case CAM_CMD_ATTRIB:
9525 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9526 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9527 arglist & CAM_ARG_ERR_RECOVER);
9529 case CAM_CMD_OPCODES:
9530 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9531 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9533 case CAM_CMD_REPROBE:
9534 error = scsireprobe(cam_dev);
9537 error = zone(cam_dev, argc, argv, combinedopt,
9538 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9541 error = epc(cam_dev, argc, argv, combinedopt,
9542 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9544 case CAM_CMD_TIMESTAMP:
9545 error = timestamp(cam_dev, argc, argv, combinedopt,
9546 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9548 #endif /* MINIMALISTIC */
9558 if (cam_dev != NULL)
9559 cam_close_device(cam_dev);