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 buses and
3183 * send the rescan or reset to those buses 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, valid_bytes;
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);
4458 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4460 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4461 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4462 && (arglist & CAM_ARG_CMD_IN)
4463 && (valid_bytes > 0)) {
4465 buff_decode_visit(data_ptr, valid_bytes, datastr,
4467 fprintf(stdout, "\n");
4469 ssize_t amt_written;
4470 int amt_to_write = valid_bytes;
4471 u_int8_t *buf_ptr = data_ptr;
4473 for (amt_written = 0; (amt_to_write > 0) &&
4474 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4475 amt_to_write -= amt_written;
4476 buf_ptr += amt_written;
4478 if (amt_written == -1) {
4479 warn("error writing data to stdout");
4481 goto scsicmd_bailout;
4482 } else if ((amt_written == 0)
4483 && (amt_to_write > 0)) {
4484 warnx("only wrote %u bytes out of %u",
4485 valid_bytes - amt_to_write, valid_bytes);
4492 if ((data_bytes > 0) && (data_ptr != NULL))
4501 camdebug(int argc, char **argv, char *combinedopt)
4504 path_id_t bus = CAM_BUS_WILDCARD;
4505 target_id_t target = CAM_TARGET_WILDCARD;
4506 lun_id_t lun = CAM_LUN_WILDCARD;
4507 char *tstr, *tmpstr = NULL;
4511 bzero(&ccb, sizeof(union ccb));
4513 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4516 arglist |= CAM_ARG_DEBUG_INFO;
4517 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4520 arglist |= CAM_ARG_DEBUG_PERIPH;
4521 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4524 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4525 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4528 arglist |= CAM_ARG_DEBUG_TRACE;
4529 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4532 arglist |= CAM_ARG_DEBUG_XPT;
4533 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4536 arglist |= CAM_ARG_DEBUG_CDB;
4537 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4540 arglist |= CAM_ARG_DEBUG_PROBE;
4541 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4548 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4549 warnx("error opening transport layer device %s", XPT_DEVICE);
4550 warn("%s", XPT_DEVICE);
4557 warnx("you must specify \"off\", \"all\" or a bus,");
4558 warnx("bus:target, or bus:target:lun");
4565 while (isspace(*tstr) && (*tstr != '\0'))
4568 if (strncmp(tstr, "off", 3) == 0) {
4569 ccb.cdbg.flags = CAM_DEBUG_NONE;
4570 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4571 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4572 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4573 } else if (strncmp(tstr, "all", 3) != 0) {
4574 tmpstr = (char *)strtok(tstr, ":");
4575 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4576 bus = strtol(tmpstr, NULL, 0);
4577 arglist |= CAM_ARG_BUS;
4578 tmpstr = (char *)strtok(NULL, ":");
4579 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4580 target = strtol(tmpstr, NULL, 0);
4581 arglist |= CAM_ARG_TARGET;
4582 tmpstr = (char *)strtok(NULL, ":");
4583 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4584 lun = strtol(tmpstr, NULL, 0);
4585 arglist |= CAM_ARG_LUN;
4590 warnx("you must specify \"all\", \"off\", or a bus,");
4591 warnx("bus:target, or bus:target:lun to debug");
4597 ccb.ccb_h.func_code = XPT_DEBUG;
4598 ccb.ccb_h.path_id = bus;
4599 ccb.ccb_h.target_id = target;
4600 ccb.ccb_h.target_lun = lun;
4602 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4603 warn("CAMIOCOMMAND ioctl failed");
4608 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4609 CAM_FUNC_NOTAVAIL) {
4610 warnx("CAM debugging not available");
4611 warnx("you need to put options CAMDEBUG in"
4612 " your kernel config file!");
4614 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4616 warnx("XPT_DEBUG CCB failed with status %#x",
4620 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4622 "Debugging turned off\n");
4625 "Debugging enabled for "
4627 bus, target, (uintmax_t)lun);
4638 tagcontrol(struct cam_device *device, int argc, char **argv,
4648 ccb = cam_getccb(device);
4651 warnx("tagcontrol: error allocating ccb");
4655 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4658 numtags = strtol(optarg, NULL, 0);
4660 warnx("tag count %d is < 0", numtags);
4662 goto tagcontrol_bailout;
4673 cam_path_string(device, pathstr, sizeof(pathstr));
4676 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4677 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4678 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4679 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4680 ccb->crs.openings = numtags;
4683 if (cam_send_ccb(device, ccb) < 0) {
4684 perror("error sending XPT_REL_SIMQ CCB");
4686 goto tagcontrol_bailout;
4689 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4690 warnx("XPT_REL_SIMQ CCB failed");
4691 cam_error_print(device, ccb, CAM_ESF_ALL,
4692 CAM_EPF_ALL, stderr);
4694 goto tagcontrol_bailout;
4699 fprintf(stdout, "%stagged openings now %d\n",
4700 pathstr, ccb->crs.openings);
4703 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4705 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4707 if (cam_send_ccb(device, ccb) < 0) {
4708 perror("error sending XPT_GDEV_STATS CCB");
4710 goto tagcontrol_bailout;
4713 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4714 warnx("XPT_GDEV_STATS CCB failed");
4715 cam_error_print(device, ccb, CAM_ESF_ALL,
4716 CAM_EPF_ALL, stderr);
4718 goto tagcontrol_bailout;
4721 if (arglist & CAM_ARG_VERBOSE) {
4722 fprintf(stdout, "%s", pathstr);
4723 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4724 fprintf(stdout, "%s", pathstr);
4725 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4726 fprintf(stdout, "%s", pathstr);
4727 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4728 fprintf(stdout, "%s", pathstr);
4729 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4730 fprintf(stdout, "%s", pathstr);
4731 fprintf(stdout, "held %d\n", ccb->cgds.held);
4732 fprintf(stdout, "%s", pathstr);
4733 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4734 fprintf(stdout, "%s", pathstr);
4735 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4738 fprintf(stdout, "%s", pathstr);
4739 fprintf(stdout, "device openings: ");
4741 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4742 ccb->cgds.dev_active);
4752 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4756 cam_path_string(device, pathstr, sizeof(pathstr));
4758 if (cts->transport == XPORT_SPI) {
4759 struct ccb_trans_settings_spi *spi =
4760 &cts->xport_specific.spi;
4762 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4764 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4767 if (spi->sync_offset != 0) {
4770 freq = scsi_calc_syncsrate(spi->sync_period);
4771 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4772 pathstr, freq / 1000, freq % 1000);
4776 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4777 fprintf(stdout, "%soffset: %d\n", pathstr,
4781 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4782 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4783 (0x01 << spi->bus_width) * 8);
4786 if (spi->valid & CTS_SPI_VALID_DISC) {
4787 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4788 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4789 "enabled" : "disabled");
4792 if (cts->transport == XPORT_FC) {
4793 struct ccb_trans_settings_fc *fc =
4794 &cts->xport_specific.fc;
4796 if (fc->valid & CTS_FC_VALID_WWNN)
4797 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4798 (long long) fc->wwnn);
4799 if (fc->valid & CTS_FC_VALID_WWPN)
4800 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4801 (long long) fc->wwpn);
4802 if (fc->valid & CTS_FC_VALID_PORT)
4803 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4804 if (fc->valid & CTS_FC_VALID_SPEED)
4805 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4806 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4808 if (cts->transport == XPORT_SAS) {
4809 struct ccb_trans_settings_sas *sas =
4810 &cts->xport_specific.sas;
4812 if (sas->valid & CTS_SAS_VALID_SPEED)
4813 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4814 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4816 if (cts->transport == XPORT_ATA) {
4817 struct ccb_trans_settings_pata *pata =
4818 &cts->xport_specific.ata;
4820 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4821 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4822 ata_mode2string(pata->mode));
4824 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4825 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4828 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4829 fprintf(stdout, "%sPIO transaction length: %d\n",
4830 pathstr, pata->bytecount);
4833 if (cts->transport == XPORT_SATA) {
4834 struct ccb_trans_settings_sata *sata =
4835 &cts->xport_specific.sata;
4837 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4838 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4841 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4842 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4843 ata_mode2string(sata->mode));
4845 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4846 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4849 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4850 fprintf(stdout, "%sPIO transaction length: %d\n",
4851 pathstr, sata->bytecount);
4853 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4854 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4857 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4858 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4861 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4862 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4866 if (cts->protocol == PROTO_ATA) {
4867 struct ccb_trans_settings_ata *ata=
4868 &cts->proto_specific.ata;
4870 if (ata->valid & CTS_ATA_VALID_TQ) {
4871 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4872 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4873 "enabled" : "disabled");
4876 if (cts->protocol == PROTO_SCSI) {
4877 struct ccb_trans_settings_scsi *scsi=
4878 &cts->proto_specific.scsi;
4880 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4881 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4882 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4883 "enabled" : "disabled");
4890 * Get a path inquiry CCB for the specified device.
4893 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4898 ccb = cam_getccb(device);
4900 warnx("get_cpi: couldn't allocate CCB");
4903 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
4904 ccb->ccb_h.func_code = XPT_PATH_INQ;
4905 if (cam_send_ccb(device, ccb) < 0) {
4906 warn("get_cpi: error sending Path Inquiry CCB");
4907 if (arglist & CAM_ARG_VERBOSE)
4908 cam_error_print(device, ccb, CAM_ESF_ALL,
4909 CAM_EPF_ALL, stderr);
4911 goto get_cpi_bailout;
4913 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4914 if (arglist & CAM_ARG_VERBOSE)
4915 cam_error_print(device, ccb, CAM_ESF_ALL,
4916 CAM_EPF_ALL, stderr);
4918 goto get_cpi_bailout;
4920 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4928 * Get a get device CCB for the specified device.
4931 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4936 ccb = cam_getccb(device);
4938 warnx("get_cgd: couldn't allocate CCB");
4941 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
4942 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4943 if (cam_send_ccb(device, ccb) < 0) {
4944 warn("get_cgd: error sending Path Inquiry CCB");
4945 if (arglist & CAM_ARG_VERBOSE)
4946 cam_error_print(device, ccb, CAM_ESF_ALL,
4947 CAM_EPF_ALL, stderr);
4949 goto get_cgd_bailout;
4951 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4952 if (arglist & CAM_ARG_VERBOSE)
4953 cam_error_print(device, ccb, CAM_ESF_ALL,
4954 CAM_EPF_ALL, stderr);
4956 goto get_cgd_bailout;
4958 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4966 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4970 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4971 int timeout, int verbosemode)
4973 union ccb *ccb = NULL;
4974 struct scsi_vpd_supported_page_list sup_pages;
4978 ccb = cam_getccb(dev);
4980 warn("Unable to allocate CCB");
4985 /* cam_getccb cleans up the header, caller has to zero the payload */
4986 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4988 bzero(&sup_pages, sizeof(sup_pages));
4990 scsi_inquiry(&ccb->csio,
4991 /*retries*/ retry_count,
4993 /* tag_action */ MSG_SIMPLE_Q_TAG,
4994 /* inq_buf */ (u_int8_t *)&sup_pages,
4995 /* inq_len */ sizeof(sup_pages),
4997 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
4998 /* sense_len */ SSD_FULL_SIZE,
4999 /* timeout */ timeout ? timeout : 5000);
5001 /* Disable freezing the device queue */
5002 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5004 if (retry_count != 0)
5005 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5007 if (cam_send_ccb(dev, ccb) < 0) {
5014 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5015 if (verbosemode != 0)
5016 cam_error_print(dev, ccb, CAM_ESF_ALL,
5017 CAM_EPF_ALL, stderr);
5022 for (i = 0; i < sup_pages.length; i++) {
5023 if (sup_pages.list[i] == page_id) {
5036 * devtype is filled in with the type of device.
5037 * Returns 0 for success, non-zero for failure.
5040 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5041 int verbosemode, camcontrol_devtype *devtype)
5043 struct ccb_getdev cgd;
5046 retval = get_cgd(dev, &cgd);
5050 switch (cgd.protocol) {
5056 *devtype = CC_DT_ATA;
5058 break; /*NOTREACHED*/
5060 *devtype = CC_DT_UNKNOWN;
5062 break; /*NOTREACHED*/
5066 * Check for the ATA Information VPD page (0x89). If this is an
5067 * ATA device behind a SCSI to ATA translation layer, this VPD page
5068 * should be present.
5070 * If that VPD page isn't present, or we get an error back from the
5071 * INQUIRY command, we'll just treat it as a normal SCSI device.
5073 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5074 timeout, verbosemode);
5076 *devtype = CC_DT_ATA_BEHIND_SCSI;
5078 *devtype = CC_DT_SCSI;
5087 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5088 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5089 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5090 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5091 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5092 int is48bit, camcontrol_devtype devtype)
5096 if (devtype == CC_DT_ATA) {
5097 cam_fill_ataio(&ccb->ataio,
5098 /*retries*/ retry_count,
5101 /*tag_action*/ tag_action,
5102 /*data_ptr*/ data_ptr,
5103 /*dxfer_len*/ dxfer_len,
5104 /*timeout*/ timeout);
5105 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5106 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5109 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5112 if (auxiliary != 0) {
5113 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5114 ccb->ataio.aux = auxiliary;
5117 if (ata_flags & AP_FLAG_CHK_COND)
5118 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5120 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5121 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5122 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5123 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5125 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5126 protocol |= AP_EXTEND;
5128 retval = scsi_ata_pass(&ccb->csio,
5129 /*retries*/ retry_count,
5132 /*tag_action*/ tag_action,
5133 /*protocol*/ protocol,
5134 /*ata_flags*/ ata_flags,
5135 /*features*/ features,
5136 /*sector_count*/ sector_count,
5138 /*command*/ command,
5141 /*auxiliary*/ auxiliary,
5143 /*data_ptr*/ data_ptr,
5144 /*dxfer_len*/ dxfer_len,
5145 /*cdb_storage*/ cdb_storage,
5146 /*cdb_storage_len*/ cdb_storage_len,
5147 /*minimum_cmd_size*/ 0,
5148 /*sense_len*/ sense_len,
5149 /*timeout*/ timeout);
5156 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5157 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5161 switch (ccb->ccb_h.func_code) {
5164 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5167 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5168 * or 16 byte, and need to see what
5170 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5171 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5173 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5174 if ((opcode != ATA_PASS_12)
5175 && (opcode != ATA_PASS_16)) {
5177 warnx("%s: unsupported opcode %02x", __func__, opcode);
5181 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5183 /* Note: the _ccb() variant returns 0 for an error */
5190 switch (error_code) {
5191 case SSD_DESC_CURRENT_ERROR:
5192 case SSD_DESC_DEFERRED_ERROR: {
5193 struct scsi_sense_data_desc *sense;
5194 struct scsi_sense_ata_ret_desc *desc;
5197 sense = (struct scsi_sense_data_desc *)
5198 &ccb->csio.sense_data;
5200 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5201 ccb->csio.sense_resid, SSD_DESC_ATA);
5202 if (desc_ptr == NULL) {
5203 cam_error_print(dev, ccb, CAM_ESF_ALL,
5204 CAM_EPF_ALL, stderr);
5208 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5210 *error = desc->error;
5211 *count = (desc->count_15_8 << 8) |
5213 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5214 ((uint64_t)desc->lba_39_32 << 32) |
5215 ((uint64_t)desc->lba_31_24 << 24) |
5216 (desc->lba_23_16 << 16) |
5217 (desc->lba_15_8 << 8) |
5219 *device = desc->device;
5220 *status = desc->status;
5223 * If the extend bit isn't set, the result is for a
5224 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5225 * command without the extend bit set. This means
5226 * that the device is supposed to return 28-bit
5227 * status. The count field is only 8 bits, and the
5228 * LBA field is only 8 bits.
5230 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5236 case SSD_CURRENT_ERROR:
5237 case SSD_DEFERRED_ERROR: {
5239 struct scsi_sense_data_fixed *sense;
5242 * XXX KDM need to support fixed sense data.
5244 warnx("%s: Fixed sense data not supported yet",
5248 break; /*NOTREACHED*/
5259 struct ata_res *res;
5262 * In this case, we have an ATA command, and we need to
5263 * fill in the requested values from the result register
5266 res = &ccb->ataio.res;
5267 *error = res->error;
5268 *status = res->status;
5269 *device = res->device;
5270 *count = res->sector_count;
5271 *lba = (res->lba_high << 16) |
5272 (res->lba_mid << 8) |
5274 if (res->flags & CAM_ATAIO_48BIT) {
5275 *count |= (res->sector_count_exp << 8);
5276 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5277 ((uint64_t)res->lba_mid_exp << 32) |
5278 ((uint64_t)res->lba_high_exp << 40);
5280 *lba |= (res->device & 0xf) << 24;
5293 cpi_print(struct ccb_pathinq *cpi)
5295 char adapter_str[1024];
5298 snprintf(adapter_str, sizeof(adapter_str),
5299 "%s%d:", cpi->dev_name, cpi->unit_number);
5301 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5304 for (i = 1; i < 0xff; i = i << 1) {
5307 if ((i & cpi->hba_inquiry) == 0)
5310 fprintf(stdout, "%s supports ", adapter_str);
5314 str = "MDP message";
5317 str = "32 bit wide SCSI";
5320 str = "16 bit wide SCSI";
5323 str = "SDTR message";
5326 str = "linked CDBs";
5329 str = "tag queue messages";
5332 str = "soft reset alternative";
5335 str = "SATA Port Multiplier";
5338 str = "unknown PI bit set";
5341 fprintf(stdout, "%s\n", str);
5344 for (i = 1; i < 0xff; i = i << 1) {
5347 if ((i & cpi->hba_misc) == 0)
5350 fprintf(stdout, "%s ", adapter_str);
5354 str = "bus scans from high ID to low ID";
5357 str = "removable devices not included in scan";
5359 case PIM_NOINITIATOR:
5360 str = "initiator role not supported";
5362 case PIM_NOBUSRESET:
5363 str = "user has disabled initial BUS RESET or"
5364 " controller is in target/mixed mode";
5367 str = "do not send 6-byte commands";
5370 str = "scan bus sequentially";
5373 str = "unknown PIM bit set";
5376 fprintf(stdout, "%s\n", str);
5379 for (i = 1; i < 0xff; i = i << 1) {
5382 if ((i & cpi->target_sprt) == 0)
5385 fprintf(stdout, "%s supports ", adapter_str);
5388 str = "target mode processor mode";
5391 str = "target mode phase cog. mode";
5393 case PIT_DISCONNECT:
5394 str = "disconnects in target mode";
5397 str = "terminate I/O message in target mode";
5400 str = "group 6 commands in target mode";
5403 str = "group 7 commands in target mode";
5406 str = "unknown PIT bit set";
5410 fprintf(stdout, "%s\n", str);
5412 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5414 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5416 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5418 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5419 adapter_str, cpi->hpath_id);
5420 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5422 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5423 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5424 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5425 adapter_str, cpi->hba_vendor);
5426 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5427 adapter_str, cpi->hba_device);
5428 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5429 adapter_str, cpi->hba_subvendor);
5430 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5431 adapter_str, cpi->hba_subdevice);
5432 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5433 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5434 if (cpi->base_transfer_speed > 1000)
5435 fprintf(stdout, "%d.%03dMB/sec\n",
5436 cpi->base_transfer_speed / 1000,
5437 cpi->base_transfer_speed % 1000);
5439 fprintf(stdout, "%dKB/sec\n",
5440 (cpi->base_transfer_speed % 1000) * 1000);
5441 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5442 adapter_str, cpi->maxio);
5446 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5447 struct ccb_trans_settings *cts)
5453 ccb = cam_getccb(device);
5456 warnx("get_print_cts: error allocating ccb");
5460 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5462 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5464 if (user_settings == 0)
5465 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5467 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5469 if (cam_send_ccb(device, ccb) < 0) {
5470 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5471 if (arglist & CAM_ARG_VERBOSE)
5472 cam_error_print(device, ccb, CAM_ESF_ALL,
5473 CAM_EPF_ALL, stderr);
5475 goto get_print_cts_bailout;
5478 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5479 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5480 if (arglist & CAM_ARG_VERBOSE)
5481 cam_error_print(device, ccb, CAM_ESF_ALL,
5482 CAM_EPF_ALL, stderr);
5484 goto get_print_cts_bailout;
5488 cts_print(device, &ccb->cts);
5491 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5493 get_print_cts_bailout:
5501 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5502 int argc, char **argv, char *combinedopt)
5506 int user_settings = 0;
5508 int disc_enable = -1, tag_enable = -1;
5511 double syncrate = -1;
5514 int change_settings = 0, send_tur = 0;
5515 struct ccb_pathinq cpi;
5517 ccb = cam_getccb(device);
5519 warnx("ratecontrol: error allocating ccb");
5522 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5531 if (strncasecmp(optarg, "enable", 6) == 0)
5533 else if (strncasecmp(optarg, "disable", 7) == 0)
5536 warnx("-D argument \"%s\" is unknown", optarg);
5538 goto ratecontrol_bailout;
5540 change_settings = 1;
5543 mode = ata_string2mode(optarg);
5545 warnx("unknown mode '%s'", optarg);
5547 goto ratecontrol_bailout;
5549 change_settings = 1;
5552 offset = strtol(optarg, NULL, 0);
5554 warnx("offset value %d is < 0", offset);
5556 goto ratecontrol_bailout;
5558 change_settings = 1;
5564 syncrate = atof(optarg);
5566 warnx("sync rate %f is < 0", syncrate);
5568 goto ratecontrol_bailout;
5570 change_settings = 1;
5573 if (strncasecmp(optarg, "enable", 6) == 0)
5575 else if (strncasecmp(optarg, "disable", 7) == 0)
5578 warnx("-T argument \"%s\" is unknown", optarg);
5580 goto ratecontrol_bailout;
5582 change_settings = 1;
5588 bus_width = strtol(optarg, NULL, 0);
5589 if (bus_width < 0) {
5590 warnx("bus width %d is < 0", bus_width);
5592 goto ratecontrol_bailout;
5594 change_settings = 1;
5600 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5602 * Grab path inquiry information, so we can determine whether
5603 * or not the initiator is capable of the things that the user
5606 ccb->ccb_h.func_code = XPT_PATH_INQ;
5607 if (cam_send_ccb(device, ccb) < 0) {
5608 perror("error sending XPT_PATH_INQ CCB");
5609 if (arglist & CAM_ARG_VERBOSE) {
5610 cam_error_print(device, ccb, CAM_ESF_ALL,
5611 CAM_EPF_ALL, stderr);
5614 goto ratecontrol_bailout;
5616 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5617 warnx("XPT_PATH_INQ CCB failed");
5618 if (arglist & CAM_ARG_VERBOSE) {
5619 cam_error_print(device, ccb, CAM_ESF_ALL,
5620 CAM_EPF_ALL, stderr);
5623 goto ratecontrol_bailout;
5625 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5626 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5628 fprintf(stdout, "%s parameters:\n",
5629 user_settings ? "User" : "Current");
5631 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5633 goto ratecontrol_bailout;
5635 if (arglist & CAM_ARG_VERBOSE)
5638 if (change_settings) {
5639 int didsettings = 0;
5640 struct ccb_trans_settings_spi *spi = NULL;
5641 struct ccb_trans_settings_pata *pata = NULL;
5642 struct ccb_trans_settings_sata *sata = NULL;
5643 struct ccb_trans_settings_ata *ata = NULL;
5644 struct ccb_trans_settings_scsi *scsi = NULL;
5646 if (ccb->cts.transport == XPORT_SPI)
5647 spi = &ccb->cts.xport_specific.spi;
5648 if (ccb->cts.transport == XPORT_ATA)
5649 pata = &ccb->cts.xport_specific.ata;
5650 if (ccb->cts.transport == XPORT_SATA)
5651 sata = &ccb->cts.xport_specific.sata;
5652 if (ccb->cts.protocol == PROTO_ATA)
5653 ata = &ccb->cts.proto_specific.ata;
5654 if (ccb->cts.protocol == PROTO_SCSI)
5655 scsi = &ccb->cts.proto_specific.scsi;
5656 ccb->cts.xport_specific.valid = 0;
5657 ccb->cts.proto_specific.valid = 0;
5658 if (spi && disc_enable != -1) {
5659 spi->valid |= CTS_SPI_VALID_DISC;
5660 if (disc_enable == 0)
5661 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5663 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5666 if (tag_enable != -1) {
5667 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5668 warnx("HBA does not support tagged queueing, "
5669 "so you cannot modify tag settings");
5671 goto ratecontrol_bailout;
5674 ata->valid |= CTS_SCSI_VALID_TQ;
5675 if (tag_enable == 0)
5676 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5678 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5681 scsi->valid |= CTS_SCSI_VALID_TQ;
5682 if (tag_enable == 0)
5683 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5685 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5689 if (spi && offset != -1) {
5690 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5691 warnx("HBA is not capable of changing offset");
5693 goto ratecontrol_bailout;
5695 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5696 spi->sync_offset = offset;
5699 if (spi && syncrate != -1) {
5700 int prelim_sync_period;
5702 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5703 warnx("HBA is not capable of changing "
5706 goto ratecontrol_bailout;
5708 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5710 * The sync rate the user gives us is in MHz.
5711 * We need to translate it into KHz for this
5716 * Next, we calculate a "preliminary" sync period
5717 * in tenths of a nanosecond.
5720 prelim_sync_period = 0;
5722 prelim_sync_period = 10000000 / syncrate;
5724 scsi_calc_syncparam(prelim_sync_period);
5727 if (sata && syncrate != -1) {
5728 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5729 warnx("HBA is not capable of changing "
5732 goto ratecontrol_bailout;
5734 if (!user_settings) {
5735 warnx("You can modify only user rate "
5736 "settings for SATA");
5738 goto ratecontrol_bailout;
5740 sata->revision = ata_speed2revision(syncrate * 100);
5741 if (sata->revision < 0) {
5742 warnx("Invalid rate %f", syncrate);
5744 goto ratecontrol_bailout;
5746 sata->valid |= CTS_SATA_VALID_REVISION;
5749 if ((pata || sata) && mode != -1) {
5750 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5751 warnx("HBA is not capable of changing "
5754 goto ratecontrol_bailout;
5756 if (!user_settings) {
5757 warnx("You can modify only user mode "
5758 "settings for ATA/SATA");
5760 goto ratecontrol_bailout;
5764 pata->valid |= CTS_ATA_VALID_MODE;
5767 sata->valid |= CTS_SATA_VALID_MODE;
5772 * The bus_width argument goes like this:
5776 * Therefore, if you shift the number of bits given on the
5777 * command line right by 4, you should get the correct
5780 if (spi && bus_width != -1) {
5782 * We might as well validate things here with a
5783 * decipherable error message, rather than what
5784 * will probably be an indecipherable error message
5785 * by the time it gets back to us.
5787 if ((bus_width == 16)
5788 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5789 warnx("HBA does not support 16 bit bus width");
5791 goto ratecontrol_bailout;
5792 } else if ((bus_width == 32)
5793 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5794 warnx("HBA does not support 32 bit bus width");
5796 goto ratecontrol_bailout;
5797 } else if ((bus_width != 8)
5798 && (bus_width != 16)
5799 && (bus_width != 32)) {
5800 warnx("Invalid bus width %d", bus_width);
5802 goto ratecontrol_bailout;
5804 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5805 spi->bus_width = bus_width >> 4;
5808 if (didsettings == 0) {
5809 goto ratecontrol_bailout;
5811 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5812 if (cam_send_ccb(device, ccb) < 0) {
5813 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5814 if (arglist & CAM_ARG_VERBOSE) {
5815 cam_error_print(device, ccb, CAM_ESF_ALL,
5816 CAM_EPF_ALL, stderr);
5819 goto ratecontrol_bailout;
5821 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5822 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5823 if (arglist & CAM_ARG_VERBOSE) {
5824 cam_error_print(device, ccb, CAM_ESF_ALL,
5825 CAM_EPF_ALL, stderr);
5828 goto ratecontrol_bailout;
5832 retval = testunitready(device, retry_count, timeout,
5833 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5835 * If the TUR didn't succeed, just bail.
5839 fprintf(stderr, "Test Unit Ready failed\n");
5840 goto ratecontrol_bailout;
5843 if ((change_settings || send_tur) && !quiet &&
5844 (ccb->cts.transport == XPORT_ATA ||
5845 ccb->cts.transport == XPORT_SATA || send_tur)) {
5846 fprintf(stdout, "New parameters:\n");
5847 retval = get_print_cts(device, user_settings, 0, NULL);
5850 ratecontrol_bailout:
5856 scsiformat(struct cam_device *device, int argc, char **argv,
5857 char *combinedopt, int retry_count, int timeout)
5861 int ycount = 0, quiet = 0;
5862 int error = 0, retval = 0;
5863 int use_timeout = 10800 * 1000;
5865 struct format_defect_list_header fh;
5866 u_int8_t *data_ptr = NULL;
5867 u_int32_t dxfer_len = 0;
5869 int num_warnings = 0;
5872 ccb = cam_getccb(device);
5875 warnx("scsiformat: error allocating ccb");
5879 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5881 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5902 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5903 "following device:\n");
5905 error = scsidoinquiry(device, argc, argv, combinedopt,
5906 retry_count, timeout);
5909 warnx("scsiformat: error sending inquiry");
5910 goto scsiformat_bailout;
5915 if (!get_confirmation()) {
5917 goto scsiformat_bailout;
5922 use_timeout = timeout;
5925 fprintf(stdout, "Current format timeout is %d seconds\n",
5926 use_timeout / 1000);
5930 * If the user hasn't disabled questions and didn't specify a
5931 * timeout on the command line, ask them if they want the current
5935 && (timeout == 0)) {
5937 int new_timeout = 0;
5939 fprintf(stdout, "Enter new timeout in seconds or press\n"
5940 "return to keep the current timeout [%d] ",
5941 use_timeout / 1000);
5943 if (fgets(str, sizeof(str), stdin) != NULL) {
5945 new_timeout = atoi(str);
5948 if (new_timeout != 0) {
5949 use_timeout = new_timeout * 1000;
5950 fprintf(stdout, "Using new timeout value %d\n",
5951 use_timeout / 1000);
5956 * Keep this outside the if block below to silence any unused
5957 * variable warnings.
5959 bzero(&fh, sizeof(fh));
5962 * If we're in immediate mode, we've got to include the format
5965 if (immediate != 0) {
5966 fh.byte2 = FU_DLH_IMMED;
5967 data_ptr = (u_int8_t *)&fh;
5968 dxfer_len = sizeof(fh);
5969 byte2 = FU_FMT_DATA;
5970 } else if (quiet == 0) {
5971 fprintf(stdout, "Formatting...");
5975 scsi_format_unit(&ccb->csio,
5976 /* retries */ retry_count,
5978 /* tag_action */ MSG_SIMPLE_Q_TAG,
5981 /* data_ptr */ data_ptr,
5982 /* dxfer_len */ dxfer_len,
5983 /* sense_len */ SSD_FULL_SIZE,
5984 /* timeout */ use_timeout);
5986 /* Disable freezing the device queue */
5987 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5989 if (arglist & CAM_ARG_ERR_RECOVER)
5990 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5992 if (((retval = cam_send_ccb(device, ccb)) < 0)
5993 || ((immediate == 0)
5994 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5995 const char errstr[] = "error sending format command";
6002 if (arglist & CAM_ARG_VERBOSE) {
6003 cam_error_print(device, ccb, CAM_ESF_ALL,
6004 CAM_EPF_ALL, stderr);
6007 goto scsiformat_bailout;
6011 * If we ran in non-immediate mode, we already checked for errors
6012 * above and printed out any necessary information. If we're in
6013 * immediate mode, we need to loop through and get status
6014 * information periodically.
6016 if (immediate == 0) {
6018 fprintf(stdout, "Format Complete\n");
6020 goto scsiformat_bailout;
6027 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6030 * There's really no need to do error recovery or
6031 * retries here, since we're just going to sit in a
6032 * loop and wait for the device to finish formatting.
6034 scsi_test_unit_ready(&ccb->csio,
6037 /* tag_action */ MSG_SIMPLE_Q_TAG,
6038 /* sense_len */ SSD_FULL_SIZE,
6039 /* timeout */ 5000);
6041 /* Disable freezing the device queue */
6042 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6044 retval = cam_send_ccb(device, ccb);
6047 * If we get an error from the ioctl, bail out. SCSI
6048 * errors are expected.
6051 warn("error sending CAMIOCOMMAND ioctl");
6052 if (arglist & CAM_ARG_VERBOSE) {
6053 cam_error_print(device, ccb, CAM_ESF_ALL,
6054 CAM_EPF_ALL, stderr);
6057 goto scsiformat_bailout;
6060 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6062 if ((status != CAM_REQ_CMP)
6063 && (status == CAM_SCSI_STATUS_ERROR)
6064 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6065 struct scsi_sense_data *sense;
6066 int error_code, sense_key, asc, ascq;
6068 sense = &ccb->csio.sense_data;
6069 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6070 ccb->csio.sense_resid, &error_code, &sense_key,
6071 &asc, &ascq, /*show_errors*/ 1);
6074 * According to the SCSI-2 and SCSI-3 specs, a
6075 * drive that is in the middle of a format should
6076 * return NOT READY with an ASC of "logical unit
6077 * not ready, format in progress". The sense key
6078 * specific bytes will then be a progress indicator.
6080 if ((sense_key == SSD_KEY_NOT_READY)
6081 && (asc == 0x04) && (ascq == 0x04)) {
6084 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6085 ccb->csio.sense_resid, sks) == 0)
6088 u_int64_t percentage;
6090 val = scsi_2btoul(&sks[1]);
6091 percentage = 10000 * val;
6094 "\rFormatting: %ju.%02u %% "
6096 (uintmax_t)(percentage /
6098 (unsigned)((percentage /
6102 } else if ((quiet == 0)
6103 && (++num_warnings <= 1)) {
6104 warnx("Unexpected SCSI Sense Key "
6105 "Specific value returned "
6107 scsi_sense_print(device, &ccb->csio,
6109 warnx("Unable to print status "
6110 "information, but format will "
6112 warnx("will exit when format is "
6117 warnx("Unexpected SCSI error during format");
6118 cam_error_print(device, ccb, CAM_ESF_ALL,
6119 CAM_EPF_ALL, stderr);
6121 goto scsiformat_bailout;
6124 } else if (status != CAM_REQ_CMP) {
6125 warnx("Unexpected CAM status %#x", status);
6126 if (arglist & CAM_ARG_VERBOSE)
6127 cam_error_print(device, ccb, CAM_ESF_ALL,
6128 CAM_EPF_ALL, stderr);
6130 goto scsiformat_bailout;
6133 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6136 fprintf(stdout, "\nFormat Complete\n");
6146 scsisanitize(struct cam_device *device, int argc, char **argv,
6147 char *combinedopt, int retry_count, int timeout)
6150 u_int8_t action = 0;
6152 int ycount = 0, quiet = 0;
6153 int error = 0, retval = 0;
6154 int use_timeout = 10800 * 1000;
6160 const char *pattern = NULL;
6161 u_int8_t *data_ptr = NULL;
6162 u_int32_t dxfer_len = 0;
6164 int num_warnings = 0;
6167 ccb = cam_getccb(device);
6170 warnx("scsisanitize: error allocating ccb");
6174 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6176 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6179 if (strcasecmp(optarg, "overwrite") == 0)
6180 action = SSZ_SERVICE_ACTION_OVERWRITE;
6181 else if (strcasecmp(optarg, "block") == 0)
6182 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6183 else if (strcasecmp(optarg, "crypto") == 0)
6184 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6185 else if (strcasecmp(optarg, "exitfailure") == 0)
6186 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6188 warnx("invalid service operation \"%s\"",
6191 goto scsisanitize_bailout;
6195 passes = strtol(optarg, NULL, 0);
6196 if (passes < 1 || passes > 31) {
6197 warnx("invalid passes value %d", passes);
6199 goto scsisanitize_bailout;
6230 warnx("an action is required");
6232 goto scsisanitize_bailout;
6233 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6234 struct scsi_sanitize_parameter_list *pl;
6238 if (pattern == NULL) {
6239 warnx("overwrite action requires -P argument");
6241 goto scsisanitize_bailout;
6243 fd = open(pattern, O_RDONLY);
6245 warn("cannot open pattern file %s", pattern);
6247 goto scsisanitize_bailout;
6249 if (fstat(fd, &sb) < 0) {
6250 warn("cannot stat pattern file %s", pattern);
6252 goto scsisanitize_bailout;
6255 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6256 warnx("pattern file size exceeds maximum value %d",
6257 SSZPL_MAX_PATTERN_LENGTH);
6259 goto scsisanitize_bailout;
6261 dxfer_len = sizeof(*pl) + sz;
6262 data_ptr = calloc(1, dxfer_len);
6263 if (data_ptr == NULL) {
6264 warnx("cannot allocate parameter list buffer");
6266 goto scsisanitize_bailout;
6269 amt = read(fd, data_ptr + sizeof(*pl), sz);
6271 warn("cannot read pattern file");
6273 goto scsisanitize_bailout;
6274 } else if (amt != sz) {
6275 warnx("short pattern file read");
6277 goto scsisanitize_bailout;
6280 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6286 pl->byte1 |= SSZPL_INVERT;
6287 scsi_ulto2b(sz, pl->length);
6293 else if (invert != 0)
6295 else if (pattern != NULL)
6300 warnx("%s argument only valid with overwrite "
6303 goto scsisanitize_bailout;
6308 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6309 "following device:\n");
6311 error = scsidoinquiry(device, argc, argv, combinedopt,
6312 retry_count, timeout);
6315 warnx("scsisanitize: error sending inquiry");
6316 goto scsisanitize_bailout;
6321 if (!get_confirmation()) {
6323 goto scsisanitize_bailout;
6328 use_timeout = timeout;
6331 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6332 use_timeout / 1000);
6336 * If the user hasn't disabled questions and didn't specify a
6337 * timeout on the command line, ask them if they want the current
6341 && (timeout == 0)) {
6343 int new_timeout = 0;
6345 fprintf(stdout, "Enter new timeout in seconds or press\n"
6346 "return to keep the current timeout [%d] ",
6347 use_timeout / 1000);
6349 if (fgets(str, sizeof(str), stdin) != NULL) {
6351 new_timeout = atoi(str);
6354 if (new_timeout != 0) {
6355 use_timeout = new_timeout * 1000;
6356 fprintf(stdout, "Using new timeout value %d\n",
6357 use_timeout / 1000);
6363 byte2 |= SSZ_UNRESTRICTED_EXIT;
6367 scsi_sanitize(&ccb->csio,
6368 /* retries */ retry_count,
6370 /* tag_action */ MSG_SIMPLE_Q_TAG,
6373 /* data_ptr */ data_ptr,
6374 /* dxfer_len */ dxfer_len,
6375 /* sense_len */ SSD_FULL_SIZE,
6376 /* timeout */ use_timeout);
6378 /* Disable freezing the device queue */
6379 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6381 if (arglist & CAM_ARG_ERR_RECOVER)
6382 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6384 if (cam_send_ccb(device, ccb) < 0) {
6385 warn("error sending sanitize command");
6387 goto scsisanitize_bailout;
6390 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6391 struct scsi_sense_data *sense;
6392 int error_code, sense_key, asc, ascq;
6394 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6395 CAM_SCSI_STATUS_ERROR) {
6396 sense = &ccb->csio.sense_data;
6397 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6398 ccb->csio.sense_resid, &error_code, &sense_key,
6399 &asc, &ascq, /*show_errors*/ 1);
6401 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6402 asc == 0x20 && ascq == 0x00)
6403 warnx("sanitize is not supported by "
6406 warnx("error sanitizing this device");
6408 warnx("error sanitizing this device");
6410 if (arglist & CAM_ARG_VERBOSE) {
6411 cam_error_print(device, ccb, CAM_ESF_ALL,
6412 CAM_EPF_ALL, stderr);
6415 goto scsisanitize_bailout;
6419 * If we ran in non-immediate mode, we already checked for errors
6420 * above and printed out any necessary information. If we're in
6421 * immediate mode, we need to loop through and get status
6422 * information periodically.
6424 if (immediate == 0) {
6426 fprintf(stdout, "Sanitize Complete\n");
6428 goto scsisanitize_bailout;
6435 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6438 * There's really no need to do error recovery or
6439 * retries here, since we're just going to sit in a
6440 * loop and wait for the device to finish sanitizing.
6442 scsi_test_unit_ready(&ccb->csio,
6445 /* tag_action */ MSG_SIMPLE_Q_TAG,
6446 /* sense_len */ SSD_FULL_SIZE,
6447 /* timeout */ 5000);
6449 /* Disable freezing the device queue */
6450 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6452 retval = cam_send_ccb(device, ccb);
6455 * If we get an error from the ioctl, bail out. SCSI
6456 * errors are expected.
6459 warn("error sending CAMIOCOMMAND ioctl");
6460 if (arglist & CAM_ARG_VERBOSE) {
6461 cam_error_print(device, ccb, CAM_ESF_ALL,
6462 CAM_EPF_ALL, stderr);
6465 goto scsisanitize_bailout;
6468 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6470 if ((status != CAM_REQ_CMP)
6471 && (status == CAM_SCSI_STATUS_ERROR)
6472 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6473 struct scsi_sense_data *sense;
6474 int error_code, sense_key, asc, ascq;
6476 sense = &ccb->csio.sense_data;
6477 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6478 ccb->csio.sense_resid, &error_code, &sense_key,
6479 &asc, &ascq, /*show_errors*/ 1);
6482 * According to the SCSI-3 spec, a drive that is in the
6483 * middle of a sanitize should return NOT READY with an
6484 * ASC of "logical unit not ready, sanitize in
6485 * progress". The sense key specific bytes will then
6486 * be a progress indicator.
6488 if ((sense_key == SSD_KEY_NOT_READY)
6489 && (asc == 0x04) && (ascq == 0x1b)) {
6492 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6493 ccb->csio.sense_resid, sks) == 0)
6496 u_int64_t percentage;
6498 val = scsi_2btoul(&sks[1]);
6499 percentage = 10000 * val;
6502 "\rSanitizing: %ju.%02u %% "
6504 (uintmax_t)(percentage /
6506 (unsigned)((percentage /
6510 } else if ((quiet == 0)
6511 && (++num_warnings <= 1)) {
6512 warnx("Unexpected SCSI Sense Key "
6513 "Specific value returned "
6514 "during sanitize:");
6515 scsi_sense_print(device, &ccb->csio,
6517 warnx("Unable to print status "
6518 "information, but sanitze will "
6520 warnx("will exit when sanitize is "
6525 warnx("Unexpected SCSI error during sanitize");
6526 cam_error_print(device, ccb, CAM_ESF_ALL,
6527 CAM_EPF_ALL, stderr);
6529 goto scsisanitize_bailout;
6532 } else if (status != CAM_REQ_CMP) {
6533 warnx("Unexpected CAM status %#x", status);
6534 if (arglist & CAM_ARG_VERBOSE)
6535 cam_error_print(device, ccb, CAM_ESF_ALL,
6536 CAM_EPF_ALL, stderr);
6538 goto scsisanitize_bailout;
6540 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6543 fprintf(stdout, "\nSanitize Complete\n");
6545 scsisanitize_bailout:
6548 if (data_ptr != NULL)
6556 scsireportluns(struct cam_device *device, int argc, char **argv,
6557 char *combinedopt, int retry_count, int timeout)
6560 int c, countonly, lunsonly;
6561 struct scsi_report_luns_data *lundata;
6563 uint8_t report_type;
6564 uint32_t list_len, i, j;
6569 report_type = RPL_REPORT_DEFAULT;
6570 ccb = cam_getccb(device);
6573 warnx("%s: error allocating ccb", __func__);
6577 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6582 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6591 if (strcasecmp(optarg, "default") == 0)
6592 report_type = RPL_REPORT_DEFAULT;
6593 else if (strcasecmp(optarg, "wellknown") == 0)
6594 report_type = RPL_REPORT_WELLKNOWN;
6595 else if (strcasecmp(optarg, "all") == 0)
6596 report_type = RPL_REPORT_ALL;
6598 warnx("%s: invalid report type \"%s\"",
6609 if ((countonly != 0)
6610 && (lunsonly != 0)) {
6611 warnx("%s: you can only specify one of -c or -l", __func__);
6616 * According to SPC-4, the allocation length must be at least 16
6617 * bytes -- enough for the header and one LUN.
6619 alloc_len = sizeof(*lundata) + 8;
6623 lundata = malloc(alloc_len);
6625 if (lundata == NULL) {
6626 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6631 scsi_report_luns(&ccb->csio,
6632 /*retries*/ retry_count,
6634 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6635 /*select_report*/ report_type,
6636 /*rpl_buf*/ lundata,
6637 /*alloc_len*/ alloc_len,
6638 /*sense_len*/ SSD_FULL_SIZE,
6639 /*timeout*/ timeout ? timeout : 5000);
6641 /* Disable freezing the device queue */
6642 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6644 if (arglist & CAM_ARG_ERR_RECOVER)
6645 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6647 if (cam_send_ccb(device, ccb) < 0) {
6648 warn("error sending REPORT LUNS command");
6650 if (arglist & CAM_ARG_VERBOSE)
6651 cam_error_print(device, ccb, CAM_ESF_ALL,
6652 CAM_EPF_ALL, stderr);
6658 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6659 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6665 list_len = scsi_4btoul(lundata->length);
6668 * If we need to list the LUNs, and our allocation
6669 * length was too short, reallocate and retry.
6671 if ((countonly == 0)
6672 && (list_len > (alloc_len - sizeof(*lundata)))) {
6673 alloc_len = list_len + sizeof(*lundata);
6679 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6680 ((list_len / 8) > 1) ? "s" : "");
6685 for (i = 0; i < (list_len / 8); i++) {
6689 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6691 fprintf(stdout, ",");
6692 switch (lundata->luns[i].lundata[j] &
6693 RPL_LUNDATA_ATYP_MASK) {
6694 case RPL_LUNDATA_ATYP_PERIPH:
6695 if ((lundata->luns[i].lundata[j] &
6696 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6697 fprintf(stdout, "%d:",
6698 lundata->luns[i].lundata[j] &
6699 RPL_LUNDATA_PERIPH_BUS_MASK);
6701 && ((lundata->luns[i].lundata[j+2] &
6702 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6705 fprintf(stdout, "%d",
6706 lundata->luns[i].lundata[j+1]);
6708 case RPL_LUNDATA_ATYP_FLAT: {
6710 tmplun[0] = lundata->luns[i].lundata[j] &
6711 RPL_LUNDATA_FLAT_LUN_MASK;
6712 tmplun[1] = lundata->luns[i].lundata[j+1];
6714 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6718 case RPL_LUNDATA_ATYP_LUN:
6719 fprintf(stdout, "%d:%d:%d",
6720 (lundata->luns[i].lundata[j+1] &
6721 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6722 lundata->luns[i].lundata[j] &
6723 RPL_LUNDATA_LUN_TARG_MASK,
6724 lundata->luns[i].lundata[j+1] &
6725 RPL_LUNDATA_LUN_LUN_MASK);
6727 case RPL_LUNDATA_ATYP_EXTLUN: {
6728 int field_len_code, eam_code;
6730 eam_code = lundata->luns[i].lundata[j] &
6731 RPL_LUNDATA_EXT_EAM_MASK;
6732 field_len_code = (lundata->luns[i].lundata[j] &
6733 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6735 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6736 && (field_len_code == 0x00)) {
6737 fprintf(stdout, "%d",
6738 lundata->luns[i].lundata[j+1]);
6739 } else if ((eam_code ==
6740 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6741 && (field_len_code == 0x03)) {
6745 * This format takes up all 8 bytes.
6746 * If we aren't starting at offset 0,
6750 fprintf(stdout, "Invalid "
6753 "specified format", j);
6757 bzero(tmp_lun, sizeof(tmp_lun));
6758 bcopy(&lundata->luns[i].lundata[j+1],
6759 &tmp_lun[1], sizeof(tmp_lun) - 1);
6760 fprintf(stdout, "%#jx",
6761 (intmax_t)scsi_8btou64(tmp_lun));
6764 fprintf(stderr, "Unknown Extended LUN"
6765 "Address method %#x, length "
6766 "code %#x", eam_code,
6773 fprintf(stderr, "Unknown LUN address method "
6774 "%#x\n", lundata->luns[i].lundata[0] &
6775 RPL_LUNDATA_ATYP_MASK);
6779 * For the flat addressing method, there are no
6780 * other levels after it.
6785 fprintf(stdout, "\n");
6798 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6799 char *combinedopt, int retry_count, int timeout)
6802 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6803 struct scsi_read_capacity_data rcap;
6804 struct scsi_read_capacity_data_long rcaplong;
6818 ccb = cam_getccb(device);
6821 warnx("%s: error allocating ccb", __func__);
6825 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6827 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6854 if ((blocksizeonly != 0)
6855 && (numblocks != 0)) {
6856 warnx("%s: you can only specify one of -b or -N", __func__);
6861 if ((blocksizeonly != 0)
6862 && (sizeonly != 0)) {
6863 warnx("%s: you can only specify one of -b or -s", __func__);
6870 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6876 && (blocksizeonly != 0)) {
6877 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6882 scsi_read_capacity(&ccb->csio,
6883 /*retries*/ retry_count,
6885 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6888 /*timeout*/ timeout ? timeout : 5000);
6890 /* Disable freezing the device queue */
6891 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6893 if (arglist & CAM_ARG_ERR_RECOVER)
6894 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6896 if (cam_send_ccb(device, ccb) < 0) {
6897 warn("error sending READ CAPACITY command");
6899 if (arglist & CAM_ARG_VERBOSE)
6900 cam_error_print(device, ccb, CAM_ESF_ALL,
6901 CAM_EPF_ALL, stderr);
6907 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6908 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6913 maxsector = scsi_4btoul(rcap.addr);
6914 block_len = scsi_4btoul(rcap.length);
6917 * A last block of 2^32-1 means that the true capacity is over 2TB,
6918 * and we need to issue the long READ CAPACITY to get the real
6919 * capacity. Otherwise, we're all set.
6921 if (maxsector != 0xffffffff)
6924 scsi_read_capacity_16(&ccb->csio,
6925 /*retries*/ retry_count,
6927 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6931 /*rcap_buf*/ (uint8_t *)&rcaplong,
6932 /*rcap_buf_len*/ sizeof(rcaplong),
6933 /*sense_len*/ SSD_FULL_SIZE,
6934 /*timeout*/ timeout ? timeout : 5000);
6936 /* Disable freezing the device queue */
6937 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6939 if (arglist & CAM_ARG_ERR_RECOVER)
6940 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6942 if (cam_send_ccb(device, ccb) < 0) {
6943 warn("error sending READ CAPACITY (16) command");
6945 if (arglist & CAM_ARG_VERBOSE)
6946 cam_error_print(device, ccb, CAM_ESF_ALL,
6947 CAM_EPF_ALL, stderr);
6953 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6954 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6959 maxsector = scsi_8btou64(rcaplong.addr);
6960 block_len = scsi_4btoul(rcaplong.length);
6963 if (blocksizeonly == 0) {
6965 * Humanize implies !quiet, and also implies numblocks.
6967 if (humanize != 0) {
6972 tmpbytes = (maxsector + 1) * block_len;
6973 ret = humanize_number(tmpstr, sizeof(tmpstr),
6974 tmpbytes, "", HN_AUTOSCALE,
6977 HN_DIVISOR_1000 : 0));
6979 warnx("%s: humanize_number failed!", __func__);
6983 fprintf(stdout, "Device Size: %s%s", tmpstr,
6984 (sizeonly == 0) ? ", " : "\n");
6985 } else if (numblocks != 0) {
6986 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6987 "Blocks: " : "", (uintmax_t)maxsector + 1,
6988 (sizeonly == 0) ? ", " : "\n");
6990 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6991 "Last Block: " : "", (uintmax_t)maxsector,
6992 (sizeonly == 0) ? ", " : "\n");
6996 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6997 "Block Length: " : "", block_len, (quiet == 0) ?
7006 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7007 int retry_count, int timeout)
7011 uint8_t *smp_request = NULL, *smp_response = NULL;
7012 int request_size = 0, response_size = 0;
7013 int fd_request = 0, fd_response = 0;
7014 char *datastr = NULL;
7015 struct get_hook hook;
7020 * Note that at the moment we don't support sending SMP CCBs to
7021 * devices that aren't probed by CAM.
7023 ccb = cam_getccb(device);
7025 warnx("%s: error allocating CCB", __func__);
7029 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7031 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7034 arglist |= CAM_ARG_CMD_IN;
7035 response_size = strtol(optarg, NULL, 0);
7036 if (response_size <= 0) {
7037 warnx("invalid number of response bytes %d",
7040 goto smpcmd_bailout;
7042 hook.argc = argc - optind;
7043 hook.argv = argv + optind;
7046 datastr = cget(&hook, NULL);
7048 * If the user supplied "-" instead of a format, he
7049 * wants the data to be written to stdout.
7051 if ((datastr != NULL)
7052 && (datastr[0] == '-'))
7055 smp_response = (u_int8_t *)malloc(response_size);
7056 if (smp_response == NULL) {
7057 warn("can't malloc memory for SMP response");
7059 goto smpcmd_bailout;
7063 arglist |= CAM_ARG_CMD_OUT;
7064 request_size = strtol(optarg, NULL, 0);
7065 if (request_size <= 0) {
7066 warnx("invalid number of request bytes %d",
7069 goto smpcmd_bailout;
7071 hook.argc = argc - optind;
7072 hook.argv = argv + optind;
7074 datastr = cget(&hook, NULL);
7075 smp_request = (u_int8_t *)malloc(request_size);
7076 if (smp_request == NULL) {
7077 warn("can't malloc memory for SMP request");
7079 goto smpcmd_bailout;
7081 bzero(smp_request, request_size);
7083 * If the user supplied "-" instead of a format, he
7084 * wants the data to be read from stdin.
7086 if ((datastr != NULL)
7087 && (datastr[0] == '-'))
7090 buff_encode_visit(smp_request, request_size,
7101 * If fd_data is set, and we're writing to the device, we need to
7102 * read the data the user wants written from stdin.
7104 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7106 int amt_to_read = request_size;
7107 u_int8_t *buf_ptr = smp_request;
7109 for (amt_read = 0; amt_to_read > 0;
7110 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7111 if (amt_read == -1) {
7112 warn("error reading data from stdin");
7114 goto smpcmd_bailout;
7116 amt_to_read -= amt_read;
7117 buf_ptr += amt_read;
7121 if (((arglist & CAM_ARG_CMD_IN) == 0)
7122 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7123 warnx("%s: need both the request (-r) and response (-R) "
7124 "arguments", __func__);
7126 goto smpcmd_bailout;
7129 flags |= CAM_DEV_QFRZDIS;
7131 cam_fill_smpio(&ccb->smpio,
7132 /*retries*/ retry_count,
7135 /*smp_request*/ smp_request,
7136 /*smp_request_len*/ request_size,
7137 /*smp_response*/ smp_response,
7138 /*smp_response_len*/ response_size,
7139 /*timeout*/ timeout ? timeout : 5000);
7141 ccb->smpio.flags = SMP_FLAG_NONE;
7143 if (((retval = cam_send_ccb(device, ccb)) < 0)
7144 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7145 const char warnstr[] = "error sending command";
7152 if (arglist & CAM_ARG_VERBOSE) {
7153 cam_error_print(device, ccb, CAM_ESF_ALL,
7154 CAM_EPF_ALL, stderr);
7158 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7159 && (response_size > 0)) {
7160 if (fd_response == 0) {
7161 buff_decode_visit(smp_response, response_size,
7162 datastr, arg_put, NULL);
7163 fprintf(stdout, "\n");
7165 ssize_t amt_written;
7166 int amt_to_write = response_size;
7167 u_int8_t *buf_ptr = smp_response;
7169 for (amt_written = 0; (amt_to_write > 0) &&
7170 (amt_written = write(STDOUT_FILENO, buf_ptr,
7171 amt_to_write)) > 0;){
7172 amt_to_write -= amt_written;
7173 buf_ptr += amt_written;
7175 if (amt_written == -1) {
7176 warn("error writing data to stdout");
7178 goto smpcmd_bailout;
7179 } else if ((amt_written == 0)
7180 && (amt_to_write > 0)) {
7181 warnx("only wrote %u bytes out of %u",
7182 response_size - amt_to_write,
7191 if (smp_request != NULL)
7194 if (smp_response != NULL)
7201 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7202 char *combinedopt, int retry_count, int timeout)
7205 struct smp_report_general_request *request = NULL;
7206 struct smp_report_general_response *response = NULL;
7207 struct sbuf *sb = NULL;
7209 int c, long_response = 0;
7213 * Note that at the moment we don't support sending SMP CCBs to
7214 * devices that aren't probed by CAM.
7216 ccb = cam_getccb(device);
7218 warnx("%s: error allocating CCB", __func__);
7222 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7224 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7233 request = malloc(sizeof(*request));
7234 if (request == NULL) {
7235 warn("%s: unable to allocate %zd bytes", __func__,
7241 response = malloc(sizeof(*response));
7242 if (response == NULL) {
7243 warn("%s: unable to allocate %zd bytes", __func__,
7250 smp_report_general(&ccb->smpio,
7254 /*request_len*/ sizeof(*request),
7255 (uint8_t *)response,
7256 /*response_len*/ sizeof(*response),
7257 /*long_response*/ long_response,
7260 if (((retval = cam_send_ccb(device, ccb)) < 0)
7261 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7262 const char warnstr[] = "error sending command";
7269 if (arglist & CAM_ARG_VERBOSE) {
7270 cam_error_print(device, ccb, CAM_ESF_ALL,
7271 CAM_EPF_ALL, stderr);
7278 * If the device supports the long response bit, try again and see
7279 * if we can get all of the data.
7281 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7282 && (long_response == 0)) {
7283 ccb->ccb_h.status = CAM_REQ_INPROG;
7284 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7290 * XXX KDM detect and decode SMP errors here.
7292 sb = sbuf_new_auto();
7294 warnx("%s: error allocating sbuf", __func__);
7298 smp_report_general_sbuf(response, sizeof(*response), sb);
7300 if (sbuf_finish(sb) != 0) {
7301 warnx("%s: sbuf_finish", __func__);
7305 printf("%s", sbuf_data(sb));
7311 if (request != NULL)
7314 if (response != NULL)
7323 static struct camcontrol_opts phy_ops[] = {
7324 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7325 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7326 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7327 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7328 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7329 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7330 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7331 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7332 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7337 smpphycontrol(struct cam_device *device, int argc, char **argv,
7338 char *combinedopt, int retry_count, int timeout)
7341 struct smp_phy_control_request *request = NULL;
7342 struct smp_phy_control_response *response = NULL;
7343 int long_response = 0;
7346 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7348 uint64_t attached_dev_name = 0;
7349 int dev_name_set = 0;
7350 uint32_t min_plr = 0, max_plr = 0;
7351 uint32_t pp_timeout_val = 0;
7352 int slumber_partial = 0;
7353 int set_pp_timeout_val = 0;
7357 * Note that at the moment we don't support sending SMP CCBs to
7358 * devices that aren't probed by CAM.
7360 ccb = cam_getccb(device);
7362 warnx("%s: error allocating CCB", __func__);
7366 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7368 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7376 if (strcasecmp(optarg, "enable") == 0)
7378 else if (strcasecmp(optarg, "disable") == 0)
7381 warnx("%s: Invalid argument %s", __func__,
7388 slumber_partial |= enable <<
7389 SMP_PC_SAS_SLUMBER_SHIFT;
7392 slumber_partial |= enable <<
7393 SMP_PC_SAS_PARTIAL_SHIFT;
7396 slumber_partial |= enable <<
7397 SMP_PC_SATA_SLUMBER_SHIFT;
7400 slumber_partial |= enable <<
7401 SMP_PC_SATA_PARTIAL_SHIFT;
7404 warnx("%s: programmer error", __func__);
7407 break; /*NOTREACHED*/
7412 attached_dev_name = (uintmax_t)strtoumax(optarg,
7421 * We don't do extensive checking here, so this
7422 * will continue to work when new speeds come out.
7424 min_plr = strtoul(optarg, NULL, 0);
7426 || (min_plr > 0xf)) {
7427 warnx("%s: invalid link rate %x",
7435 * We don't do extensive checking here, so this
7436 * will continue to work when new speeds come out.
7438 max_plr = strtoul(optarg, NULL, 0);
7440 || (max_plr > 0xf)) {
7441 warnx("%s: invalid link rate %x",
7448 camcontrol_optret optreturn;
7449 cam_argmask argnums;
7452 if (phy_op_set != 0) {
7453 warnx("%s: only one phy operation argument "
7454 "(-o) allowed", __func__);
7462 * Allow the user to specify the phy operation
7463 * numerically, as well as with a name. This will
7464 * future-proof it a bit, so options that are added
7465 * in future specs can be used.
7467 if (isdigit(optarg[0])) {
7468 phy_operation = strtoul(optarg, NULL, 0);
7469 if ((phy_operation == 0)
7470 || (phy_operation > 0xff)) {
7471 warnx("%s: invalid phy operation %#x",
7472 __func__, phy_operation);
7478 optreturn = getoption(phy_ops, optarg, &phy_operation,
7481 if (optreturn == CC_OR_AMBIGUOUS) {
7482 warnx("%s: ambiguous option %s", __func__,
7487 } else if (optreturn == CC_OR_NOT_FOUND) {
7488 warnx("%s: option %s not found", __func__,
7500 pp_timeout_val = strtoul(optarg, NULL, 0);
7501 if (pp_timeout_val > 15) {
7502 warnx("%s: invalid partial pathway timeout "
7503 "value %u, need a value less than 16",
7504 __func__, pp_timeout_val);
7508 set_pp_timeout_val = 1;
7516 warnx("%s: a PHY (-p phy) argument is required",__func__);
7521 if (((dev_name_set != 0)
7522 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7523 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7524 && (dev_name_set == 0))) {
7525 warnx("%s: -d name and -o setdevname arguments both "
7526 "required to set device name", __func__);
7531 request = malloc(sizeof(*request));
7532 if (request == NULL) {
7533 warn("%s: unable to allocate %zd bytes", __func__,
7539 response = malloc(sizeof(*response));
7540 if (response == NULL) {
7541 warn("%s: unable to allocate %zd bytes", __func__,
7547 smp_phy_control(&ccb->smpio,
7552 (uint8_t *)response,
7555 /*expected_exp_change_count*/ 0,
7558 (set_pp_timeout_val != 0) ? 1 : 0,
7566 if (((retval = cam_send_ccb(device, ccb)) < 0)
7567 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7568 const char warnstr[] = "error sending command";
7575 if (arglist & CAM_ARG_VERBOSE) {
7577 * Use CAM_EPF_NORMAL so we only get one line of
7578 * SMP command decoding.
7580 cam_error_print(device, ccb, CAM_ESF_ALL,
7581 CAM_EPF_NORMAL, stderr);
7587 /* XXX KDM print out something here for success? */
7592 if (request != NULL)
7595 if (response != NULL)
7602 smpmaninfo(struct cam_device *device, int argc, char **argv,
7603 char *combinedopt, int retry_count, int timeout)
7606 struct smp_report_manuf_info_request request;
7607 struct smp_report_manuf_info_response response;
7608 struct sbuf *sb = NULL;
7609 int long_response = 0;
7614 * Note that at the moment we don't support sending SMP CCBs to
7615 * devices that aren't probed by CAM.
7617 ccb = cam_getccb(device);
7619 warnx("%s: error allocating CCB", __func__);
7623 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7625 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7634 bzero(&request, sizeof(request));
7635 bzero(&response, sizeof(response));
7637 smp_report_manuf_info(&ccb->smpio,
7642 (uint8_t *)&response,
7647 if (((retval = cam_send_ccb(device, ccb)) < 0)
7648 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7649 const char warnstr[] = "error sending command";
7656 if (arglist & CAM_ARG_VERBOSE) {
7657 cam_error_print(device, ccb, CAM_ESF_ALL,
7658 CAM_EPF_ALL, stderr);
7664 sb = sbuf_new_auto();
7666 warnx("%s: error allocating sbuf", __func__);
7670 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7672 if (sbuf_finish(sb) != 0) {
7673 warnx("%s: sbuf_finish", __func__);
7677 printf("%s", sbuf_data(sb));
7691 getdevid(struct cam_devitem *item)
7694 union ccb *ccb = NULL;
7696 struct cam_device *dev;
7698 dev = cam_open_btl(item->dev_match.path_id,
7699 item->dev_match.target_id,
7700 item->dev_match.target_lun, O_RDWR, NULL);
7703 warnx("%s", cam_errbuf);
7708 item->device_id_len = 0;
7710 ccb = cam_getccb(dev);
7712 warnx("%s: error allocating CCB", __func__);
7717 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7720 * On the first try, we just probe for the size of the data, and
7721 * then allocate that much memory and try again.
7724 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7725 ccb->ccb_h.flags = CAM_DIR_IN;
7726 ccb->cdai.flags = CDAI_FLAG_NONE;
7727 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7728 ccb->cdai.bufsiz = item->device_id_len;
7729 if (item->device_id_len != 0)
7730 ccb->cdai.buf = (uint8_t *)item->device_id;
7732 if (cam_send_ccb(dev, ccb) < 0) {
7733 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7738 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7739 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7744 if (item->device_id_len == 0) {
7746 * This is our first time through. Allocate the buffer,
7747 * and then go back to get the data.
7749 if (ccb->cdai.provsiz == 0) {
7750 warnx("%s: invalid .provsiz field returned with "
7751 "XPT_GDEV_ADVINFO CCB", __func__);
7755 item->device_id_len = ccb->cdai.provsiz;
7756 item->device_id = malloc(item->device_id_len);
7757 if (item->device_id == NULL) {
7758 warn("%s: unable to allocate %d bytes", __func__,
7759 item->device_id_len);
7763 ccb->ccb_h.status = CAM_REQ_INPROG;
7769 cam_close_device(dev);
7778 * XXX KDM merge this code with getdevtree()?
7781 buildbusdevlist(struct cam_devlist *devlist)
7784 int bufsize, fd = -1;
7785 struct dev_match_pattern *patterns;
7786 struct cam_devitem *item = NULL;
7787 int skip_device = 0;
7790 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7791 warn("couldn't open %s", XPT_DEVICE);
7795 bzero(&ccb, sizeof(union ccb));
7797 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7798 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7799 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7801 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7802 bufsize = sizeof(struct dev_match_result) * 100;
7803 ccb.cdm.match_buf_len = bufsize;
7804 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7805 if (ccb.cdm.matches == NULL) {
7806 warnx("can't malloc memory for matches");
7810 ccb.cdm.num_matches = 0;
7811 ccb.cdm.num_patterns = 2;
7812 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7813 ccb.cdm.num_patterns;
7815 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7816 if (patterns == NULL) {
7817 warnx("can't malloc memory for patterns");
7822 ccb.cdm.patterns = patterns;
7823 bzero(patterns, ccb.cdm.pattern_buf_len);
7825 patterns[0].type = DEV_MATCH_DEVICE;
7826 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7827 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7828 patterns[1].type = DEV_MATCH_PERIPH;
7829 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7830 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7833 * We do the ioctl multiple times if necessary, in case there are
7834 * more than 100 nodes in the EDT.
7839 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7840 warn("error sending CAMIOCOMMAND ioctl");
7845 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7846 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7847 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7848 warnx("got CAM error %#x, CDM error %d\n",
7849 ccb.ccb_h.status, ccb.cdm.status);
7854 for (i = 0; i < ccb.cdm.num_matches; i++) {
7855 switch (ccb.cdm.matches[i].type) {
7856 case DEV_MATCH_DEVICE: {
7857 struct device_match_result *dev_result;
7860 &ccb.cdm.matches[i].result.device_result;
7862 if (dev_result->flags &
7863 DEV_RESULT_UNCONFIGURED) {
7869 item = malloc(sizeof(*item));
7871 warn("%s: unable to allocate %zd bytes",
7872 __func__, sizeof(*item));
7876 bzero(item, sizeof(*item));
7877 bcopy(dev_result, &item->dev_match,
7878 sizeof(*dev_result));
7879 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7882 if (getdevid(item) != 0) {
7888 case DEV_MATCH_PERIPH: {
7889 struct periph_match_result *periph_result;
7892 &ccb.cdm.matches[i].result.periph_result;
7894 if (skip_device != 0)
7896 item->num_periphs++;
7897 item->periph_matches = realloc(
7898 item->periph_matches,
7900 sizeof(struct periph_match_result));
7901 if (item->periph_matches == NULL) {
7902 warn("%s: error allocating periph "
7907 bcopy(periph_result, &item->periph_matches[
7908 item->num_periphs - 1],
7909 sizeof(*periph_result));
7913 fprintf(stderr, "%s: unexpected match "
7914 "type %d\n", __func__,
7915 ccb.cdm.matches[i].type);
7918 break; /*NOTREACHED*/
7921 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7922 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7930 free(ccb.cdm.matches);
7933 freebusdevlist(devlist);
7939 freebusdevlist(struct cam_devlist *devlist)
7941 struct cam_devitem *item, *item2;
7943 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7944 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7946 free(item->device_id);
7947 free(item->periph_matches);
7952 static struct cam_devitem *
7953 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7955 struct cam_devitem *item;
7957 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7958 struct scsi_vpd_id_descriptor *idd;
7961 * XXX KDM look for LUN IDs as well?
7963 idd = scsi_get_devid(item->device_id,
7964 item->device_id_len,
7965 scsi_devid_is_sas_target);
7969 if (scsi_8btou64(idd->identifier) == sasaddr)
7977 smpphylist(struct cam_device *device, int argc, char **argv,
7978 char *combinedopt, int retry_count, int timeout)
7980 struct smp_report_general_request *rgrequest = NULL;
7981 struct smp_report_general_response *rgresponse = NULL;
7982 struct smp_discover_request *disrequest = NULL;
7983 struct smp_discover_response *disresponse = NULL;
7984 struct cam_devlist devlist;
7986 int long_response = 0;
7993 * Note that at the moment we don't support sending SMP CCBs to
7994 * devices that aren't probed by CAM.
7996 ccb = cam_getccb(device);
7998 warnx("%s: error allocating CCB", __func__);
8002 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8003 STAILQ_INIT(&devlist.dev_queue);
8005 rgrequest = malloc(sizeof(*rgrequest));
8006 if (rgrequest == NULL) {
8007 warn("%s: unable to allocate %zd bytes", __func__,
8008 sizeof(*rgrequest));
8013 rgresponse = malloc(sizeof(*rgresponse));
8014 if (rgresponse == NULL) {
8015 warn("%s: unable to allocate %zd bytes", __func__,
8016 sizeof(*rgresponse));
8021 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8034 smp_report_general(&ccb->smpio,
8038 /*request_len*/ sizeof(*rgrequest),
8039 (uint8_t *)rgresponse,
8040 /*response_len*/ sizeof(*rgresponse),
8041 /*long_response*/ long_response,
8044 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8046 if (((retval = cam_send_ccb(device, ccb)) < 0)
8047 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8048 const char warnstr[] = "error sending command";
8055 if (arglist & CAM_ARG_VERBOSE) {
8056 cam_error_print(device, ccb, CAM_ESF_ALL,
8057 CAM_EPF_ALL, stderr);
8063 num_phys = rgresponse->num_phys;
8065 if (num_phys == 0) {
8067 fprintf(stdout, "%s: No Phys reported\n", __func__);
8072 devlist.path_id = device->path_id;
8074 retval = buildbusdevlist(&devlist);
8079 fprintf(stdout, "%d PHYs:\n", num_phys);
8080 fprintf(stdout, "PHY Attached SAS Address\n");
8083 disrequest = malloc(sizeof(*disrequest));
8084 if (disrequest == NULL) {
8085 warn("%s: unable to allocate %zd bytes", __func__,
8086 sizeof(*disrequest));
8091 disresponse = malloc(sizeof(*disresponse));
8092 if (disresponse == NULL) {
8093 warn("%s: unable to allocate %zd bytes", __func__,
8094 sizeof(*disresponse));
8099 for (i = 0; i < num_phys; i++) {
8100 struct cam_devitem *item;
8101 struct device_match_result *dev_match;
8102 char vendor[16], product[48], revision[16];
8106 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8108 ccb->ccb_h.status = CAM_REQ_INPROG;
8109 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8111 smp_discover(&ccb->smpio,
8115 sizeof(*disrequest),
8116 (uint8_t *)disresponse,
8117 sizeof(*disresponse),
8119 /*ignore_zone_group*/ 0,
8123 if (((retval = cam_send_ccb(device, ccb)) < 0)
8124 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8125 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8126 const char warnstr[] = "error sending command";
8133 if (arglist & CAM_ARG_VERBOSE) {
8134 cam_error_print(device, ccb, CAM_ESF_ALL,
8135 CAM_EPF_ALL, stderr);
8141 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8143 fprintf(stdout, "%3d <vacant>\n", i);
8147 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8150 item = findsasdevice(&devlist,
8151 scsi_8btou64(disresponse->attached_sas_address));
8155 || (item != NULL)) {
8156 fprintf(stdout, "%3d 0x%016jx", i,
8157 (uintmax_t)scsi_8btou64(
8158 disresponse->attached_sas_address));
8160 fprintf(stdout, "\n");
8163 } else if (quiet != 0)
8166 dev_match = &item->dev_match;
8168 if (dev_match->protocol == PROTO_SCSI) {
8169 cam_strvis(vendor, dev_match->inq_data.vendor,
8170 sizeof(dev_match->inq_data.vendor),
8172 cam_strvis(product, dev_match->inq_data.product,
8173 sizeof(dev_match->inq_data.product),
8175 cam_strvis(revision, dev_match->inq_data.revision,
8176 sizeof(dev_match->inq_data.revision),
8178 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8180 } else if ((dev_match->protocol == PROTO_ATA)
8181 || (dev_match->protocol == PROTO_SATAPM)) {
8182 cam_strvis(product, dev_match->ident_data.model,
8183 sizeof(dev_match->ident_data.model),
8185 cam_strvis(revision, dev_match->ident_data.revision,
8186 sizeof(dev_match->ident_data.revision),
8188 sprintf(tmpstr, "<%s %s>", product, revision);
8190 sprintf(tmpstr, "<>");
8192 fprintf(stdout, " %-33s ", tmpstr);
8195 * If we have 0 periphs, that's a bug...
8197 if (item->num_periphs == 0) {
8198 fprintf(stdout, "\n");
8202 fprintf(stdout, "(");
8203 for (j = 0; j < item->num_periphs; j++) {
8205 fprintf(stdout, ",");
8207 fprintf(stdout, "%s%d",
8208 item->periph_matches[j].periph_name,
8209 item->periph_matches[j].unit_number);
8212 fprintf(stdout, ")\n");
8226 freebusdevlist(&devlist);
8232 atapm(struct cam_device *device, int argc, char **argv,
8233 char *combinedopt, int retry_count, int timeout)
8241 ccb = cam_getccb(device);
8244 warnx("%s: error allocating ccb", __func__);
8248 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8257 if (strcmp(argv[1], "idle") == 0) {
8259 cmd = ATA_IDLE_IMMEDIATE;
8262 } else if (strcmp(argv[1], "standby") == 0) {
8264 cmd = ATA_STANDBY_IMMEDIATE;
8266 cmd = ATA_STANDBY_CMD;
8274 else if (t <= (240 * 5))
8276 else if (t <= (252 * 5))
8277 /* special encoding for 21 minutes */
8279 else if (t <= (11 * 30 * 60))
8280 sc = (t - 1) / (30 * 60) + 241;
8284 retval = ata_do_28bit_cmd(device,
8286 /*retries*/retry_count,
8287 /*flags*/CAM_DIR_NONE,
8288 /*protocol*/AP_PROTO_NON_DATA,
8289 /*tag_action*/MSG_SIMPLE_Q_TAG,
8296 /*timeout*/timeout ? timeout : 30 * 1000,
8304 ataaxm(struct cam_device *device, int argc, char **argv,
8305 char *combinedopt, int retry_count, int timeout)
8313 ccb = cam_getccb(device);
8316 warnx("%s: error allocating ccb", __func__);
8320 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8330 if (strcmp(argv[1], "apm") == 0) {
8346 retval = ata_do_28bit_cmd(device,
8348 /*retries*/retry_count,
8349 /*flags*/CAM_DIR_NONE,
8350 /*protocol*/AP_PROTO_NON_DATA,
8351 /*tag_action*/MSG_SIMPLE_Q_TAG,
8352 /*command*/ATA_SETFEATURES,
8358 /*timeout*/timeout ? timeout : 30 * 1000,
8366 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8367 int show_sa_errors, int sa_set, int service_action,
8368 int timeout_desc, int retry_count, int timeout, int verbosemode,
8369 uint32_t *fill_len, uint8_t **data_ptr)
8371 union ccb *ccb = NULL;
8372 uint8_t *buf = NULL;
8373 uint32_t alloc_len = 0, num_opcodes;
8374 uint32_t valid_len = 0;
8375 uint32_t avail_len = 0;
8376 struct scsi_report_supported_opcodes_all *all_hdr;
8377 struct scsi_report_supported_opcodes_one *one;
8382 * Make it clear that we haven't yet allocated or filled anything.
8387 ccb = cam_getccb(device);
8389 warnx("couldn't allocate CCB");
8394 /* cam_getccb cleans up the header, caller has to zero the payload */
8395 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8397 if (opcode_set != 0) {
8398 options |= RSO_OPTIONS_OC;
8400 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8403 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8404 sizeof(struct scsi_report_supported_opcodes_descr));
8407 if (timeout_desc != 0) {
8408 options |= RSO_RCTD;
8409 alloc_len += num_opcodes *
8410 sizeof(struct scsi_report_supported_opcodes_timeout);
8414 options |= RSO_OPTIONS_OC_SA;
8415 if (show_sa_errors != 0)
8416 options &= ~RSO_OPTIONS_OC;
8425 buf = malloc(alloc_len);
8427 warn("Unable to allocate %u bytes", alloc_len);
8431 bzero(buf, alloc_len);
8433 scsi_report_supported_opcodes(&ccb->csio,
8434 /*retries*/ retry_count,
8436 /*tag_action*/ MSG_SIMPLE_Q_TAG,
8437 /*options*/ options,
8438 /*req_opcode*/ opcode,
8439 /*req_service_action*/ service_action,
8441 /*dxfer_len*/ alloc_len,
8442 /*sense_len*/ SSD_FULL_SIZE,
8443 /*timeout*/ timeout ? timeout : 10000);
8445 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8447 if (retry_count != 0)
8448 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8450 if (cam_send_ccb(device, ccb) < 0) {
8451 perror("error sending REPORT SUPPORTED OPERATION CODES");
8456 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8457 if (verbosemode != 0)
8458 cam_error_print(device, ccb, CAM_ESF_ALL,
8459 CAM_EPF_ALL, stderr);
8465 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8467 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8468 && (valid_len >= sizeof(*all_hdr))) {
8469 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8470 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8471 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8472 && (valid_len >= sizeof(*one))) {
8473 uint32_t cdb_length;
8475 one = (struct scsi_report_supported_opcodes_one *)buf;
8476 cdb_length = scsi_2btoul(one->cdb_length);
8477 avail_len = sizeof(*one) + cdb_length;
8478 if (one->support & RSO_ONE_CTDP) {
8479 struct scsi_report_supported_opcodes_timeout *td;
8481 td = (struct scsi_report_supported_opcodes_timeout *)
8483 if (valid_len >= (avail_len + sizeof(td->length))) {
8484 avail_len += scsi_2btoul(td->length) +
8487 avail_len += sizeof(*td);
8493 * avail_len could be zero if we didn't get enough data back from
8494 * thet target to determine
8496 if ((avail_len != 0)
8497 && (avail_len > valid_len)) {
8498 alloc_len = avail_len;
8502 *fill_len = valid_len;
8514 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8515 int req_sa, uint8_t *buf, uint32_t valid_len)
8517 struct scsi_report_supported_opcodes_one *one;
8518 struct scsi_report_supported_opcodes_timeout *td;
8519 uint32_t cdb_len = 0, td_len = 0;
8520 const char *op_desc = NULL;
8524 one = (struct scsi_report_supported_opcodes_one *)buf;
8527 * If we don't have the full single opcode descriptor, no point in
8530 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8532 warnx("Only %u bytes returned, not enough to verify support",
8538 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8540 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8543 printf(", SA 0x%x", req_sa);
8546 switch (one->support & RSO_ONE_SUP_MASK) {
8547 case RSO_ONE_SUP_UNAVAIL:
8548 printf("No command support information currently available\n");
8550 case RSO_ONE_SUP_NOT_SUP:
8551 printf("Command not supported\n");
8554 break; /*NOTREACHED*/
8555 case RSO_ONE_SUP_AVAIL:
8556 printf("Command is supported, complies with a SCSI standard\n");
8558 case RSO_ONE_SUP_VENDOR:
8559 printf("Command is supported, vendor-specific "
8560 "implementation\n");
8563 printf("Unknown command support flags 0x%#x\n",
8564 one->support & RSO_ONE_SUP_MASK);
8569 * If we don't have the CDB length, it isn't exactly an error, the
8570 * command probably isn't supported.
8572 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8576 cdb_len = scsi_2btoul(one->cdb_length);
8579 * If our valid data doesn't include the full reported length,
8580 * return. The caller should have detected this and adjusted his
8581 * allocation length to get all of the available data.
8583 if (valid_len < sizeof(*one) + cdb_len) {
8589 * If all we have is the opcode, there is no point in printing out
8597 printf("CDB usage bitmap:");
8598 for (i = 0; i < cdb_len; i++) {
8599 printf(" %02x", one->cdb_usage[i]);
8604 * If we don't have a timeout descriptor, we're done.
8606 if ((one->support & RSO_ONE_CTDP) == 0)
8610 * If we don't have enough valid length to include the timeout
8611 * descriptor length, we're done.
8613 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8616 td = (struct scsi_report_supported_opcodes_timeout *)
8617 &buf[sizeof(*one) + cdb_len];
8618 td_len = scsi_2btoul(td->length);
8619 td_len += sizeof(td->length);
8622 * If we don't have the full timeout descriptor, we're done.
8624 if (td_len < sizeof(*td))
8628 * If we don't have enough valid length to contain the full timeout
8629 * descriptor, we're done.
8631 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8634 printf("Timeout information:\n");
8635 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8636 printf("Nominal timeout: %u seconds\n",
8637 scsi_4btoul(td->nominal_time));
8638 printf("Recommended timeout: %u seconds\n",
8639 scsi_4btoul(td->recommended_time));
8646 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8649 struct scsi_report_supported_opcodes_all *hdr;
8650 struct scsi_report_supported_opcodes_descr *desc;
8651 uint32_t avail_len = 0, used_len = 0;
8655 if (valid_len < sizeof(*hdr)) {
8656 warnx("%s: not enough returned data (%u bytes) opcode list",
8657 __func__, valid_len);
8661 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8662 avail_len = scsi_4btoul(hdr->length);
8663 avail_len += sizeof(hdr->length);
8665 * Take the lesser of the amount of data the drive claims is
8666 * available, and the amount of data the HBA says was returned.
8668 avail_len = MIN(avail_len, valid_len);
8670 used_len = sizeof(hdr->length);
8672 printf("%-6s %4s %8s ",
8673 "Opcode", "SA", "CDB len" );
8676 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8677 printf(" Description\n");
8679 while ((avail_len - used_len) > sizeof(*desc)) {
8680 struct scsi_report_supported_opcodes_timeout *td;
8682 const char *op_desc = NULL;
8684 cur_ptr = &buf[used_len];
8685 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8687 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8688 if (op_desc == NULL)
8689 op_desc = "UNKNOWN";
8691 printf("0x%02x %#4x %8u ", desc->opcode,
8692 scsi_2btoul(desc->service_action),
8693 scsi_2btoul(desc->cdb_length));
8695 used_len += sizeof(*desc);
8697 if ((desc->flags & RSO_CTDP) == 0) {
8698 printf(" %s\n", op_desc);
8703 * If we don't have enough space to fit a timeout
8704 * descriptor, then we're done.
8706 if (avail_len - used_len < sizeof(*td)) {
8707 used_len = avail_len;
8708 printf(" %s\n", op_desc);
8711 cur_ptr = &buf[used_len];
8712 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8713 td_len = scsi_2btoul(td->length);
8714 td_len += sizeof(td->length);
8718 * If the given timeout descriptor length is less than what
8719 * we understand, skip it.
8721 if (td_len < sizeof(*td)) {
8722 printf(" %s\n", op_desc);
8726 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8727 scsi_4btoul(td->nominal_time),
8728 scsi_4btoul(td->recommended_time), op_desc);
8735 scsiopcodes(struct cam_device *device, int argc, char **argv,
8736 char *combinedopt, int retry_count, int timeout, int verbosemode)
8739 uint32_t opcode = 0, service_action = 0;
8740 int td_set = 0, opcode_set = 0, sa_set = 0;
8741 int show_sa_errors = 1;
8742 uint32_t valid_len = 0;
8743 uint8_t *buf = NULL;
8747 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8753 opcode = strtoul(optarg, &endptr, 0);
8754 if (*endptr != '\0') {
8755 warnx("Invalid opcode \"%s\", must be a number",
8760 if (opcode > 0xff) {
8761 warnx("Invalid opcode 0x%#x, must be between"
8762 "0 and 0xff inclusive", opcode);
8769 service_action = strtoul(optarg, &endptr, 0);
8770 if (*endptr != '\0') {
8771 warnx("Invalid service action \"%s\", must "
8772 "be a number", optarg);
8776 if (service_action > 0xffff) {
8777 warnx("Invalid service action 0x%#x, must "
8778 "be between 0 and 0xffff inclusive",
8793 && (opcode_set == 0)) {
8794 warnx("You must specify an opcode with -o if a service "
8799 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8800 sa_set, service_action, td_set, retry_count,
8801 timeout, verbosemode, &valid_len, &buf);
8805 if ((opcode_set != 0)
8807 retval = scsiprintoneopcode(device, opcode, sa_set,
8808 service_action, buf, valid_len);
8810 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8819 #endif /* MINIMALISTIC */
8822 scsireprobe(struct cam_device *device)
8827 ccb = cam_getccb(device);
8830 warnx("%s: error allocating ccb", __func__);
8834 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8836 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8838 if (cam_send_ccb(device, ccb) < 0) {
8839 warn("error sending XPT_REPROBE_LUN CCB");
8844 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8845 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8857 usage(int printlong)
8860 fprintf(printlong ? stdout : stderr,
8861 "usage: camcontrol <command> [device id][generic args][command args]\n"
8862 " camcontrol devlist [-b] [-v]\n"
8863 #ifndef MINIMALISTIC
8864 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8865 " camcontrol tur [dev_id][generic args]\n"
8866 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8867 " camcontrol identify [dev_id][generic args] [-v]\n"
8868 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8869 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8871 " camcontrol start [dev_id][generic args]\n"
8872 " camcontrol stop [dev_id][generic args]\n"
8873 " camcontrol load [dev_id][generic args]\n"
8874 " camcontrol eject [dev_id][generic args]\n"
8875 " camcontrol reprobe [dev_id][generic args]\n"
8876 #endif /* MINIMALISTIC */
8877 " camcontrol rescan <all | bus[:target:lun]>\n"
8878 " camcontrol reset <all | bus[:target:lun]>\n"
8879 #ifndef MINIMALISTIC
8880 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8881 " [-q][-s][-S offset][-X]\n"
8882 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8883 " [-P pagectl][-e | -b][-d]\n"
8884 " camcontrol cmd [dev_id][generic args]\n"
8885 " <-a cmd [args] | -c cmd [args]>\n"
8886 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8887 " camcontrol smpcmd [dev_id][generic args]\n"
8888 " <-r len fmt [args]> <-R len fmt [args]>\n"
8889 " camcontrol smprg [dev_id][generic args][-l]\n"
8890 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8891 " [-o operation][-d name][-m rate][-M rate]\n"
8892 " [-T pp_timeout][-a enable|disable]\n"
8893 " [-A enable|disable][-s enable|disable]\n"
8894 " [-S enable|disable]\n"
8895 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8896 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8897 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8898 " <all|bus[:target[:lun]]|off>\n"
8899 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8900 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8901 " [-D <enable|disable>][-M mode][-O offset]\n"
8902 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8903 " [-U][-W bus_width]\n"
8904 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8905 " camcontrol sanitize [dev_id][generic args]\n"
8906 " [-a overwrite|block|crypto|exitfailure]\n"
8907 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8909 " camcontrol idle [dev_id][generic args][-t time]\n"
8910 " camcontrol standby [dev_id][generic args][-t time]\n"
8911 " camcontrol sleep [dev_id][generic args]\n"
8912 " camcontrol apm [dev_id][generic args][-l level]\n"
8913 " camcontrol aam [dev_id][generic args][-l level]\n"
8914 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8916 " camcontrol security [dev_id][generic args]\n"
8917 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8918 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8919 " [-U <user|master>] [-y]\n"
8920 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8921 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8922 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8923 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8924 " [-s scope][-S][-T type][-U]\n"
8925 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8926 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8927 " [-p part][-s start][-T type][-V vol]\n"
8928 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8930 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
8931 " [-o rep_opts] [-P print_opts]\n"
8932 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
8933 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
8934 " [-S power_src] [-T timer]\n"
8935 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
8936 " <-s <-f format -T time | -U >>\n"
8938 #endif /* MINIMALISTIC */
8939 " camcontrol help\n");
8942 #ifndef MINIMALISTIC
8944 "Specify one of the following options:\n"
8945 "devlist list all CAM devices\n"
8946 "periphlist list all CAM peripheral drivers attached to a device\n"
8947 "tur send a test unit ready to the named device\n"
8948 "inquiry send a SCSI inquiry command to the named device\n"
8949 "identify send a ATA identify command to the named device\n"
8950 "reportluns send a SCSI report luns command to the device\n"
8951 "readcap send a SCSI read capacity command to the device\n"
8952 "start send a Start Unit command to the device\n"
8953 "stop send a Stop Unit command to the device\n"
8954 "load send a Start Unit command to the device with the load bit set\n"
8955 "eject send a Stop Unit command to the device with the eject bit set\n"
8956 "reprobe update capacity information of the given device\n"
8957 "rescan rescan all buses, the given bus, or bus:target:lun\n"
8958 "reset reset all buses, the given bus, or bus:target:lun\n"
8959 "defects read the defect list of the specified device\n"
8960 "modepage display or edit (-e) the given mode page\n"
8961 "cmd send the given SCSI command, may need -i or -o as well\n"
8962 "smpcmd send the given SMP command, requires -o and -i\n"
8963 "smprg send the SMP Report General command\n"
8964 "smppc send the SMP PHY Control command, requires -p\n"
8965 "smpphylist display phys attached to a SAS expander\n"
8966 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8967 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8968 "tags report or set the number of transaction slots for a device\n"
8969 "negotiate report or set device negotiation parameters\n"
8970 "format send the SCSI FORMAT UNIT command to the named device\n"
8971 "sanitize send the SCSI SANITIZE command to the named device\n"
8972 "idle send the ATA IDLE command to the named device\n"
8973 "standby send the ATA STANDBY command to the named device\n"
8974 "sleep send the ATA SLEEP command to the named device\n"
8975 "fwdownload program firmware of the named device with the given image\n"
8976 "security report or send ATA security commands to the named device\n"
8977 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8978 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8979 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8980 "zone manage Zoned Block (Shingled) devices\n"
8981 "epc send ATA Extended Power Conditions commands\n"
8982 "timestamp report or set the device's timestamp\n"
8983 "help this message\n"
8984 "Device Identifiers:\n"
8985 "bus:target specify the bus and target, lun defaults to 0\n"
8986 "bus:target:lun specify the bus, target and lun\n"
8987 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8988 "Generic arguments:\n"
8989 "-v be verbose, print out sense information\n"
8990 "-t timeout command timeout in seconds, overrides default timeout\n"
8991 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8992 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8993 "-E have the kernel attempt to perform SCSI error recovery\n"
8994 "-C count specify the SCSI command retry count (needs -E to work)\n"
8995 "modepage arguments:\n"
8996 "-l list all available mode pages\n"
8997 "-m page specify the mode page to view or edit\n"
8998 "-e edit the specified mode page\n"
8999 "-b force view to binary mode\n"
9000 "-d disable block descriptors for mode sense\n"
9001 "-P pgctl page control field 0-3\n"
9002 "defects arguments:\n"
9003 "-f format specify defect list format (block, bfi or phys)\n"
9004 "-G get the grown defect list\n"
9005 "-P get the permanent defect list\n"
9006 "inquiry arguments:\n"
9007 "-D get the standard inquiry data\n"
9008 "-S get the serial number\n"
9009 "-R get the transfer rate, etc.\n"
9010 "reportluns arguments:\n"
9011 "-c only report a count of available LUNs\n"
9012 "-l only print out luns, and not a count\n"
9013 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9014 "readcap arguments\n"
9015 "-b only report the blocksize\n"
9016 "-h human readable device size, base 2\n"
9017 "-H human readable device size, base 10\n"
9018 "-N print the number of blocks instead of last block\n"
9019 "-q quiet, print numbers only\n"
9020 "-s only report the last block/device size\n"
9022 "-c cdb [args] specify the SCSI CDB\n"
9023 "-i len fmt specify input data and input data format\n"
9024 "-o len fmt [args] specify output data and output data fmt\n"
9025 "smpcmd arguments:\n"
9026 "-r len fmt [args] specify the SMP command to be sent\n"
9027 "-R len fmt [args] specify SMP response format\n"
9028 "smprg arguments:\n"
9029 "-l specify the long response format\n"
9030 "smppc arguments:\n"
9031 "-p phy specify the PHY to operate on\n"
9032 "-l specify the long request/response format\n"
9033 "-o operation specify the phy control operation\n"
9034 "-d name set the attached device name\n"
9035 "-m rate set the minimum physical link rate\n"
9036 "-M rate set the maximum physical link rate\n"
9037 "-T pp_timeout set the partial pathway timeout value\n"
9038 "-a enable|disable enable or disable SATA slumber\n"
9039 "-A enable|disable enable or disable SATA partial phy power\n"
9040 "-s enable|disable enable or disable SAS slumber\n"
9041 "-S enable|disable enable or disable SAS partial phy power\n"
9042 "smpphylist arguments:\n"
9043 "-l specify the long response format\n"
9044 "-q only print phys with attached devices\n"
9045 "smpmaninfo arguments:\n"
9046 "-l specify the long response format\n"
9047 "debug arguments:\n"
9048 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9049 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9050 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9051 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9053 "-N tags specify the number of tags to use for this device\n"
9054 "-q be quiet, don't report the number of tags\n"
9055 "-v report a number of tag-related parameters\n"
9056 "negotiate arguments:\n"
9057 "-a send a test unit ready after negotiation\n"
9058 "-c report/set current negotiation settings\n"
9059 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9060 "-M mode set ATA mode\n"
9061 "-O offset set command delay offset\n"
9062 "-q be quiet, don't report anything\n"
9063 "-R syncrate synchronization rate in MHz\n"
9064 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9065 "-U report/set user negotiation settings\n"
9066 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9067 "-v also print a Path Inquiry CCB for the controller\n"
9068 "format arguments:\n"
9069 "-q be quiet, don't print status messages\n"
9070 "-r run in report only mode\n"
9071 "-w don't send immediate format command\n"
9072 "-y don't ask any questions\n"
9073 "sanitize arguments:\n"
9074 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9075 "-c passes overwrite passes to perform (1 to 31)\n"
9076 "-I invert overwrite pattern after each pass\n"
9077 "-P pattern path to overwrite pattern file\n"
9078 "-q be quiet, don't print status messages\n"
9079 "-r run in report only mode\n"
9080 "-U run operation in unrestricted completion exit mode\n"
9081 "-w don't send immediate sanitize command\n"
9082 "-y don't ask any questions\n"
9083 "idle/standby arguments:\n"
9084 "-t <arg> number of seconds before respective state.\n"
9085 "fwdownload arguments:\n"
9086 "-f fw_image path to firmware image file\n"
9087 "-q don't print informational messages, only errors\n"
9088 "-s run in simulation mode\n"
9089 "-v print info for every firmware segment sent to device\n"
9090 "-y don't ask any questions\n"
9091 "security arguments:\n"
9092 "-d pwd disable security using the given password for the selected\n"
9094 "-e pwd erase the device using the given pwd for the selected user\n"
9095 "-f freeze the security configuration of the specified device\n"
9096 "-h pwd enhanced erase the device using the given pwd for the\n"
9098 "-k pwd unlock the device using the given pwd for the selected\n"
9100 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9101 "-q be quiet, do not print any status messages\n"
9102 "-s pwd password the device (enable security) using the given\n"
9103 " pwd for the selected user\n"
9104 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9105 "-U <user|master> specifies which user to set: user or master\n"
9106 "-y don't ask any questions\n"
9108 "-f freeze the HPA configuration of the device\n"
9109 "-l lock the HPA configuration of the device\n"
9110 "-P make the HPA max sectors persist\n"
9111 "-p pwd Set the HPA configuration password required for unlock\n"
9113 "-q be quiet, do not print any status messages\n"
9114 "-s sectors configures the maximum user accessible sectors of the\n"
9116 "-U pwd unlock the HPA configuration of the device\n"
9117 "-y don't ask any questions\n"
9118 "persist arguments:\n"
9119 "-i action specify read_keys, read_reservation, report_cap, or\n"
9120 " read_full_status\n"
9121 "-o action specify register, register_ignore, reserve, release,\n"
9122 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9123 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9124 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9125 "-k key specify the Reservation Key\n"
9126 "-K sa_key specify the Service Action Reservation Key\n"
9127 "-p set the Activate Persist Through Power Loss bit\n"
9128 "-R rtp specify the Relative Target Port\n"
9129 "-s scope specify the scope: lun, extent, element or a number\n"
9130 "-S specify Transport ID for register, requires -I\n"
9131 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9132 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9133 "-U unregister the current initiator for register_move\n"
9134 "attrib arguments:\n"
9135 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9137 "-w attr specify an attribute to write, one -w argument per attr\n"
9138 "-a attr_num only display this attribute number\n"
9139 "-c get cached attributes\n"
9140 "-e elem_addr request attributes for the given element in a changer\n"
9141 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9142 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9143 " field_none, field_desc, field_num, field_size, field_rw\n"
9144 "-p partition request attributes for the given partition\n"
9145 "-s start_attr request attributes starting at the given number\n"
9146 "-T elem_type specify the element type (used with -e)\n"
9147 "-V logical_vol specify the logical volume ID\n"
9148 "opcodes arguments:\n"
9149 "-o opcode specify the individual opcode to list\n"
9150 "-s service_action specify the service action for the opcode\n"
9151 "-N do not return SCSI error for unsupported SA\n"
9152 "-T request nominal and recommended timeout values\n"
9154 "-c cmd required: rz, open, close, finish, or rwp\n"
9155 "-a apply the action to all zones\n"
9156 "-l LBA specify the zone starting LBA\n"
9157 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9158 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9159 "-P print_opt report zones printing: normal, summary, script\n"
9161 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9162 " source, status, list\n"
9163 "-d disable power mode (timer, state)\n"
9164 "-D delayed entry (goto)\n"
9165 "-e enable power mode (timer, state)\n"
9166 "-H hold power mode (goto)\n"
9167 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9169 "-P only display power mode (status)\n"
9170 "-r rst_src restore settings from: default, saved (restore)\n"
9171 "-s save mode (timer, state, restore)\n"
9172 "-S power_src set power source: battery, nonbattery (source)\n"
9173 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9174 "timestamp arguments:\n"
9175 "-r report the timestamp of the device\n"
9176 "-f format report the timestamp of the device with the given\n"
9177 " strftime(3) format string\n"
9178 "-m report the timestamp of the device as milliseconds since\n"
9179 " January 1st, 1970\n"
9180 "-U report the time with UTC instead of the local time zone\n"
9181 "-s set the timestamp of the device\n"
9182 "-f format the format of the time string passed into strptime(3)\n"
9183 "-T time the time value passed into strptime(3)\n"
9184 "-U set the timestamp of the device to UTC time\n"
9186 #endif /* MINIMALISTIC */
9190 main(int argc, char **argv)
9193 char *device = NULL;
9195 struct cam_device *cam_dev = NULL;
9196 int timeout = 0, retry_count = 1;
9197 camcontrol_optret optreturn;
9199 const char *mainopt = "C:En:t:u:v";
9200 const char *subopt = NULL;
9201 char combinedopt[256];
9202 int error = 0, optstart = 2;
9204 #ifndef MINIMALISTIC
9208 #endif /* MINIMALISTIC */
9210 cmdlist = CAM_CMD_NONE;
9211 arglist = CAM_ARG_NONE;
9219 * Get the base option.
9221 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9223 if (optreturn == CC_OR_AMBIGUOUS) {
9224 warnx("ambiguous option %s", argv[1]);
9227 } else if (optreturn == CC_OR_NOT_FOUND) {
9228 warnx("option %s not found", argv[1]);
9234 * Ahh, getopt(3) is a pain.
9236 * This is a gross hack. There really aren't many other good
9237 * options (excuse the pun) for parsing options in a situation like
9238 * this. getopt is kinda braindead, so you end up having to run
9239 * through the options twice, and give each invocation of getopt
9240 * the option string for the other invocation.
9242 * You would think that you could just have two groups of options.
9243 * The first group would get parsed by the first invocation of
9244 * getopt, and the second group would get parsed by the second
9245 * invocation of getopt. It doesn't quite work out that way. When
9246 * the first invocation of getopt finishes, it leaves optind pointing
9247 * to the argument _after_ the first argument in the second group.
9248 * So when the second invocation of getopt comes around, it doesn't
9249 * recognize the first argument it gets and then bails out.
9251 * A nice alternative would be to have a flag for getopt that says
9252 * "just keep parsing arguments even when you encounter an unknown
9253 * argument", but there isn't one. So there's no real clean way to
9254 * easily parse two sets of arguments without having one invocation
9255 * of getopt know about the other.
9257 * Without this hack, the first invocation of getopt would work as
9258 * long as the generic arguments are first, but the second invocation
9259 * (in the subfunction) would fail in one of two ways. In the case
9260 * where you don't set optreset, it would fail because optind may be
9261 * pointing to the argument after the one it should be pointing at.
9262 * In the case where you do set optreset, and reset optind, it would
9263 * fail because getopt would run into the first set of options, which
9264 * it doesn't understand.
9266 * All of this would "sort of" work if you could somehow figure out
9267 * whether optind had been incremented one option too far. The
9268 * mechanics of that, however, are more daunting than just giving
9269 * both invocations all of the expect options for either invocation.
9271 * Needless to say, I wouldn't mind if someone invented a better
9272 * (non-GPL!) command line parsing interface than getopt. I
9273 * wouldn't mind if someone added more knobs to getopt to make it
9274 * work better. Who knows, I may talk myself into doing it someday,
9275 * if the standards weenies let me. As it is, it just leads to
9276 * hackery like this and causes people to avoid it in some cases.
9278 * KDM, September 8th, 1998
9281 sprintf(combinedopt, "%s%s", mainopt, subopt);
9283 sprintf(combinedopt, "%s", mainopt);
9286 * For these options we do not parse optional device arguments and
9287 * we do not open a passthrough device.
9289 if ((cmdlist == CAM_CMD_RESCAN)
9290 || (cmdlist == CAM_CMD_RESET)
9291 || (cmdlist == CAM_CMD_DEVTREE)
9292 || (cmdlist == CAM_CMD_USAGE)
9293 || (cmdlist == CAM_CMD_DEBUG))
9296 #ifndef MINIMALISTIC
9298 && (argc > 2 && argv[2][0] != '-')) {
9302 if (isdigit(argv[2][0])) {
9303 /* device specified as bus:target[:lun] */
9304 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9306 errx(1, "numeric device specification must "
9307 "be either bus:target, or "
9309 /* default to 0 if lun was not specified */
9310 if ((arglist & CAM_ARG_LUN) == 0) {
9312 arglist |= CAM_ARG_LUN;
9316 if (cam_get_device(argv[2], name, sizeof name, &unit)
9318 errx(1, "%s", cam_errbuf);
9319 device = strdup(name);
9320 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9324 #endif /* MINIMALISTIC */
9326 * Start getopt processing at argv[2/3], since we've already
9327 * accepted argv[1..2] as the command name, and as a possible
9333 * Now we run through the argument list looking for generic
9334 * options, and ignoring options that possibly belong to
9337 while ((c = getopt(argc, argv, combinedopt))!= -1){
9340 retry_count = strtol(optarg, NULL, 0);
9341 if (retry_count < 0)
9342 errx(1, "retry count %d is < 0",
9344 arglist |= CAM_ARG_RETRIES;
9347 arglist |= CAM_ARG_ERR_RECOVER;
9350 arglist |= CAM_ARG_DEVICE;
9352 while (isspace(*tstr) && (*tstr != '\0'))
9354 device = (char *)strdup(tstr);
9357 timeout = strtol(optarg, NULL, 0);
9359 errx(1, "invalid timeout %d", timeout);
9360 /* Convert the timeout from seconds to ms */
9362 arglist |= CAM_ARG_TIMEOUT;
9365 arglist |= CAM_ARG_UNIT;
9366 unit = strtol(optarg, NULL, 0);
9369 arglist |= CAM_ARG_VERBOSE;
9376 #ifndef MINIMALISTIC
9378 * For most commands we'll want to open the passthrough device
9379 * associated with the specified device. In the case of the rescan
9380 * commands, we don't use a passthrough device at all, just the
9381 * transport layer device.
9384 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9385 && (((arglist & CAM_ARG_DEVICE) == 0)
9386 || ((arglist & CAM_ARG_UNIT) == 0))) {
9387 errx(1, "subcommand \"%s\" requires a valid device "
9388 "identifier", argv[1]);
9391 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9392 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9393 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9395 errx(1,"%s", cam_errbuf);
9397 #endif /* MINIMALISTIC */
9400 * Reset optind to 2, and reset getopt, so these routines can parse
9401 * the arguments again.
9407 #ifndef MINIMALISTIC
9408 case CAM_CMD_DEVLIST:
9409 error = getdevlist(cam_dev);
9412 error = atahpa(cam_dev, retry_count, timeout,
9413 argc, argv, combinedopt);
9415 #endif /* MINIMALISTIC */
9416 case CAM_CMD_DEVTREE:
9417 error = getdevtree(argc, argv, combinedopt);
9419 #ifndef MINIMALISTIC
9421 error = testunitready(cam_dev, retry_count, timeout, 0);
9423 case CAM_CMD_INQUIRY:
9424 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9425 retry_count, timeout);
9427 case CAM_CMD_IDENTIFY:
9428 error = ataidentify(cam_dev, retry_count, timeout);
9430 case CAM_CMD_STARTSTOP:
9431 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9432 arglist & CAM_ARG_EJECT, retry_count,
9435 #endif /* MINIMALISTIC */
9436 case CAM_CMD_RESCAN:
9437 error = dorescan_or_reset(argc, argv, 1);
9440 error = dorescan_or_reset(argc, argv, 0);
9442 #ifndef MINIMALISTIC
9443 case CAM_CMD_READ_DEFECTS:
9444 error = readdefects(cam_dev, argc, argv, combinedopt,
9445 retry_count, timeout);
9447 case CAM_CMD_MODE_PAGE:
9448 modepage(cam_dev, argc, argv, combinedopt,
9449 retry_count, timeout);
9451 case CAM_CMD_SCSI_CMD:
9452 error = scsicmd(cam_dev, argc, argv, combinedopt,
9453 retry_count, timeout);
9455 case CAM_CMD_SMP_CMD:
9456 error = smpcmd(cam_dev, argc, argv, combinedopt,
9457 retry_count, timeout);
9459 case CAM_CMD_SMP_RG:
9460 error = smpreportgeneral(cam_dev, argc, argv,
9461 combinedopt, retry_count,
9464 case CAM_CMD_SMP_PC:
9465 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9466 retry_count, timeout);
9468 case CAM_CMD_SMP_PHYLIST:
9469 error = smpphylist(cam_dev, argc, argv, combinedopt,
9470 retry_count, timeout);
9472 case CAM_CMD_SMP_MANINFO:
9473 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9474 retry_count, timeout);
9477 error = camdebug(argc, argv, combinedopt);
9480 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9483 error = ratecontrol(cam_dev, retry_count, timeout,
9484 argc, argv, combinedopt);
9486 case CAM_CMD_FORMAT:
9487 error = scsiformat(cam_dev, argc, argv,
9488 combinedopt, retry_count, timeout);
9490 case CAM_CMD_REPORTLUNS:
9491 error = scsireportluns(cam_dev, argc, argv,
9492 combinedopt, retry_count,
9495 case CAM_CMD_READCAP:
9496 error = scsireadcapacity(cam_dev, argc, argv,
9497 combinedopt, retry_count,
9501 case CAM_CMD_STANDBY:
9503 error = atapm(cam_dev, argc, argv,
9504 combinedopt, retry_count, timeout);
9508 error = ataaxm(cam_dev, argc, argv,
9509 combinedopt, retry_count, timeout);
9511 case CAM_CMD_SECURITY:
9512 error = atasecurity(cam_dev, retry_count, timeout,
9513 argc, argv, combinedopt);
9515 case CAM_CMD_DOWNLOAD_FW:
9516 error = fwdownload(cam_dev, argc, argv, combinedopt,
9517 arglist & CAM_ARG_VERBOSE, retry_count, timeout);
9519 case CAM_CMD_SANITIZE:
9520 error = scsisanitize(cam_dev, argc, argv,
9521 combinedopt, retry_count, timeout);
9523 case CAM_CMD_PERSIST:
9524 error = scsipersist(cam_dev, argc, argv, combinedopt,
9525 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9526 arglist & CAM_ARG_ERR_RECOVER);
9528 case CAM_CMD_ATTRIB:
9529 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9530 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9531 arglist & CAM_ARG_ERR_RECOVER);
9533 case CAM_CMD_OPCODES:
9534 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9535 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9537 case CAM_CMD_REPROBE:
9538 error = scsireprobe(cam_dev);
9541 error = zone(cam_dev, argc, argv, combinedopt,
9542 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9545 error = epc(cam_dev, argc, argv, combinedopt,
9546 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9548 case CAM_CMD_TIMESTAMP:
9549 error = timestamp(cam_dev, argc, argv, combinedopt,
9550 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9552 #endif /* MINIMALISTIC */
9562 if (cam_dev != NULL)
9563 cam_close_device(cam_dev);