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
108 CAM_ARG_NONE = 0x00000000,
109 CAM_ARG_VERBOSE = 0x00000001,
110 CAM_ARG_DEVICE = 0x00000002,
111 CAM_ARG_BUS = 0x00000004,
112 CAM_ARG_TARGET = 0x00000008,
113 CAM_ARG_LUN = 0x00000010,
114 CAM_ARG_EJECT = 0x00000020,
115 CAM_ARG_UNIT = 0x00000040,
116 CAM_ARG_FORMAT_BLOCK = 0x00000080,
117 CAM_ARG_FORMAT_BFI = 0x00000100,
118 CAM_ARG_FORMAT_PHYS = 0x00000200,
119 CAM_ARG_PLIST = 0x00000400,
120 CAM_ARG_GLIST = 0x00000800,
121 CAM_ARG_GET_SERIAL = 0x00001000,
122 CAM_ARG_GET_STDINQ = 0x00002000,
123 CAM_ARG_GET_XFERRATE = 0x00004000,
124 CAM_ARG_INQ_MASK = 0x00007000,
125 CAM_ARG_MODE_EDIT = 0x00008000,
126 CAM_ARG_PAGE_CNTL = 0x00010000,
127 CAM_ARG_TIMEOUT = 0x00020000,
128 CAM_ARG_CMD_IN = 0x00040000,
129 CAM_ARG_CMD_OUT = 0x00080000,
130 CAM_ARG_DBD = 0x00100000,
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 #endif /* MINIMALISTIC */
234 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
235 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
236 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
241 struct device_match_result dev_match;
243 struct periph_match_result *periph_matches;
244 struct scsi_vpd_device_id *device_id;
246 STAILQ_ENTRY(cam_devitem) links;
250 STAILQ_HEAD(, cam_devitem) dev_queue;
254 static cam_cmdmask cmdlist;
255 static cam_argmask arglist;
257 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
258 uint32_t *cmdnum, cam_argmask *argnum,
259 const char **subopt);
261 static int getdevlist(struct cam_device *device);
262 #endif /* MINIMALISTIC */
263 static int getdevtree(int argc, char **argv, char *combinedopt);
265 static int testunitready(struct cam_device *device, int retry_count,
266 int timeout, int quiet);
267 static int scsistart(struct cam_device *device, int startstop, int loadeject,
268 int retry_count, int timeout);
269 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
270 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
271 #endif /* MINIMALISTIC */
272 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
273 lun_id_t *lun, cam_argmask *arglst);
274 static int dorescan_or_reset(int argc, char **argv, int rescan);
275 static int rescan_or_reset_bus(path_id_t bus, int rescan);
276 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
277 lun_id_t lun, int scan);
279 static int readdefects(struct cam_device *device, int argc, char **argv,
280 char *combinedopt, int retry_count, int timeout);
281 static void modepage(struct cam_device *device, int argc, char **argv,
282 char *combinedopt, int retry_count, int timeout);
283 static int scsicmd(struct cam_device *device, int argc, char **argv,
284 char *combinedopt, int retry_count, int timeout);
285 static int smpcmd(struct cam_device *device, int argc, char **argv,
286 char *combinedopt, int retry_count, int timeout);
287 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
288 char *combinedopt, int retry_count, int timeout);
289 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
290 char *combinedopt, int retry_count, int timeout);
291 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
292 char *combinedopt, int retry_count, int timeout);
293 static int getdevid(struct cam_devitem *item);
294 static int buildbusdevlist(struct cam_devlist *devlist);
295 static void freebusdevlist(struct cam_devlist *devlist);
296 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
298 static int smpphylist(struct cam_device *device, int argc, char **argv,
299 char *combinedopt, int retry_count, int timeout);
300 static int tagcontrol(struct cam_device *device, int argc, char **argv,
302 static void cts_print(struct cam_device *device,
303 struct ccb_trans_settings *cts);
304 static void cpi_print(struct ccb_pathinq *cpi);
305 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
306 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
307 static int get_print_cts(struct cam_device *device, int user_settings,
308 int quiet, struct ccb_trans_settings *cts);
309 static int ratecontrol(struct cam_device *device, int retry_count,
310 int timeout, int argc, char **argv, char *combinedopt);
311 static int scsiformat(struct cam_device *device, int argc, char **argv,
312 char *combinedopt, int retry_count, int timeout);
313 static int scsisanitize(struct cam_device *device, int argc, char **argv,
314 char *combinedopt, int retry_count, int timeout);
315 static int scsireportluns(struct cam_device *device, int argc, char **argv,
316 char *combinedopt, int retry_count, int timeout);
317 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int atapm(struct cam_device *device, int argc, char **argv,
320 char *combinedopt, int retry_count, int timeout);
321 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
322 int argc, char **argv, char *combinedopt);
323 static int atahpa(struct cam_device *device, int retry_count, int timeout,
324 int argc, char **argv, char *combinedopt);
325 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
326 int sa_set, int req_sa, uint8_t *buf,
328 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
330 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
331 char *combinedopt, int retry_count, int timeout,
333 static int scsireprobe(struct cam_device *device);
335 #endif /* MINIMALISTIC */
337 #define min(a,b) (((a)<(b))?(a):(b))
340 #define max(a,b) (((a)>(b))?(a):(b))
344 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
345 cam_argmask *argnum, const char **subopt)
347 struct camcontrol_opts *opts;
350 for (opts = table; (opts != NULL) && (opts->optname != NULL);
352 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
353 *cmdnum = opts->cmdnum;
354 *argnum = opts->argnum;
355 *subopt = opts->subopt;
356 if (++num_matches > 1)
357 return(CC_OR_AMBIGUOUS);
364 return(CC_OR_NOT_FOUND);
369 getdevlist(struct cam_device *device)
375 ccb = cam_getccb(device);
377 ccb->ccb_h.func_code = XPT_GDEVLIST;
378 ccb->ccb_h.flags = CAM_DIR_NONE;
379 ccb->ccb_h.retry_count = 1;
381 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
382 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
383 if (cam_send_ccb(device, ccb) < 0) {
384 perror("error getting device list");
391 switch (ccb->cgdl.status) {
392 case CAM_GDEVLIST_MORE_DEVS:
393 strcpy(status, "MORE");
395 case CAM_GDEVLIST_LAST_DEVICE:
396 strcpy(status, "LAST");
398 case CAM_GDEVLIST_LIST_CHANGED:
399 strcpy(status, "CHANGED");
401 case CAM_GDEVLIST_ERROR:
402 strcpy(status, "ERROR");
407 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
408 ccb->cgdl.periph_name,
409 ccb->cgdl.unit_number,
410 ccb->cgdl.generation,
415 * If the list has changed, we need to start over from the
418 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
426 #endif /* MINIMALISTIC */
429 getdevtree(int argc, char **argv, char *combinedopt)
440 while ((c = getopt(argc, argv, combinedopt)) != -1) {
443 if ((arglist & CAM_ARG_VERBOSE) == 0)
451 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
452 warn("couldn't open %s", XPT_DEVICE);
456 bzero(&ccb, sizeof(union ccb));
458 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
459 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
460 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
462 ccb.ccb_h.func_code = XPT_DEV_MATCH;
463 bufsize = sizeof(struct dev_match_result) * 100;
464 ccb.cdm.match_buf_len = bufsize;
465 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
466 if (ccb.cdm.matches == NULL) {
467 warnx("can't malloc memory for matches");
471 ccb.cdm.num_matches = 0;
474 * We fetch all nodes, since we display most of them in the default
475 * case, and all in the verbose case.
477 ccb.cdm.num_patterns = 0;
478 ccb.cdm.pattern_buf_len = 0;
481 * We do the ioctl multiple times if necessary, in case there are
482 * more than 100 nodes in the EDT.
485 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
486 warn("error sending CAMIOCOMMAND ioctl");
491 if ((ccb.ccb_h.status != CAM_REQ_CMP)
492 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
493 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
494 warnx("got CAM error %#x, CDM error %d\n",
495 ccb.ccb_h.status, ccb.cdm.status);
500 for (i = 0; i < ccb.cdm.num_matches; i++) {
501 switch (ccb.cdm.matches[i].type) {
502 case DEV_MATCH_BUS: {
503 struct bus_match_result *bus_result;
506 * Only print the bus information if the
507 * user turns on the verbose flag.
509 if ((busonly == 0) &&
510 (arglist & CAM_ARG_VERBOSE) == 0)
514 &ccb.cdm.matches[i].result.bus_result;
517 fprintf(stdout, ")\n");
521 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
523 bus_result->dev_name,
524 bus_result->unit_number,
526 (busonly ? "" : ":"));
529 case DEV_MATCH_DEVICE: {
530 struct device_match_result *dev_result;
531 char vendor[16], product[48], revision[16];
532 char fw[5], tmpstr[256];
538 &ccb.cdm.matches[i].result.device_result;
540 if ((dev_result->flags
541 & DEV_RESULT_UNCONFIGURED)
542 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
548 if (dev_result->protocol == PROTO_SCSI) {
549 cam_strvis(vendor, dev_result->inq_data.vendor,
550 sizeof(dev_result->inq_data.vendor),
553 dev_result->inq_data.product,
554 sizeof(dev_result->inq_data.product),
557 dev_result->inq_data.revision,
558 sizeof(dev_result->inq_data.revision),
560 sprintf(tmpstr, "<%s %s %s>", vendor, product,
562 } else if (dev_result->protocol == PROTO_ATA ||
563 dev_result->protocol == PROTO_SATAPM) {
565 dev_result->ident_data.model,
566 sizeof(dev_result->ident_data.model),
569 dev_result->ident_data.revision,
570 sizeof(dev_result->ident_data.revision),
572 sprintf(tmpstr, "<%s %s>", product,
574 } else if (dev_result->protocol == PROTO_SEMB) {
575 struct sep_identify_data *sid;
577 sid = (struct sep_identify_data *)
578 &dev_result->ident_data;
579 cam_strvis(vendor, sid->vendor_id,
580 sizeof(sid->vendor_id),
582 cam_strvis(product, sid->product_id,
583 sizeof(sid->product_id),
585 cam_strvis(revision, sid->product_rev,
586 sizeof(sid->product_rev),
588 cam_strvis(fw, sid->firmware_rev,
589 sizeof(sid->firmware_rev),
591 sprintf(tmpstr, "<%s %s %s %s>",
592 vendor, product, revision, fw);
594 sprintf(tmpstr, "<>");
597 fprintf(stdout, ")\n");
601 fprintf(stdout, "%-33s at scbus%d "
602 "target %d lun %jx (",
605 dev_result->target_id,
606 (uintmax_t)dev_result->target_lun);
612 case DEV_MATCH_PERIPH: {
613 struct periph_match_result *periph_result;
616 &ccb.cdm.matches[i].result.periph_result;
618 if (busonly || skip_device != 0)
622 fprintf(stdout, ",");
624 fprintf(stdout, "%s%d",
625 periph_result->periph_name,
626 periph_result->unit_number);
632 fprintf(stdout, "unknown match type\n");
637 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
638 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
641 fprintf(stdout, ")\n");
650 testunitready(struct cam_device *device, int retry_count, int timeout,
656 ccb = cam_getccb(device);
658 scsi_test_unit_ready(&ccb->csio,
659 /* retries */ retry_count,
661 /* tag_action */ MSG_SIMPLE_Q_TAG,
662 /* sense_len */ SSD_FULL_SIZE,
663 /* timeout */ timeout ? timeout : 5000);
665 /* Disable freezing the device queue */
666 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
668 if (arglist & CAM_ARG_ERR_RECOVER)
669 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
671 if (cam_send_ccb(device, ccb) < 0) {
673 perror("error sending test unit ready");
675 if (arglist & CAM_ARG_VERBOSE) {
676 cam_error_print(device, ccb, CAM_ESF_ALL,
677 CAM_EPF_ALL, stderr);
684 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
686 fprintf(stdout, "Unit is ready\n");
689 fprintf(stdout, "Unit is not ready\n");
692 if (arglist & CAM_ARG_VERBOSE) {
693 cam_error_print(device, ccb, CAM_ESF_ALL,
694 CAM_EPF_ALL, stderr);
704 scsistart(struct cam_device *device, int startstop, int loadeject,
705 int retry_count, int timeout)
710 ccb = cam_getccb(device);
713 * If we're stopping, send an ordered tag so the drive in question
714 * will finish any previously queued writes before stopping. If
715 * the device isn't capable of tagged queueing, or if tagged
716 * queueing is turned off, the tag action is a no-op.
718 scsi_start_stop(&ccb->csio,
719 /* retries */ retry_count,
721 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
723 /* start/stop */ startstop,
724 /* load_eject */ loadeject,
726 /* sense_len */ SSD_FULL_SIZE,
727 /* timeout */ timeout ? timeout : 120000);
729 /* Disable freezing the device queue */
730 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
732 if (arglist & CAM_ARG_ERR_RECOVER)
733 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
735 if (cam_send_ccb(device, ccb) < 0) {
736 perror("error sending start unit");
738 if (arglist & CAM_ARG_VERBOSE) {
739 cam_error_print(device, ccb, CAM_ESF_ALL,
740 CAM_EPF_ALL, stderr);
747 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
749 fprintf(stdout, "Unit started successfully");
751 fprintf(stdout,", Media loaded\n");
753 fprintf(stdout,"\n");
755 fprintf(stdout, "Unit stopped successfully");
757 fprintf(stdout, ", Media ejected\n");
759 fprintf(stdout, "\n");
765 "Error received from start unit command\n");
768 "Error received from stop unit command\n");
770 if (arglist & CAM_ARG_VERBOSE) {
771 cam_error_print(device, ccb, CAM_ESF_ALL,
772 CAM_EPF_ALL, stderr);
782 scsidoinquiry(struct cam_device *device, int argc, char **argv,
783 char *combinedopt, int retry_count, int timeout)
788 while ((c = getopt(argc, argv, combinedopt)) != -1) {
791 arglist |= CAM_ARG_GET_STDINQ;
794 arglist |= CAM_ARG_GET_XFERRATE;
797 arglist |= CAM_ARG_GET_SERIAL;
805 * If the user didn't specify any inquiry options, he wants all of
808 if ((arglist & CAM_ARG_INQ_MASK) == 0)
809 arglist |= CAM_ARG_INQ_MASK;
811 if (arglist & CAM_ARG_GET_STDINQ)
812 error = scsiinquiry(device, retry_count, timeout);
817 if (arglist & CAM_ARG_GET_SERIAL)
818 scsiserial(device, retry_count, timeout);
820 if (arglist & CAM_ARG_GET_XFERRATE)
821 error = camxferrate(device);
827 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
830 struct scsi_inquiry_data *inq_buf;
833 ccb = cam_getccb(device);
836 warnx("couldn't allocate CCB");
840 /* cam_getccb cleans up the header, caller has to zero the payload */
841 bzero(&(&ccb->ccb_h)[1],
842 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
844 inq_buf = (struct scsi_inquiry_data *)malloc(
845 sizeof(struct scsi_inquiry_data));
847 if (inq_buf == NULL) {
849 warnx("can't malloc memory for inquiry\n");
852 bzero(inq_buf, sizeof(*inq_buf));
855 * Note that although the size of the inquiry buffer is the full
856 * 256 bytes specified in the SCSI spec, we only tell the device
857 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
858 * two reasons for this:
860 * - The SCSI spec says that when a length field is only 1 byte,
861 * a value of 0 will be interpreted as 256. Therefore
862 * scsi_inquiry() will convert an inq_len (which is passed in as
863 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
864 * to 0. Evidently, very few devices meet the spec in that
865 * regard. Some devices, like many Seagate disks, take the 0 as
866 * 0, and don't return any data. One Pioneer DVD-R drive
867 * returns more data than the command asked for.
869 * So, since there are numerous devices that just don't work
870 * right with the full inquiry size, we don't send the full size.
872 * - The second reason not to use the full inquiry data length is
873 * that we don't need it here. The only reason we issue a
874 * standard inquiry is to get the vendor name, device name,
875 * and revision so scsi_print_inquiry() can print them.
877 * If, at some point in the future, more inquiry data is needed for
878 * some reason, this code should use a procedure similar to the
879 * probe code. i.e., issue a short inquiry, and determine from
880 * the additional length passed back from the device how much
881 * inquiry data the device supports. Once the amount the device
882 * supports is determined, issue an inquiry for that amount and no
887 scsi_inquiry(&ccb->csio,
888 /* retries */ retry_count,
890 /* tag_action */ MSG_SIMPLE_Q_TAG,
891 /* inq_buf */ (u_int8_t *)inq_buf,
892 /* inq_len */ SHORT_INQUIRY_LENGTH,
895 /* sense_len */ SSD_FULL_SIZE,
896 /* timeout */ timeout ? timeout : 5000);
898 /* Disable freezing the device queue */
899 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
901 if (arglist & CAM_ARG_ERR_RECOVER)
902 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
904 if (cam_send_ccb(device, ccb) < 0) {
905 perror("error sending SCSI inquiry");
907 if (arglist & CAM_ARG_VERBOSE) {
908 cam_error_print(device, ccb, CAM_ESF_ALL,
909 CAM_EPF_ALL, stderr);
916 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
919 if (arglist & CAM_ARG_VERBOSE) {
920 cam_error_print(device, ccb, CAM_ESF_ALL,
921 CAM_EPF_ALL, stderr);
932 fprintf(stdout, "%s%d: ", device->device_name,
933 device->dev_unit_num);
934 scsi_print_inquiry(inq_buf);
942 scsiserial(struct cam_device *device, int retry_count, int timeout)
945 struct scsi_vpd_unit_serial_number *serial_buf;
946 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
949 ccb = cam_getccb(device);
952 warnx("couldn't allocate CCB");
956 /* cam_getccb cleans up the header, caller has to zero the payload */
957 bzero(&(&ccb->ccb_h)[1],
958 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
960 serial_buf = (struct scsi_vpd_unit_serial_number *)
961 malloc(sizeof(*serial_buf));
963 if (serial_buf == NULL) {
965 warnx("can't malloc memory for serial number");
969 scsi_inquiry(&ccb->csio,
970 /*retries*/ retry_count,
972 /* tag_action */ MSG_SIMPLE_Q_TAG,
973 /* inq_buf */ (u_int8_t *)serial_buf,
974 /* inq_len */ sizeof(*serial_buf),
976 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
977 /* sense_len */ SSD_FULL_SIZE,
978 /* timeout */ timeout ? timeout : 5000);
980 /* Disable freezing the device queue */
981 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
983 if (arglist & CAM_ARG_ERR_RECOVER)
984 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
986 if (cam_send_ccb(device, ccb) < 0) {
987 warn("error getting serial number");
989 if (arglist & CAM_ARG_VERBOSE) {
990 cam_error_print(device, ccb, CAM_ESF_ALL,
991 CAM_EPF_ALL, stderr);
999 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1002 if (arglist & CAM_ARG_VERBOSE) {
1003 cam_error_print(device, ccb, CAM_ESF_ALL,
1004 CAM_EPF_ALL, stderr);
1015 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1016 serial_num[serial_buf->length] = '\0';
1018 if ((arglist & CAM_ARG_GET_STDINQ)
1019 || (arglist & CAM_ARG_GET_XFERRATE))
1020 fprintf(stdout, "%s%d: Serial Number ",
1021 device->device_name, device->dev_unit_num);
1023 fprintf(stdout, "%.60s\n", serial_num);
1031 camxferrate(struct cam_device *device)
1033 struct ccb_pathinq cpi;
1035 u_int32_t speed = 0;
1040 if ((retval = get_cpi(device, &cpi)) != 0)
1043 ccb = cam_getccb(device);
1046 warnx("couldn't allocate CCB");
1050 bzero(&(&ccb->ccb_h)[1],
1051 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
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 bzero(&(&ccb->ccb_h)[1],
1605 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1607 scsi_ata_pass_16(&ccb->csio,
1621 /*sense_len*/SSD_FULL_SIZE,
1624 return scsi_cam_pass_16_send(device, ccb, quiet);
1628 ata_try_pass_16(struct cam_device *device)
1630 struct ccb_pathinq cpi;
1632 if (get_cpi(device, &cpi) != 0) {
1633 warnx("couldn't get CPI");
1637 if (cpi.protocol == PROTO_SCSI) {
1638 /* possibly compatible with pass_16 */
1642 /* likely not compatible with pass_16 */
1647 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1648 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1649 u_int8_t command, u_int8_t features, u_int32_t lba,
1650 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1651 int timeout, int quiet)
1655 switch (ata_try_pass_16(device)) {
1659 /* Try using SCSI Passthrough */
1660 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1661 0, tag_action, command, features, lba,
1662 sector_count, data_ptr, dxfer_len,
1666 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1667 sizeof(struct ccb_hdr));
1668 cam_fill_ataio(&ccb->ataio,
1677 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1678 return ata_cam_send(device, ccb, quiet);
1682 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1683 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1684 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1685 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1686 u_int16_t dxfer_len, int timeout, int force48bit)
1690 retval = ata_try_pass_16(device);
1697 /* Try using SCSI Passthrough */
1698 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1699 ata_flags, tag_action, command, features,
1700 lba, sector_count, data_ptr, dxfer_len,
1703 if (ata_flags & AP_FLAG_CHK_COND) {
1704 /* Decode ata_res from sense data */
1705 struct ata_res_pass16 *res_pass16;
1706 struct ata_res *res;
1710 /* sense_data is 4 byte aligned */
1711 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1712 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1713 ptr[i] = le16toh(ptr[i]);
1715 /* sense_data is 4 byte aligned */
1716 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1717 &ccb->csio.sense_data;
1718 res = &ccb->ataio.res;
1719 res->flags = res_pass16->flags;
1720 res->status = res_pass16->status;
1721 res->error = res_pass16->error;
1722 res->lba_low = res_pass16->lba_low;
1723 res->lba_mid = res_pass16->lba_mid;
1724 res->lba_high = res_pass16->lba_high;
1725 res->device = res_pass16->device;
1726 res->lba_low_exp = res_pass16->lba_low_exp;
1727 res->lba_mid_exp = res_pass16->lba_mid_exp;
1728 res->lba_high_exp = res_pass16->lba_high_exp;
1729 res->sector_count = res_pass16->sector_count;
1730 res->sector_count_exp = res_pass16->sector_count_exp;
1736 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1737 sizeof(struct ccb_hdr));
1738 cam_fill_ataio(&ccb->ataio,
1747 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1748 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1750 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1752 if (ata_flags & AP_FLAG_CHK_COND)
1753 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1755 return ata_cam_send(device, ccb, 0);
1759 dump_data(uint16_t *ptr, uint32_t len)
1763 for (i = 0; i < len / 2; i++) {
1765 printf(" %3d: ", i);
1766 printf("%04hx ", ptr[i]);
1775 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1776 int is48bit, u_int64_t *hpasize)
1778 struct ata_res *res;
1780 res = &ccb->ataio.res;
1781 if (res->status & ATA_STATUS_ERROR) {
1782 if (arglist & CAM_ARG_VERBOSE) {
1783 cam_error_print(device, ccb, CAM_ESF_ALL,
1784 CAM_EPF_ALL, stderr);
1785 printf("error = 0x%02x, sector_count = 0x%04x, "
1786 "device = 0x%02x, status = 0x%02x\n",
1787 res->error, res->sector_count,
1788 res->device, res->status);
1791 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1792 warnx("Max address has already been set since "
1793 "last power-on or hardware reset");
1799 if (arglist & CAM_ARG_VERBOSE) {
1800 fprintf(stdout, "%s%d: Raw native max data:\n",
1801 device->device_name, device->dev_unit_num);
1802 /* res is 4 byte aligned */
1803 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1805 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1806 "status = 0x%02x\n", res->error, res->sector_count,
1807 res->device, res->status);
1810 if (hpasize != NULL) {
1812 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1813 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1814 ((res->lba_high << 16) | (res->lba_mid << 8) |
1817 *hpasize = (((res->device & 0x0f) << 24) |
1818 (res->lba_high << 16) | (res->lba_mid << 8) |
1827 ata_read_native_max(struct cam_device *device, int retry_count,
1828 u_int32_t timeout, union ccb *ccb,
1829 struct ata_params *parm, u_int64_t *hpasize)
1835 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1836 protocol = AP_PROTO_NON_DATA;
1839 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1840 protocol |= AP_EXTEND;
1842 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1845 error = ata_do_cmd(device,
1848 /*flags*/CAM_DIR_NONE,
1849 /*protocol*/protocol,
1850 /*ata_flags*/AP_FLAG_CHK_COND,
1851 /*tag_action*/MSG_SIMPLE_Q_TAG,
1858 timeout ? timeout : 1000,
1864 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1868 atahpa_set_max(struct cam_device *device, int retry_count,
1869 u_int32_t timeout, union ccb *ccb,
1870 int is48bit, u_int64_t maxsize, int persist)
1876 protocol = AP_PROTO_NON_DATA;
1879 cmd = ATA_SET_MAX_ADDRESS48;
1880 protocol |= AP_EXTEND;
1882 cmd = ATA_SET_MAX_ADDRESS;
1885 /* lba's are zero indexed so the max lba is requested max - 1 */
1889 error = ata_do_cmd(device,
1892 /*flags*/CAM_DIR_NONE,
1893 /*protocol*/protocol,
1894 /*ata_flags*/AP_FLAG_CHK_COND,
1895 /*tag_action*/MSG_SIMPLE_Q_TAG,
1897 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1899 /*sector_count*/persist,
1902 timeout ? timeout : 1000,
1908 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1912 atahpa_password(struct cam_device *device, int retry_count,
1913 u_int32_t timeout, union ccb *ccb,
1914 int is48bit, struct ata_set_max_pwd *pwd)
1920 protocol = AP_PROTO_PIO_OUT;
1921 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1923 error = ata_do_cmd(device,
1926 /*flags*/CAM_DIR_OUT,
1927 /*protocol*/protocol,
1928 /*ata_flags*/AP_FLAG_CHK_COND,
1929 /*tag_action*/MSG_SIMPLE_Q_TAG,
1931 /*features*/ATA_HPA_FEAT_SET_PWD,
1934 /*data_ptr*/(u_int8_t*)pwd,
1935 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1936 timeout ? timeout : 1000,
1942 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1946 atahpa_lock(struct cam_device *device, int retry_count,
1947 u_int32_t timeout, union ccb *ccb, int is48bit)
1953 protocol = AP_PROTO_NON_DATA;
1954 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1956 error = ata_do_cmd(device,
1959 /*flags*/CAM_DIR_NONE,
1960 /*protocol*/protocol,
1961 /*ata_flags*/AP_FLAG_CHK_COND,
1962 /*tag_action*/MSG_SIMPLE_Q_TAG,
1964 /*features*/ATA_HPA_FEAT_LOCK,
1969 timeout ? timeout : 1000,
1975 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1979 atahpa_unlock(struct cam_device *device, int retry_count,
1980 u_int32_t timeout, union ccb *ccb,
1981 int is48bit, struct ata_set_max_pwd *pwd)
1987 protocol = AP_PROTO_PIO_OUT;
1988 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1990 error = ata_do_cmd(device,
1993 /*flags*/CAM_DIR_OUT,
1994 /*protocol*/protocol,
1995 /*ata_flags*/AP_FLAG_CHK_COND,
1996 /*tag_action*/MSG_SIMPLE_Q_TAG,
1998 /*features*/ATA_HPA_FEAT_UNLOCK,
2001 /*data_ptr*/(u_int8_t*)pwd,
2002 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2003 timeout ? timeout : 1000,
2009 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2013 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2014 u_int32_t timeout, union ccb *ccb, int is48bit)
2020 protocol = AP_PROTO_NON_DATA;
2021 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2023 error = ata_do_cmd(device,
2026 /*flags*/CAM_DIR_NONE,
2027 /*protocol*/protocol,
2028 /*ata_flags*/AP_FLAG_CHK_COND,
2029 /*tag_action*/MSG_SIMPLE_Q_TAG,
2031 /*features*/ATA_HPA_FEAT_FREEZE,
2036 timeout ? timeout : 1000,
2042 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2047 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2048 union ccb *ccb, struct ata_params** ident_bufp)
2050 struct ata_params *ident_buf;
2051 struct ccb_pathinq cpi;
2052 struct ccb_getdev cgd;
2055 u_int8_t command, retry_command;
2057 if (get_cpi(device, &cpi) != 0) {
2058 warnx("couldn't get CPI");
2062 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2063 if (cpi.protocol == PROTO_ATA) {
2064 if (get_cgd(device, &cgd) != 0) {
2065 warnx("couldn't get CGD");
2069 command = (cgd.protocol == PROTO_ATA) ?
2070 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2073 /* We don't know which for sure so try both */
2074 command = ATA_ATA_IDENTIFY;
2075 retry_command = ATA_ATAPI_IDENTIFY;
2078 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2080 warnx("can't calloc memory for identify\n");
2084 error = ata_do_28bit_cmd(device,
2086 /*retries*/retry_count,
2087 /*flags*/CAM_DIR_IN,
2088 /*protocol*/AP_PROTO_PIO_IN,
2089 /*tag_action*/MSG_SIMPLE_Q_TAG,
2093 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2094 /*data_ptr*/(u_int8_t *)ptr,
2095 /*dxfer_len*/sizeof(struct ata_params),
2096 /*timeout*/timeout ? timeout : 30 * 1000,
2100 if (retry_command == 0) {
2104 error = ata_do_28bit_cmd(device,
2106 /*retries*/retry_count,
2107 /*flags*/CAM_DIR_IN,
2108 /*protocol*/AP_PROTO_PIO_IN,
2109 /*tag_action*/MSG_SIMPLE_Q_TAG,
2110 /*command*/retry_command,
2113 /*sector_count*/(u_int8_t)
2114 sizeof(struct ata_params),
2115 /*data_ptr*/(u_int8_t *)ptr,
2116 /*dxfer_len*/sizeof(struct ata_params),
2117 /*timeout*/timeout ? timeout : 30 * 1000,
2127 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2128 ptr[i] = le16toh(ptr[i]);
2133 if (arglist & CAM_ARG_VERBOSE) {
2134 fprintf(stdout, "%s%d: Raw identify data:\n",
2135 device->device_name, device->dev_unit_num);
2136 dump_data(ptr, sizeof(struct ata_params));
2139 /* check for invalid (all zero) response */
2141 warnx("Invalid identify response detected");
2146 ident_buf = (struct ata_params *)ptr;
2147 if (strncmp(ident_buf->model, "FX", 2) &&
2148 strncmp(ident_buf->model, "NEC", 3) &&
2149 strncmp(ident_buf->model, "Pioneer", 7) &&
2150 strncmp(ident_buf->model, "SHARP", 5)) {
2151 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2152 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2153 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2154 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2156 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2157 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2158 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2159 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2160 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2161 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2162 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2163 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2164 sizeof(ident_buf->media_serial));
2166 *ident_bufp = ident_buf;
2173 ataidentify(struct cam_device *device, int retry_count, int timeout)
2176 struct ata_params *ident_buf;
2179 if ((ccb = cam_getccb(device)) == NULL) {
2180 warnx("couldn't allocate CCB");
2184 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2189 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2190 if (ata_read_native_max(device, retry_count, timeout, ccb,
2191 ident_buf, &hpasize) != 0) {
2199 printf("%s%d: ", device->device_name, device->dev_unit_num);
2200 ata_print_ident(ident_buf);
2201 camxferrate(device);
2202 atacapprint(ident_buf);
2203 atahpa_print(ident_buf, hpasize, 0);
2210 #endif /* MINIMALISTIC */
2213 #ifndef MINIMALISTIC
2215 ATA_SECURITY_ACTION_PRINT,
2216 ATA_SECURITY_ACTION_FREEZE,
2217 ATA_SECURITY_ACTION_UNLOCK,
2218 ATA_SECURITY_ACTION_DISABLE,
2219 ATA_SECURITY_ACTION_ERASE,
2220 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2221 ATA_SECURITY_ACTION_SET_PASSWORD
2225 atasecurity_print_time(u_int16_t tw)
2229 printf("unspecified");
2231 printf("> 508 min");
2233 printf("%i min", 2 * tw);
2237 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2241 return 2 * 3600 * 1000; /* default: two hours */
2242 else if (timeout > 255)
2243 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2245 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2250 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2254 bzero(&cmd, sizeof(cmd));
2255 cmd.command = command;
2256 printf("Issuing %s", ata_op_string(&cmd));
2259 char pass[sizeof(pwd->password)+1];
2261 /* pwd->password may not be null terminated */
2262 pass[sizeof(pwd->password)] = '\0';
2263 strncpy(pass, pwd->password, sizeof(pwd->password));
2264 printf(" password='%s', user='%s'",
2266 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2269 if (command == ATA_SECURITY_SET_PASSWORD) {
2270 printf(", mode='%s'",
2271 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2272 "maximum" : "high");
2280 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2281 int retry_count, u_int32_t timeout, int quiet)
2285 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2287 return ata_do_28bit_cmd(device,
2290 /*flags*/CAM_DIR_NONE,
2291 /*protocol*/AP_PROTO_NON_DATA,
2292 /*tag_action*/MSG_SIMPLE_Q_TAG,
2293 /*command*/ATA_SECURITY_FREEZE_LOCK,
2304 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2305 int retry_count, u_int32_t timeout,
2306 struct ata_security_password *pwd, int quiet)
2310 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2312 return ata_do_28bit_cmd(device,
2315 /*flags*/CAM_DIR_OUT,
2316 /*protocol*/AP_PROTO_PIO_OUT,
2317 /*tag_action*/MSG_SIMPLE_Q_TAG,
2318 /*command*/ATA_SECURITY_UNLOCK,
2322 /*data_ptr*/(u_int8_t *)pwd,
2323 /*dxfer_len*/sizeof(*pwd),
2329 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2330 int retry_count, u_int32_t timeout,
2331 struct ata_security_password *pwd, int quiet)
2335 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2336 return ata_do_28bit_cmd(device,
2339 /*flags*/CAM_DIR_OUT,
2340 /*protocol*/AP_PROTO_PIO_OUT,
2341 /*tag_action*/MSG_SIMPLE_Q_TAG,
2342 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2346 /*data_ptr*/(u_int8_t *)pwd,
2347 /*dxfer_len*/sizeof(*pwd),
2354 atasecurity_erase_confirm(struct cam_device *device,
2355 struct ata_params* ident_buf)
2358 printf("\nYou are about to ERASE ALL DATA from the following"
2359 " device:\n%s%d,%s%d: ", device->device_name,
2360 device->dev_unit_num, device->given_dev_name,
2361 device->given_unit_number);
2362 ata_print_ident(ident_buf);
2366 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2368 if (fgets(str, sizeof(str), stdin) != NULL) {
2369 if (strncasecmp(str, "yes", 3) == 0) {
2371 } else if (strncasecmp(str, "no", 2) == 0) {
2374 printf("Please answer \"yes\" or "
2385 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2386 int retry_count, u_int32_t timeout,
2387 u_int32_t erase_timeout,
2388 struct ata_security_password *pwd, int quiet)
2393 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2395 error = ata_do_28bit_cmd(device,
2398 /*flags*/CAM_DIR_NONE,
2399 /*protocol*/AP_PROTO_NON_DATA,
2400 /*tag_action*/MSG_SIMPLE_Q_TAG,
2401 /*command*/ATA_SECURITY_ERASE_PREPARE,
2414 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2416 error = ata_do_28bit_cmd(device,
2419 /*flags*/CAM_DIR_OUT,
2420 /*protocol*/AP_PROTO_PIO_OUT,
2421 /*tag_action*/MSG_SIMPLE_Q_TAG,
2422 /*command*/ATA_SECURITY_ERASE_UNIT,
2426 /*data_ptr*/(u_int8_t *)pwd,
2427 /*dxfer_len*/sizeof(*pwd),
2428 /*timeout*/erase_timeout,
2431 if (error == 0 && quiet == 0)
2432 printf("\nErase Complete\n");
2438 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2439 int retry_count, u_int32_t timeout,
2440 struct ata_security_password *pwd, int quiet)
2444 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2446 return ata_do_28bit_cmd(device,
2449 /*flags*/CAM_DIR_OUT,
2450 /*protocol*/AP_PROTO_PIO_OUT,
2451 /*tag_action*/MSG_SIMPLE_Q_TAG,
2452 /*command*/ATA_SECURITY_SET_PASSWORD,
2456 /*data_ptr*/(u_int8_t *)pwd,
2457 /*dxfer_len*/sizeof(*pwd),
2463 atasecurity_print(struct ata_params *parm)
2466 printf("\nSecurity Option Value\n");
2467 if (arglist & CAM_ARG_VERBOSE) {
2468 printf("status %04x\n",
2469 parm->security_status);
2471 printf("supported %s\n",
2472 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2473 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2475 printf("enabled %s\n",
2476 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2477 printf("drive locked %s\n",
2478 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2479 printf("security config frozen %s\n",
2480 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2481 printf("count expired %s\n",
2482 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2483 printf("security level %s\n",
2484 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2485 printf("enhanced erase supported %s\n",
2486 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2487 printf("erase time ");
2488 atasecurity_print_time(parm->erase_time);
2490 printf("enhanced erase time ");
2491 atasecurity_print_time(parm->enhanced_erase_time);
2493 printf("master password rev %04x%s\n",
2494 parm->master_passwd_revision,
2495 parm->master_passwd_revision == 0x0000 ||
2496 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2500 * Validates and copies the password in optarg to the passed buffer.
2501 * If the password in optarg is the same length as the buffer then
2502 * the data will still be copied but no null termination will occur.
2505 ata_getpwd(u_int8_t *passwd, int max, char opt)
2509 len = strlen(optarg);
2511 warnx("-%c password is too long", opt);
2513 } else if (len == 0) {
2514 warnx("-%c password is missing", opt);
2516 } else if (optarg[0] == '-'){
2517 warnx("-%c password starts with '-' (generic arg?)", opt);
2519 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2520 warnx("-%c password conflicts with existing password from -%c",
2525 /* Callers pass in a buffer which does NOT need to be terminated */
2526 strncpy(passwd, optarg, max);
2533 ATA_HPA_ACTION_PRINT,
2534 ATA_HPA_ACTION_SET_MAX,
2535 ATA_HPA_ACTION_SET_PWD,
2536 ATA_HPA_ACTION_LOCK,
2537 ATA_HPA_ACTION_UNLOCK,
2538 ATA_HPA_ACTION_FREEZE_LOCK
2542 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2543 u_int64_t maxsize, int persist)
2545 printf("\nYou are about to configure HPA to limit the user accessible\n"
2546 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2547 persist ? "persistently" : "temporarily",
2548 device->device_name, device->dev_unit_num,
2549 device->given_dev_name, device->given_unit_number);
2550 ata_print_ident(ident_buf);
2554 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2556 if (NULL != fgets(str, sizeof(str), stdin)) {
2557 if (0 == strncasecmp(str, "yes", 3)) {
2559 } else if (0 == strncasecmp(str, "no", 2)) {
2562 printf("Please answer \"yes\" or "
2573 atahpa(struct cam_device *device, int retry_count, int timeout,
2574 int argc, char **argv, char *combinedopt)
2577 struct ata_params *ident_buf;
2578 struct ccb_getdev cgd;
2579 struct ata_set_max_pwd pwd;
2580 int error, confirm, quiet, c, action, actions, persist;
2581 int security, is48bit, pwdsize;
2582 u_int64_t hpasize, maxsize;
2591 memset(&pwd, 0, sizeof(pwd));
2593 /* default action is to print hpa information */
2594 action = ATA_HPA_ACTION_PRINT;
2595 pwdsize = sizeof(pwd.password);
2597 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2600 action = ATA_HPA_ACTION_SET_MAX;
2601 maxsize = strtoumax(optarg, NULL, 0);
2606 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2608 action = ATA_HPA_ACTION_SET_PWD;
2614 action = ATA_HPA_ACTION_LOCK;
2620 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2622 action = ATA_HPA_ACTION_UNLOCK;
2628 action = ATA_HPA_ACTION_FREEZE_LOCK;
2648 warnx("too many hpa actions specified");
2652 if (get_cgd(device, &cgd) != 0) {
2653 warnx("couldn't get CGD");
2657 ccb = cam_getccb(device);
2659 warnx("couldn't allocate CCB");
2663 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2670 printf("%s%d: ", device->device_name, device->dev_unit_num);
2671 ata_print_ident(ident_buf);
2672 camxferrate(device);
2675 if (action == ATA_HPA_ACTION_PRINT) {
2676 error = ata_read_native_max(device, retry_count, timeout, ccb,
2677 ident_buf, &hpasize);
2679 atahpa_print(ident_buf, hpasize, 1);
2686 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2687 warnx("HPA is not supported by this device");
2693 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2694 warnx("HPA Security is not supported by this device");
2700 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2703 * The ATA spec requires:
2704 * 1. Read native max addr is called directly before set max addr
2705 * 2. Read native max addr is NOT called before any other set max call
2708 case ATA_HPA_ACTION_SET_MAX:
2710 atahpa_set_confirm(device, ident_buf, maxsize,
2717 error = ata_read_native_max(device, retry_count, timeout,
2718 ccb, ident_buf, &hpasize);
2720 error = atahpa_set_max(device, retry_count, timeout,
2721 ccb, is48bit, maxsize, persist);
2723 /* redo identify to get new lba values */
2724 error = ata_do_identify(device, retry_count,
2727 atahpa_print(ident_buf, hpasize, 1);
2732 case ATA_HPA_ACTION_SET_PWD:
2733 error = atahpa_password(device, retry_count, timeout,
2734 ccb, is48bit, &pwd);
2736 printf("HPA password has been set\n");
2739 case ATA_HPA_ACTION_LOCK:
2740 error = atahpa_lock(device, retry_count, timeout,
2743 printf("HPA has been locked\n");
2746 case ATA_HPA_ACTION_UNLOCK:
2747 error = atahpa_unlock(device, retry_count, timeout,
2748 ccb, is48bit, &pwd);
2750 printf("HPA has been unlocked\n");
2753 case ATA_HPA_ACTION_FREEZE_LOCK:
2754 error = atahpa_freeze_lock(device, retry_count, timeout,
2757 printf("HPA has been frozen\n");
2761 errx(1, "Option currently not supported");
2771 atasecurity(struct cam_device *device, int retry_count, int timeout,
2772 int argc, char **argv, char *combinedopt)
2775 struct ata_params *ident_buf;
2776 int error, confirm, quiet, c, action, actions, setpwd;
2777 int security_enabled, erase_timeout, pwdsize;
2778 struct ata_security_password pwd;
2786 memset(&pwd, 0, sizeof(pwd));
2788 /* default action is to print security information */
2789 action = ATA_SECURITY_ACTION_PRINT;
2791 /* user is master by default as its safer that way */
2792 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2793 pwdsize = sizeof(pwd.password);
2795 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2798 action = ATA_SECURITY_ACTION_FREEZE;
2803 if (strcasecmp(optarg, "user") == 0) {
2804 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2805 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2806 } else if (strcasecmp(optarg, "master") == 0) {
2807 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2808 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2810 warnx("-U argument '%s' is invalid (must be "
2811 "'user' or 'master')", optarg);
2817 if (strcasecmp(optarg, "high") == 0) {
2818 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2819 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2820 } else if (strcasecmp(optarg, "maximum") == 0) {
2821 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2822 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2824 warnx("-l argument '%s' is unknown (must be "
2825 "'high' or 'maximum')", optarg);
2831 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2833 action = ATA_SECURITY_ACTION_UNLOCK;
2838 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2840 action = ATA_SECURITY_ACTION_DISABLE;
2845 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2847 action = ATA_SECURITY_ACTION_ERASE;
2852 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2854 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2855 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2860 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2863 if (action == ATA_SECURITY_ACTION_PRINT)
2864 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2866 * Don't increment action as this can be combined
2867 * with other actions.
2880 erase_timeout = atoi(optarg) * 1000;
2886 warnx("too many security actions specified");
2890 if ((ccb = cam_getccb(device)) == NULL) {
2891 warnx("couldn't allocate CCB");
2895 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2902 printf("%s%d: ", device->device_name, device->dev_unit_num);
2903 ata_print_ident(ident_buf);
2904 camxferrate(device);
2907 if (action == ATA_SECURITY_ACTION_PRINT) {
2908 atasecurity_print(ident_buf);
2914 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2915 warnx("Security not supported");
2921 /* default timeout 15 seconds the same as linux hdparm */
2922 timeout = timeout ? timeout : 15 * 1000;
2924 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2926 /* first set the password if requested */
2928 /* confirm we can erase before setting the password if erasing */
2930 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2931 action == ATA_SECURITY_ACTION_ERASE) &&
2932 atasecurity_erase_confirm(device, ident_buf) == 0) {
2938 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2939 pwd.revision = ident_buf->master_passwd_revision;
2940 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2941 --pwd.revision == 0) {
2942 pwd.revision = 0xfffe;
2945 error = atasecurity_set_password(device, ccb, retry_count,
2946 timeout, &pwd, quiet);
2952 security_enabled = 1;
2956 case ATA_SECURITY_ACTION_FREEZE:
2957 error = atasecurity_freeze(device, ccb, retry_count,
2961 case ATA_SECURITY_ACTION_UNLOCK:
2962 if (security_enabled) {
2963 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2964 error = atasecurity_unlock(device, ccb,
2965 retry_count, timeout, &pwd, quiet);
2967 warnx("Can't unlock, drive is not locked");
2971 warnx("Can't unlock, security is disabled");
2976 case ATA_SECURITY_ACTION_DISABLE:
2977 if (security_enabled) {
2978 /* First unlock the drive if its locked */
2979 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2980 error = atasecurity_unlock(device, ccb,
2988 error = atasecurity_disable(device,
2996 warnx("Can't disable security (already disabled)");
3001 case ATA_SECURITY_ACTION_ERASE:
3002 if (security_enabled) {
3003 if (erase_timeout == 0) {
3004 erase_timeout = atasecurity_erase_timeout_msecs(
3005 ident_buf->erase_time);
3008 error = atasecurity_erase(device, ccb, retry_count,
3009 timeout, erase_timeout, &pwd,
3012 warnx("Can't secure erase (security is disabled)");
3017 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3018 if (security_enabled) {
3019 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3020 if (erase_timeout == 0) {
3022 atasecurity_erase_timeout_msecs(
3023 ident_buf->enhanced_erase_time);
3026 error = atasecurity_erase(device, ccb,
3027 retry_count, timeout,
3028 erase_timeout, &pwd,
3031 warnx("Enhanced erase is not supported");
3035 warnx("Can't secure erase (enhanced), "
3036 "(security is disabled)");
3047 #endif /* MINIMALISTIC */
3050 * Parse out a bus, or a bus, target and lun in the following
3056 * Returns the number of parsed components, or 0.
3059 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3060 cam_argmask *arglst)
3065 while (isspace(*tstr) && (*tstr != '\0'))
3068 tmpstr = (char *)strtok(tstr, ":");
3069 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3070 *bus = strtol(tmpstr, NULL, 0);
3071 *arglst |= CAM_ARG_BUS;
3073 tmpstr = (char *)strtok(NULL, ":");
3074 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3075 *target = strtol(tmpstr, NULL, 0);
3076 *arglst |= CAM_ARG_TARGET;
3078 tmpstr = (char *)strtok(NULL, ":");
3079 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3080 *lun = strtol(tmpstr, NULL, 0);
3081 *arglst |= CAM_ARG_LUN;
3091 dorescan_or_reset(int argc, char **argv, int rescan)
3093 static const char must[] =
3094 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3096 path_id_t bus = CAM_BUS_WILDCARD;
3097 target_id_t target = CAM_TARGET_WILDCARD;
3098 lun_id_t lun = CAM_LUN_WILDCARD;
3102 warnx(must, rescan? "rescan" : "reset");
3106 tstr = argv[optind];
3107 while (isspace(*tstr) && (*tstr != '\0'))
3109 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3110 arglist |= CAM_ARG_BUS;
3112 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3113 if (rv != 1 && rv != 3) {
3114 warnx(must, rescan? "rescan" : "reset");
3119 if ((arglist & CAM_ARG_BUS)
3120 && (arglist & CAM_ARG_TARGET)
3121 && (arglist & CAM_ARG_LUN))
3122 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3124 error = rescan_or_reset_bus(bus, rescan);
3130 rescan_or_reset_bus(path_id_t bus, int rescan)
3132 union ccb ccb, matchccb;
3138 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3139 warnx("error opening transport layer device %s", XPT_DEVICE);
3140 warn("%s", XPT_DEVICE);
3144 if (bus != CAM_BUS_WILDCARD) {
3145 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3146 ccb.ccb_h.path_id = bus;
3147 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3148 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3149 ccb.crcn.flags = CAM_FLAG_NONE;
3151 /* run this at a low priority */
3152 ccb.ccb_h.pinfo.priority = 5;
3154 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3155 warn("CAMIOCOMMAND ioctl failed");
3160 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3161 fprintf(stdout, "%s of bus %d was successful\n",
3162 rescan ? "Re-scan" : "Reset", bus);
3164 fprintf(stdout, "%s of bus %d returned error %#x\n",
3165 rescan ? "Re-scan" : "Reset", bus,
3166 ccb.ccb_h.status & CAM_STATUS_MASK);
3177 * The right way to handle this is to modify the xpt so that it can
3178 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3179 * that isn't implemented, so instead we enumerate the busses and
3180 * send the rescan or reset to those busses in the case where the
3181 * given bus is -1 (wildcard). We don't send a rescan or reset
3182 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3183 * no-op, sending a rescan to the xpt bus would result in a status of
3186 bzero(&(&matchccb.ccb_h)[1],
3187 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3188 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3189 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3190 bufsize = sizeof(struct dev_match_result) * 20;
3191 matchccb.cdm.match_buf_len = bufsize;
3192 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3193 if (matchccb.cdm.matches == NULL) {
3194 warnx("can't malloc memory for matches");
3198 matchccb.cdm.num_matches = 0;
3200 matchccb.cdm.num_patterns = 1;
3201 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3203 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3204 matchccb.cdm.pattern_buf_len);
3205 if (matchccb.cdm.patterns == NULL) {
3206 warnx("can't malloc memory for patterns");
3210 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3211 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3216 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3217 warn("CAMIOCOMMAND ioctl failed");
3222 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3223 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3224 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3225 warnx("got CAM error %#x, CDM error %d\n",
3226 matchccb.ccb_h.status, matchccb.cdm.status);
3231 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3232 struct bus_match_result *bus_result;
3234 /* This shouldn't happen. */
3235 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3238 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3241 * We don't want to rescan or reset the xpt bus.
3244 if (bus_result->path_id == CAM_XPT_PATH_ID)
3247 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3249 ccb.ccb_h.path_id = bus_result->path_id;
3250 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3251 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3252 ccb.crcn.flags = CAM_FLAG_NONE;
3254 /* run this at a low priority */
3255 ccb.ccb_h.pinfo.priority = 5;
3257 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3258 warn("CAMIOCOMMAND ioctl failed");
3263 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3264 fprintf(stdout, "%s of bus %d was successful\n",
3265 rescan? "Re-scan" : "Reset",
3266 bus_result->path_id);
3269 * Don't bail out just yet, maybe the other
3270 * rescan or reset commands will complete
3273 fprintf(stderr, "%s of bus %d returned error "
3274 "%#x\n", rescan? "Re-scan" : "Reset",
3275 bus_result->path_id,
3276 ccb.ccb_h.status & CAM_STATUS_MASK);
3280 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3281 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3288 if (matchccb.cdm.patterns != NULL)
3289 free(matchccb.cdm.patterns);
3290 if (matchccb.cdm.matches != NULL)
3291 free(matchccb.cdm.matches);
3297 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3300 struct cam_device *device;
3305 if (bus == CAM_BUS_WILDCARD) {
3306 warnx("invalid bus number %d", bus);
3310 if (target == CAM_TARGET_WILDCARD) {
3311 warnx("invalid target number %d", target);
3315 if (lun == CAM_LUN_WILDCARD) {
3316 warnx("invalid lun number %jx", (uintmax_t)lun);
3322 bzero(&ccb, sizeof(union ccb));
3325 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3326 warnx("error opening transport layer device %s\n",
3328 warn("%s", XPT_DEVICE);
3332 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3333 if (device == NULL) {
3334 warnx("%s", cam_errbuf);
3339 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3340 ccb.ccb_h.path_id = bus;
3341 ccb.ccb_h.target_id = target;
3342 ccb.ccb_h.target_lun = lun;
3343 ccb.ccb_h.timeout = 5000;
3344 ccb.crcn.flags = CAM_FLAG_NONE;
3346 /* run this at a low priority */
3347 ccb.ccb_h.pinfo.priority = 5;
3350 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3351 warn("CAMIOCOMMAND ioctl failed");
3356 if (cam_send_ccb(device, &ccb) < 0) {
3357 warn("error sending XPT_RESET_DEV CCB");
3358 cam_close_device(device);
3366 cam_close_device(device);
3369 * An error code of CAM_BDR_SENT is normal for a BDR request.
3371 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3373 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3374 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3375 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3378 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3379 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3380 ccb.ccb_h.status & CAM_STATUS_MASK);
3385 #ifndef MINIMALISTIC
3387 static struct scsi_nv defect_list_type_map[] = {
3388 { "block", SRDD10_BLOCK_FORMAT },
3389 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3390 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3391 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3392 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3393 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3397 readdefects(struct cam_device *device, int argc, char **argv,
3398 char *combinedopt, int retry_count, int timeout)
3400 union ccb *ccb = NULL;
3401 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3402 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3403 size_t hdr_size = 0, entry_size = 0;
3406 u_int8_t *defect_list = NULL;
3407 u_int8_t list_format = 0;
3408 int list_type_set = 0;
3409 u_int32_t dlist_length = 0;
3410 u_int32_t returned_length = 0, valid_len = 0;
3411 u_int32_t num_returned = 0, num_valid = 0;
3412 u_int32_t max_possible_size = 0, hdr_max = 0;
3413 u_int32_t starting_offset = 0;
3414 u_int8_t returned_format, returned_type;
3416 int summary = 0, quiet = 0;
3418 int lists_specified = 0;
3419 int get_length = 1, first_pass = 1;
3422 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3426 scsi_nv_status status;
3429 status = scsi_get_nv(defect_list_type_map,
3430 sizeof(defect_list_type_map) /
3431 sizeof(defect_list_type_map[0]), optarg,
3432 &entry_num, SCSI_NV_FLAG_IG_CASE);
3434 if (status == SCSI_NV_FOUND) {
3435 list_format = defect_list_type_map[
3439 warnx("%s: %s %s option %s", __func__,
3440 (status == SCSI_NV_AMBIGUOUS) ?
3441 "ambiguous" : "invalid", "defect list type",
3444 goto defect_bailout;
3449 arglist |= CAM_ARG_GLIST;
3452 arglist |= CAM_ARG_PLIST;
3463 starting_offset = strtoul(optarg, &endptr, 0);
3464 if (*endptr != '\0') {
3466 warnx("invalid starting offset %s", optarg);
3467 goto defect_bailout;
3479 if (list_type_set == 0) {
3481 warnx("no defect list format specified");
3482 goto defect_bailout;
3485 if (arglist & CAM_ARG_PLIST) {
3486 list_format |= SRDD10_PLIST;
3490 if (arglist & CAM_ARG_GLIST) {
3491 list_format |= SRDD10_GLIST;
3496 * This implies a summary, and was the previous behavior.
3498 if (lists_specified == 0)
3501 ccb = cam_getccb(device);
3506 * We start off asking for just the header to determine how much
3507 * defect data is available. Some Hitachi drives return an error
3508 * if you ask for more data than the drive has. Once we know the
3509 * length, we retry the command with the returned length.
3511 if (use_12byte == 0)
3512 dlist_length = sizeof(*hdr10);
3514 dlist_length = sizeof(*hdr12);
3517 if (defect_list != NULL) {
3521 defect_list = malloc(dlist_length);
3522 if (defect_list == NULL) {
3523 warnx("can't malloc memory for defect list");
3525 goto defect_bailout;
3529 bzero(defect_list, dlist_length);
3532 * cam_getccb() zeros the CCB header only. So we need to zero the
3533 * payload portion of the ccb.
3535 bzero(&(&ccb->ccb_h)[1],
3536 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3538 scsi_read_defects(&ccb->csio,
3539 /*retries*/ retry_count,
3541 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3542 /*list_format*/ list_format,
3543 /*addr_desc_index*/ starting_offset,
3544 /*data_ptr*/ defect_list,
3545 /*dxfer_len*/ dlist_length,
3546 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3547 /*sense_len*/ SSD_FULL_SIZE,
3548 /*timeout*/ timeout ? timeout : 5000);
3550 /* Disable freezing the device queue */
3551 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3553 if (cam_send_ccb(device, ccb) < 0) {
3554 perror("error reading defect list");
3556 if (arglist & CAM_ARG_VERBOSE) {
3557 cam_error_print(device, ccb, CAM_ESF_ALL,
3558 CAM_EPF_ALL, stderr);
3562 goto defect_bailout;
3565 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3567 if (use_12byte == 0) {
3568 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3569 hdr_size = sizeof(*hdr10);
3570 hdr_max = SRDDH10_MAX_LENGTH;
3572 if (valid_len >= hdr_size) {
3573 returned_length = scsi_2btoul(hdr10->length);
3574 returned_format = hdr10->format;
3576 returned_length = 0;
3577 returned_format = 0;
3580 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3581 hdr_size = sizeof(*hdr12);
3582 hdr_max = SRDDH12_MAX_LENGTH;
3584 if (valid_len >= hdr_size) {
3585 returned_length = scsi_4btoul(hdr12->length);
3586 returned_format = hdr12->format;
3588 returned_length = 0;
3589 returned_format = 0;
3593 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3594 switch (returned_type) {
3595 case SRDD10_BLOCK_FORMAT:
3596 entry_size = sizeof(struct scsi_defect_desc_block);
3598 case SRDD10_LONG_BLOCK_FORMAT:
3599 entry_size = sizeof(struct scsi_defect_desc_long_block);
3601 case SRDD10_EXT_PHYS_FORMAT:
3602 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3603 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3605 case SRDD10_EXT_BFI_FORMAT:
3606 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3607 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3610 warnx("Unknown defect format 0x%x\n", returned_type);
3612 goto defect_bailout;
3616 max_possible_size = (hdr_max / entry_size) * entry_size;
3617 num_returned = returned_length / entry_size;
3618 num_valid = min(returned_length, valid_len - hdr_size);
3619 num_valid /= entry_size;
3621 if (get_length != 0) {
3624 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3625 CAM_SCSI_STATUS_ERROR) {
3626 struct scsi_sense_data *sense;
3627 int error_code, sense_key, asc, ascq;
3629 sense = &ccb->csio.sense_data;
3630 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3631 ccb->csio.sense_resid, &error_code, &sense_key,
3632 &asc, &ascq, /*show_errors*/ 1);
3635 * If the drive is reporting that it just doesn't
3636 * support the defect list format, go ahead and use
3637 * the length it reported. Otherwise, the length
3638 * may not be valid, so use the maximum.
3640 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3641 && (asc == 0x1c) && (ascq == 0x00)
3642 && (returned_length > 0)) {
3643 if ((use_12byte == 0)
3644 && (returned_length >= max_possible_size)) {
3649 dlist_length = returned_length + hdr_size;
3650 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3651 && (asc == 0x1f) && (ascq == 0x00)
3652 && (returned_length > 0)) {
3653 /* Partial defect list transfer */
3655 * Hitachi drives return this error
3656 * along with a partial defect list if they
3657 * have more defects than the 10 byte
3658 * command can support. Retry with the 12
3661 if (use_12byte == 0) {
3666 dlist_length = returned_length + hdr_size;
3667 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3668 && (asc == 0x24) && (ascq == 0x00)) {
3669 /* Invalid field in CDB */
3671 * SBC-3 says that if the drive has more
3672 * defects than can be reported with the
3673 * 10 byte command, it should return this
3674 * error and no data. Retry with the 12
3677 if (use_12byte == 0) {
3682 dlist_length = returned_length + hdr_size;
3685 * If we got a SCSI error and no valid length,
3686 * just use the 10 byte maximum. The 12
3687 * byte maximum is too large.
3689 if (returned_length == 0)
3690 dlist_length = SRDD10_MAX_LENGTH;
3692 if ((use_12byte == 0)
3693 && (returned_length >=
3694 max_possible_size)) {
3699 dlist_length = returned_length +
3703 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3706 warnx("Error reading defect header");
3707 if (arglist & CAM_ARG_VERBOSE)
3708 cam_error_print(device, ccb, CAM_ESF_ALL,
3709 CAM_EPF_ALL, stderr);
3710 goto defect_bailout;
3712 if ((use_12byte == 0)
3713 && (returned_length >= max_possible_size)) {
3718 dlist_length = returned_length + hdr_size;
3721 fprintf(stdout, "%u", num_returned);
3723 fprintf(stdout, " defect%s",
3724 (num_returned != 1) ? "s" : "");
3726 fprintf(stdout, "\n");
3728 goto defect_bailout;
3732 * We always limit the list length to the 10-byte maximum
3733 * length (0xffff). The reason is that some controllers
3734 * can't handle larger I/Os, and we can transfer the entire
3735 * 10 byte list in one shot. For drives that support the 12
3736 * byte read defects command, we'll step through the list
3737 * by specifying a starting offset. For drives that don't
3738 * support the 12 byte command's starting offset, we'll
3739 * just display the first 64K.
3741 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3747 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3748 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3749 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3750 struct scsi_sense_data *sense;
3751 int error_code, sense_key, asc, ascq;
3753 sense = &ccb->csio.sense_data;
3754 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3755 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3756 &ascq, /*show_errors*/ 1);
3759 * According to the SCSI spec, if the disk doesn't support
3760 * the requested format, it will generally return a sense
3761 * key of RECOVERED ERROR, and an additional sense code
3762 * of "DEFECT LIST NOT FOUND". HGST drives also return
3763 * Primary/Grown defect list not found errors. So just
3764 * check for an ASC of 0x1c.
3766 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3768 const char *format_str;
3770 format_str = scsi_nv_to_str(defect_list_type_map,
3771 sizeof(defect_list_type_map) /
3772 sizeof(defect_list_type_map[0]),
3773 list_format & SRDD10_DLIST_FORMAT_MASK);
3774 warnx("requested defect format %s not available",
3775 format_str ? format_str : "unknown");
3777 format_str = scsi_nv_to_str(defect_list_type_map,
3778 sizeof(defect_list_type_map) /
3779 sizeof(defect_list_type_map[0]), returned_type);
3780 if (format_str != NULL) {
3781 warnx("Device returned %s format",
3785 warnx("Device returned unknown defect"
3786 " data format %#x", returned_type);
3787 goto defect_bailout;
3791 warnx("Error returned from read defect data command");
3792 if (arglist & CAM_ARG_VERBOSE)
3793 cam_error_print(device, ccb, CAM_ESF_ALL,
3794 CAM_EPF_ALL, stderr);
3795 goto defect_bailout;
3797 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3799 warnx("Error returned from read defect data command");
3800 if (arglist & CAM_ARG_VERBOSE)
3801 cam_error_print(device, ccb, CAM_ESF_ALL,
3802 CAM_EPF_ALL, stderr);
3803 goto defect_bailout;
3806 if (first_pass != 0) {
3807 fprintf(stderr, "Got %d defect", num_returned);
3809 if ((lists_specified == 0) || (num_returned == 0)) {
3810 fprintf(stderr, "s.\n");
3811 goto defect_bailout;
3812 } else if (num_returned == 1)
3813 fprintf(stderr, ":\n");
3815 fprintf(stderr, "s:\n");
3821 * XXX KDM I should probably clean up the printout format for the
3824 switch (returned_type) {
3825 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3826 case SRDD10_EXT_PHYS_FORMAT:
3828 struct scsi_defect_desc_phys_sector *dlist;
3830 dlist = (struct scsi_defect_desc_phys_sector *)
3831 (defect_list + hdr_size);
3833 for (i = 0; i < num_valid; i++) {
3836 sector = scsi_4btoul(dlist[i].sector);
3837 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3838 mads = (sector & SDD_EXT_PHYS_MADS) ?
3840 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3842 if (hex_format == 0)
3843 fprintf(stdout, "%d:%d:%d%s",
3844 scsi_3btoul(dlist[i].cylinder),
3846 scsi_4btoul(dlist[i].sector),
3847 mads ? " - " : "\n");
3849 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3850 scsi_3btoul(dlist[i].cylinder),
3852 scsi_4btoul(dlist[i].sector),
3853 mads ? " - " : "\n");
3856 if (num_valid < num_returned) {
3857 starting_offset += num_valid;
3862 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3863 case SRDD10_EXT_BFI_FORMAT:
3865 struct scsi_defect_desc_bytes_from_index *dlist;
3867 dlist = (struct scsi_defect_desc_bytes_from_index *)
3868 (defect_list + hdr_size);
3870 for (i = 0; i < num_valid; i++) {
3873 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3874 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3875 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3876 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3878 if (hex_format == 0)
3879 fprintf(stdout, "%d:%d:%d%s",
3880 scsi_3btoul(dlist[i].cylinder),
3882 scsi_4btoul(dlist[i].bytes_from_index),
3883 mads ? " - " : "\n");
3885 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3886 scsi_3btoul(dlist[i].cylinder),
3888 scsi_4btoul(dlist[i].bytes_from_index),
3889 mads ? " - " : "\n");
3893 if (num_valid < num_returned) {
3894 starting_offset += num_valid;
3899 case SRDDH10_BLOCK_FORMAT:
3901 struct scsi_defect_desc_block *dlist;
3903 dlist = (struct scsi_defect_desc_block *)
3904 (defect_list + hdr_size);
3906 for (i = 0; i < num_valid; i++) {
3907 if (hex_format == 0)
3908 fprintf(stdout, "%u\n",
3909 scsi_4btoul(dlist[i].address));
3911 fprintf(stdout, "0x%x\n",
3912 scsi_4btoul(dlist[i].address));
3915 if (num_valid < num_returned) {
3916 starting_offset += num_valid;
3922 case SRDD10_LONG_BLOCK_FORMAT:
3924 struct scsi_defect_desc_long_block *dlist;
3926 dlist = (struct scsi_defect_desc_long_block *)
3927 (defect_list + hdr_size);
3929 for (i = 0; i < num_valid; i++) {
3930 if (hex_format == 0)
3931 fprintf(stdout, "%ju\n",
3932 (uintmax_t)scsi_8btou64(
3935 fprintf(stdout, "0x%jx\n",
3936 (uintmax_t)scsi_8btou64(
3940 if (num_valid < num_returned) {
3941 starting_offset += num_valid;
3947 fprintf(stderr, "Unknown defect format 0x%x\n",
3954 if (defect_list != NULL)
3962 #endif /* MINIMALISTIC */
3966 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3970 ccb = cam_getccb(device);
3976 #ifndef MINIMALISTIC
3978 mode_sense(struct cam_device *device, int mode_page, int page_control,
3979 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3984 ccb = cam_getccb(device);
3987 errx(1, "mode_sense: couldn't allocate CCB");
3989 bzero(&(&ccb->ccb_h)[1],
3990 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3992 scsi_mode_sense(&ccb->csio,
3993 /* retries */ retry_count,
3995 /* tag_action */ MSG_SIMPLE_Q_TAG,
3997 /* page_code */ page_control << 6,
3998 /* page */ mode_page,
3999 /* param_buf */ data,
4000 /* param_len */ datalen,
4001 /* sense_len */ SSD_FULL_SIZE,
4002 /* timeout */ timeout ? timeout : 5000);
4004 if (arglist & CAM_ARG_ERR_RECOVER)
4005 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4007 /* Disable freezing the device queue */
4008 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4010 if (((retval = cam_send_ccb(device, ccb)) < 0)
4011 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4012 if (arglist & CAM_ARG_VERBOSE) {
4013 cam_error_print(device, ccb, CAM_ESF_ALL,
4014 CAM_EPF_ALL, stderr);
4017 cam_close_device(device);
4019 err(1, "error sending mode sense command");
4021 errx(1, "error sending mode sense command");
4028 mode_select(struct cam_device *device, int save_pages, int retry_count,
4029 int timeout, u_int8_t *data, int datalen)
4034 ccb = cam_getccb(device);
4037 errx(1, "mode_select: couldn't allocate CCB");
4039 bzero(&(&ccb->ccb_h)[1],
4040 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4042 scsi_mode_select(&ccb->csio,
4043 /* retries */ retry_count,
4045 /* tag_action */ MSG_SIMPLE_Q_TAG,
4046 /* scsi_page_fmt */ 1,
4047 /* save_pages */ save_pages,
4048 /* param_buf */ data,
4049 /* param_len */ datalen,
4050 /* sense_len */ SSD_FULL_SIZE,
4051 /* timeout */ timeout ? timeout : 5000);
4053 if (arglist & CAM_ARG_ERR_RECOVER)
4054 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4056 /* Disable freezing the device queue */
4057 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4059 if (((retval = cam_send_ccb(device, ccb)) < 0)
4060 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4061 if (arglist & CAM_ARG_VERBOSE) {
4062 cam_error_print(device, ccb, CAM_ESF_ALL,
4063 CAM_EPF_ALL, stderr);
4066 cam_close_device(device);
4069 err(1, "error sending mode select command");
4071 errx(1, "error sending mode select command");
4079 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4080 int retry_count, int timeout)
4082 int c, mode_page = -1, page_control = 0;
4083 int binary = 0, list = 0;
4085 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4091 arglist |= CAM_ARG_DBD;
4094 arglist |= CAM_ARG_MODE_EDIT;
4100 mode_page = strtol(optarg, NULL, 0);
4102 errx(1, "invalid mode page %d", mode_page);
4105 page_control = strtol(optarg, NULL, 0);
4106 if ((page_control < 0) || (page_control > 3))
4107 errx(1, "invalid page control field %d",
4109 arglist |= CAM_ARG_PAGE_CNTL;
4116 if (mode_page == -1 && list == 0)
4117 errx(1, "you must specify a mode page!");
4120 mode_list(device, page_control, arglist & CAM_ARG_DBD,
4121 retry_count, timeout);
4123 mode_edit(device, mode_page, page_control,
4124 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
4125 retry_count, timeout);
4130 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4131 int retry_count, int timeout)
4134 u_int32_t flags = CAM_DIR_NONE;
4135 u_int8_t *data_ptr = NULL;
4137 u_int8_t atacmd[12];
4138 struct get_hook hook;
4139 int c, data_bytes = 0;
4145 char *datastr = NULL, *tstr, *resstr = NULL;
4147 int fd_data = 0, fd_res = 0;
4150 ccb = cam_getccb(device);
4153 warnx("scsicmd: error allocating ccb");
4157 bzero(&(&ccb->ccb_h)[1],
4158 sizeof(union ccb) - sizeof(struct ccb_hdr));
4160 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4164 while (isspace(*tstr) && (*tstr != '\0'))
4166 hook.argc = argc - optind;
4167 hook.argv = argv + optind;
4169 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4172 * Increment optind by the number of arguments the
4173 * encoding routine processed. After each call to
4174 * getopt(3), optind points to the argument that
4175 * getopt should process _next_. In this case,
4176 * that means it points to the first command string
4177 * argument, if there is one. Once we increment
4178 * this, it should point to either the next command
4179 * line argument, or it should be past the end of
4186 while (isspace(*tstr) && (*tstr != '\0'))
4188 hook.argc = argc - optind;
4189 hook.argv = argv + optind;
4191 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4194 * Increment optind by the number of arguments the
4195 * encoding routine processed. After each call to
4196 * getopt(3), optind points to the argument that
4197 * getopt should process _next_. In this case,
4198 * that means it points to the first command string
4199 * argument, if there is one. Once we increment
4200 * this, it should point to either the next command
4201 * line argument, or it should be past the end of
4213 if (arglist & CAM_ARG_CMD_OUT) {
4214 warnx("command must either be "
4215 "read or write, not both");
4217 goto scsicmd_bailout;
4219 arglist |= CAM_ARG_CMD_IN;
4221 data_bytes = strtol(optarg, NULL, 0);
4222 if (data_bytes <= 0) {
4223 warnx("invalid number of input bytes %d",
4226 goto scsicmd_bailout;
4228 hook.argc = argc - optind;
4229 hook.argv = argv + optind;
4232 datastr = cget(&hook, NULL);
4234 * If the user supplied "-" instead of a format, he
4235 * wants the data to be written to stdout.
4237 if ((datastr != NULL)
4238 && (datastr[0] == '-'))
4241 data_ptr = (u_int8_t *)malloc(data_bytes);
4242 if (data_ptr == NULL) {
4243 warnx("can't malloc memory for data_ptr");
4245 goto scsicmd_bailout;
4249 if (arglist & CAM_ARG_CMD_IN) {
4250 warnx("command must either be "
4251 "read or write, not both");
4253 goto scsicmd_bailout;
4255 arglist |= CAM_ARG_CMD_OUT;
4256 flags = CAM_DIR_OUT;
4257 data_bytes = strtol(optarg, NULL, 0);
4258 if (data_bytes <= 0) {
4259 warnx("invalid number of output bytes %d",
4262 goto scsicmd_bailout;
4264 hook.argc = argc - optind;
4265 hook.argv = argv + optind;
4267 datastr = cget(&hook, NULL);
4268 data_ptr = (u_int8_t *)malloc(data_bytes);
4269 if (data_ptr == NULL) {
4270 warnx("can't malloc memory for data_ptr");
4272 goto scsicmd_bailout;
4274 bzero(data_ptr, data_bytes);
4276 * If the user supplied "-" instead of a format, he
4277 * wants the data to be read from stdin.
4279 if ((datastr != NULL)
4280 && (datastr[0] == '-'))
4283 buff_encode_visit(data_ptr, data_bytes, datastr,
4289 hook.argc = argc - optind;
4290 hook.argv = argv + optind;
4292 resstr = cget(&hook, NULL);
4293 if ((resstr != NULL) && (resstr[0] == '-'))
4303 * If fd_data is set, and we're writing to the device, we need to
4304 * read the data the user wants written from stdin.
4306 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4308 int amt_to_read = data_bytes;
4309 u_int8_t *buf_ptr = data_ptr;
4311 for (amt_read = 0; amt_to_read > 0;
4312 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4313 if (amt_read == -1) {
4314 warn("error reading data from stdin");
4316 goto scsicmd_bailout;
4318 amt_to_read -= amt_read;
4319 buf_ptr += amt_read;
4323 if (arglist & CAM_ARG_ERR_RECOVER)
4324 flags |= CAM_PASS_ERR_RECOVER;
4326 /* Disable freezing the device queue */
4327 flags |= CAM_DEV_QFRZDIS;
4331 * This is taken from the SCSI-3 draft spec.
4332 * (T10/1157D revision 0.3)
4333 * The top 3 bits of an opcode are the group code.
4334 * The next 5 bits are the command code.
4335 * Group 0: six byte commands
4336 * Group 1: ten byte commands
4337 * Group 2: ten byte commands
4339 * Group 4: sixteen byte commands
4340 * Group 5: twelve byte commands
4341 * Group 6: vendor specific
4342 * Group 7: vendor specific
4344 switch((cdb[0] >> 5) & 0x7) {
4355 /* computed by buff_encode_visit */
4366 * We should probably use csio_build_visit or something like that
4367 * here, but it's easier to encode arguments as you go. The
4368 * alternative would be skipping the CDB argument and then encoding
4369 * it here, since we've got the data buffer argument by now.
4371 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4373 cam_fill_csio(&ccb->csio,
4374 /*retries*/ retry_count,
4377 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4378 /*data_ptr*/ data_ptr,
4379 /*dxfer_len*/ data_bytes,
4380 /*sense_len*/ SSD_FULL_SIZE,
4381 /*cdb_len*/ cdb_len,
4382 /*timeout*/ timeout ? timeout : 5000);
4385 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4387 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4389 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4391 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4393 cam_fill_ataio(&ccb->ataio,
4394 /*retries*/ retry_count,
4398 /*data_ptr*/ data_ptr,
4399 /*dxfer_len*/ data_bytes,
4400 /*timeout*/ timeout ? timeout : 5000);
4403 if (((retval = cam_send_ccb(device, ccb)) < 0)
4404 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4405 const char warnstr[] = "error sending command";
4412 if (arglist & CAM_ARG_VERBOSE) {
4413 cam_error_print(device, ccb, CAM_ESF_ALL,
4414 CAM_EPF_ALL, stderr);
4418 goto scsicmd_bailout;
4421 if (atacmd_len && need_res) {
4423 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4425 fprintf(stdout, "\n");
4428 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4429 ccb->ataio.res.status,
4430 ccb->ataio.res.error,
4431 ccb->ataio.res.lba_low,
4432 ccb->ataio.res.lba_mid,
4433 ccb->ataio.res.lba_high,
4434 ccb->ataio.res.device,
4435 ccb->ataio.res.lba_low_exp,
4436 ccb->ataio.res.lba_mid_exp,
4437 ccb->ataio.res.lba_high_exp,
4438 ccb->ataio.res.sector_count,
4439 ccb->ataio.res.sector_count_exp);
4444 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4445 && (arglist & CAM_ARG_CMD_IN)
4446 && (data_bytes > 0)) {
4448 buff_decode_visit(data_ptr, data_bytes, datastr,
4450 fprintf(stdout, "\n");
4452 ssize_t amt_written;
4453 int amt_to_write = data_bytes;
4454 u_int8_t *buf_ptr = data_ptr;
4456 for (amt_written = 0; (amt_to_write > 0) &&
4457 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4458 amt_to_write -= amt_written;
4459 buf_ptr += amt_written;
4461 if (amt_written == -1) {
4462 warn("error writing data to stdout");
4464 goto scsicmd_bailout;
4465 } else if ((amt_written == 0)
4466 && (amt_to_write > 0)) {
4467 warnx("only wrote %u bytes out of %u",
4468 data_bytes - amt_to_write, data_bytes);
4475 if ((data_bytes > 0) && (data_ptr != NULL))
4484 camdebug(int argc, char **argv, char *combinedopt)
4487 path_id_t bus = CAM_BUS_WILDCARD;
4488 target_id_t target = CAM_TARGET_WILDCARD;
4489 lun_id_t lun = CAM_LUN_WILDCARD;
4490 char *tstr, *tmpstr = NULL;
4494 bzero(&ccb, sizeof(union ccb));
4496 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4499 arglist |= CAM_ARG_DEBUG_INFO;
4500 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4503 arglist |= CAM_ARG_DEBUG_PERIPH;
4504 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4507 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4508 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4511 arglist |= CAM_ARG_DEBUG_TRACE;
4512 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4515 arglist |= CAM_ARG_DEBUG_XPT;
4516 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4519 arglist |= CAM_ARG_DEBUG_CDB;
4520 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4523 arglist |= CAM_ARG_DEBUG_PROBE;
4524 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4531 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4532 warnx("error opening transport layer device %s", XPT_DEVICE);
4533 warn("%s", XPT_DEVICE);
4540 warnx("you must specify \"off\", \"all\" or a bus,");
4541 warnx("bus:target, or bus:target:lun");
4548 while (isspace(*tstr) && (*tstr != '\0'))
4551 if (strncmp(tstr, "off", 3) == 0) {
4552 ccb.cdbg.flags = CAM_DEBUG_NONE;
4553 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4554 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4555 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4556 } else if (strncmp(tstr, "all", 3) != 0) {
4557 tmpstr = (char *)strtok(tstr, ":");
4558 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4559 bus = strtol(tmpstr, NULL, 0);
4560 arglist |= CAM_ARG_BUS;
4561 tmpstr = (char *)strtok(NULL, ":");
4562 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4563 target = strtol(tmpstr, NULL, 0);
4564 arglist |= CAM_ARG_TARGET;
4565 tmpstr = (char *)strtok(NULL, ":");
4566 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4567 lun = strtol(tmpstr, NULL, 0);
4568 arglist |= CAM_ARG_LUN;
4573 warnx("you must specify \"all\", \"off\", or a bus,");
4574 warnx("bus:target, or bus:target:lun to debug");
4580 ccb.ccb_h.func_code = XPT_DEBUG;
4581 ccb.ccb_h.path_id = bus;
4582 ccb.ccb_h.target_id = target;
4583 ccb.ccb_h.target_lun = lun;
4585 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4586 warn("CAMIOCOMMAND ioctl failed");
4591 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4592 CAM_FUNC_NOTAVAIL) {
4593 warnx("CAM debugging not available");
4594 warnx("you need to put options CAMDEBUG in"
4595 " your kernel config file!");
4597 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4599 warnx("XPT_DEBUG CCB failed with status %#x",
4603 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4605 "Debugging turned off\n");
4608 "Debugging enabled for "
4610 bus, target, (uintmax_t)lun);
4621 tagcontrol(struct cam_device *device, int argc, char **argv,
4631 ccb = cam_getccb(device);
4634 warnx("tagcontrol: error allocating ccb");
4638 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4641 numtags = strtol(optarg, NULL, 0);
4643 warnx("tag count %d is < 0", numtags);
4645 goto tagcontrol_bailout;
4656 cam_path_string(device, pathstr, sizeof(pathstr));
4659 bzero(&(&ccb->ccb_h)[1],
4660 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4661 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4662 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4663 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4664 ccb->crs.openings = numtags;
4667 if (cam_send_ccb(device, ccb) < 0) {
4668 perror("error sending XPT_REL_SIMQ CCB");
4670 goto tagcontrol_bailout;
4673 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4674 warnx("XPT_REL_SIMQ CCB failed");
4675 cam_error_print(device, ccb, CAM_ESF_ALL,
4676 CAM_EPF_ALL, stderr);
4678 goto tagcontrol_bailout;
4683 fprintf(stdout, "%stagged openings now %d\n",
4684 pathstr, ccb->crs.openings);
4687 bzero(&(&ccb->ccb_h)[1],
4688 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4690 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4692 if (cam_send_ccb(device, ccb) < 0) {
4693 perror("error sending XPT_GDEV_STATS CCB");
4695 goto tagcontrol_bailout;
4698 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4699 warnx("XPT_GDEV_STATS CCB failed");
4700 cam_error_print(device, ccb, CAM_ESF_ALL,
4701 CAM_EPF_ALL, stderr);
4703 goto tagcontrol_bailout;
4706 if (arglist & CAM_ARG_VERBOSE) {
4707 fprintf(stdout, "%s", pathstr);
4708 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4709 fprintf(stdout, "%s", pathstr);
4710 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4711 fprintf(stdout, "%s", pathstr);
4712 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4713 fprintf(stdout, "%s", pathstr);
4714 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4715 fprintf(stdout, "%s", pathstr);
4716 fprintf(stdout, "held %d\n", ccb->cgds.held);
4717 fprintf(stdout, "%s", pathstr);
4718 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4719 fprintf(stdout, "%s", pathstr);
4720 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4723 fprintf(stdout, "%s", pathstr);
4724 fprintf(stdout, "device openings: ");
4726 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4727 ccb->cgds.dev_active);
4737 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4741 cam_path_string(device, pathstr, sizeof(pathstr));
4743 if (cts->transport == XPORT_SPI) {
4744 struct ccb_trans_settings_spi *spi =
4745 &cts->xport_specific.spi;
4747 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4749 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4752 if (spi->sync_offset != 0) {
4755 freq = scsi_calc_syncsrate(spi->sync_period);
4756 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4757 pathstr, freq / 1000, freq % 1000);
4761 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4762 fprintf(stdout, "%soffset: %d\n", pathstr,
4766 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4767 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4768 (0x01 << spi->bus_width) * 8);
4771 if (spi->valid & CTS_SPI_VALID_DISC) {
4772 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4773 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4774 "enabled" : "disabled");
4777 if (cts->transport == XPORT_FC) {
4778 struct ccb_trans_settings_fc *fc =
4779 &cts->xport_specific.fc;
4781 if (fc->valid & CTS_FC_VALID_WWNN)
4782 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4783 (long long) fc->wwnn);
4784 if (fc->valid & CTS_FC_VALID_WWPN)
4785 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4786 (long long) fc->wwpn);
4787 if (fc->valid & CTS_FC_VALID_PORT)
4788 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4789 if (fc->valid & CTS_FC_VALID_SPEED)
4790 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4791 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4793 if (cts->transport == XPORT_SAS) {
4794 struct ccb_trans_settings_sas *sas =
4795 &cts->xport_specific.sas;
4797 if (sas->valid & CTS_SAS_VALID_SPEED)
4798 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4799 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4801 if (cts->transport == XPORT_ATA) {
4802 struct ccb_trans_settings_pata *pata =
4803 &cts->xport_specific.ata;
4805 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4806 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4807 ata_mode2string(pata->mode));
4809 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4810 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4813 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4814 fprintf(stdout, "%sPIO transaction length: %d\n",
4815 pathstr, pata->bytecount);
4818 if (cts->transport == XPORT_SATA) {
4819 struct ccb_trans_settings_sata *sata =
4820 &cts->xport_specific.sata;
4822 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4823 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4826 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4827 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4828 ata_mode2string(sata->mode));
4830 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4831 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4834 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4835 fprintf(stdout, "%sPIO transaction length: %d\n",
4836 pathstr, sata->bytecount);
4838 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4839 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4842 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4843 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4846 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4847 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4851 if (cts->protocol == PROTO_ATA) {
4852 struct ccb_trans_settings_ata *ata=
4853 &cts->proto_specific.ata;
4855 if (ata->valid & CTS_ATA_VALID_TQ) {
4856 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4857 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4858 "enabled" : "disabled");
4861 if (cts->protocol == PROTO_SCSI) {
4862 struct ccb_trans_settings_scsi *scsi=
4863 &cts->proto_specific.scsi;
4865 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4866 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4867 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4868 "enabled" : "disabled");
4875 * Get a path inquiry CCB for the specified device.
4878 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4883 ccb = cam_getccb(device);
4885 warnx("get_cpi: couldn't allocate CCB");
4888 bzero(&(&ccb->ccb_h)[1],
4889 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4890 ccb->ccb_h.func_code = XPT_PATH_INQ;
4891 if (cam_send_ccb(device, ccb) < 0) {
4892 warn("get_cpi: error sending Path Inquiry CCB");
4893 if (arglist & CAM_ARG_VERBOSE)
4894 cam_error_print(device, ccb, CAM_ESF_ALL,
4895 CAM_EPF_ALL, stderr);
4897 goto get_cpi_bailout;
4899 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4900 if (arglist & CAM_ARG_VERBOSE)
4901 cam_error_print(device, ccb, CAM_ESF_ALL,
4902 CAM_EPF_ALL, stderr);
4904 goto get_cpi_bailout;
4906 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4914 * Get a get device CCB for the specified device.
4917 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4922 ccb = cam_getccb(device);
4924 warnx("get_cgd: couldn't allocate CCB");
4927 bzero(&(&ccb->ccb_h)[1],
4928 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4929 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4930 if (cam_send_ccb(device, ccb) < 0) {
4931 warn("get_cgd: error sending Path Inquiry CCB");
4932 if (arglist & CAM_ARG_VERBOSE)
4933 cam_error_print(device, ccb, CAM_ESF_ALL,
4934 CAM_EPF_ALL, stderr);
4936 goto get_cgd_bailout;
4938 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4939 if (arglist & CAM_ARG_VERBOSE)
4940 cam_error_print(device, ccb, CAM_ESF_ALL,
4941 CAM_EPF_ALL, stderr);
4943 goto get_cgd_bailout;
4945 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4953 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4957 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4958 int timeout, int verbosemode)
4960 union ccb *ccb = NULL;
4961 struct scsi_vpd_supported_page_list sup_pages;
4965 ccb = cam_getccb(dev);
4967 warn("Unable to allocate CCB");
4972 /* cam_getccb cleans up the header, caller has to zero the payload */
4973 bzero(&(&ccb->ccb_h)[1],
4974 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4976 bzero(&sup_pages, sizeof(sup_pages));
4978 scsi_inquiry(&ccb->csio,
4979 /*retries*/ retry_count,
4981 /* tag_action */ MSG_SIMPLE_Q_TAG,
4982 /* inq_buf */ (u_int8_t *)&sup_pages,
4983 /* inq_len */ sizeof(sup_pages),
4985 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
4986 /* sense_len */ SSD_FULL_SIZE,
4987 /* timeout */ timeout ? timeout : 5000);
4989 /* Disable freezing the device queue */
4990 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4992 if (retry_count != 0)
4993 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4995 if (cam_send_ccb(dev, ccb) < 0) {
5002 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5003 if (verbosemode != 0)
5004 cam_error_print(dev, ccb, CAM_ESF_ALL,
5005 CAM_EPF_ALL, stderr);
5010 for (i = 0; i < sup_pages.length; i++) {
5011 if (sup_pages.list[i] == page_id) {
5024 * devtype is filled in with the type of device.
5025 * Returns 0 for success, non-zero for failure.
5028 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5029 int verbosemode, camcontrol_devtype *devtype)
5031 struct ccb_getdev cgd;
5034 retval = get_cgd(dev, &cgd);
5038 switch (cgd.protocol) {
5044 *devtype = CC_DT_ATA;
5046 break; /*NOTREACHED*/
5048 *devtype = CC_DT_UNKNOWN;
5050 break; /*NOTREACHED*/
5054 * Check for the ATA Information VPD page (0x89). If this is an
5055 * ATA device behind a SCSI to ATA translation layer, this VPD page
5056 * should be present.
5058 * If that VPD page isn't present, or we get an error back from the
5059 * INQUIRY command, we'll just treat it as a normal SCSI device.
5061 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5062 timeout, verbosemode);
5064 *devtype = CC_DT_ATA_BEHIND_SCSI;
5066 *devtype = CC_DT_SCSI;
5075 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5076 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5077 uint16_t sector_count, uint64_t lba, uint8_t command, uint8_t *data_ptr,
5078 uint16_t dxfer_len, uint8_t sense_len, uint32_t timeout,
5079 int is48bit, camcontrol_devtype devtype)
5081 if (devtype == CC_DT_ATA) {
5082 cam_fill_ataio(&ccb->ataio,
5083 /*retries*/ retry_count,
5086 /*tag_action*/ tag_action,
5087 /*data_ptr*/ data_ptr,
5088 /*dxfer_len*/ dxfer_len,
5089 /*timeout*/ timeout);
5090 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5091 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5094 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5097 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5098 protocol |= AP_EXTEND;
5100 scsi_ata_pass_16(&ccb->csio,
5101 /*retries*/ retry_count,
5104 /*tag_action*/ tag_action,
5105 /*protocol*/ protocol,
5106 /*ata_flags*/ ata_flags,
5107 /*features*/ features,
5108 /*sector_count*/ sector_count,
5110 /*command*/ command,
5112 /*data_ptr*/ data_ptr,
5113 /*dxfer_len*/ dxfer_len,
5114 /*sense_len*/ sense_len,
5115 /*timeout*/ timeout);
5121 cpi_print(struct ccb_pathinq *cpi)
5123 char adapter_str[1024];
5126 snprintf(adapter_str, sizeof(adapter_str),
5127 "%s%d:", cpi->dev_name, cpi->unit_number);
5129 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5132 for (i = 1; i < 0xff; i = i << 1) {
5135 if ((i & cpi->hba_inquiry) == 0)
5138 fprintf(stdout, "%s supports ", adapter_str);
5142 str = "MDP message";
5145 str = "32 bit wide SCSI";
5148 str = "16 bit wide SCSI";
5151 str = "SDTR message";
5154 str = "linked CDBs";
5157 str = "tag queue messages";
5160 str = "soft reset alternative";
5163 str = "SATA Port Multiplier";
5166 str = "unknown PI bit set";
5169 fprintf(stdout, "%s\n", str);
5172 for (i = 1; i < 0xff; i = i << 1) {
5175 if ((i & cpi->hba_misc) == 0)
5178 fprintf(stdout, "%s ", adapter_str);
5182 str = "bus scans from high ID to low ID";
5185 str = "removable devices not included in scan";
5187 case PIM_NOINITIATOR:
5188 str = "initiator role not supported";
5190 case PIM_NOBUSRESET:
5191 str = "user has disabled initial BUS RESET or"
5192 " controller is in target/mixed mode";
5195 str = "do not send 6-byte commands";
5198 str = "scan bus sequentially";
5201 str = "unknown PIM bit set";
5204 fprintf(stdout, "%s\n", str);
5207 for (i = 1; i < 0xff; i = i << 1) {
5210 if ((i & cpi->target_sprt) == 0)
5213 fprintf(stdout, "%s supports ", adapter_str);
5216 str = "target mode processor mode";
5219 str = "target mode phase cog. mode";
5221 case PIT_DISCONNECT:
5222 str = "disconnects in target mode";
5225 str = "terminate I/O message in target mode";
5228 str = "group 6 commands in target mode";
5231 str = "group 7 commands in target mode";
5234 str = "unknown PIT bit set";
5238 fprintf(stdout, "%s\n", str);
5240 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5242 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5244 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5246 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5247 adapter_str, cpi->hpath_id);
5248 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5250 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5251 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5252 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5253 adapter_str, cpi->hba_vendor);
5254 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5255 adapter_str, cpi->hba_device);
5256 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5257 adapter_str, cpi->hba_subvendor);
5258 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5259 adapter_str, cpi->hba_subdevice);
5260 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5261 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5262 if (cpi->base_transfer_speed > 1000)
5263 fprintf(stdout, "%d.%03dMB/sec\n",
5264 cpi->base_transfer_speed / 1000,
5265 cpi->base_transfer_speed % 1000);
5267 fprintf(stdout, "%dKB/sec\n",
5268 (cpi->base_transfer_speed % 1000) * 1000);
5269 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5270 adapter_str, cpi->maxio);
5274 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5275 struct ccb_trans_settings *cts)
5281 ccb = cam_getccb(device);
5284 warnx("get_print_cts: error allocating ccb");
5288 bzero(&(&ccb->ccb_h)[1],
5289 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5291 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5293 if (user_settings == 0)
5294 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5296 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5298 if (cam_send_ccb(device, ccb) < 0) {
5299 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5300 if (arglist & CAM_ARG_VERBOSE)
5301 cam_error_print(device, ccb, CAM_ESF_ALL,
5302 CAM_EPF_ALL, stderr);
5304 goto get_print_cts_bailout;
5307 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5308 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5309 if (arglist & CAM_ARG_VERBOSE)
5310 cam_error_print(device, ccb, CAM_ESF_ALL,
5311 CAM_EPF_ALL, stderr);
5313 goto get_print_cts_bailout;
5317 cts_print(device, &ccb->cts);
5320 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5322 get_print_cts_bailout:
5330 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5331 int argc, char **argv, char *combinedopt)
5335 int user_settings = 0;
5337 int disc_enable = -1, tag_enable = -1;
5340 double syncrate = -1;
5343 int change_settings = 0, send_tur = 0;
5344 struct ccb_pathinq cpi;
5346 ccb = cam_getccb(device);
5348 warnx("ratecontrol: error allocating ccb");
5351 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5360 if (strncasecmp(optarg, "enable", 6) == 0)
5362 else if (strncasecmp(optarg, "disable", 7) == 0)
5365 warnx("-D argument \"%s\" is unknown", optarg);
5367 goto ratecontrol_bailout;
5369 change_settings = 1;
5372 mode = ata_string2mode(optarg);
5374 warnx("unknown mode '%s'", optarg);
5376 goto ratecontrol_bailout;
5378 change_settings = 1;
5381 offset = strtol(optarg, NULL, 0);
5383 warnx("offset value %d is < 0", offset);
5385 goto ratecontrol_bailout;
5387 change_settings = 1;
5393 syncrate = atof(optarg);
5395 warnx("sync rate %f is < 0", syncrate);
5397 goto ratecontrol_bailout;
5399 change_settings = 1;
5402 if (strncasecmp(optarg, "enable", 6) == 0)
5404 else if (strncasecmp(optarg, "disable", 7) == 0)
5407 warnx("-T argument \"%s\" is unknown", optarg);
5409 goto ratecontrol_bailout;
5411 change_settings = 1;
5417 bus_width = strtol(optarg, NULL, 0);
5418 if (bus_width < 0) {
5419 warnx("bus width %d is < 0", bus_width);
5421 goto ratecontrol_bailout;
5423 change_settings = 1;
5429 bzero(&(&ccb->ccb_h)[1],
5430 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
5432 * Grab path inquiry information, so we can determine whether
5433 * or not the initiator is capable of the things that the user
5436 ccb->ccb_h.func_code = XPT_PATH_INQ;
5437 if (cam_send_ccb(device, ccb) < 0) {
5438 perror("error sending XPT_PATH_INQ CCB");
5439 if (arglist & CAM_ARG_VERBOSE) {
5440 cam_error_print(device, ccb, CAM_ESF_ALL,
5441 CAM_EPF_ALL, stderr);
5444 goto ratecontrol_bailout;
5446 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5447 warnx("XPT_PATH_INQ CCB failed");
5448 if (arglist & CAM_ARG_VERBOSE) {
5449 cam_error_print(device, ccb, CAM_ESF_ALL,
5450 CAM_EPF_ALL, stderr);
5453 goto ratecontrol_bailout;
5455 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5456 bzero(&(&ccb->ccb_h)[1],
5457 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5459 fprintf(stdout, "%s parameters:\n",
5460 user_settings ? "User" : "Current");
5462 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5464 goto ratecontrol_bailout;
5466 if (arglist & CAM_ARG_VERBOSE)
5469 if (change_settings) {
5470 int didsettings = 0;
5471 struct ccb_trans_settings_spi *spi = NULL;
5472 struct ccb_trans_settings_pata *pata = NULL;
5473 struct ccb_trans_settings_sata *sata = NULL;
5474 struct ccb_trans_settings_ata *ata = NULL;
5475 struct ccb_trans_settings_scsi *scsi = NULL;
5477 if (ccb->cts.transport == XPORT_SPI)
5478 spi = &ccb->cts.xport_specific.spi;
5479 if (ccb->cts.transport == XPORT_ATA)
5480 pata = &ccb->cts.xport_specific.ata;
5481 if (ccb->cts.transport == XPORT_SATA)
5482 sata = &ccb->cts.xport_specific.sata;
5483 if (ccb->cts.protocol == PROTO_ATA)
5484 ata = &ccb->cts.proto_specific.ata;
5485 if (ccb->cts.protocol == PROTO_SCSI)
5486 scsi = &ccb->cts.proto_specific.scsi;
5487 ccb->cts.xport_specific.valid = 0;
5488 ccb->cts.proto_specific.valid = 0;
5489 if (spi && disc_enable != -1) {
5490 spi->valid |= CTS_SPI_VALID_DISC;
5491 if (disc_enable == 0)
5492 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5494 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5497 if (tag_enable != -1) {
5498 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5499 warnx("HBA does not support tagged queueing, "
5500 "so you cannot modify tag settings");
5502 goto ratecontrol_bailout;
5505 ata->valid |= CTS_SCSI_VALID_TQ;
5506 if (tag_enable == 0)
5507 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5509 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5512 scsi->valid |= CTS_SCSI_VALID_TQ;
5513 if (tag_enable == 0)
5514 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5516 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5520 if (spi && offset != -1) {
5521 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5522 warnx("HBA is not capable of changing offset");
5524 goto ratecontrol_bailout;
5526 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5527 spi->sync_offset = offset;
5530 if (spi && syncrate != -1) {
5531 int prelim_sync_period;
5533 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5534 warnx("HBA is not capable of changing "
5537 goto ratecontrol_bailout;
5539 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5541 * The sync rate the user gives us is in MHz.
5542 * We need to translate it into KHz for this
5547 * Next, we calculate a "preliminary" sync period
5548 * in tenths of a nanosecond.
5551 prelim_sync_period = 0;
5553 prelim_sync_period = 10000000 / syncrate;
5555 scsi_calc_syncparam(prelim_sync_period);
5558 if (sata && syncrate != -1) {
5559 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5560 warnx("HBA is not capable of changing "
5563 goto ratecontrol_bailout;
5565 if (!user_settings) {
5566 warnx("You can modify only user rate "
5567 "settings for SATA");
5569 goto ratecontrol_bailout;
5571 sata->revision = ata_speed2revision(syncrate * 100);
5572 if (sata->revision < 0) {
5573 warnx("Invalid rate %f", syncrate);
5575 goto ratecontrol_bailout;
5577 sata->valid |= CTS_SATA_VALID_REVISION;
5580 if ((pata || sata) && mode != -1) {
5581 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5582 warnx("HBA is not capable of changing "
5585 goto ratecontrol_bailout;
5587 if (!user_settings) {
5588 warnx("You can modify only user mode "
5589 "settings for ATA/SATA");
5591 goto ratecontrol_bailout;
5595 pata->valid |= CTS_ATA_VALID_MODE;
5598 sata->valid |= CTS_SATA_VALID_MODE;
5603 * The bus_width argument goes like this:
5607 * Therefore, if you shift the number of bits given on the
5608 * command line right by 4, you should get the correct
5611 if (spi && bus_width != -1) {
5613 * We might as well validate things here with a
5614 * decipherable error message, rather than what
5615 * will probably be an indecipherable error message
5616 * by the time it gets back to us.
5618 if ((bus_width == 16)
5619 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5620 warnx("HBA does not support 16 bit bus width");
5622 goto ratecontrol_bailout;
5623 } else if ((bus_width == 32)
5624 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5625 warnx("HBA does not support 32 bit bus width");
5627 goto ratecontrol_bailout;
5628 } else if ((bus_width != 8)
5629 && (bus_width != 16)
5630 && (bus_width != 32)) {
5631 warnx("Invalid bus width %d", bus_width);
5633 goto ratecontrol_bailout;
5635 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5636 spi->bus_width = bus_width >> 4;
5639 if (didsettings == 0) {
5640 goto ratecontrol_bailout;
5642 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5643 if (cam_send_ccb(device, ccb) < 0) {
5644 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5645 if (arglist & CAM_ARG_VERBOSE) {
5646 cam_error_print(device, ccb, CAM_ESF_ALL,
5647 CAM_EPF_ALL, stderr);
5650 goto ratecontrol_bailout;
5652 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5653 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5654 if (arglist & CAM_ARG_VERBOSE) {
5655 cam_error_print(device, ccb, CAM_ESF_ALL,
5656 CAM_EPF_ALL, stderr);
5659 goto ratecontrol_bailout;
5663 retval = testunitready(device, retry_count, timeout,
5664 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5666 * If the TUR didn't succeed, just bail.
5670 fprintf(stderr, "Test Unit Ready failed\n");
5671 goto ratecontrol_bailout;
5674 if ((change_settings || send_tur) && !quiet &&
5675 (ccb->cts.transport == XPORT_ATA ||
5676 ccb->cts.transport == XPORT_SATA || send_tur)) {
5677 fprintf(stdout, "New parameters:\n");
5678 retval = get_print_cts(device, user_settings, 0, NULL);
5681 ratecontrol_bailout:
5687 scsiformat(struct cam_device *device, int argc, char **argv,
5688 char *combinedopt, int retry_count, int timeout)
5692 int ycount = 0, quiet = 0;
5693 int error = 0, retval = 0;
5694 int use_timeout = 10800 * 1000;
5696 struct format_defect_list_header fh;
5697 u_int8_t *data_ptr = NULL;
5698 u_int32_t dxfer_len = 0;
5700 int num_warnings = 0;
5703 ccb = cam_getccb(device);
5706 warnx("scsiformat: error allocating ccb");
5710 bzero(&(&ccb->ccb_h)[1],
5711 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5713 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5734 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5735 "following device:\n");
5737 error = scsidoinquiry(device, argc, argv, combinedopt,
5738 retry_count, timeout);
5741 warnx("scsiformat: error sending inquiry");
5742 goto scsiformat_bailout;
5747 if (!get_confirmation()) {
5749 goto scsiformat_bailout;
5754 use_timeout = timeout;
5757 fprintf(stdout, "Current format timeout is %d seconds\n",
5758 use_timeout / 1000);
5762 * If the user hasn't disabled questions and didn't specify a
5763 * timeout on the command line, ask them if they want the current
5767 && (timeout == 0)) {
5769 int new_timeout = 0;
5771 fprintf(stdout, "Enter new timeout in seconds or press\n"
5772 "return to keep the current timeout [%d] ",
5773 use_timeout / 1000);
5775 if (fgets(str, sizeof(str), stdin) != NULL) {
5777 new_timeout = atoi(str);
5780 if (new_timeout != 0) {
5781 use_timeout = new_timeout * 1000;
5782 fprintf(stdout, "Using new timeout value %d\n",
5783 use_timeout / 1000);
5788 * Keep this outside the if block below to silence any unused
5789 * variable warnings.
5791 bzero(&fh, sizeof(fh));
5794 * If we're in immediate mode, we've got to include the format
5797 if (immediate != 0) {
5798 fh.byte2 = FU_DLH_IMMED;
5799 data_ptr = (u_int8_t *)&fh;
5800 dxfer_len = sizeof(fh);
5801 byte2 = FU_FMT_DATA;
5802 } else if (quiet == 0) {
5803 fprintf(stdout, "Formatting...");
5807 scsi_format_unit(&ccb->csio,
5808 /* retries */ retry_count,
5810 /* tag_action */ MSG_SIMPLE_Q_TAG,
5813 /* data_ptr */ data_ptr,
5814 /* dxfer_len */ dxfer_len,
5815 /* sense_len */ SSD_FULL_SIZE,
5816 /* timeout */ use_timeout);
5818 /* Disable freezing the device queue */
5819 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5821 if (arglist & CAM_ARG_ERR_RECOVER)
5822 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5824 if (((retval = cam_send_ccb(device, ccb)) < 0)
5825 || ((immediate == 0)
5826 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5827 const char errstr[] = "error sending format command";
5834 if (arglist & CAM_ARG_VERBOSE) {
5835 cam_error_print(device, ccb, CAM_ESF_ALL,
5836 CAM_EPF_ALL, stderr);
5839 goto scsiformat_bailout;
5843 * If we ran in non-immediate mode, we already checked for errors
5844 * above and printed out any necessary information. If we're in
5845 * immediate mode, we need to loop through and get status
5846 * information periodically.
5848 if (immediate == 0) {
5850 fprintf(stdout, "Format Complete\n");
5852 goto scsiformat_bailout;
5859 bzero(&(&ccb->ccb_h)[1],
5860 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5863 * There's really no need to do error recovery or
5864 * retries here, since we're just going to sit in a
5865 * loop and wait for the device to finish formatting.
5867 scsi_test_unit_ready(&ccb->csio,
5870 /* tag_action */ MSG_SIMPLE_Q_TAG,
5871 /* sense_len */ SSD_FULL_SIZE,
5872 /* timeout */ 5000);
5874 /* Disable freezing the device queue */
5875 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5877 retval = cam_send_ccb(device, ccb);
5880 * If we get an error from the ioctl, bail out. SCSI
5881 * errors are expected.
5884 warn("error sending CAMIOCOMMAND ioctl");
5885 if (arglist & CAM_ARG_VERBOSE) {
5886 cam_error_print(device, ccb, CAM_ESF_ALL,
5887 CAM_EPF_ALL, stderr);
5890 goto scsiformat_bailout;
5893 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5895 if ((status != CAM_REQ_CMP)
5896 && (status == CAM_SCSI_STATUS_ERROR)
5897 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5898 struct scsi_sense_data *sense;
5899 int error_code, sense_key, asc, ascq;
5901 sense = &ccb->csio.sense_data;
5902 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5903 ccb->csio.sense_resid, &error_code, &sense_key,
5904 &asc, &ascq, /*show_errors*/ 1);
5907 * According to the SCSI-2 and SCSI-3 specs, a
5908 * drive that is in the middle of a format should
5909 * return NOT READY with an ASC of "logical unit
5910 * not ready, format in progress". The sense key
5911 * specific bytes will then be a progress indicator.
5913 if ((sense_key == SSD_KEY_NOT_READY)
5914 && (asc == 0x04) && (ascq == 0x04)) {
5917 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5918 ccb->csio.sense_resid, sks) == 0)
5921 u_int64_t percentage;
5923 val = scsi_2btoul(&sks[1]);
5924 percentage = 10000 * val;
5927 "\rFormatting: %ju.%02u %% "
5929 (uintmax_t)(percentage /
5931 (unsigned)((percentage /
5935 } else if ((quiet == 0)
5936 && (++num_warnings <= 1)) {
5937 warnx("Unexpected SCSI Sense Key "
5938 "Specific value returned "
5940 scsi_sense_print(device, &ccb->csio,
5942 warnx("Unable to print status "
5943 "information, but format will "
5945 warnx("will exit when format is "
5950 warnx("Unexpected SCSI error during format");
5951 cam_error_print(device, ccb, CAM_ESF_ALL,
5952 CAM_EPF_ALL, stderr);
5954 goto scsiformat_bailout;
5957 } else if (status != CAM_REQ_CMP) {
5958 warnx("Unexpected CAM status %#x", status);
5959 if (arglist & CAM_ARG_VERBOSE)
5960 cam_error_print(device, ccb, CAM_ESF_ALL,
5961 CAM_EPF_ALL, stderr);
5963 goto scsiformat_bailout;
5966 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5969 fprintf(stdout, "\nFormat Complete\n");
5979 scsisanitize(struct cam_device *device, int argc, char **argv,
5980 char *combinedopt, int retry_count, int timeout)
5983 u_int8_t action = 0;
5985 int ycount = 0, quiet = 0;
5986 int error = 0, retval = 0;
5987 int use_timeout = 10800 * 1000;
5993 const char *pattern = NULL;
5994 u_int8_t *data_ptr = NULL;
5995 u_int32_t dxfer_len = 0;
5997 int num_warnings = 0;
6000 ccb = cam_getccb(device);
6003 warnx("scsisanitize: error allocating ccb");
6007 bzero(&(&ccb->ccb_h)[1],
6008 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6010 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6013 if (strcasecmp(optarg, "overwrite") == 0)
6014 action = SSZ_SERVICE_ACTION_OVERWRITE;
6015 else if (strcasecmp(optarg, "block") == 0)
6016 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6017 else if (strcasecmp(optarg, "crypto") == 0)
6018 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6019 else if (strcasecmp(optarg, "exitfailure") == 0)
6020 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6022 warnx("invalid service operation \"%s\"",
6025 goto scsisanitize_bailout;
6029 passes = strtol(optarg, NULL, 0);
6030 if (passes < 1 || passes > 31) {
6031 warnx("invalid passes value %d", passes);
6033 goto scsisanitize_bailout;
6064 warnx("an action is required");
6066 goto scsisanitize_bailout;
6067 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6068 struct scsi_sanitize_parameter_list *pl;
6072 if (pattern == NULL) {
6073 warnx("overwrite action requires -P argument");
6075 goto scsisanitize_bailout;
6077 fd = open(pattern, O_RDONLY);
6079 warn("cannot open pattern file %s", pattern);
6081 goto scsisanitize_bailout;
6083 if (fstat(fd, &sb) < 0) {
6084 warn("cannot stat pattern file %s", pattern);
6086 goto scsisanitize_bailout;
6089 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6090 warnx("pattern file size exceeds maximum value %d",
6091 SSZPL_MAX_PATTERN_LENGTH);
6093 goto scsisanitize_bailout;
6095 dxfer_len = sizeof(*pl) + sz;
6096 data_ptr = calloc(1, dxfer_len);
6097 if (data_ptr == NULL) {
6098 warnx("cannot allocate parameter list buffer");
6100 goto scsisanitize_bailout;
6103 amt = read(fd, data_ptr + sizeof(*pl), sz);
6105 warn("cannot read pattern file");
6107 goto scsisanitize_bailout;
6108 } else if (amt != sz) {
6109 warnx("short pattern file read");
6111 goto scsisanitize_bailout;
6114 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6120 pl->byte1 |= SSZPL_INVERT;
6121 scsi_ulto2b(sz, pl->length);
6127 else if (invert != 0)
6129 else if (pattern != NULL)
6134 warnx("%s argument only valid with overwrite "
6137 goto scsisanitize_bailout;
6142 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6143 "following device:\n");
6145 error = scsidoinquiry(device, argc, argv, combinedopt,
6146 retry_count, timeout);
6149 warnx("scsisanitize: error sending inquiry");
6150 goto scsisanitize_bailout;
6155 if (!get_confirmation()) {
6157 goto scsisanitize_bailout;
6162 use_timeout = timeout;
6165 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6166 use_timeout / 1000);
6170 * If the user hasn't disabled questions and didn't specify a
6171 * timeout on the command line, ask them if they want the current
6175 && (timeout == 0)) {
6177 int new_timeout = 0;
6179 fprintf(stdout, "Enter new timeout in seconds or press\n"
6180 "return to keep the current timeout [%d] ",
6181 use_timeout / 1000);
6183 if (fgets(str, sizeof(str), stdin) != NULL) {
6185 new_timeout = atoi(str);
6188 if (new_timeout != 0) {
6189 use_timeout = new_timeout * 1000;
6190 fprintf(stdout, "Using new timeout value %d\n",
6191 use_timeout / 1000);
6197 byte2 |= SSZ_UNRESTRICTED_EXIT;
6201 scsi_sanitize(&ccb->csio,
6202 /* retries */ retry_count,
6204 /* tag_action */ MSG_SIMPLE_Q_TAG,
6207 /* data_ptr */ data_ptr,
6208 /* dxfer_len */ dxfer_len,
6209 /* sense_len */ SSD_FULL_SIZE,
6210 /* timeout */ use_timeout);
6212 /* Disable freezing the device queue */
6213 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6215 if (arglist & CAM_ARG_ERR_RECOVER)
6216 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6218 if (cam_send_ccb(device, ccb) < 0) {
6219 warn("error sending sanitize command");
6221 goto scsisanitize_bailout;
6224 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6225 struct scsi_sense_data *sense;
6226 int error_code, sense_key, asc, ascq;
6228 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6229 CAM_SCSI_STATUS_ERROR) {
6230 sense = &ccb->csio.sense_data;
6231 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6232 ccb->csio.sense_resid, &error_code, &sense_key,
6233 &asc, &ascq, /*show_errors*/ 1);
6235 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6236 asc == 0x20 && ascq == 0x00)
6237 warnx("sanitize is not supported by "
6240 warnx("error sanitizing this device");
6242 warnx("error sanitizing this device");
6244 if (arglist & CAM_ARG_VERBOSE) {
6245 cam_error_print(device, ccb, CAM_ESF_ALL,
6246 CAM_EPF_ALL, stderr);
6249 goto scsisanitize_bailout;
6253 * If we ran in non-immediate mode, we already checked for errors
6254 * above and printed out any necessary information. If we're in
6255 * immediate mode, we need to loop through and get status
6256 * information periodically.
6258 if (immediate == 0) {
6260 fprintf(stdout, "Sanitize Complete\n");
6262 goto scsisanitize_bailout;
6269 bzero(&(&ccb->ccb_h)[1],
6270 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6273 * There's really no need to do error recovery or
6274 * retries here, since we're just going to sit in a
6275 * loop and wait for the device to finish sanitizing.
6277 scsi_test_unit_ready(&ccb->csio,
6280 /* tag_action */ MSG_SIMPLE_Q_TAG,
6281 /* sense_len */ SSD_FULL_SIZE,
6282 /* timeout */ 5000);
6284 /* Disable freezing the device queue */
6285 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6287 retval = cam_send_ccb(device, ccb);
6290 * If we get an error from the ioctl, bail out. SCSI
6291 * errors are expected.
6294 warn("error sending CAMIOCOMMAND ioctl");
6295 if (arglist & CAM_ARG_VERBOSE) {
6296 cam_error_print(device, ccb, CAM_ESF_ALL,
6297 CAM_EPF_ALL, stderr);
6300 goto scsisanitize_bailout;
6303 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6305 if ((status != CAM_REQ_CMP)
6306 && (status == CAM_SCSI_STATUS_ERROR)
6307 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6308 struct scsi_sense_data *sense;
6309 int error_code, sense_key, asc, ascq;
6311 sense = &ccb->csio.sense_data;
6312 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6313 ccb->csio.sense_resid, &error_code, &sense_key,
6314 &asc, &ascq, /*show_errors*/ 1);
6317 * According to the SCSI-3 spec, a drive that is in the
6318 * middle of a sanitize should return NOT READY with an
6319 * ASC of "logical unit not ready, sanitize in
6320 * progress". The sense key specific bytes will then
6321 * be a progress indicator.
6323 if ((sense_key == SSD_KEY_NOT_READY)
6324 && (asc == 0x04) && (ascq == 0x1b)) {
6327 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6328 ccb->csio.sense_resid, sks) == 0)
6331 u_int64_t percentage;
6333 val = scsi_2btoul(&sks[1]);
6334 percentage = 10000 * val;
6337 "\rSanitizing: %ju.%02u %% "
6339 (uintmax_t)(percentage /
6341 (unsigned)((percentage /
6345 } else if ((quiet == 0)
6346 && (++num_warnings <= 1)) {
6347 warnx("Unexpected SCSI Sense Key "
6348 "Specific value returned "
6349 "during sanitize:");
6350 scsi_sense_print(device, &ccb->csio,
6352 warnx("Unable to print status "
6353 "information, but sanitze will "
6355 warnx("will exit when sanitize is "
6360 warnx("Unexpected SCSI error during sanitize");
6361 cam_error_print(device, ccb, CAM_ESF_ALL,
6362 CAM_EPF_ALL, stderr);
6364 goto scsisanitize_bailout;
6367 } else if (status != CAM_REQ_CMP) {
6368 warnx("Unexpected CAM status %#x", status);
6369 if (arglist & CAM_ARG_VERBOSE)
6370 cam_error_print(device, ccb, CAM_ESF_ALL,
6371 CAM_EPF_ALL, stderr);
6373 goto scsisanitize_bailout;
6375 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6378 fprintf(stdout, "\nSanitize Complete\n");
6380 scsisanitize_bailout:
6383 if (data_ptr != NULL)
6391 scsireportluns(struct cam_device *device, int argc, char **argv,
6392 char *combinedopt, int retry_count, int timeout)
6395 int c, countonly, lunsonly;
6396 struct scsi_report_luns_data *lundata;
6398 uint8_t report_type;
6399 uint32_t list_len, i, j;
6404 report_type = RPL_REPORT_DEFAULT;
6405 ccb = cam_getccb(device);
6408 warnx("%s: error allocating ccb", __func__);
6412 bzero(&(&ccb->ccb_h)[1],
6413 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6418 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6427 if (strcasecmp(optarg, "default") == 0)
6428 report_type = RPL_REPORT_DEFAULT;
6429 else if (strcasecmp(optarg, "wellknown") == 0)
6430 report_type = RPL_REPORT_WELLKNOWN;
6431 else if (strcasecmp(optarg, "all") == 0)
6432 report_type = RPL_REPORT_ALL;
6434 warnx("%s: invalid report type \"%s\"",
6445 if ((countonly != 0)
6446 && (lunsonly != 0)) {
6447 warnx("%s: you can only specify one of -c or -l", __func__);
6452 * According to SPC-4, the allocation length must be at least 16
6453 * bytes -- enough for the header and one LUN.
6455 alloc_len = sizeof(*lundata) + 8;
6459 lundata = malloc(alloc_len);
6461 if (lundata == NULL) {
6462 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6467 scsi_report_luns(&ccb->csio,
6468 /*retries*/ retry_count,
6470 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6471 /*select_report*/ report_type,
6472 /*rpl_buf*/ lundata,
6473 /*alloc_len*/ alloc_len,
6474 /*sense_len*/ SSD_FULL_SIZE,
6475 /*timeout*/ timeout ? timeout : 5000);
6477 /* Disable freezing the device queue */
6478 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6480 if (arglist & CAM_ARG_ERR_RECOVER)
6481 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6483 if (cam_send_ccb(device, ccb) < 0) {
6484 warn("error sending REPORT LUNS command");
6486 if (arglist & CAM_ARG_VERBOSE)
6487 cam_error_print(device, ccb, CAM_ESF_ALL,
6488 CAM_EPF_ALL, stderr);
6494 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6495 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6501 list_len = scsi_4btoul(lundata->length);
6504 * If we need to list the LUNs, and our allocation
6505 * length was too short, reallocate and retry.
6507 if ((countonly == 0)
6508 && (list_len > (alloc_len - sizeof(*lundata)))) {
6509 alloc_len = list_len + sizeof(*lundata);
6515 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6516 ((list_len / 8) > 1) ? "s" : "");
6521 for (i = 0; i < (list_len / 8); i++) {
6525 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6527 fprintf(stdout, ",");
6528 switch (lundata->luns[i].lundata[j] &
6529 RPL_LUNDATA_ATYP_MASK) {
6530 case RPL_LUNDATA_ATYP_PERIPH:
6531 if ((lundata->luns[i].lundata[j] &
6532 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6533 fprintf(stdout, "%d:",
6534 lundata->luns[i].lundata[j] &
6535 RPL_LUNDATA_PERIPH_BUS_MASK);
6537 && ((lundata->luns[i].lundata[j+2] &
6538 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6541 fprintf(stdout, "%d",
6542 lundata->luns[i].lundata[j+1]);
6544 case RPL_LUNDATA_ATYP_FLAT: {
6546 tmplun[0] = lundata->luns[i].lundata[j] &
6547 RPL_LUNDATA_FLAT_LUN_MASK;
6548 tmplun[1] = lundata->luns[i].lundata[j+1];
6550 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6554 case RPL_LUNDATA_ATYP_LUN:
6555 fprintf(stdout, "%d:%d:%d",
6556 (lundata->luns[i].lundata[j+1] &
6557 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6558 lundata->luns[i].lundata[j] &
6559 RPL_LUNDATA_LUN_TARG_MASK,
6560 lundata->luns[i].lundata[j+1] &
6561 RPL_LUNDATA_LUN_LUN_MASK);
6563 case RPL_LUNDATA_ATYP_EXTLUN: {
6564 int field_len_code, eam_code;
6566 eam_code = lundata->luns[i].lundata[j] &
6567 RPL_LUNDATA_EXT_EAM_MASK;
6568 field_len_code = (lundata->luns[i].lundata[j] &
6569 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6571 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6572 && (field_len_code == 0x00)) {
6573 fprintf(stdout, "%d",
6574 lundata->luns[i].lundata[j+1]);
6575 } else if ((eam_code ==
6576 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6577 && (field_len_code == 0x03)) {
6581 * This format takes up all 8 bytes.
6582 * If we aren't starting at offset 0,
6586 fprintf(stdout, "Invalid "
6589 "specified format", j);
6593 bzero(tmp_lun, sizeof(tmp_lun));
6594 bcopy(&lundata->luns[i].lundata[j+1],
6595 &tmp_lun[1], sizeof(tmp_lun) - 1);
6596 fprintf(stdout, "%#jx",
6597 (intmax_t)scsi_8btou64(tmp_lun));
6600 fprintf(stderr, "Unknown Extended LUN"
6601 "Address method %#x, length "
6602 "code %#x", eam_code,
6609 fprintf(stderr, "Unknown LUN address method "
6610 "%#x\n", lundata->luns[i].lundata[0] &
6611 RPL_LUNDATA_ATYP_MASK);
6615 * For the flat addressing method, there are no
6616 * other levels after it.
6621 fprintf(stdout, "\n");
6634 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6635 char *combinedopt, int retry_count, int timeout)
6638 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6639 struct scsi_read_capacity_data rcap;
6640 struct scsi_read_capacity_data_long rcaplong;
6654 ccb = cam_getccb(device);
6657 warnx("%s: error allocating ccb", __func__);
6661 bzero(&(&ccb->ccb_h)[1],
6662 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6664 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6691 if ((blocksizeonly != 0)
6692 && (numblocks != 0)) {
6693 warnx("%s: you can only specify one of -b or -N", __func__);
6698 if ((blocksizeonly != 0)
6699 && (sizeonly != 0)) {
6700 warnx("%s: you can only specify one of -b or -s", __func__);
6707 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6713 && (blocksizeonly != 0)) {
6714 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6719 scsi_read_capacity(&ccb->csio,
6720 /*retries*/ retry_count,
6722 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6725 /*timeout*/ timeout ? timeout : 5000);
6727 /* Disable freezing the device queue */
6728 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6730 if (arglist & CAM_ARG_ERR_RECOVER)
6731 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6733 if (cam_send_ccb(device, ccb) < 0) {
6734 warn("error sending READ CAPACITY command");
6736 if (arglist & CAM_ARG_VERBOSE)
6737 cam_error_print(device, ccb, CAM_ESF_ALL,
6738 CAM_EPF_ALL, stderr);
6744 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6745 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6750 maxsector = scsi_4btoul(rcap.addr);
6751 block_len = scsi_4btoul(rcap.length);
6754 * A last block of 2^32-1 means that the true capacity is over 2TB,
6755 * and we need to issue the long READ CAPACITY to get the real
6756 * capacity. Otherwise, we're all set.
6758 if (maxsector != 0xffffffff)
6761 scsi_read_capacity_16(&ccb->csio,
6762 /*retries*/ retry_count,
6764 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6768 /*rcap_buf*/ (uint8_t *)&rcaplong,
6769 /*rcap_buf_len*/ sizeof(rcaplong),
6770 /*sense_len*/ SSD_FULL_SIZE,
6771 /*timeout*/ timeout ? timeout : 5000);
6773 /* Disable freezing the device queue */
6774 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6776 if (arglist & CAM_ARG_ERR_RECOVER)
6777 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6779 if (cam_send_ccb(device, ccb) < 0) {
6780 warn("error sending READ CAPACITY (16) command");
6782 if (arglist & CAM_ARG_VERBOSE)
6783 cam_error_print(device, ccb, CAM_ESF_ALL,
6784 CAM_EPF_ALL, stderr);
6790 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6791 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6796 maxsector = scsi_8btou64(rcaplong.addr);
6797 block_len = scsi_4btoul(rcaplong.length);
6800 if (blocksizeonly == 0) {
6802 * Humanize implies !quiet, and also implies numblocks.
6804 if (humanize != 0) {
6809 tmpbytes = (maxsector + 1) * block_len;
6810 ret = humanize_number(tmpstr, sizeof(tmpstr),
6811 tmpbytes, "", HN_AUTOSCALE,
6814 HN_DIVISOR_1000 : 0));
6816 warnx("%s: humanize_number failed!", __func__);
6820 fprintf(stdout, "Device Size: %s%s", tmpstr,
6821 (sizeonly == 0) ? ", " : "\n");
6822 } else if (numblocks != 0) {
6823 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6824 "Blocks: " : "", (uintmax_t)maxsector + 1,
6825 (sizeonly == 0) ? ", " : "\n");
6827 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6828 "Last Block: " : "", (uintmax_t)maxsector,
6829 (sizeonly == 0) ? ", " : "\n");
6833 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6834 "Block Length: " : "", block_len, (quiet == 0) ?
6843 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6844 int retry_count, int timeout)
6848 uint8_t *smp_request = NULL, *smp_response = NULL;
6849 int request_size = 0, response_size = 0;
6850 int fd_request = 0, fd_response = 0;
6851 char *datastr = NULL;
6852 struct get_hook hook;
6857 * Note that at the moment we don't support sending SMP CCBs to
6858 * devices that aren't probed by CAM.
6860 ccb = cam_getccb(device);
6862 warnx("%s: error allocating CCB", __func__);
6866 bzero(&(&ccb->ccb_h)[1],
6867 sizeof(union ccb) - sizeof(struct ccb_hdr));
6869 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6872 arglist |= CAM_ARG_CMD_IN;
6873 response_size = strtol(optarg, NULL, 0);
6874 if (response_size <= 0) {
6875 warnx("invalid number of response bytes %d",
6878 goto smpcmd_bailout;
6880 hook.argc = argc - optind;
6881 hook.argv = argv + optind;
6884 datastr = cget(&hook, NULL);
6886 * If the user supplied "-" instead of a format, he
6887 * wants the data to be written to stdout.
6889 if ((datastr != NULL)
6890 && (datastr[0] == '-'))
6893 smp_response = (u_int8_t *)malloc(response_size);
6894 if (smp_response == NULL) {
6895 warn("can't malloc memory for SMP response");
6897 goto smpcmd_bailout;
6901 arglist |= CAM_ARG_CMD_OUT;
6902 request_size = strtol(optarg, NULL, 0);
6903 if (request_size <= 0) {
6904 warnx("invalid number of request bytes %d",
6907 goto smpcmd_bailout;
6909 hook.argc = argc - optind;
6910 hook.argv = argv + optind;
6912 datastr = cget(&hook, NULL);
6913 smp_request = (u_int8_t *)malloc(request_size);
6914 if (smp_request == NULL) {
6915 warn("can't malloc memory for SMP request");
6917 goto smpcmd_bailout;
6919 bzero(smp_request, request_size);
6921 * If the user supplied "-" instead of a format, he
6922 * wants the data to be read from stdin.
6924 if ((datastr != NULL)
6925 && (datastr[0] == '-'))
6928 buff_encode_visit(smp_request, request_size,
6939 * If fd_data is set, and we're writing to the device, we need to
6940 * read the data the user wants written from stdin.
6942 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6944 int amt_to_read = request_size;
6945 u_int8_t *buf_ptr = smp_request;
6947 for (amt_read = 0; amt_to_read > 0;
6948 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6949 if (amt_read == -1) {
6950 warn("error reading data from stdin");
6952 goto smpcmd_bailout;
6954 amt_to_read -= amt_read;
6955 buf_ptr += amt_read;
6959 if (((arglist & CAM_ARG_CMD_IN) == 0)
6960 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6961 warnx("%s: need both the request (-r) and response (-R) "
6962 "arguments", __func__);
6964 goto smpcmd_bailout;
6967 flags |= CAM_DEV_QFRZDIS;
6969 cam_fill_smpio(&ccb->smpio,
6970 /*retries*/ retry_count,
6973 /*smp_request*/ smp_request,
6974 /*smp_request_len*/ request_size,
6975 /*smp_response*/ smp_response,
6976 /*smp_response_len*/ response_size,
6977 /*timeout*/ timeout ? timeout : 5000);
6979 ccb->smpio.flags = SMP_FLAG_NONE;
6981 if (((retval = cam_send_ccb(device, ccb)) < 0)
6982 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6983 const char warnstr[] = "error sending command";
6990 if (arglist & CAM_ARG_VERBOSE) {
6991 cam_error_print(device, ccb, CAM_ESF_ALL,
6992 CAM_EPF_ALL, stderr);
6996 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6997 && (response_size > 0)) {
6998 if (fd_response == 0) {
6999 buff_decode_visit(smp_response, response_size,
7000 datastr, arg_put, NULL);
7001 fprintf(stdout, "\n");
7003 ssize_t amt_written;
7004 int amt_to_write = response_size;
7005 u_int8_t *buf_ptr = smp_response;
7007 for (amt_written = 0; (amt_to_write > 0) &&
7008 (amt_written = write(STDOUT_FILENO, buf_ptr,
7009 amt_to_write)) > 0;){
7010 amt_to_write -= amt_written;
7011 buf_ptr += amt_written;
7013 if (amt_written == -1) {
7014 warn("error writing data to stdout");
7016 goto smpcmd_bailout;
7017 } else if ((amt_written == 0)
7018 && (amt_to_write > 0)) {
7019 warnx("only wrote %u bytes out of %u",
7020 response_size - amt_to_write,
7029 if (smp_request != NULL)
7032 if (smp_response != NULL)
7039 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7040 char *combinedopt, int retry_count, int timeout)
7043 struct smp_report_general_request *request = NULL;
7044 struct smp_report_general_response *response = NULL;
7045 struct sbuf *sb = NULL;
7047 int c, long_response = 0;
7051 * Note that at the moment we don't support sending SMP CCBs to
7052 * devices that aren't probed by CAM.
7054 ccb = cam_getccb(device);
7056 warnx("%s: error allocating CCB", __func__);
7060 bzero(&(&ccb->ccb_h)[1],
7061 sizeof(union ccb) - sizeof(struct ccb_hdr));
7063 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7072 request = malloc(sizeof(*request));
7073 if (request == NULL) {
7074 warn("%s: unable to allocate %zd bytes", __func__,
7080 response = malloc(sizeof(*response));
7081 if (response == NULL) {
7082 warn("%s: unable to allocate %zd bytes", __func__,
7089 smp_report_general(&ccb->smpio,
7093 /*request_len*/ sizeof(*request),
7094 (uint8_t *)response,
7095 /*response_len*/ sizeof(*response),
7096 /*long_response*/ long_response,
7099 if (((retval = cam_send_ccb(device, ccb)) < 0)
7100 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7101 const char warnstr[] = "error sending command";
7108 if (arglist & CAM_ARG_VERBOSE) {
7109 cam_error_print(device, ccb, CAM_ESF_ALL,
7110 CAM_EPF_ALL, stderr);
7117 * If the device supports the long response bit, try again and see
7118 * if we can get all of the data.
7120 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7121 && (long_response == 0)) {
7122 ccb->ccb_h.status = CAM_REQ_INPROG;
7123 bzero(&(&ccb->ccb_h)[1],
7124 sizeof(union ccb) - sizeof(struct ccb_hdr));
7130 * XXX KDM detect and decode SMP errors here.
7132 sb = sbuf_new_auto();
7134 warnx("%s: error allocating sbuf", __func__);
7138 smp_report_general_sbuf(response, sizeof(*response), sb);
7140 if (sbuf_finish(sb) != 0) {
7141 warnx("%s: sbuf_finish", __func__);
7145 printf("%s", sbuf_data(sb));
7151 if (request != NULL)
7154 if (response != NULL)
7163 static struct camcontrol_opts phy_ops[] = {
7164 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7165 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7166 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7167 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7168 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7169 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7170 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7171 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7172 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7177 smpphycontrol(struct cam_device *device, int argc, char **argv,
7178 char *combinedopt, int retry_count, int timeout)
7181 struct smp_phy_control_request *request = NULL;
7182 struct smp_phy_control_response *response = NULL;
7183 int long_response = 0;
7186 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7188 uint64_t attached_dev_name = 0;
7189 int dev_name_set = 0;
7190 uint32_t min_plr = 0, max_plr = 0;
7191 uint32_t pp_timeout_val = 0;
7192 int slumber_partial = 0;
7193 int set_pp_timeout_val = 0;
7197 * Note that at the moment we don't support sending SMP CCBs to
7198 * devices that aren't probed by CAM.
7200 ccb = cam_getccb(device);
7202 warnx("%s: error allocating CCB", __func__);
7206 bzero(&(&ccb->ccb_h)[1],
7207 sizeof(union ccb) - sizeof(struct ccb_hdr));
7209 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7217 if (strcasecmp(optarg, "enable") == 0)
7219 else if (strcasecmp(optarg, "disable") == 0)
7222 warnx("%s: Invalid argument %s", __func__,
7229 slumber_partial |= enable <<
7230 SMP_PC_SAS_SLUMBER_SHIFT;
7233 slumber_partial |= enable <<
7234 SMP_PC_SAS_PARTIAL_SHIFT;
7237 slumber_partial |= enable <<
7238 SMP_PC_SATA_SLUMBER_SHIFT;
7241 slumber_partial |= enable <<
7242 SMP_PC_SATA_PARTIAL_SHIFT;
7245 warnx("%s: programmer error", __func__);
7248 break; /*NOTREACHED*/
7253 attached_dev_name = (uintmax_t)strtoumax(optarg,
7262 * We don't do extensive checking here, so this
7263 * will continue to work when new speeds come out.
7265 min_plr = strtoul(optarg, NULL, 0);
7267 || (min_plr > 0xf)) {
7268 warnx("%s: invalid link rate %x",
7276 * We don't do extensive checking here, so this
7277 * will continue to work when new speeds come out.
7279 max_plr = strtoul(optarg, NULL, 0);
7281 || (max_plr > 0xf)) {
7282 warnx("%s: invalid link rate %x",
7289 camcontrol_optret optreturn;
7290 cam_argmask argnums;
7293 if (phy_op_set != 0) {
7294 warnx("%s: only one phy operation argument "
7295 "(-o) allowed", __func__);
7303 * Allow the user to specify the phy operation
7304 * numerically, as well as with a name. This will
7305 * future-proof it a bit, so options that are added
7306 * in future specs can be used.
7308 if (isdigit(optarg[0])) {
7309 phy_operation = strtoul(optarg, NULL, 0);
7310 if ((phy_operation == 0)
7311 || (phy_operation > 0xff)) {
7312 warnx("%s: invalid phy operation %#x",
7313 __func__, phy_operation);
7319 optreturn = getoption(phy_ops, optarg, &phy_operation,
7322 if (optreturn == CC_OR_AMBIGUOUS) {
7323 warnx("%s: ambiguous option %s", __func__,
7328 } else if (optreturn == CC_OR_NOT_FOUND) {
7329 warnx("%s: option %s not found", __func__,
7341 pp_timeout_val = strtoul(optarg, NULL, 0);
7342 if (pp_timeout_val > 15) {
7343 warnx("%s: invalid partial pathway timeout "
7344 "value %u, need a value less than 16",
7345 __func__, pp_timeout_val);
7349 set_pp_timeout_val = 1;
7357 warnx("%s: a PHY (-p phy) argument is required",__func__);
7362 if (((dev_name_set != 0)
7363 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7364 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7365 && (dev_name_set == 0))) {
7366 warnx("%s: -d name and -o setdevname arguments both "
7367 "required to set device name", __func__);
7372 request = malloc(sizeof(*request));
7373 if (request == NULL) {
7374 warn("%s: unable to allocate %zd bytes", __func__,
7380 response = malloc(sizeof(*response));
7381 if (response == NULL) {
7382 warn("%s: unable to allocate %zd bytes", __func__,
7388 smp_phy_control(&ccb->smpio,
7393 (uint8_t *)response,
7396 /*expected_exp_change_count*/ 0,
7399 (set_pp_timeout_val != 0) ? 1 : 0,
7407 if (((retval = cam_send_ccb(device, ccb)) < 0)
7408 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7409 const char warnstr[] = "error sending command";
7416 if (arglist & CAM_ARG_VERBOSE) {
7418 * Use CAM_EPF_NORMAL so we only get one line of
7419 * SMP command decoding.
7421 cam_error_print(device, ccb, CAM_ESF_ALL,
7422 CAM_EPF_NORMAL, stderr);
7428 /* XXX KDM print out something here for success? */
7433 if (request != NULL)
7436 if (response != NULL)
7443 smpmaninfo(struct cam_device *device, int argc, char **argv,
7444 char *combinedopt, int retry_count, int timeout)
7447 struct smp_report_manuf_info_request request;
7448 struct smp_report_manuf_info_response response;
7449 struct sbuf *sb = NULL;
7450 int long_response = 0;
7455 * Note that at the moment we don't support sending SMP CCBs to
7456 * devices that aren't probed by CAM.
7458 ccb = cam_getccb(device);
7460 warnx("%s: error allocating CCB", __func__);
7464 bzero(&(&ccb->ccb_h)[1],
7465 sizeof(union ccb) - sizeof(struct ccb_hdr));
7467 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7476 bzero(&request, sizeof(request));
7477 bzero(&response, sizeof(response));
7479 smp_report_manuf_info(&ccb->smpio,
7484 (uint8_t *)&response,
7489 if (((retval = cam_send_ccb(device, ccb)) < 0)
7490 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7491 const char warnstr[] = "error sending command";
7498 if (arglist & CAM_ARG_VERBOSE) {
7499 cam_error_print(device, ccb, CAM_ESF_ALL,
7500 CAM_EPF_ALL, stderr);
7506 sb = sbuf_new_auto();
7508 warnx("%s: error allocating sbuf", __func__);
7512 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7514 if (sbuf_finish(sb) != 0) {
7515 warnx("%s: sbuf_finish", __func__);
7519 printf("%s", sbuf_data(sb));
7533 getdevid(struct cam_devitem *item)
7536 union ccb *ccb = NULL;
7538 struct cam_device *dev;
7540 dev = cam_open_btl(item->dev_match.path_id,
7541 item->dev_match.target_id,
7542 item->dev_match.target_lun, O_RDWR, NULL);
7545 warnx("%s", cam_errbuf);
7550 item->device_id_len = 0;
7552 ccb = cam_getccb(dev);
7554 warnx("%s: error allocating CCB", __func__);
7559 bzero(&(&ccb->ccb_h)[1],
7560 sizeof(union ccb) - sizeof(struct ccb_hdr));
7563 * On the first try, we just probe for the size of the data, and
7564 * then allocate that much memory and try again.
7567 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7568 ccb->ccb_h.flags = CAM_DIR_IN;
7569 ccb->cdai.flags = CDAI_FLAG_NONE;
7570 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7571 ccb->cdai.bufsiz = item->device_id_len;
7572 if (item->device_id_len != 0)
7573 ccb->cdai.buf = (uint8_t *)item->device_id;
7575 if (cam_send_ccb(dev, ccb) < 0) {
7576 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7581 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7582 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7587 if (item->device_id_len == 0) {
7589 * This is our first time through. Allocate the buffer,
7590 * and then go back to get the data.
7592 if (ccb->cdai.provsiz == 0) {
7593 warnx("%s: invalid .provsiz field returned with "
7594 "XPT_GDEV_ADVINFO CCB", __func__);
7598 item->device_id_len = ccb->cdai.provsiz;
7599 item->device_id = malloc(item->device_id_len);
7600 if (item->device_id == NULL) {
7601 warn("%s: unable to allocate %d bytes", __func__,
7602 item->device_id_len);
7606 ccb->ccb_h.status = CAM_REQ_INPROG;
7612 cam_close_device(dev);
7621 * XXX KDM merge this code with getdevtree()?
7624 buildbusdevlist(struct cam_devlist *devlist)
7627 int bufsize, fd = -1;
7628 struct dev_match_pattern *patterns;
7629 struct cam_devitem *item = NULL;
7630 int skip_device = 0;
7633 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7634 warn("couldn't open %s", XPT_DEVICE);
7638 bzero(&ccb, sizeof(union ccb));
7640 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7641 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7642 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7644 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7645 bufsize = sizeof(struct dev_match_result) * 100;
7646 ccb.cdm.match_buf_len = bufsize;
7647 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7648 if (ccb.cdm.matches == NULL) {
7649 warnx("can't malloc memory for matches");
7653 ccb.cdm.num_matches = 0;
7654 ccb.cdm.num_patterns = 2;
7655 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7656 ccb.cdm.num_patterns;
7658 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7659 if (patterns == NULL) {
7660 warnx("can't malloc memory for patterns");
7665 ccb.cdm.patterns = patterns;
7666 bzero(patterns, ccb.cdm.pattern_buf_len);
7668 patterns[0].type = DEV_MATCH_DEVICE;
7669 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7670 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7671 patterns[1].type = DEV_MATCH_PERIPH;
7672 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7673 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7676 * We do the ioctl multiple times if necessary, in case there are
7677 * more than 100 nodes in the EDT.
7682 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7683 warn("error sending CAMIOCOMMAND ioctl");
7688 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7689 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7690 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7691 warnx("got CAM error %#x, CDM error %d\n",
7692 ccb.ccb_h.status, ccb.cdm.status);
7697 for (i = 0; i < ccb.cdm.num_matches; i++) {
7698 switch (ccb.cdm.matches[i].type) {
7699 case DEV_MATCH_DEVICE: {
7700 struct device_match_result *dev_result;
7703 &ccb.cdm.matches[i].result.device_result;
7705 if (dev_result->flags &
7706 DEV_RESULT_UNCONFIGURED) {
7712 item = malloc(sizeof(*item));
7714 warn("%s: unable to allocate %zd bytes",
7715 __func__, sizeof(*item));
7719 bzero(item, sizeof(*item));
7720 bcopy(dev_result, &item->dev_match,
7721 sizeof(*dev_result));
7722 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7725 if (getdevid(item) != 0) {
7731 case DEV_MATCH_PERIPH: {
7732 struct periph_match_result *periph_result;
7735 &ccb.cdm.matches[i].result.periph_result;
7737 if (skip_device != 0)
7739 item->num_periphs++;
7740 item->periph_matches = realloc(
7741 item->periph_matches,
7743 sizeof(struct periph_match_result));
7744 if (item->periph_matches == NULL) {
7745 warn("%s: error allocating periph "
7750 bcopy(periph_result, &item->periph_matches[
7751 item->num_periphs - 1],
7752 sizeof(*periph_result));
7756 fprintf(stderr, "%s: unexpected match "
7757 "type %d\n", __func__,
7758 ccb.cdm.matches[i].type);
7761 break; /*NOTREACHED*/
7764 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7765 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7773 free(ccb.cdm.matches);
7776 freebusdevlist(devlist);
7782 freebusdevlist(struct cam_devlist *devlist)
7784 struct cam_devitem *item, *item2;
7786 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7787 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7789 free(item->device_id);
7790 free(item->periph_matches);
7795 static struct cam_devitem *
7796 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7798 struct cam_devitem *item;
7800 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7801 struct scsi_vpd_id_descriptor *idd;
7804 * XXX KDM look for LUN IDs as well?
7806 idd = scsi_get_devid(item->device_id,
7807 item->device_id_len,
7808 scsi_devid_is_sas_target);
7812 if (scsi_8btou64(idd->identifier) == sasaddr)
7820 smpphylist(struct cam_device *device, int argc, char **argv,
7821 char *combinedopt, int retry_count, int timeout)
7823 struct smp_report_general_request *rgrequest = NULL;
7824 struct smp_report_general_response *rgresponse = NULL;
7825 struct smp_discover_request *disrequest = NULL;
7826 struct smp_discover_response *disresponse = NULL;
7827 struct cam_devlist devlist;
7829 int long_response = 0;
7836 * Note that at the moment we don't support sending SMP CCBs to
7837 * devices that aren't probed by CAM.
7839 ccb = cam_getccb(device);
7841 warnx("%s: error allocating CCB", __func__);
7845 bzero(&(&ccb->ccb_h)[1],
7846 sizeof(union ccb) - sizeof(struct ccb_hdr));
7847 STAILQ_INIT(&devlist.dev_queue);
7849 rgrequest = malloc(sizeof(*rgrequest));
7850 if (rgrequest == NULL) {
7851 warn("%s: unable to allocate %zd bytes", __func__,
7852 sizeof(*rgrequest));
7857 rgresponse = malloc(sizeof(*rgresponse));
7858 if (rgresponse == NULL) {
7859 warn("%s: unable to allocate %zd bytes", __func__,
7860 sizeof(*rgresponse));
7865 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7878 smp_report_general(&ccb->smpio,
7882 /*request_len*/ sizeof(*rgrequest),
7883 (uint8_t *)rgresponse,
7884 /*response_len*/ sizeof(*rgresponse),
7885 /*long_response*/ long_response,
7888 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7890 if (((retval = cam_send_ccb(device, ccb)) < 0)
7891 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7892 const char warnstr[] = "error sending command";
7899 if (arglist & CAM_ARG_VERBOSE) {
7900 cam_error_print(device, ccb, CAM_ESF_ALL,
7901 CAM_EPF_ALL, stderr);
7907 num_phys = rgresponse->num_phys;
7909 if (num_phys == 0) {
7911 fprintf(stdout, "%s: No Phys reported\n", __func__);
7916 devlist.path_id = device->path_id;
7918 retval = buildbusdevlist(&devlist);
7923 fprintf(stdout, "%d PHYs:\n", num_phys);
7924 fprintf(stdout, "PHY Attached SAS Address\n");
7927 disrequest = malloc(sizeof(*disrequest));
7928 if (disrequest == NULL) {
7929 warn("%s: unable to allocate %zd bytes", __func__,
7930 sizeof(*disrequest));
7935 disresponse = malloc(sizeof(*disresponse));
7936 if (disresponse == NULL) {
7937 warn("%s: unable to allocate %zd bytes", __func__,
7938 sizeof(*disresponse));
7943 for (i = 0; i < num_phys; i++) {
7944 struct cam_devitem *item;
7945 struct device_match_result *dev_match;
7946 char vendor[16], product[48], revision[16];
7950 bzero(&(&ccb->ccb_h)[1],
7951 sizeof(union ccb) - sizeof(struct ccb_hdr));
7953 ccb->ccb_h.status = CAM_REQ_INPROG;
7954 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7956 smp_discover(&ccb->smpio,
7960 sizeof(*disrequest),
7961 (uint8_t *)disresponse,
7962 sizeof(*disresponse),
7964 /*ignore_zone_group*/ 0,
7968 if (((retval = cam_send_ccb(device, ccb)) < 0)
7969 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7970 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7971 const char warnstr[] = "error sending command";
7978 if (arglist & CAM_ARG_VERBOSE) {
7979 cam_error_print(device, ccb, CAM_ESF_ALL,
7980 CAM_EPF_ALL, stderr);
7986 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7988 fprintf(stdout, "%3d <vacant>\n", i);
7992 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7995 item = findsasdevice(&devlist,
7996 scsi_8btou64(disresponse->attached_sas_address));
8000 || (item != NULL)) {
8001 fprintf(stdout, "%3d 0x%016jx", i,
8002 (uintmax_t)scsi_8btou64(
8003 disresponse->attached_sas_address));
8005 fprintf(stdout, "\n");
8008 } else if (quiet != 0)
8011 dev_match = &item->dev_match;
8013 if (dev_match->protocol == PROTO_SCSI) {
8014 cam_strvis(vendor, dev_match->inq_data.vendor,
8015 sizeof(dev_match->inq_data.vendor),
8017 cam_strvis(product, dev_match->inq_data.product,
8018 sizeof(dev_match->inq_data.product),
8020 cam_strvis(revision, dev_match->inq_data.revision,
8021 sizeof(dev_match->inq_data.revision),
8023 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8025 } else if ((dev_match->protocol == PROTO_ATA)
8026 || (dev_match->protocol == PROTO_SATAPM)) {
8027 cam_strvis(product, dev_match->ident_data.model,
8028 sizeof(dev_match->ident_data.model),
8030 cam_strvis(revision, dev_match->ident_data.revision,
8031 sizeof(dev_match->ident_data.revision),
8033 sprintf(tmpstr, "<%s %s>", product, revision);
8035 sprintf(tmpstr, "<>");
8037 fprintf(stdout, " %-33s ", tmpstr);
8040 * If we have 0 periphs, that's a bug...
8042 if (item->num_periphs == 0) {
8043 fprintf(stdout, "\n");
8047 fprintf(stdout, "(");
8048 for (j = 0; j < item->num_periphs; j++) {
8050 fprintf(stdout, ",");
8052 fprintf(stdout, "%s%d",
8053 item->periph_matches[j].periph_name,
8054 item->periph_matches[j].unit_number);
8057 fprintf(stdout, ")\n");
8071 freebusdevlist(&devlist);
8077 atapm(struct cam_device *device, int argc, char **argv,
8078 char *combinedopt, int retry_count, int timeout)
8086 ccb = cam_getccb(device);
8089 warnx("%s: error allocating ccb", __func__);
8093 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8102 if (strcmp(argv[1], "idle") == 0) {
8104 cmd = ATA_IDLE_IMMEDIATE;
8107 } else if (strcmp(argv[1], "standby") == 0) {
8109 cmd = ATA_STANDBY_IMMEDIATE;
8111 cmd = ATA_STANDBY_CMD;
8119 else if (t <= (240 * 5))
8121 else if (t <= (252 * 5))
8122 /* special encoding for 21 minutes */
8124 else if (t <= (11 * 30 * 60))
8125 sc = (t - 1) / (30 * 60) + 241;
8129 retval = ata_do_28bit_cmd(device,
8131 /*retries*/retry_count,
8132 /*flags*/CAM_DIR_NONE,
8133 /*protocol*/AP_PROTO_NON_DATA,
8134 /*tag_action*/MSG_SIMPLE_Q_TAG,
8141 /*timeout*/timeout ? timeout : 30 * 1000,
8149 ataaxm(struct cam_device *device, int argc, char **argv,
8150 char *combinedopt, int retry_count, int timeout)
8158 ccb = cam_getccb(device);
8161 warnx("%s: error allocating ccb", __func__);
8165 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8175 if (strcmp(argv[1], "apm") == 0) {
8191 retval = ata_do_28bit_cmd(device,
8193 /*retries*/retry_count,
8194 /*flags*/CAM_DIR_NONE,
8195 /*protocol*/AP_PROTO_NON_DATA,
8196 /*tag_action*/MSG_SIMPLE_Q_TAG,
8197 /*command*/ATA_SETFEATURES,
8203 /*timeout*/timeout ? timeout : 30 * 1000,
8211 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8212 int show_sa_errors, int sa_set, int service_action,
8213 int timeout_desc, int retry_count, int timeout, int verbosemode,
8214 uint32_t *fill_len, uint8_t **data_ptr)
8216 union ccb *ccb = NULL;
8217 uint8_t *buf = NULL;
8218 uint32_t alloc_len = 0, num_opcodes;
8219 uint32_t valid_len = 0;
8220 uint32_t avail_len = 0;
8221 struct scsi_report_supported_opcodes_all *all_hdr;
8222 struct scsi_report_supported_opcodes_one *one;
8227 * Make it clear that we haven't yet allocated or filled anything.
8232 ccb = cam_getccb(device);
8234 warnx("couldn't allocate CCB");
8239 /* cam_getccb cleans up the header, caller has to zero the payload */
8240 bzero(&(&ccb->ccb_h)[1],
8241 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
8243 if (opcode_set != 0) {
8244 options |= RSO_OPTIONS_OC;
8246 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8249 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8250 sizeof(struct scsi_report_supported_opcodes_descr));
8253 if (timeout_desc != 0) {
8254 options |= RSO_RCTD;
8255 alloc_len += num_opcodes *
8256 sizeof(struct scsi_report_supported_opcodes_timeout);
8260 options |= RSO_OPTIONS_OC_SA;
8261 if (show_sa_errors != 0)
8262 options &= ~RSO_OPTIONS_OC;
8271 buf = malloc(alloc_len);
8273 warn("Unable to allocate %u bytes", alloc_len);
8277 bzero(buf, alloc_len);
8279 scsi_report_supported_opcodes(&ccb->csio,
8280 /*retries*/ retry_count,
8282 /*tag_action*/ MSG_SIMPLE_Q_TAG,
8283 /*options*/ options,
8284 /*req_opcode*/ opcode,
8285 /*req_service_action*/ service_action,
8287 /*dxfer_len*/ alloc_len,
8288 /*sense_len*/ SSD_FULL_SIZE,
8289 /*timeout*/ timeout ? timeout : 10000);
8291 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8293 if (retry_count != 0)
8294 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8296 if (cam_send_ccb(device, ccb) < 0) {
8297 perror("error sending REPORT SUPPORTED OPERATION CODES");
8302 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8303 if (verbosemode != 0)
8304 cam_error_print(device, ccb, CAM_ESF_ALL,
8305 CAM_EPF_ALL, stderr);
8311 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8313 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8314 && (valid_len >= sizeof(*all_hdr))) {
8315 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8316 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8317 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8318 && (valid_len >= sizeof(*one))) {
8319 uint32_t cdb_length;
8321 one = (struct scsi_report_supported_opcodes_one *)buf;
8322 cdb_length = scsi_2btoul(one->cdb_length);
8323 avail_len = sizeof(*one) + cdb_length;
8324 if (one->support & RSO_ONE_CTDP) {
8325 struct scsi_report_supported_opcodes_timeout *td;
8327 td = (struct scsi_report_supported_opcodes_timeout *)
8329 if (valid_len >= (avail_len + sizeof(td->length))) {
8330 avail_len += scsi_2btoul(td->length) +
8333 avail_len += sizeof(*td);
8339 * avail_len could be zero if we didn't get enough data back from
8340 * thet target to determine
8342 if ((avail_len != 0)
8343 && (avail_len > valid_len)) {
8344 alloc_len = avail_len;
8348 *fill_len = valid_len;
8360 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8361 int req_sa, uint8_t *buf, uint32_t valid_len)
8363 struct scsi_report_supported_opcodes_one *one;
8364 struct scsi_report_supported_opcodes_timeout *td;
8365 uint32_t cdb_len = 0, td_len = 0;
8366 const char *op_desc = NULL;
8370 one = (struct scsi_report_supported_opcodes_one *)buf;
8373 * If we don't have the full single opcode descriptor, no point in
8376 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8378 warnx("Only %u bytes returned, not enough to verify support",
8384 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8386 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8389 printf(", SA 0x%x", req_sa);
8392 switch (one->support & RSO_ONE_SUP_MASK) {
8393 case RSO_ONE_SUP_UNAVAIL:
8394 printf("No command support information currently available\n");
8396 case RSO_ONE_SUP_NOT_SUP:
8397 printf("Command not supported\n");
8400 break; /*NOTREACHED*/
8401 case RSO_ONE_SUP_AVAIL:
8402 printf("Command is supported, complies with a SCSI standard\n");
8404 case RSO_ONE_SUP_VENDOR:
8405 printf("Command is supported, vendor-specific "
8406 "implementation\n");
8409 printf("Unknown command support flags 0x%#x\n",
8410 one->support & RSO_ONE_SUP_MASK);
8415 * If we don't have the CDB length, it isn't exactly an error, the
8416 * command probably isn't supported.
8418 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8422 cdb_len = scsi_2btoul(one->cdb_length);
8425 * If our valid data doesn't include the full reported length,
8426 * return. The caller should have detected this and adjusted his
8427 * allocation length to get all of the available data.
8429 if (valid_len < sizeof(*one) + cdb_len) {
8435 * If all we have is the opcode, there is no point in printing out
8443 printf("CDB usage bitmap:");
8444 for (i = 0; i < cdb_len; i++) {
8445 printf(" %02x", one->cdb_usage[i]);
8450 * If we don't have a timeout descriptor, we're done.
8452 if ((one->support & RSO_ONE_CTDP) == 0)
8456 * If we don't have enough valid length to include the timeout
8457 * descriptor length, we're done.
8459 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8462 td = (struct scsi_report_supported_opcodes_timeout *)
8463 &buf[sizeof(*one) + cdb_len];
8464 td_len = scsi_2btoul(td->length);
8465 td_len += sizeof(td->length);
8468 * If we don't have the full timeout descriptor, we're done.
8470 if (td_len < sizeof(*td))
8474 * If we don't have enough valid length to contain the full timeout
8475 * descriptor, we're done.
8477 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8480 printf("Timeout information:\n");
8481 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8482 printf("Nominal timeout: %u seconds\n",
8483 scsi_4btoul(td->nominal_time));
8484 printf("Recommended timeout: %u seconds\n",
8485 scsi_4btoul(td->recommended_time));
8492 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8495 struct scsi_report_supported_opcodes_all *hdr;
8496 struct scsi_report_supported_opcodes_descr *desc;
8497 uint32_t avail_len = 0, used_len = 0;
8501 if (valid_len < sizeof(*hdr)) {
8502 warnx("%s: not enough returned data (%u bytes) opcode list",
8503 __func__, valid_len);
8507 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8508 avail_len = scsi_4btoul(hdr->length);
8509 avail_len += sizeof(hdr->length);
8511 * Take the lesser of the amount of data the drive claims is
8512 * available, and the amount of data the HBA says was returned.
8514 avail_len = MIN(avail_len, valid_len);
8516 used_len = sizeof(hdr->length);
8518 printf("%-6s %4s %8s ",
8519 "Opcode", "SA", "CDB len" );
8522 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8523 printf(" Description\n");
8525 while ((avail_len - used_len) > sizeof(*desc)) {
8526 struct scsi_report_supported_opcodes_timeout *td;
8528 const char *op_desc = NULL;
8530 cur_ptr = &buf[used_len];
8531 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8533 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8534 if (op_desc == NULL)
8535 op_desc = "UNKNOWN";
8537 printf("0x%02x %#4x %8u ", desc->opcode,
8538 scsi_2btoul(desc->service_action),
8539 scsi_2btoul(desc->cdb_length));
8541 used_len += sizeof(*desc);
8543 if ((desc->flags & RSO_CTDP) == 0) {
8544 printf(" %s\n", op_desc);
8549 * If we don't have enough space to fit a timeout
8550 * descriptor, then we're done.
8552 if (avail_len - used_len < sizeof(*td)) {
8553 used_len = avail_len;
8554 printf(" %s\n", op_desc);
8557 cur_ptr = &buf[used_len];
8558 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8559 td_len = scsi_2btoul(td->length);
8560 td_len += sizeof(td->length);
8564 * If the given timeout descriptor length is less than what
8565 * we understand, skip it.
8567 if (td_len < sizeof(*td)) {
8568 printf(" %s\n", op_desc);
8572 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8573 scsi_4btoul(td->nominal_time),
8574 scsi_4btoul(td->recommended_time), op_desc);
8581 scsiopcodes(struct cam_device *device, int argc, char **argv,
8582 char *combinedopt, int retry_count, int timeout, int verbosemode)
8585 uint32_t opcode = 0, service_action = 0;
8586 int td_set = 0, opcode_set = 0, sa_set = 0;
8587 int show_sa_errors = 1;
8588 uint32_t valid_len = 0;
8589 uint8_t *buf = NULL;
8593 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8599 opcode = strtoul(optarg, &endptr, 0);
8600 if (*endptr != '\0') {
8601 warnx("Invalid opcode \"%s\", must be a number",
8606 if (opcode > 0xff) {
8607 warnx("Invalid opcode 0x%#x, must be between"
8608 "0 and 0xff inclusive", opcode);
8615 service_action = strtoul(optarg, &endptr, 0);
8616 if (*endptr != '\0') {
8617 warnx("Invalid service action \"%s\", must "
8618 "be a number", optarg);
8622 if (service_action > 0xffff) {
8623 warnx("Invalid service action 0x%#x, must "
8624 "be between 0 and 0xffff inclusive",
8639 && (opcode_set == 0)) {
8640 warnx("You must specify an opcode with -o if a service "
8645 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8646 sa_set, service_action, td_set, retry_count,
8647 timeout, verbosemode, &valid_len, &buf);
8651 if ((opcode_set != 0)
8653 retval = scsiprintoneopcode(device, opcode, sa_set,
8654 service_action, buf, valid_len);
8656 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8665 #endif /* MINIMALISTIC */
8668 scsireprobe(struct cam_device *device)
8673 ccb = cam_getccb(device);
8676 warnx("%s: error allocating ccb", __func__);
8680 bzero(&(&ccb->ccb_h)[1],
8681 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
8683 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8685 if (cam_send_ccb(device, ccb) < 0) {
8686 warn("error sending XPT_REPROBE_LUN CCB");
8691 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8692 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8704 usage(int printlong)
8707 fprintf(printlong ? stdout : stderr,
8708 "usage: camcontrol <command> [device id][generic args][command args]\n"
8709 " camcontrol devlist [-b] [-v]\n"
8710 #ifndef MINIMALISTIC
8711 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8712 " camcontrol tur [dev_id][generic args]\n"
8713 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8714 " camcontrol identify [dev_id][generic args] [-v]\n"
8715 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8716 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8718 " camcontrol start [dev_id][generic args]\n"
8719 " camcontrol stop [dev_id][generic args]\n"
8720 " camcontrol load [dev_id][generic args]\n"
8721 " camcontrol eject [dev_id][generic args]\n"
8722 " camcontrol reprobe [dev_id][generic args]\n"
8723 #endif /* MINIMALISTIC */
8724 " camcontrol rescan <all | bus[:target:lun]>\n"
8725 " camcontrol reset <all | bus[:target:lun]>\n"
8726 #ifndef MINIMALISTIC
8727 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8728 " [-q][-s][-S offset][-X]\n"
8729 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8730 " [-P pagectl][-e | -b][-d]\n"
8731 " camcontrol cmd [dev_id][generic args]\n"
8732 " <-a cmd [args] | -c cmd [args]>\n"
8733 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8734 " camcontrol smpcmd [dev_id][generic args]\n"
8735 " <-r len fmt [args]> <-R len fmt [args]>\n"
8736 " camcontrol smprg [dev_id][generic args][-l]\n"
8737 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8738 " [-o operation][-d name][-m rate][-M rate]\n"
8739 " [-T pp_timeout][-a enable|disable]\n"
8740 " [-A enable|disable][-s enable|disable]\n"
8741 " [-S enable|disable]\n"
8742 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8743 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8744 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8745 " <all|bus[:target[:lun]]|off>\n"
8746 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8747 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8748 " [-D <enable|disable>][-M mode][-O offset]\n"
8749 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8750 " [-U][-W bus_width]\n"
8751 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8752 " camcontrol sanitize [dev_id][generic args]\n"
8753 " [-a overwrite|block|crypto|exitfailure]\n"
8754 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8756 " camcontrol idle [dev_id][generic args][-t time]\n"
8757 " camcontrol standby [dev_id][generic args][-t time]\n"
8758 " camcontrol sleep [dev_id][generic args]\n"
8759 " camcontrol apm [dev_id][generic args][-l level]\n"
8760 " camcontrol aam [dev_id][generic args][-l level]\n"
8761 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8763 " camcontrol security [dev_id][generic args]\n"
8764 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8765 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8766 " [-U <user|master>] [-y]\n"
8767 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8768 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8769 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8770 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8771 " [-s scope][-S][-T type][-U]\n"
8772 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8773 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8774 " [-p part][-s start][-T type][-V vol]\n"
8775 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8777 #endif /* MINIMALISTIC */
8778 " camcontrol help\n");
8781 #ifndef MINIMALISTIC
8783 "Specify one of the following options:\n"
8784 "devlist list all CAM devices\n"
8785 "periphlist list all CAM peripheral drivers attached to a device\n"
8786 "tur send a test unit ready to the named device\n"
8787 "inquiry send a SCSI inquiry command to the named device\n"
8788 "identify send a ATA identify command to the named device\n"
8789 "reportluns send a SCSI report luns command to the device\n"
8790 "readcap send a SCSI read capacity command to the device\n"
8791 "start send a Start Unit command to the device\n"
8792 "stop send a Stop Unit command to the device\n"
8793 "load send a Start Unit command to the device with the load bit set\n"
8794 "eject send a Stop Unit command to the device with the eject bit set\n"
8795 "reprobe update capacity information of the given device\n"
8796 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8797 "reset reset all busses, the given bus, or bus:target:lun\n"
8798 "defects read the defect list of the specified device\n"
8799 "modepage display or edit (-e) the given mode page\n"
8800 "cmd send the given SCSI command, may need -i or -o as well\n"
8801 "smpcmd send the given SMP command, requires -o and -i\n"
8802 "smprg send the SMP Report General command\n"
8803 "smppc send the SMP PHY Control command, requires -p\n"
8804 "smpphylist display phys attached to a SAS expander\n"
8805 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8806 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8807 "tags report or set the number of transaction slots for a device\n"
8808 "negotiate report or set device negotiation parameters\n"
8809 "format send the SCSI FORMAT UNIT command to the named device\n"
8810 "sanitize send the SCSI SANITIZE command to the named device\n"
8811 "idle send the ATA IDLE command to the named device\n"
8812 "standby send the ATA STANDBY command to the named device\n"
8813 "sleep send the ATA SLEEP command to the named device\n"
8814 "fwdownload program firmware of the named device with the given image\n"
8815 "security report or send ATA security commands to the named device\n"
8816 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8817 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8818 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8819 "help this message\n"
8820 "Device Identifiers:\n"
8821 "bus:target specify the bus and target, lun defaults to 0\n"
8822 "bus:target:lun specify the bus, target and lun\n"
8823 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8824 "Generic arguments:\n"
8825 "-v be verbose, print out sense information\n"
8826 "-t timeout command timeout in seconds, overrides default timeout\n"
8827 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8828 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8829 "-E have the kernel attempt to perform SCSI error recovery\n"
8830 "-C count specify the SCSI command retry count (needs -E to work)\n"
8831 "modepage arguments:\n"
8832 "-l list all available mode pages\n"
8833 "-m page specify the mode page to view or edit\n"
8834 "-e edit the specified mode page\n"
8835 "-b force view to binary mode\n"
8836 "-d disable block descriptors for mode sense\n"
8837 "-P pgctl page control field 0-3\n"
8838 "defects arguments:\n"
8839 "-f format specify defect list format (block, bfi or phys)\n"
8840 "-G get the grown defect list\n"
8841 "-P get the permanent defect list\n"
8842 "inquiry arguments:\n"
8843 "-D get the standard inquiry data\n"
8844 "-S get the serial number\n"
8845 "-R get the transfer rate, etc.\n"
8846 "reportluns arguments:\n"
8847 "-c only report a count of available LUNs\n"
8848 "-l only print out luns, and not a count\n"
8849 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
8850 "readcap arguments\n"
8851 "-b only report the blocksize\n"
8852 "-h human readable device size, base 2\n"
8853 "-H human readable device size, base 10\n"
8854 "-N print the number of blocks instead of last block\n"
8855 "-q quiet, print numbers only\n"
8856 "-s only report the last block/device size\n"
8858 "-c cdb [args] specify the SCSI CDB\n"
8859 "-i len fmt specify input data and input data format\n"
8860 "-o len fmt [args] specify output data and output data fmt\n"
8861 "smpcmd arguments:\n"
8862 "-r len fmt [args] specify the SMP command to be sent\n"
8863 "-R len fmt [args] specify SMP response format\n"
8864 "smprg arguments:\n"
8865 "-l specify the long response format\n"
8866 "smppc arguments:\n"
8867 "-p phy specify the PHY to operate on\n"
8868 "-l specify the long request/response format\n"
8869 "-o operation specify the phy control operation\n"
8870 "-d name set the attached device name\n"
8871 "-m rate set the minimum physical link rate\n"
8872 "-M rate set the maximum physical link rate\n"
8873 "-T pp_timeout set the partial pathway timeout value\n"
8874 "-a enable|disable enable or disable SATA slumber\n"
8875 "-A enable|disable enable or disable SATA partial phy power\n"
8876 "-s enable|disable enable or disable SAS slumber\n"
8877 "-S enable|disable enable or disable SAS partial phy power\n"
8878 "smpphylist arguments:\n"
8879 "-l specify the long response format\n"
8880 "-q only print phys with attached devices\n"
8881 "smpmaninfo arguments:\n"
8882 "-l specify the long response format\n"
8883 "debug arguments:\n"
8884 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
8885 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
8886 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
8887 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
8889 "-N tags specify the number of tags to use for this device\n"
8890 "-q be quiet, don't report the number of tags\n"
8891 "-v report a number of tag-related parameters\n"
8892 "negotiate arguments:\n"
8893 "-a send a test unit ready after negotiation\n"
8894 "-c report/set current negotiation settings\n"
8895 "-D <arg> \"enable\" or \"disable\" disconnection\n"
8896 "-M mode set ATA mode\n"
8897 "-O offset set command delay offset\n"
8898 "-q be quiet, don't report anything\n"
8899 "-R syncrate synchronization rate in MHz\n"
8900 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
8901 "-U report/set user negotiation settings\n"
8902 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
8903 "-v also print a Path Inquiry CCB for the controller\n"
8904 "format arguments:\n"
8905 "-q be quiet, don't print status messages\n"
8906 "-r run in report only mode\n"
8907 "-w don't send immediate format command\n"
8908 "-y don't ask any questions\n"
8909 "sanitize arguments:\n"
8910 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
8911 "-c passes overwrite passes to perform (1 to 31)\n"
8912 "-I invert overwrite pattern after each pass\n"
8913 "-P pattern path to overwrite pattern file\n"
8914 "-q be quiet, don't print status messages\n"
8915 "-r run in report only mode\n"
8916 "-U run operation in unrestricted completion exit mode\n"
8917 "-w don't send immediate sanitize command\n"
8918 "-y don't ask any questions\n"
8919 "idle/standby arguments:\n"
8920 "-t <arg> number of seconds before respective state.\n"
8921 "fwdownload arguments:\n"
8922 "-f fw_image path to firmware image file\n"
8923 "-q don't print informational messages, only errors\n"
8924 "-s run in simulation mode\n"
8925 "-v print info for every firmware segment sent to device\n"
8926 "-y don't ask any questions\n"
8927 "security arguments:\n"
8928 "-d pwd disable security using the given password for the selected\n"
8930 "-e pwd erase the device using the given pwd for the selected user\n"
8931 "-f freeze the security configuration of the specified device\n"
8932 "-h pwd enhanced erase the device using the given pwd for the\n"
8934 "-k pwd unlock the device using the given pwd for the selected\n"
8936 "-l <high|maximum> specifies which security level to set: high or maximum\n"
8937 "-q be quiet, do not print any status messages\n"
8938 "-s pwd password the device (enable security) using the given\n"
8939 " pwd for the selected user\n"
8940 "-T timeout overrides the timeout (seconds) used for erase operation\n"
8941 "-U <user|master> specifies which user to set: user or master\n"
8942 "-y don't ask any questions\n"
8944 "-f freeze the HPA configuration of the device\n"
8945 "-l lock the HPA configuration of the device\n"
8946 "-P make the HPA max sectors persist\n"
8947 "-p pwd Set the HPA configuration password required for unlock\n"
8949 "-q be quiet, do not print any status messages\n"
8950 "-s sectors configures the maximum user accessible sectors of the\n"
8952 "-U pwd unlock the HPA configuration of the device\n"
8953 "-y don't ask any questions\n"
8954 "persist arguments:\n"
8955 "-i action specify read_keys, read_reservation, report_cap, or\n"
8956 " read_full_status\n"
8957 "-o action specify register, register_ignore, reserve, release,\n"
8958 " clear, preempt, preempt_abort, register_move, replace_lost\n"
8959 "-a set the All Target Ports (ALL_TG_PT) bit\n"
8960 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
8961 "-k key specify the Reservation Key\n"
8962 "-K sa_key specify the Service Action Reservation Key\n"
8963 "-p set the Activate Persist Through Power Loss bit\n"
8964 "-R rtp specify the Relative Target Port\n"
8965 "-s scope specify the scope: lun, extent, element or a number\n"
8966 "-S specify Transport ID for register, requires -I\n"
8967 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
8968 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
8969 "-U unregister the current initiator for register_move\n"
8970 "attrib arguments:\n"
8971 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
8973 "-w attr specify an attribute to write, one -w argument per attr\n"
8974 "-a attr_num only display this attribute number\n"
8975 "-c get cached attributes\n"
8976 "-e elem_addr request attributes for the given element in a changer\n"
8977 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
8978 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
8979 " field_none, field_desc, field_num, field_size, field_rw\n"
8980 "-p partition request attributes for the given partition\n"
8981 "-s start_attr request attributes starting at the given number\n"
8982 "-T elem_type specify the element type (used with -e)\n"
8983 "-V logical_vol specify the logical volume ID\n"
8984 "opcodes arguments:\n"
8985 "-o opcode specify the individual opcode to list\n"
8986 "-s service_action specify the service action for the opcode\n"
8987 "-N do not return SCSI error for unsupported SA\n"
8988 "-T request nominal and recommended timeout values\n"
8990 #endif /* MINIMALISTIC */
8994 main(int argc, char **argv)
8997 char *device = NULL;
8999 struct cam_device *cam_dev = NULL;
9000 int timeout = 0, retry_count = 1;
9001 camcontrol_optret optreturn;
9003 const char *mainopt = "C:En:t:u:v";
9004 const char *subopt = NULL;
9005 char combinedopt[256];
9006 int error = 0, optstart = 2;
9008 #ifndef MINIMALISTIC
9012 #endif /* MINIMALISTIC */
9014 cmdlist = CAM_CMD_NONE;
9015 arglist = CAM_ARG_NONE;
9023 * Get the base option.
9025 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9027 if (optreturn == CC_OR_AMBIGUOUS) {
9028 warnx("ambiguous option %s", argv[1]);
9031 } else if (optreturn == CC_OR_NOT_FOUND) {
9032 warnx("option %s not found", argv[1]);
9038 * Ahh, getopt(3) is a pain.
9040 * This is a gross hack. There really aren't many other good
9041 * options (excuse the pun) for parsing options in a situation like
9042 * this. getopt is kinda braindead, so you end up having to run
9043 * through the options twice, and give each invocation of getopt
9044 * the option string for the other invocation.
9046 * You would think that you could just have two groups of options.
9047 * The first group would get parsed by the first invocation of
9048 * getopt, and the second group would get parsed by the second
9049 * invocation of getopt. It doesn't quite work out that way. When
9050 * the first invocation of getopt finishes, it leaves optind pointing
9051 * to the argument _after_ the first argument in the second group.
9052 * So when the second invocation of getopt comes around, it doesn't
9053 * recognize the first argument it gets and then bails out.
9055 * A nice alternative would be to have a flag for getopt that says
9056 * "just keep parsing arguments even when you encounter an unknown
9057 * argument", but there isn't one. So there's no real clean way to
9058 * easily parse two sets of arguments without having one invocation
9059 * of getopt know about the other.
9061 * Without this hack, the first invocation of getopt would work as
9062 * long as the generic arguments are first, but the second invocation
9063 * (in the subfunction) would fail in one of two ways. In the case
9064 * where you don't set optreset, it would fail because optind may be
9065 * pointing to the argument after the one it should be pointing at.
9066 * In the case where you do set optreset, and reset optind, it would
9067 * fail because getopt would run into the first set of options, which
9068 * it doesn't understand.
9070 * All of this would "sort of" work if you could somehow figure out
9071 * whether optind had been incremented one option too far. The
9072 * mechanics of that, however, are more daunting than just giving
9073 * both invocations all of the expect options for either invocation.
9075 * Needless to say, I wouldn't mind if someone invented a better
9076 * (non-GPL!) command line parsing interface than getopt. I
9077 * wouldn't mind if someone added more knobs to getopt to make it
9078 * work better. Who knows, I may talk myself into doing it someday,
9079 * if the standards weenies let me. As it is, it just leads to
9080 * hackery like this and causes people to avoid it in some cases.
9082 * KDM, September 8th, 1998
9085 sprintf(combinedopt, "%s%s", mainopt, subopt);
9087 sprintf(combinedopt, "%s", mainopt);
9090 * For these options we do not parse optional device arguments and
9091 * we do not open a passthrough device.
9093 if ((cmdlist == CAM_CMD_RESCAN)
9094 || (cmdlist == CAM_CMD_RESET)
9095 || (cmdlist == CAM_CMD_DEVTREE)
9096 || (cmdlist == CAM_CMD_USAGE)
9097 || (cmdlist == CAM_CMD_DEBUG))
9100 #ifndef MINIMALISTIC
9102 && (argc > 2 && argv[2][0] != '-')) {
9106 if (isdigit(argv[2][0])) {
9107 /* device specified as bus:target[:lun] */
9108 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9110 errx(1, "numeric device specification must "
9111 "be either bus:target, or "
9113 /* default to 0 if lun was not specified */
9114 if ((arglist & CAM_ARG_LUN) == 0) {
9116 arglist |= CAM_ARG_LUN;
9120 if (cam_get_device(argv[2], name, sizeof name, &unit)
9122 errx(1, "%s", cam_errbuf);
9123 device = strdup(name);
9124 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9128 #endif /* MINIMALISTIC */
9130 * Start getopt processing at argv[2/3], since we've already
9131 * accepted argv[1..2] as the command name, and as a possible
9137 * Now we run through the argument list looking for generic
9138 * options, and ignoring options that possibly belong to
9141 while ((c = getopt(argc, argv, combinedopt))!= -1){
9144 retry_count = strtol(optarg, NULL, 0);
9145 if (retry_count < 0)
9146 errx(1, "retry count %d is < 0",
9148 arglist |= CAM_ARG_RETRIES;
9151 arglist |= CAM_ARG_ERR_RECOVER;
9154 arglist |= CAM_ARG_DEVICE;
9156 while (isspace(*tstr) && (*tstr != '\0'))
9158 device = (char *)strdup(tstr);
9161 timeout = strtol(optarg, NULL, 0);
9163 errx(1, "invalid timeout %d", timeout);
9164 /* Convert the timeout from seconds to ms */
9166 arglist |= CAM_ARG_TIMEOUT;
9169 arglist |= CAM_ARG_UNIT;
9170 unit = strtol(optarg, NULL, 0);
9173 arglist |= CAM_ARG_VERBOSE;
9180 #ifndef MINIMALISTIC
9182 * For most commands we'll want to open the passthrough device
9183 * associated with the specified device. In the case of the rescan
9184 * commands, we don't use a passthrough device at all, just the
9185 * transport layer device.
9188 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9189 && (((arglist & CAM_ARG_DEVICE) == 0)
9190 || ((arglist & CAM_ARG_UNIT) == 0))) {
9191 errx(1, "subcommand \"%s\" requires a valid device "
9192 "identifier", argv[1]);
9195 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9196 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9197 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9199 errx(1,"%s", cam_errbuf);
9201 #endif /* MINIMALISTIC */
9204 * Reset optind to 2, and reset getopt, so these routines can parse
9205 * the arguments again.
9211 #ifndef MINIMALISTIC
9212 case CAM_CMD_DEVLIST:
9213 error = getdevlist(cam_dev);
9216 error = atahpa(cam_dev, retry_count, timeout,
9217 argc, argv, combinedopt);
9219 #endif /* MINIMALISTIC */
9220 case CAM_CMD_DEVTREE:
9221 error = getdevtree(argc, argv, combinedopt);
9223 #ifndef MINIMALISTIC
9225 error = testunitready(cam_dev, retry_count, timeout, 0);
9227 case CAM_CMD_INQUIRY:
9228 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9229 retry_count, timeout);
9231 case CAM_CMD_IDENTIFY:
9232 error = ataidentify(cam_dev, retry_count, timeout);
9234 case CAM_CMD_STARTSTOP:
9235 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9236 arglist & CAM_ARG_EJECT, retry_count,
9239 #endif /* MINIMALISTIC */
9240 case CAM_CMD_RESCAN:
9241 error = dorescan_or_reset(argc, argv, 1);
9244 error = dorescan_or_reset(argc, argv, 0);
9246 #ifndef MINIMALISTIC
9247 case CAM_CMD_READ_DEFECTS:
9248 error = readdefects(cam_dev, argc, argv, combinedopt,
9249 retry_count, timeout);
9251 case CAM_CMD_MODE_PAGE:
9252 modepage(cam_dev, argc, argv, combinedopt,
9253 retry_count, timeout);
9255 case CAM_CMD_SCSI_CMD:
9256 error = scsicmd(cam_dev, argc, argv, combinedopt,
9257 retry_count, timeout);
9259 case CAM_CMD_SMP_CMD:
9260 error = smpcmd(cam_dev, argc, argv, combinedopt,
9261 retry_count, timeout);
9263 case CAM_CMD_SMP_RG:
9264 error = smpreportgeneral(cam_dev, argc, argv,
9265 combinedopt, retry_count,
9268 case CAM_CMD_SMP_PC:
9269 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9270 retry_count, timeout);
9272 case CAM_CMD_SMP_PHYLIST:
9273 error = smpphylist(cam_dev, argc, argv, combinedopt,
9274 retry_count, timeout);
9276 case CAM_CMD_SMP_MANINFO:
9277 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9278 retry_count, timeout);
9281 error = camdebug(argc, argv, combinedopt);
9284 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9287 error = ratecontrol(cam_dev, retry_count, timeout,
9288 argc, argv, combinedopt);
9290 case CAM_CMD_FORMAT:
9291 error = scsiformat(cam_dev, argc, argv,
9292 combinedopt, retry_count, timeout);
9294 case CAM_CMD_REPORTLUNS:
9295 error = scsireportluns(cam_dev, argc, argv,
9296 combinedopt, retry_count,
9299 case CAM_CMD_READCAP:
9300 error = scsireadcapacity(cam_dev, argc, argv,
9301 combinedopt, retry_count,
9305 case CAM_CMD_STANDBY:
9307 error = atapm(cam_dev, argc, argv,
9308 combinedopt, retry_count, timeout);
9312 error = ataaxm(cam_dev, argc, argv,
9313 combinedopt, retry_count, timeout);
9315 case CAM_CMD_SECURITY:
9316 error = atasecurity(cam_dev, retry_count, timeout,
9317 argc, argv, combinedopt);
9319 case CAM_CMD_DOWNLOAD_FW:
9320 error = fwdownload(cam_dev, argc, argv, combinedopt,
9321 arglist & CAM_ARG_VERBOSE, retry_count, timeout);
9323 case CAM_CMD_SANITIZE:
9324 error = scsisanitize(cam_dev, argc, argv,
9325 combinedopt, retry_count, timeout);
9327 case CAM_CMD_PERSIST:
9328 error = scsipersist(cam_dev, argc, argv, combinedopt,
9329 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9330 arglist & CAM_ARG_ERR_RECOVER);
9332 case CAM_CMD_ATTRIB:
9333 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9334 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9335 arglist & CAM_ARG_ERR_RECOVER);
9337 case CAM_CMD_OPCODES:
9338 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9339 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9341 case CAM_CMD_REPROBE:
9342 error = scsireprobe(cam_dev);
9345 #endif /* MINIMALISTIC */
9355 if (cam_dev != NULL)
9356 cam_close_device(cam_dev);