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 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
843 inq_buf = (struct scsi_inquiry_data *)malloc(
844 sizeof(struct scsi_inquiry_data));
846 if (inq_buf == NULL) {
848 warnx("can't malloc memory for inquiry\n");
851 bzero(inq_buf, sizeof(*inq_buf));
854 * Note that although the size of the inquiry buffer is the full
855 * 256 bytes specified in the SCSI spec, we only tell the device
856 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
857 * two reasons for this:
859 * - The SCSI spec says that when a length field is only 1 byte,
860 * a value of 0 will be interpreted as 256. Therefore
861 * scsi_inquiry() will convert an inq_len (which is passed in as
862 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
863 * to 0. Evidently, very few devices meet the spec in that
864 * regard. Some devices, like many Seagate disks, take the 0 as
865 * 0, and don't return any data. One Pioneer DVD-R drive
866 * returns more data than the command asked for.
868 * So, since there are numerous devices that just don't work
869 * right with the full inquiry size, we don't send the full size.
871 * - The second reason not to use the full inquiry data length is
872 * that we don't need it here. The only reason we issue a
873 * standard inquiry is to get the vendor name, device name,
874 * and revision so scsi_print_inquiry() can print them.
876 * If, at some point in the future, more inquiry data is needed for
877 * some reason, this code should use a procedure similar to the
878 * probe code. i.e., issue a short inquiry, and determine from
879 * the additional length passed back from the device how much
880 * inquiry data the device supports. Once the amount the device
881 * supports is determined, issue an inquiry for that amount and no
886 scsi_inquiry(&ccb->csio,
887 /* retries */ retry_count,
889 /* tag_action */ MSG_SIMPLE_Q_TAG,
890 /* inq_buf */ (u_int8_t *)inq_buf,
891 /* inq_len */ SHORT_INQUIRY_LENGTH,
894 /* sense_len */ SSD_FULL_SIZE,
895 /* timeout */ timeout ? timeout : 5000);
897 /* Disable freezing the device queue */
898 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
900 if (arglist & CAM_ARG_ERR_RECOVER)
901 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
903 if (cam_send_ccb(device, ccb) < 0) {
904 perror("error sending SCSI inquiry");
906 if (arglist & CAM_ARG_VERBOSE) {
907 cam_error_print(device, ccb, CAM_ESF_ALL,
908 CAM_EPF_ALL, stderr);
915 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
918 if (arglist & CAM_ARG_VERBOSE) {
919 cam_error_print(device, ccb, CAM_ESF_ALL,
920 CAM_EPF_ALL, stderr);
931 fprintf(stdout, "%s%d: ", device->device_name,
932 device->dev_unit_num);
933 scsi_print_inquiry(inq_buf);
941 scsiserial(struct cam_device *device, int retry_count, int timeout)
944 struct scsi_vpd_unit_serial_number *serial_buf;
945 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
948 ccb = cam_getccb(device);
951 warnx("couldn't allocate CCB");
955 /* cam_getccb cleans up the header, caller has to zero the payload */
956 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
958 serial_buf = (struct scsi_vpd_unit_serial_number *)
959 malloc(sizeof(*serial_buf));
961 if (serial_buf == NULL) {
963 warnx("can't malloc memory for serial number");
967 scsi_inquiry(&ccb->csio,
968 /*retries*/ retry_count,
970 /* tag_action */ MSG_SIMPLE_Q_TAG,
971 /* inq_buf */ (u_int8_t *)serial_buf,
972 /* inq_len */ sizeof(*serial_buf),
974 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
975 /* sense_len */ SSD_FULL_SIZE,
976 /* timeout */ timeout ? timeout : 5000);
978 /* Disable freezing the device queue */
979 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
981 if (arglist & CAM_ARG_ERR_RECOVER)
982 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
984 if (cam_send_ccb(device, ccb) < 0) {
985 warn("error getting serial number");
987 if (arglist & CAM_ARG_VERBOSE) {
988 cam_error_print(device, ccb, CAM_ESF_ALL,
989 CAM_EPF_ALL, stderr);
997 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1000 if (arglist & CAM_ARG_VERBOSE) {
1001 cam_error_print(device, ccb, CAM_ESF_ALL,
1002 CAM_EPF_ALL, stderr);
1013 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1014 serial_num[serial_buf->length] = '\0';
1016 if ((arglist & CAM_ARG_GET_STDINQ)
1017 || (arglist & CAM_ARG_GET_XFERRATE))
1018 fprintf(stdout, "%s%d: Serial Number ",
1019 device->device_name, device->dev_unit_num);
1021 fprintf(stdout, "%.60s\n", serial_num);
1029 camxferrate(struct cam_device *device)
1031 struct ccb_pathinq cpi;
1033 u_int32_t speed = 0;
1038 if ((retval = get_cpi(device, &cpi)) != 0)
1041 ccb = cam_getccb(device);
1044 warnx("couldn't allocate CCB");
1048 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1050 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1051 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1053 if (((retval = cam_send_ccb(device, ccb)) < 0)
1054 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1055 const char error_string[] = "error getting transfer settings";
1060 warnx(error_string);
1062 if (arglist & CAM_ARG_VERBOSE)
1063 cam_error_print(device, ccb, CAM_ESF_ALL,
1064 CAM_EPF_ALL, stderr);
1068 goto xferrate_bailout;
1072 speed = cpi.base_transfer_speed;
1074 if (ccb->cts.transport == XPORT_SPI) {
1075 struct ccb_trans_settings_spi *spi =
1076 &ccb->cts.xport_specific.spi;
1078 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1079 freq = scsi_calc_syncsrate(spi->sync_period);
1082 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1083 speed *= (0x01 << spi->bus_width);
1085 } else if (ccb->cts.transport == XPORT_FC) {
1086 struct ccb_trans_settings_fc *fc =
1087 &ccb->cts.xport_specific.fc;
1089 if (fc->valid & CTS_FC_VALID_SPEED)
1090 speed = fc->bitrate;
1091 } else if (ccb->cts.transport == XPORT_SAS) {
1092 struct ccb_trans_settings_sas *sas =
1093 &ccb->cts.xport_specific.sas;
1095 if (sas->valid & CTS_SAS_VALID_SPEED)
1096 speed = sas->bitrate;
1097 } else if (ccb->cts.transport == XPORT_ATA) {
1098 struct ccb_trans_settings_pata *pata =
1099 &ccb->cts.xport_specific.ata;
1101 if (pata->valid & CTS_ATA_VALID_MODE)
1102 speed = ata_mode2speed(pata->mode);
1103 } else if (ccb->cts.transport == XPORT_SATA) {
1104 struct ccb_trans_settings_sata *sata =
1105 &ccb->cts.xport_specific.sata;
1107 if (sata->valid & CTS_SATA_VALID_REVISION)
1108 speed = ata_revision2speed(sata->revision);
1113 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1114 device->device_name, device->dev_unit_num,
1117 fprintf(stdout, "%s%d: %dKB/s transfers",
1118 device->device_name, device->dev_unit_num,
1122 if (ccb->cts.transport == XPORT_SPI) {
1123 struct ccb_trans_settings_spi *spi =
1124 &ccb->cts.xport_specific.spi;
1126 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1127 && (spi->sync_offset != 0))
1128 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1129 freq % 1000, spi->sync_offset);
1131 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1132 && (spi->bus_width > 0)) {
1133 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1134 && (spi->sync_offset != 0)) {
1135 fprintf(stdout, ", ");
1137 fprintf(stdout, " (");
1139 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1140 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1141 && (spi->sync_offset != 0)) {
1142 fprintf(stdout, ")");
1144 } else if (ccb->cts.transport == XPORT_ATA) {
1145 struct ccb_trans_settings_pata *pata =
1146 &ccb->cts.xport_specific.ata;
1149 if (pata->valid & CTS_ATA_VALID_MODE)
1150 printf("%s, ", ata_mode2string(pata->mode));
1151 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1152 printf("ATAPI %dbytes, ", pata->atapi);
1153 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1154 printf("PIO %dbytes", pata->bytecount);
1156 } else if (ccb->cts.transport == XPORT_SATA) {
1157 struct ccb_trans_settings_sata *sata =
1158 &ccb->cts.xport_specific.sata;
1161 if (sata->valid & CTS_SATA_VALID_REVISION)
1162 printf("SATA %d.x, ", sata->revision);
1165 if (sata->valid & CTS_SATA_VALID_MODE)
1166 printf("%s, ", ata_mode2string(sata->mode));
1167 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1168 printf("ATAPI %dbytes, ", sata->atapi);
1169 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1170 printf("PIO %dbytes", sata->bytecount);
1174 if (ccb->cts.protocol == PROTO_SCSI) {
1175 struct ccb_trans_settings_scsi *scsi =
1176 &ccb->cts.proto_specific.scsi;
1177 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1178 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1179 fprintf(stdout, ", Command Queueing Enabled");
1184 fprintf(stdout, "\n");
1194 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1196 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1197 ((u_int32_t)parm->lba_size_2 << 16);
1199 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1200 ((u_int64_t)parm->lba_size48_2 << 16) |
1201 ((u_int64_t)parm->lba_size48_3 << 32) |
1202 ((u_int64_t)parm->lba_size48_4 << 48);
1206 "Support Enabled Value\n");
1209 printf("Host Protected Area (HPA) ");
1210 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1211 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1212 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1215 printf("HPA - Security ");
1216 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1226 atasata(struct ata_params *parm)
1230 if (parm->satacapabilities != 0xffff &&
1231 parm->satacapabilities != 0x0000)
1238 atacapprint(struct ata_params *parm)
1240 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1241 ((u_int32_t)parm->lba_size_2 << 16);
1243 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1244 ((u_int64_t)parm->lba_size48_2 << 16) |
1245 ((u_int64_t)parm->lba_size48_3 << 32) |
1246 ((u_int64_t)parm->lba_size48_4 << 48);
1249 printf("protocol ");
1250 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1251 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1252 if (parm->satacapabilities & ATA_SATA_GEN3)
1253 printf(" SATA 3.x\n");
1254 else if (parm->satacapabilities & ATA_SATA_GEN2)
1255 printf(" SATA 2.x\n");
1256 else if (parm->satacapabilities & ATA_SATA_GEN1)
1257 printf(" SATA 1.x\n");
1263 printf("device model %.40s\n", parm->model);
1264 printf("firmware revision %.8s\n", parm->revision);
1265 printf("serial number %.20s\n", parm->serial);
1266 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1267 printf("WWN %04x%04x%04x%04x\n",
1268 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1270 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1271 printf("media serial number %.30s\n",
1272 parm->media_serial);
1275 printf("cylinders %d\n", parm->cylinders);
1276 printf("heads %d\n", parm->heads);
1277 printf("sectors/track %d\n", parm->sectors);
1278 printf("sector size logical %u, physical %lu, offset %lu\n",
1279 ata_logical_sector_size(parm),
1280 (unsigned long)ata_physical_sector_size(parm),
1281 (unsigned long)ata_logical_sector_offset(parm));
1283 if (parm->config == ATA_PROTO_CFA ||
1284 (parm->support.command2 & ATA_SUPPORT_CFA))
1285 printf("CFA supported\n");
1287 printf("LBA%ssupported ",
1288 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1290 printf("%d sectors\n", lbasize);
1294 printf("LBA48%ssupported ",
1295 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1297 printf("%ju sectors\n", (uintmax_t)lbasize48);
1301 printf("PIO supported PIO");
1302 switch (ata_max_pmode(parm)) {
1318 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1319 printf(" w/o IORDY");
1322 printf("DMA%ssupported ",
1323 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1324 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1325 if (parm->mwdmamodes & 0xff) {
1327 if (parm->mwdmamodes & 0x04)
1329 else if (parm->mwdmamodes & 0x02)
1331 else if (parm->mwdmamodes & 0x01)
1335 if ((parm->atavalid & ATA_FLAG_88) &&
1336 (parm->udmamodes & 0xff)) {
1338 if (parm->udmamodes & 0x40)
1340 else if (parm->udmamodes & 0x20)
1342 else if (parm->udmamodes & 0x10)
1344 else if (parm->udmamodes & 0x08)
1346 else if (parm->udmamodes & 0x04)
1348 else if (parm->udmamodes & 0x02)
1350 else if (parm->udmamodes & 0x01)
1357 if (parm->media_rotation_rate == 1) {
1358 printf("media RPM non-rotating\n");
1359 } else if (parm->media_rotation_rate >= 0x0401 &&
1360 parm->media_rotation_rate <= 0xFFFE) {
1361 printf("media RPM %d\n",
1362 parm->media_rotation_rate);
1366 "Support Enabled Value Vendor\n");
1367 printf("read ahead %s %s\n",
1368 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1369 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1370 printf("write cache %s %s\n",
1371 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1372 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1373 printf("flush cache %s %s\n",
1374 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1375 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1376 printf("overlap %s\n",
1377 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1378 printf("Tagged Command Queuing (TCQ) %s %s",
1379 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1380 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1381 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1382 printf(" %d tags\n",
1383 ATA_QUEUE_LEN(parm->queue) + 1);
1386 printf("Native Command Queuing (NCQ) ");
1387 if (parm->satacapabilities != 0xffff &&
1388 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1389 printf("yes %d tags\n",
1390 ATA_QUEUE_LEN(parm->queue) + 1);
1394 printf("NCQ Queue Management %s\n", atasata(parm) &&
1395 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1397 printf("NCQ Streaming %s\n", atasata(parm) &&
1398 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1400 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1401 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1404 printf("SMART %s %s\n",
1405 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1406 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1407 printf("microcode download %s %s\n",
1408 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1409 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1410 printf("security %s %s\n",
1411 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1412 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1413 printf("power management %s %s\n",
1414 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1415 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1416 printf("advanced power management %s %s",
1417 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1418 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1419 if (parm->support.command2 & ATA_SUPPORT_APM) {
1420 printf(" %d/0x%02X\n",
1421 parm->apm_value & 0xff, parm->apm_value & 0xff);
1424 printf("automatic acoustic management %s %s",
1425 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1426 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1427 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1428 printf(" %d/0x%02X %d/0x%02X\n",
1429 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1430 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1431 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1432 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1435 printf("media status notification %s %s\n",
1436 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1437 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1438 printf("power-up in Standby %s %s\n",
1439 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1440 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1441 printf("write-read-verify %s %s",
1442 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1443 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1444 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1445 printf(" %d/0x%x\n",
1446 parm->wrv_mode, parm->wrv_mode);
1449 printf("unload %s %s\n",
1450 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1451 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1452 printf("general purpose logging %s %s\n",
1453 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1454 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1455 printf("free-fall %s %s\n",
1456 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1457 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1458 printf("Data Set Management (DSM/TRIM) ");
1459 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1461 printf("DSM - max 512byte blocks ");
1462 if (parm->max_dsm_blocks == 0x00)
1463 printf("yes not specified\n");
1466 parm->max_dsm_blocks);
1468 printf("DSM - deterministic read ");
1469 if (parm->support3 & ATA_SUPPORT_DRAT) {
1470 if (parm->support3 & ATA_SUPPORT_RZAT)
1471 printf("yes zeroed\n");
1473 printf("yes any value\n");
1483 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1485 struct ata_pass_16 *ata_pass_16;
1486 struct ata_cmd ata_cmd;
1488 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1489 ata_cmd.command = ata_pass_16->command;
1490 ata_cmd.control = ata_pass_16->control;
1491 ata_cmd.features = ata_pass_16->features;
1493 if (arglist & CAM_ARG_VERBOSE) {
1494 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1495 ata_op_string(&ata_cmd),
1496 ccb->csio.ccb_h.timeout);
1499 /* Disable freezing the device queue */
1500 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1502 if (arglist & CAM_ARG_ERR_RECOVER)
1503 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1505 if (cam_send_ccb(device, ccb) < 0) {
1506 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1507 warn("error sending ATA %s via pass_16",
1508 ata_op_string(&ata_cmd));
1511 if (arglist & CAM_ARG_VERBOSE) {
1512 cam_error_print(device, ccb, CAM_ESF_ALL,
1513 CAM_EPF_ALL, stderr);
1519 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1520 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1521 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1522 warnx("ATA %s via pass_16 failed",
1523 ata_op_string(&ata_cmd));
1525 if (arglist & CAM_ARG_VERBOSE) {
1526 cam_error_print(device, ccb, CAM_ESF_ALL,
1527 CAM_EPF_ALL, stderr);
1538 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1540 if (arglist & CAM_ARG_VERBOSE) {
1541 warnx("sending ATA %s with timeout of %u msecs",
1542 ata_op_string(&(ccb->ataio.cmd)),
1543 ccb->ataio.ccb_h.timeout);
1546 /* Disable freezing the device queue */
1547 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1549 if (arglist & CAM_ARG_ERR_RECOVER)
1550 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1552 if (cam_send_ccb(device, ccb) < 0) {
1553 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1554 warn("error sending ATA %s",
1555 ata_op_string(&(ccb->ataio.cmd)));
1558 if (arglist & CAM_ARG_VERBOSE) {
1559 cam_error_print(device, ccb, CAM_ESF_ALL,
1560 CAM_EPF_ALL, stderr);
1566 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1567 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1568 warnx("ATA %s failed: %d",
1569 ata_op_string(&(ccb->ataio.cmd)), quiet);
1572 if (arglist & CAM_ARG_VERBOSE) {
1573 cam_error_print(device, ccb, CAM_ESF_ALL,
1574 CAM_EPF_ALL, stderr);
1584 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1585 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1586 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1587 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1588 u_int16_t dxfer_len, int timeout, int quiet)
1590 if (data_ptr != NULL) {
1591 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1592 AP_FLAG_TLEN_SECT_CNT;
1593 if (flags & CAM_DIR_OUT)
1594 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1596 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1598 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1601 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1603 scsi_ata_pass_16(&ccb->csio,
1617 /*sense_len*/SSD_FULL_SIZE,
1620 return scsi_cam_pass_16_send(device, ccb, quiet);
1624 ata_try_pass_16(struct cam_device *device)
1626 struct ccb_pathinq cpi;
1628 if (get_cpi(device, &cpi) != 0) {
1629 warnx("couldn't get CPI");
1633 if (cpi.protocol == PROTO_SCSI) {
1634 /* possibly compatible with pass_16 */
1638 /* likely not compatible with pass_16 */
1643 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1644 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1645 u_int8_t command, u_int8_t features, u_int32_t lba,
1646 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1647 int timeout, int quiet)
1651 switch (ata_try_pass_16(device)) {
1655 /* Try using SCSI Passthrough */
1656 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1657 0, tag_action, command, features, lba,
1658 sector_count, data_ptr, dxfer_len,
1662 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1663 cam_fill_ataio(&ccb->ataio,
1672 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1673 return ata_cam_send(device, ccb, quiet);
1677 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1678 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1679 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1680 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1681 u_int16_t dxfer_len, int timeout, int force48bit)
1685 retval = ata_try_pass_16(device);
1692 /* Try using SCSI Passthrough */
1693 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1694 ata_flags, tag_action, command, features,
1695 lba, sector_count, data_ptr, dxfer_len,
1698 if (ata_flags & AP_FLAG_CHK_COND) {
1699 /* Decode ata_res from sense data */
1700 struct ata_res_pass16 *res_pass16;
1701 struct ata_res *res;
1705 /* sense_data is 4 byte aligned */
1706 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1707 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1708 ptr[i] = le16toh(ptr[i]);
1710 /* sense_data is 4 byte aligned */
1711 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1712 &ccb->csio.sense_data;
1713 res = &ccb->ataio.res;
1714 res->flags = res_pass16->flags;
1715 res->status = res_pass16->status;
1716 res->error = res_pass16->error;
1717 res->lba_low = res_pass16->lba_low;
1718 res->lba_mid = res_pass16->lba_mid;
1719 res->lba_high = res_pass16->lba_high;
1720 res->device = res_pass16->device;
1721 res->lba_low_exp = res_pass16->lba_low_exp;
1722 res->lba_mid_exp = res_pass16->lba_mid_exp;
1723 res->lba_high_exp = res_pass16->lba_high_exp;
1724 res->sector_count = res_pass16->sector_count;
1725 res->sector_count_exp = res_pass16->sector_count_exp;
1731 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1732 cam_fill_ataio(&ccb->ataio,
1741 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1742 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1744 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1746 if (ata_flags & AP_FLAG_CHK_COND)
1747 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1749 return ata_cam_send(device, ccb, 0);
1753 dump_data(uint16_t *ptr, uint32_t len)
1757 for (i = 0; i < len / 2; i++) {
1759 printf(" %3d: ", i);
1760 printf("%04hx ", ptr[i]);
1769 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1770 int is48bit, u_int64_t *hpasize)
1772 struct ata_res *res;
1774 res = &ccb->ataio.res;
1775 if (res->status & ATA_STATUS_ERROR) {
1776 if (arglist & CAM_ARG_VERBOSE) {
1777 cam_error_print(device, ccb, CAM_ESF_ALL,
1778 CAM_EPF_ALL, stderr);
1779 printf("error = 0x%02x, sector_count = 0x%04x, "
1780 "device = 0x%02x, status = 0x%02x\n",
1781 res->error, res->sector_count,
1782 res->device, res->status);
1785 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1786 warnx("Max address has already been set since "
1787 "last power-on or hardware reset");
1793 if (arglist & CAM_ARG_VERBOSE) {
1794 fprintf(stdout, "%s%d: Raw native max data:\n",
1795 device->device_name, device->dev_unit_num);
1796 /* res is 4 byte aligned */
1797 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1799 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1800 "status = 0x%02x\n", res->error, res->sector_count,
1801 res->device, res->status);
1804 if (hpasize != NULL) {
1806 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1807 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1808 ((res->lba_high << 16) | (res->lba_mid << 8) |
1811 *hpasize = (((res->device & 0x0f) << 24) |
1812 (res->lba_high << 16) | (res->lba_mid << 8) |
1821 ata_read_native_max(struct cam_device *device, int retry_count,
1822 u_int32_t timeout, union ccb *ccb,
1823 struct ata_params *parm, u_int64_t *hpasize)
1829 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1830 protocol = AP_PROTO_NON_DATA;
1833 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1834 protocol |= AP_EXTEND;
1836 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1839 error = ata_do_cmd(device,
1842 /*flags*/CAM_DIR_NONE,
1843 /*protocol*/protocol,
1844 /*ata_flags*/AP_FLAG_CHK_COND,
1845 /*tag_action*/MSG_SIMPLE_Q_TAG,
1852 timeout ? timeout : 1000,
1858 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1862 atahpa_set_max(struct cam_device *device, int retry_count,
1863 u_int32_t timeout, union ccb *ccb,
1864 int is48bit, u_int64_t maxsize, int persist)
1870 protocol = AP_PROTO_NON_DATA;
1873 cmd = ATA_SET_MAX_ADDRESS48;
1874 protocol |= AP_EXTEND;
1876 cmd = ATA_SET_MAX_ADDRESS;
1879 /* lba's are zero indexed so the max lba is requested max - 1 */
1883 error = ata_do_cmd(device,
1886 /*flags*/CAM_DIR_NONE,
1887 /*protocol*/protocol,
1888 /*ata_flags*/AP_FLAG_CHK_COND,
1889 /*tag_action*/MSG_SIMPLE_Q_TAG,
1891 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1893 /*sector_count*/persist,
1896 timeout ? timeout : 1000,
1902 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1906 atahpa_password(struct cam_device *device, int retry_count,
1907 u_int32_t timeout, union ccb *ccb,
1908 int is48bit, struct ata_set_max_pwd *pwd)
1914 protocol = AP_PROTO_PIO_OUT;
1915 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1917 error = ata_do_cmd(device,
1920 /*flags*/CAM_DIR_OUT,
1921 /*protocol*/protocol,
1922 /*ata_flags*/AP_FLAG_CHK_COND,
1923 /*tag_action*/MSG_SIMPLE_Q_TAG,
1925 /*features*/ATA_HPA_FEAT_SET_PWD,
1928 /*data_ptr*/(u_int8_t*)pwd,
1929 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1930 timeout ? timeout : 1000,
1936 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1940 atahpa_lock(struct cam_device *device, int retry_count,
1941 u_int32_t timeout, union ccb *ccb, int is48bit)
1947 protocol = AP_PROTO_NON_DATA;
1948 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1950 error = ata_do_cmd(device,
1953 /*flags*/CAM_DIR_NONE,
1954 /*protocol*/protocol,
1955 /*ata_flags*/AP_FLAG_CHK_COND,
1956 /*tag_action*/MSG_SIMPLE_Q_TAG,
1958 /*features*/ATA_HPA_FEAT_LOCK,
1963 timeout ? timeout : 1000,
1969 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1973 atahpa_unlock(struct cam_device *device, int retry_count,
1974 u_int32_t timeout, union ccb *ccb,
1975 int is48bit, struct ata_set_max_pwd *pwd)
1981 protocol = AP_PROTO_PIO_OUT;
1982 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1984 error = ata_do_cmd(device,
1987 /*flags*/CAM_DIR_OUT,
1988 /*protocol*/protocol,
1989 /*ata_flags*/AP_FLAG_CHK_COND,
1990 /*tag_action*/MSG_SIMPLE_Q_TAG,
1992 /*features*/ATA_HPA_FEAT_UNLOCK,
1995 /*data_ptr*/(u_int8_t*)pwd,
1996 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1997 timeout ? timeout : 1000,
2003 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2007 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2008 u_int32_t timeout, union ccb *ccb, int is48bit)
2014 protocol = AP_PROTO_NON_DATA;
2015 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2017 error = ata_do_cmd(device,
2020 /*flags*/CAM_DIR_NONE,
2021 /*protocol*/protocol,
2022 /*ata_flags*/AP_FLAG_CHK_COND,
2023 /*tag_action*/MSG_SIMPLE_Q_TAG,
2025 /*features*/ATA_HPA_FEAT_FREEZE,
2030 timeout ? timeout : 1000,
2036 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2041 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2042 union ccb *ccb, struct ata_params** ident_bufp)
2044 struct ata_params *ident_buf;
2045 struct ccb_pathinq cpi;
2046 struct ccb_getdev cgd;
2049 u_int8_t command, retry_command;
2051 if (get_cpi(device, &cpi) != 0) {
2052 warnx("couldn't get CPI");
2056 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2057 if (cpi.protocol == PROTO_ATA) {
2058 if (get_cgd(device, &cgd) != 0) {
2059 warnx("couldn't get CGD");
2063 command = (cgd.protocol == PROTO_ATA) ?
2064 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2067 /* We don't know which for sure so try both */
2068 command = ATA_ATA_IDENTIFY;
2069 retry_command = ATA_ATAPI_IDENTIFY;
2072 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2074 warnx("can't calloc memory for identify\n");
2078 error = ata_do_28bit_cmd(device,
2080 /*retries*/retry_count,
2081 /*flags*/CAM_DIR_IN,
2082 /*protocol*/AP_PROTO_PIO_IN,
2083 /*tag_action*/MSG_SIMPLE_Q_TAG,
2087 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2088 /*data_ptr*/(u_int8_t *)ptr,
2089 /*dxfer_len*/sizeof(struct ata_params),
2090 /*timeout*/timeout ? timeout : 30 * 1000,
2094 if (retry_command == 0) {
2098 error = ata_do_28bit_cmd(device,
2100 /*retries*/retry_count,
2101 /*flags*/CAM_DIR_IN,
2102 /*protocol*/AP_PROTO_PIO_IN,
2103 /*tag_action*/MSG_SIMPLE_Q_TAG,
2104 /*command*/retry_command,
2107 /*sector_count*/(u_int8_t)
2108 sizeof(struct ata_params),
2109 /*data_ptr*/(u_int8_t *)ptr,
2110 /*dxfer_len*/sizeof(struct ata_params),
2111 /*timeout*/timeout ? timeout : 30 * 1000,
2121 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2122 ptr[i] = le16toh(ptr[i]);
2127 if (arglist & CAM_ARG_VERBOSE) {
2128 fprintf(stdout, "%s%d: Raw identify data:\n",
2129 device->device_name, device->dev_unit_num);
2130 dump_data(ptr, sizeof(struct ata_params));
2133 /* check for invalid (all zero) response */
2135 warnx("Invalid identify response detected");
2140 ident_buf = (struct ata_params *)ptr;
2141 if (strncmp(ident_buf->model, "FX", 2) &&
2142 strncmp(ident_buf->model, "NEC", 3) &&
2143 strncmp(ident_buf->model, "Pioneer", 7) &&
2144 strncmp(ident_buf->model, "SHARP", 5)) {
2145 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2146 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2147 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2148 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2150 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2151 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2152 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2153 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2154 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2155 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2156 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2157 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2158 sizeof(ident_buf->media_serial));
2160 *ident_bufp = ident_buf;
2167 ataidentify(struct cam_device *device, int retry_count, int timeout)
2170 struct ata_params *ident_buf;
2173 if ((ccb = cam_getccb(device)) == NULL) {
2174 warnx("couldn't allocate CCB");
2178 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2183 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2184 if (ata_read_native_max(device, retry_count, timeout, ccb,
2185 ident_buf, &hpasize) != 0) {
2193 printf("%s%d: ", device->device_name, device->dev_unit_num);
2194 ata_print_ident(ident_buf);
2195 camxferrate(device);
2196 atacapprint(ident_buf);
2197 atahpa_print(ident_buf, hpasize, 0);
2204 #endif /* MINIMALISTIC */
2207 #ifndef MINIMALISTIC
2209 ATA_SECURITY_ACTION_PRINT,
2210 ATA_SECURITY_ACTION_FREEZE,
2211 ATA_SECURITY_ACTION_UNLOCK,
2212 ATA_SECURITY_ACTION_DISABLE,
2213 ATA_SECURITY_ACTION_ERASE,
2214 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2215 ATA_SECURITY_ACTION_SET_PASSWORD
2219 atasecurity_print_time(u_int16_t tw)
2223 printf("unspecified");
2225 printf("> 508 min");
2227 printf("%i min", 2 * tw);
2231 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2235 return 2 * 3600 * 1000; /* default: two hours */
2236 else if (timeout > 255)
2237 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2239 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2244 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2248 bzero(&cmd, sizeof(cmd));
2249 cmd.command = command;
2250 printf("Issuing %s", ata_op_string(&cmd));
2253 char pass[sizeof(pwd->password)+1];
2255 /* pwd->password may not be null terminated */
2256 pass[sizeof(pwd->password)] = '\0';
2257 strncpy(pass, pwd->password, sizeof(pwd->password));
2258 printf(" password='%s', user='%s'",
2260 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2263 if (command == ATA_SECURITY_SET_PASSWORD) {
2264 printf(", mode='%s'",
2265 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2266 "maximum" : "high");
2274 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2275 int retry_count, u_int32_t timeout, int quiet)
2279 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2281 return ata_do_28bit_cmd(device,
2284 /*flags*/CAM_DIR_NONE,
2285 /*protocol*/AP_PROTO_NON_DATA,
2286 /*tag_action*/MSG_SIMPLE_Q_TAG,
2287 /*command*/ATA_SECURITY_FREEZE_LOCK,
2298 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2299 int retry_count, u_int32_t timeout,
2300 struct ata_security_password *pwd, int quiet)
2304 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2306 return ata_do_28bit_cmd(device,
2309 /*flags*/CAM_DIR_OUT,
2310 /*protocol*/AP_PROTO_PIO_OUT,
2311 /*tag_action*/MSG_SIMPLE_Q_TAG,
2312 /*command*/ATA_SECURITY_UNLOCK,
2316 /*data_ptr*/(u_int8_t *)pwd,
2317 /*dxfer_len*/sizeof(*pwd),
2323 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2324 int retry_count, u_int32_t timeout,
2325 struct ata_security_password *pwd, int quiet)
2329 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2330 return ata_do_28bit_cmd(device,
2333 /*flags*/CAM_DIR_OUT,
2334 /*protocol*/AP_PROTO_PIO_OUT,
2335 /*tag_action*/MSG_SIMPLE_Q_TAG,
2336 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2340 /*data_ptr*/(u_int8_t *)pwd,
2341 /*dxfer_len*/sizeof(*pwd),
2348 atasecurity_erase_confirm(struct cam_device *device,
2349 struct ata_params* ident_buf)
2352 printf("\nYou are about to ERASE ALL DATA from the following"
2353 " device:\n%s%d,%s%d: ", device->device_name,
2354 device->dev_unit_num, device->given_dev_name,
2355 device->given_unit_number);
2356 ata_print_ident(ident_buf);
2360 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2362 if (fgets(str, sizeof(str), stdin) != NULL) {
2363 if (strncasecmp(str, "yes", 3) == 0) {
2365 } else if (strncasecmp(str, "no", 2) == 0) {
2368 printf("Please answer \"yes\" or "
2379 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2380 int retry_count, u_int32_t timeout,
2381 u_int32_t erase_timeout,
2382 struct ata_security_password *pwd, int quiet)
2387 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2389 error = ata_do_28bit_cmd(device,
2392 /*flags*/CAM_DIR_NONE,
2393 /*protocol*/AP_PROTO_NON_DATA,
2394 /*tag_action*/MSG_SIMPLE_Q_TAG,
2395 /*command*/ATA_SECURITY_ERASE_PREPARE,
2408 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2410 error = ata_do_28bit_cmd(device,
2413 /*flags*/CAM_DIR_OUT,
2414 /*protocol*/AP_PROTO_PIO_OUT,
2415 /*tag_action*/MSG_SIMPLE_Q_TAG,
2416 /*command*/ATA_SECURITY_ERASE_UNIT,
2420 /*data_ptr*/(u_int8_t *)pwd,
2421 /*dxfer_len*/sizeof(*pwd),
2422 /*timeout*/erase_timeout,
2425 if (error == 0 && quiet == 0)
2426 printf("\nErase Complete\n");
2432 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2433 int retry_count, u_int32_t timeout,
2434 struct ata_security_password *pwd, int quiet)
2438 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2440 return ata_do_28bit_cmd(device,
2443 /*flags*/CAM_DIR_OUT,
2444 /*protocol*/AP_PROTO_PIO_OUT,
2445 /*tag_action*/MSG_SIMPLE_Q_TAG,
2446 /*command*/ATA_SECURITY_SET_PASSWORD,
2450 /*data_ptr*/(u_int8_t *)pwd,
2451 /*dxfer_len*/sizeof(*pwd),
2457 atasecurity_print(struct ata_params *parm)
2460 printf("\nSecurity Option Value\n");
2461 if (arglist & CAM_ARG_VERBOSE) {
2462 printf("status %04x\n",
2463 parm->security_status);
2465 printf("supported %s\n",
2466 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2467 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2469 printf("enabled %s\n",
2470 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2471 printf("drive locked %s\n",
2472 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2473 printf("security config frozen %s\n",
2474 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2475 printf("count expired %s\n",
2476 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2477 printf("security level %s\n",
2478 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2479 printf("enhanced erase supported %s\n",
2480 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2481 printf("erase time ");
2482 atasecurity_print_time(parm->erase_time);
2484 printf("enhanced erase time ");
2485 atasecurity_print_time(parm->enhanced_erase_time);
2487 printf("master password rev %04x%s\n",
2488 parm->master_passwd_revision,
2489 parm->master_passwd_revision == 0x0000 ||
2490 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2494 * Validates and copies the password in optarg to the passed buffer.
2495 * If the password in optarg is the same length as the buffer then
2496 * the data will still be copied but no null termination will occur.
2499 ata_getpwd(u_int8_t *passwd, int max, char opt)
2503 len = strlen(optarg);
2505 warnx("-%c password is too long", opt);
2507 } else if (len == 0) {
2508 warnx("-%c password is missing", opt);
2510 } else if (optarg[0] == '-'){
2511 warnx("-%c password starts with '-' (generic arg?)", opt);
2513 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2514 warnx("-%c password conflicts with existing password from -%c",
2519 /* Callers pass in a buffer which does NOT need to be terminated */
2520 strncpy(passwd, optarg, max);
2527 ATA_HPA_ACTION_PRINT,
2528 ATA_HPA_ACTION_SET_MAX,
2529 ATA_HPA_ACTION_SET_PWD,
2530 ATA_HPA_ACTION_LOCK,
2531 ATA_HPA_ACTION_UNLOCK,
2532 ATA_HPA_ACTION_FREEZE_LOCK
2536 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2537 u_int64_t maxsize, int persist)
2539 printf("\nYou are about to configure HPA to limit the user accessible\n"
2540 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2541 persist ? "persistently" : "temporarily",
2542 device->device_name, device->dev_unit_num,
2543 device->given_dev_name, device->given_unit_number);
2544 ata_print_ident(ident_buf);
2548 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2550 if (NULL != fgets(str, sizeof(str), stdin)) {
2551 if (0 == strncasecmp(str, "yes", 3)) {
2553 } else if (0 == strncasecmp(str, "no", 2)) {
2556 printf("Please answer \"yes\" or "
2567 atahpa(struct cam_device *device, int retry_count, int timeout,
2568 int argc, char **argv, char *combinedopt)
2571 struct ata_params *ident_buf;
2572 struct ccb_getdev cgd;
2573 struct ata_set_max_pwd pwd;
2574 int error, confirm, quiet, c, action, actions, setpwd, persist;
2575 int security, is48bit, pwdsize;
2576 u_int64_t hpasize, maxsize;
2586 memset(&pwd, 0, sizeof(pwd));
2588 /* default action is to print hpa information */
2589 action = ATA_HPA_ACTION_PRINT;
2590 pwdsize = sizeof(pwd.password);
2592 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2595 action = ATA_HPA_ACTION_SET_MAX;
2596 maxsize = strtoumax(optarg, NULL, 0);
2601 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2603 action = ATA_HPA_ACTION_SET_PWD;
2609 action = ATA_HPA_ACTION_LOCK;
2615 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2617 action = ATA_HPA_ACTION_UNLOCK;
2623 action = ATA_HPA_ACTION_FREEZE_LOCK;
2643 warnx("too many hpa actions specified");
2647 if (get_cgd(device, &cgd) != 0) {
2648 warnx("couldn't get CGD");
2652 ccb = cam_getccb(device);
2654 warnx("couldn't allocate CCB");
2658 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2665 printf("%s%d: ", device->device_name, device->dev_unit_num);
2666 ata_print_ident(ident_buf);
2667 camxferrate(device);
2670 if (action == ATA_HPA_ACTION_PRINT) {
2671 error = ata_read_native_max(device, retry_count, timeout, ccb,
2672 ident_buf, &hpasize);
2674 atahpa_print(ident_buf, hpasize, 1);
2681 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2682 warnx("HPA is not supported by this device");
2688 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2689 warnx("HPA Security is not supported by this device");
2695 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2698 * The ATA spec requires:
2699 * 1. Read native max addr is called directly before set max addr
2700 * 2. Read native max addr is NOT called before any other set max call
2703 case ATA_HPA_ACTION_SET_MAX:
2705 atahpa_set_confirm(device, ident_buf, maxsize,
2712 error = ata_read_native_max(device, retry_count, timeout,
2713 ccb, ident_buf, &hpasize);
2715 error = atahpa_set_max(device, retry_count, timeout,
2716 ccb, is48bit, maxsize, persist);
2718 /* redo identify to get new lba values */
2719 error = ata_do_identify(device, retry_count,
2722 atahpa_print(ident_buf, hpasize, 1);
2727 case ATA_HPA_ACTION_SET_PWD:
2728 error = atahpa_password(device, retry_count, timeout,
2729 ccb, is48bit, &pwd);
2731 printf("HPA password has been set\n");
2734 case ATA_HPA_ACTION_LOCK:
2735 error = atahpa_lock(device, retry_count, timeout,
2738 printf("HPA has been locked\n");
2741 case ATA_HPA_ACTION_UNLOCK:
2742 error = atahpa_unlock(device, retry_count, timeout,
2743 ccb, is48bit, &pwd);
2745 printf("HPA has been unlocked\n");
2748 case ATA_HPA_ACTION_FREEZE_LOCK:
2749 error = atahpa_freeze_lock(device, retry_count, timeout,
2752 printf("HPA has been frozen\n");
2756 errx(1, "Option currently not supported");
2766 atasecurity(struct cam_device *device, int retry_count, int timeout,
2767 int argc, char **argv, char *combinedopt)
2770 struct ata_params *ident_buf;
2771 int error, confirm, quiet, c, action, actions, setpwd;
2772 int security_enabled, erase_timeout, pwdsize;
2773 struct ata_security_password pwd;
2781 memset(&pwd, 0, sizeof(pwd));
2783 /* default action is to print security information */
2784 action = ATA_SECURITY_ACTION_PRINT;
2786 /* user is master by default as its safer that way */
2787 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2788 pwdsize = sizeof(pwd.password);
2790 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2793 action = ATA_SECURITY_ACTION_FREEZE;
2798 if (strcasecmp(optarg, "user") == 0) {
2799 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2800 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2801 } else if (strcasecmp(optarg, "master") == 0) {
2802 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2803 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2805 warnx("-U argument '%s' is invalid (must be "
2806 "'user' or 'master')", optarg);
2812 if (strcasecmp(optarg, "high") == 0) {
2813 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2814 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2815 } else if (strcasecmp(optarg, "maximum") == 0) {
2816 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2817 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2819 warnx("-l argument '%s' is unknown (must be "
2820 "'high' or 'maximum')", optarg);
2826 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2828 action = ATA_SECURITY_ACTION_UNLOCK;
2833 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2835 action = ATA_SECURITY_ACTION_DISABLE;
2840 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2842 action = ATA_SECURITY_ACTION_ERASE;
2847 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2849 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2850 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2855 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2858 if (action == ATA_SECURITY_ACTION_PRINT)
2859 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2861 * Don't increment action as this can be combined
2862 * with other actions.
2875 erase_timeout = atoi(optarg) * 1000;
2881 warnx("too many security actions specified");
2885 if ((ccb = cam_getccb(device)) == NULL) {
2886 warnx("couldn't allocate CCB");
2890 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2897 printf("%s%d: ", device->device_name, device->dev_unit_num);
2898 ata_print_ident(ident_buf);
2899 camxferrate(device);
2902 if (action == ATA_SECURITY_ACTION_PRINT) {
2903 atasecurity_print(ident_buf);
2909 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2910 warnx("Security not supported");
2916 /* default timeout 15 seconds the same as linux hdparm */
2917 timeout = timeout ? timeout : 15 * 1000;
2919 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2921 /* first set the password if requested */
2923 /* confirm we can erase before setting the password if erasing */
2925 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2926 action == ATA_SECURITY_ACTION_ERASE) &&
2927 atasecurity_erase_confirm(device, ident_buf) == 0) {
2933 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2934 pwd.revision = ident_buf->master_passwd_revision;
2935 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2936 --pwd.revision == 0) {
2937 pwd.revision = 0xfffe;
2940 error = atasecurity_set_password(device, ccb, retry_count,
2941 timeout, &pwd, quiet);
2947 security_enabled = 1;
2951 case ATA_SECURITY_ACTION_FREEZE:
2952 error = atasecurity_freeze(device, ccb, retry_count,
2956 case ATA_SECURITY_ACTION_UNLOCK:
2957 if (security_enabled) {
2958 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2959 error = atasecurity_unlock(device, ccb,
2960 retry_count, timeout, &pwd, quiet);
2962 warnx("Can't unlock, drive is not locked");
2966 warnx("Can't unlock, security is disabled");
2971 case ATA_SECURITY_ACTION_DISABLE:
2972 if (security_enabled) {
2973 /* First unlock the drive if its locked */
2974 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2975 error = atasecurity_unlock(device, ccb,
2983 error = atasecurity_disable(device,
2991 warnx("Can't disable security (already disabled)");
2996 case ATA_SECURITY_ACTION_ERASE:
2997 if (security_enabled) {
2998 if (erase_timeout == 0) {
2999 erase_timeout = atasecurity_erase_timeout_msecs(
3000 ident_buf->erase_time);
3003 error = atasecurity_erase(device, ccb, retry_count,
3004 timeout, erase_timeout, &pwd,
3007 warnx("Can't secure erase (security is disabled)");
3012 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3013 if (security_enabled) {
3014 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3015 if (erase_timeout == 0) {
3017 atasecurity_erase_timeout_msecs(
3018 ident_buf->enhanced_erase_time);
3021 error = atasecurity_erase(device, ccb,
3022 retry_count, timeout,
3023 erase_timeout, &pwd,
3026 warnx("Enhanced erase is not supported");
3030 warnx("Can't secure erase (enhanced), "
3031 "(security is disabled)");
3042 #endif /* MINIMALISTIC */
3045 * Parse out a bus, or a bus, target and lun in the following
3051 * Returns the number of parsed components, or 0.
3054 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3055 cam_argmask *arglst)
3060 while (isspace(*tstr) && (*tstr != '\0'))
3063 tmpstr = (char *)strtok(tstr, ":");
3064 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3065 *bus = strtol(tmpstr, NULL, 0);
3066 *arglst |= CAM_ARG_BUS;
3068 tmpstr = (char *)strtok(NULL, ":");
3069 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3070 *target = strtol(tmpstr, NULL, 0);
3071 *arglst |= CAM_ARG_TARGET;
3073 tmpstr = (char *)strtok(NULL, ":");
3074 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3075 *lun = strtol(tmpstr, NULL, 0);
3076 *arglst |= CAM_ARG_LUN;
3086 dorescan_or_reset(int argc, char **argv, int rescan)
3088 static const char must[] =
3089 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3091 path_id_t bus = CAM_BUS_WILDCARD;
3092 target_id_t target = CAM_TARGET_WILDCARD;
3093 lun_id_t lun = CAM_LUN_WILDCARD;
3097 warnx(must, rescan? "rescan" : "reset");
3101 tstr = argv[optind];
3102 while (isspace(*tstr) && (*tstr != '\0'))
3104 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3105 arglist |= CAM_ARG_BUS;
3107 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3108 if (rv != 1 && rv != 3) {
3109 warnx(must, rescan? "rescan" : "reset");
3114 if ((arglist & CAM_ARG_BUS)
3115 && (arglist & CAM_ARG_TARGET)
3116 && (arglist & CAM_ARG_LUN))
3117 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3119 error = rescan_or_reset_bus(bus, rescan);
3125 rescan_or_reset_bus(path_id_t bus, int rescan)
3127 union ccb ccb, matchccb;
3133 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3134 warnx("error opening transport layer device %s", XPT_DEVICE);
3135 warn("%s", XPT_DEVICE);
3139 if (bus != CAM_BUS_WILDCARD) {
3140 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3141 ccb.ccb_h.path_id = bus;
3142 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3143 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3144 ccb.crcn.flags = CAM_FLAG_NONE;
3146 /* run this at a low priority */
3147 ccb.ccb_h.pinfo.priority = 5;
3149 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3150 warn("CAMIOCOMMAND ioctl failed");
3155 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3156 fprintf(stdout, "%s of bus %d was successful\n",
3157 rescan ? "Re-scan" : "Reset", bus);
3159 fprintf(stdout, "%s of bus %d returned error %#x\n",
3160 rescan ? "Re-scan" : "Reset", bus,
3161 ccb.ccb_h.status & CAM_STATUS_MASK);
3172 * The right way to handle this is to modify the xpt so that it can
3173 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3174 * that isn't implemented, so instead we enumerate the busses and
3175 * send the rescan or reset to those busses in the case where the
3176 * given bus is -1 (wildcard). We don't send a rescan or reset
3177 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3178 * no-op, sending a rescan to the xpt bus would result in a status of
3181 CCB_CLEAR_ALL_EXCEPT_HDR(&matchccb.cdm);
3182 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3183 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3184 bufsize = sizeof(struct dev_match_result) * 20;
3185 matchccb.cdm.match_buf_len = bufsize;
3186 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3187 if (matchccb.cdm.matches == NULL) {
3188 warnx("can't malloc memory for matches");
3192 matchccb.cdm.num_matches = 0;
3194 matchccb.cdm.num_patterns = 1;
3195 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3197 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3198 matchccb.cdm.pattern_buf_len);
3199 if (matchccb.cdm.patterns == NULL) {
3200 warnx("can't malloc memory for patterns");
3204 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3205 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3210 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3211 warn("CAMIOCOMMAND ioctl failed");
3216 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3217 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3218 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3219 warnx("got CAM error %#x, CDM error %d\n",
3220 matchccb.ccb_h.status, matchccb.cdm.status);
3225 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3226 struct bus_match_result *bus_result;
3228 /* This shouldn't happen. */
3229 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3232 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3235 * We don't want to rescan or reset the xpt bus.
3238 if (bus_result->path_id == CAM_XPT_PATH_ID)
3241 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3243 ccb.ccb_h.path_id = bus_result->path_id;
3244 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3245 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3246 ccb.crcn.flags = CAM_FLAG_NONE;
3248 /* run this at a low priority */
3249 ccb.ccb_h.pinfo.priority = 5;
3251 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3252 warn("CAMIOCOMMAND ioctl failed");
3257 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3258 fprintf(stdout, "%s of bus %d was successful\n",
3259 rescan? "Re-scan" : "Reset",
3260 bus_result->path_id);
3263 * Don't bail out just yet, maybe the other
3264 * rescan or reset commands will complete
3267 fprintf(stderr, "%s of bus %d returned error "
3268 "%#x\n", rescan? "Re-scan" : "Reset",
3269 bus_result->path_id,
3270 ccb.ccb_h.status & CAM_STATUS_MASK);
3274 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3275 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3282 if (matchccb.cdm.patterns != NULL)
3283 free(matchccb.cdm.patterns);
3284 if (matchccb.cdm.matches != NULL)
3285 free(matchccb.cdm.matches);
3291 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3294 struct cam_device *device;
3299 if (bus == CAM_BUS_WILDCARD) {
3300 warnx("invalid bus number %d", bus);
3304 if (target == CAM_TARGET_WILDCARD) {
3305 warnx("invalid target number %d", target);
3309 if (lun == CAM_LUN_WILDCARD) {
3310 warnx("invalid lun number %jx", (uintmax_t)lun);
3316 bzero(&ccb, sizeof(union ccb));
3319 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3320 warnx("error opening transport layer device %s\n",
3322 warn("%s", XPT_DEVICE);
3326 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3327 if (device == NULL) {
3328 warnx("%s", cam_errbuf);
3333 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3334 ccb.ccb_h.path_id = bus;
3335 ccb.ccb_h.target_id = target;
3336 ccb.ccb_h.target_lun = lun;
3337 ccb.ccb_h.timeout = 5000;
3338 ccb.crcn.flags = CAM_FLAG_NONE;
3340 /* run this at a low priority */
3341 ccb.ccb_h.pinfo.priority = 5;
3344 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3345 warn("CAMIOCOMMAND ioctl failed");
3350 if (cam_send_ccb(device, &ccb) < 0) {
3351 warn("error sending XPT_RESET_DEV CCB");
3352 cam_close_device(device);
3360 cam_close_device(device);
3363 * An error code of CAM_BDR_SENT is normal for a BDR request.
3365 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3367 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3368 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3369 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3372 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3373 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3374 ccb.ccb_h.status & CAM_STATUS_MASK);
3379 #ifndef MINIMALISTIC
3381 static struct scsi_nv defect_list_type_map[] = {
3382 { "block", SRDD10_BLOCK_FORMAT },
3383 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3384 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3385 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3386 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3387 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3391 readdefects(struct cam_device *device, int argc, char **argv,
3392 char *combinedopt, int retry_count, int timeout)
3394 union ccb *ccb = NULL;
3395 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3396 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3397 size_t hdr_size = 0, entry_size = 0;
3400 u_int8_t *defect_list = NULL;
3401 u_int8_t list_format = 0;
3402 int list_type_set = 0;
3403 u_int32_t dlist_length = 0;
3404 u_int32_t returned_length = 0, valid_len = 0;
3405 u_int32_t num_returned = 0, num_valid = 0;
3406 u_int32_t max_possible_size = 0, hdr_max = 0;
3407 u_int32_t starting_offset = 0;
3408 u_int8_t returned_format, returned_type;
3410 int summary = 0, quiet = 0;
3412 int lists_specified = 0;
3413 int get_length = 1, first_pass = 1;
3416 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3420 scsi_nv_status status;
3423 status = scsi_get_nv(defect_list_type_map,
3424 sizeof(defect_list_type_map) /
3425 sizeof(defect_list_type_map[0]), optarg,
3426 &entry_num, SCSI_NV_FLAG_IG_CASE);
3428 if (status == SCSI_NV_FOUND) {
3429 list_format = defect_list_type_map[
3433 warnx("%s: %s %s option %s", __func__,
3434 (status == SCSI_NV_AMBIGUOUS) ?
3435 "ambiguous" : "invalid", "defect list type",
3438 goto defect_bailout;
3443 arglist |= CAM_ARG_GLIST;
3446 arglist |= CAM_ARG_PLIST;
3457 starting_offset = strtoul(optarg, &endptr, 0);
3458 if (*endptr != '\0') {
3460 warnx("invalid starting offset %s", optarg);
3461 goto defect_bailout;
3473 if (list_type_set == 0) {
3475 warnx("no defect list format specified");
3476 goto defect_bailout;
3479 if (arglist & CAM_ARG_PLIST) {
3480 list_format |= SRDD10_PLIST;
3484 if (arglist & CAM_ARG_GLIST) {
3485 list_format |= SRDD10_GLIST;
3490 * This implies a summary, and was the previous behavior.
3492 if (lists_specified == 0)
3495 ccb = cam_getccb(device);
3500 * We start off asking for just the header to determine how much
3501 * defect data is available. Some Hitachi drives return an error
3502 * if you ask for more data than the drive has. Once we know the
3503 * length, we retry the command with the returned length.
3505 if (use_12byte == 0)
3506 dlist_length = sizeof(*hdr10);
3508 dlist_length = sizeof(*hdr12);
3511 if (defect_list != NULL) {
3515 defect_list = malloc(dlist_length);
3516 if (defect_list == NULL) {
3517 warnx("can't malloc memory for defect list");
3519 goto defect_bailout;
3523 bzero(defect_list, dlist_length);
3526 * cam_getccb() zeros the CCB header only. So we need to zero the
3527 * payload portion of the ccb.
3529 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3531 scsi_read_defects(&ccb->csio,
3532 /*retries*/ retry_count,
3534 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3535 /*list_format*/ list_format,
3536 /*addr_desc_index*/ starting_offset,
3537 /*data_ptr*/ defect_list,
3538 /*dxfer_len*/ dlist_length,
3539 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3540 /*sense_len*/ SSD_FULL_SIZE,
3541 /*timeout*/ timeout ? timeout : 5000);
3543 /* Disable freezing the device queue */
3544 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3546 if (cam_send_ccb(device, ccb) < 0) {
3547 perror("error reading defect list");
3549 if (arglist & CAM_ARG_VERBOSE) {
3550 cam_error_print(device, ccb, CAM_ESF_ALL,
3551 CAM_EPF_ALL, stderr);
3555 goto defect_bailout;
3558 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3560 if (use_12byte == 0) {
3561 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3562 hdr_size = sizeof(*hdr10);
3563 hdr_max = SRDDH10_MAX_LENGTH;
3565 if (valid_len >= hdr_size) {
3566 returned_length = scsi_2btoul(hdr10->length);
3567 returned_format = hdr10->format;
3569 returned_length = 0;
3570 returned_format = 0;
3573 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3574 hdr_size = sizeof(*hdr12);
3575 hdr_max = SRDDH12_MAX_LENGTH;
3577 if (valid_len >= hdr_size) {
3578 returned_length = scsi_4btoul(hdr12->length);
3579 returned_format = hdr12->format;
3581 returned_length = 0;
3582 returned_format = 0;
3586 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3587 switch (returned_type) {
3588 case SRDD10_BLOCK_FORMAT:
3589 entry_size = sizeof(struct scsi_defect_desc_block);
3591 case SRDD10_LONG_BLOCK_FORMAT:
3592 entry_size = sizeof(struct scsi_defect_desc_long_block);
3594 case SRDD10_EXT_PHYS_FORMAT:
3595 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3596 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3598 case SRDD10_EXT_BFI_FORMAT:
3599 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3600 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3603 warnx("Unknown defect format 0x%x\n", returned_type);
3605 goto defect_bailout;
3609 max_possible_size = (hdr_max / entry_size) * entry_size;
3610 num_returned = returned_length / entry_size;
3611 num_valid = min(returned_length, valid_len - hdr_size);
3612 num_valid /= entry_size;
3614 if (get_length != 0) {
3617 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3618 CAM_SCSI_STATUS_ERROR) {
3619 struct scsi_sense_data *sense;
3620 int error_code, sense_key, asc, ascq;
3622 sense = &ccb->csio.sense_data;
3623 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3624 ccb->csio.sense_resid, &error_code, &sense_key,
3625 &asc, &ascq, /*show_errors*/ 1);
3628 * If the drive is reporting that it just doesn't
3629 * support the defect list format, go ahead and use
3630 * the length it reported. Otherwise, the length
3631 * may not be valid, so use the maximum.
3633 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3634 && (asc == 0x1c) && (ascq == 0x00)
3635 && (returned_length > 0)) {
3636 if ((use_12byte == 0)
3637 && (returned_length >= max_possible_size)) {
3642 dlist_length = returned_length + hdr_size;
3643 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3644 && (asc == 0x1f) && (ascq == 0x00)
3645 && (returned_length > 0)) {
3646 /* Partial defect list transfer */
3648 * Hitachi drives return this error
3649 * along with a partial defect list if they
3650 * have more defects than the 10 byte
3651 * command can support. Retry with the 12
3654 if (use_12byte == 0) {
3659 dlist_length = returned_length + hdr_size;
3660 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3661 && (asc == 0x24) && (ascq == 0x00)) {
3662 /* Invalid field in CDB */
3664 * SBC-3 says that if the drive has more
3665 * defects than can be reported with the
3666 * 10 byte command, it should return this
3667 * error and no data. Retry with the 12
3670 if (use_12byte == 0) {
3675 dlist_length = returned_length + hdr_size;
3678 * If we got a SCSI error and no valid length,
3679 * just use the 10 byte maximum. The 12
3680 * byte maximum is too large.
3682 if (returned_length == 0)
3683 dlist_length = SRDD10_MAX_LENGTH;
3685 if ((use_12byte == 0)
3686 && (returned_length >=
3687 max_possible_size)) {
3692 dlist_length = returned_length +
3696 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3699 warnx("Error reading defect header");
3700 if (arglist & CAM_ARG_VERBOSE)
3701 cam_error_print(device, ccb, CAM_ESF_ALL,
3702 CAM_EPF_ALL, stderr);
3703 goto defect_bailout;
3705 if ((use_12byte == 0)
3706 && (returned_length >= max_possible_size)) {
3711 dlist_length = returned_length + hdr_size;
3714 fprintf(stdout, "%u", num_returned);
3716 fprintf(stdout, " defect%s",
3717 (num_returned != 1) ? "s" : "");
3719 fprintf(stdout, "\n");
3721 goto defect_bailout;
3725 * We always limit the list length to the 10-byte maximum
3726 * length (0xffff). The reason is that some controllers
3727 * can't handle larger I/Os, and we can transfer the entire
3728 * 10 byte list in one shot. For drives that support the 12
3729 * byte read defects command, we'll step through the list
3730 * by specifying a starting offset. For drives that don't
3731 * support the 12 byte command's starting offset, we'll
3732 * just display the first 64K.
3734 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3740 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3741 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3742 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3743 struct scsi_sense_data *sense;
3744 int error_code, sense_key, asc, ascq;
3746 sense = &ccb->csio.sense_data;
3747 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3748 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3749 &ascq, /*show_errors*/ 1);
3752 * According to the SCSI spec, if the disk doesn't support
3753 * the requested format, it will generally return a sense
3754 * key of RECOVERED ERROR, and an additional sense code
3755 * of "DEFECT LIST NOT FOUND". HGST drives also return
3756 * Primary/Grown defect list not found errors. So just
3757 * check for an ASC of 0x1c.
3759 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3761 const char *format_str;
3763 format_str = scsi_nv_to_str(defect_list_type_map,
3764 sizeof(defect_list_type_map) /
3765 sizeof(defect_list_type_map[0]),
3766 list_format & SRDD10_DLIST_FORMAT_MASK);
3767 warnx("requested defect format %s not available",
3768 format_str ? format_str : "unknown");
3770 format_str = scsi_nv_to_str(defect_list_type_map,
3771 sizeof(defect_list_type_map) /
3772 sizeof(defect_list_type_map[0]), returned_type);
3773 if (format_str != NULL) {
3774 warnx("Device returned %s format",
3778 warnx("Device returned unknown defect"
3779 " data format %#x", returned_type);
3780 goto defect_bailout;
3784 warnx("Error returned from read defect data command");
3785 if (arglist & CAM_ARG_VERBOSE)
3786 cam_error_print(device, ccb, CAM_ESF_ALL,
3787 CAM_EPF_ALL, stderr);
3788 goto defect_bailout;
3790 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3792 warnx("Error returned from read defect data command");
3793 if (arglist & CAM_ARG_VERBOSE)
3794 cam_error_print(device, ccb, CAM_ESF_ALL,
3795 CAM_EPF_ALL, stderr);
3796 goto defect_bailout;
3799 if (first_pass != 0) {
3800 fprintf(stderr, "Got %d defect", num_returned);
3802 if ((lists_specified == 0) || (num_returned == 0)) {
3803 fprintf(stderr, "s.\n");
3804 goto defect_bailout;
3805 } else if (num_returned == 1)
3806 fprintf(stderr, ":\n");
3808 fprintf(stderr, "s:\n");
3814 * XXX KDM I should probably clean up the printout format for the
3817 switch (returned_type) {
3818 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3819 case SRDD10_EXT_PHYS_FORMAT:
3821 struct scsi_defect_desc_phys_sector *dlist;
3823 dlist = (struct scsi_defect_desc_phys_sector *)
3824 (defect_list + hdr_size);
3826 for (i = 0; i < num_valid; i++) {
3829 sector = scsi_4btoul(dlist[i].sector);
3830 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3831 mads = (sector & SDD_EXT_PHYS_MADS) ?
3833 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3835 if (hex_format == 0)
3836 fprintf(stdout, "%d:%d:%d%s",
3837 scsi_3btoul(dlist[i].cylinder),
3839 scsi_4btoul(dlist[i].sector),
3840 mads ? " - " : "\n");
3842 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3843 scsi_3btoul(dlist[i].cylinder),
3845 scsi_4btoul(dlist[i].sector),
3846 mads ? " - " : "\n");
3849 if (num_valid < num_returned) {
3850 starting_offset += num_valid;
3855 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3856 case SRDD10_EXT_BFI_FORMAT:
3858 struct scsi_defect_desc_bytes_from_index *dlist;
3860 dlist = (struct scsi_defect_desc_bytes_from_index *)
3861 (defect_list + hdr_size);
3863 for (i = 0; i < num_valid; i++) {
3866 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3867 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3868 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3869 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3871 if (hex_format == 0)
3872 fprintf(stdout, "%d:%d:%d%s",
3873 scsi_3btoul(dlist[i].cylinder),
3875 scsi_4btoul(dlist[i].bytes_from_index),
3876 mads ? " - " : "\n");
3878 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3879 scsi_3btoul(dlist[i].cylinder),
3881 scsi_4btoul(dlist[i].bytes_from_index),
3882 mads ? " - " : "\n");
3886 if (num_valid < num_returned) {
3887 starting_offset += num_valid;
3892 case SRDDH10_BLOCK_FORMAT:
3894 struct scsi_defect_desc_block *dlist;
3896 dlist = (struct scsi_defect_desc_block *)
3897 (defect_list + hdr_size);
3899 for (i = 0; i < num_valid; i++) {
3900 if (hex_format == 0)
3901 fprintf(stdout, "%u\n",
3902 scsi_4btoul(dlist[i].address));
3904 fprintf(stdout, "0x%x\n",
3905 scsi_4btoul(dlist[i].address));
3908 if (num_valid < num_returned) {
3909 starting_offset += num_valid;
3915 case SRDD10_LONG_BLOCK_FORMAT:
3917 struct scsi_defect_desc_long_block *dlist;
3919 dlist = (struct scsi_defect_desc_long_block *)
3920 (defect_list + hdr_size);
3922 for (i = 0; i < num_valid; i++) {
3923 if (hex_format == 0)
3924 fprintf(stdout, "%ju\n",
3925 (uintmax_t)scsi_8btou64(
3928 fprintf(stdout, "0x%jx\n",
3929 (uintmax_t)scsi_8btou64(
3933 if (num_valid < num_returned) {
3934 starting_offset += num_valid;
3940 fprintf(stderr, "Unknown defect format 0x%x\n",
3947 if (defect_list != NULL)
3955 #endif /* MINIMALISTIC */
3959 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3963 ccb = cam_getccb(device);
3969 #ifndef MINIMALISTIC
3971 mode_sense(struct cam_device *device, int mode_page, int page_control,
3972 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3977 ccb = cam_getccb(device);
3980 errx(1, "mode_sense: couldn't allocate CCB");
3982 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3984 scsi_mode_sense(&ccb->csio,
3985 /* retries */ retry_count,
3987 /* tag_action */ MSG_SIMPLE_Q_TAG,
3989 /* page_code */ page_control << 6,
3990 /* page */ mode_page,
3991 /* param_buf */ data,
3992 /* param_len */ datalen,
3993 /* sense_len */ SSD_FULL_SIZE,
3994 /* timeout */ timeout ? timeout : 5000);
3996 if (arglist & CAM_ARG_ERR_RECOVER)
3997 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3999 /* Disable freezing the device queue */
4000 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4002 if (((retval = cam_send_ccb(device, ccb)) < 0)
4003 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4004 if (arglist & CAM_ARG_VERBOSE) {
4005 cam_error_print(device, ccb, CAM_ESF_ALL,
4006 CAM_EPF_ALL, stderr);
4009 cam_close_device(device);
4011 err(1, "error sending mode sense command");
4013 errx(1, "error sending mode sense command");
4020 mode_select(struct cam_device *device, int save_pages, int retry_count,
4021 int timeout, u_int8_t *data, int datalen)
4026 ccb = cam_getccb(device);
4029 errx(1, "mode_select: couldn't allocate CCB");
4031 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4033 scsi_mode_select(&ccb->csio,
4034 /* retries */ retry_count,
4036 /* tag_action */ MSG_SIMPLE_Q_TAG,
4037 /* scsi_page_fmt */ 1,
4038 /* save_pages */ save_pages,
4039 /* param_buf */ data,
4040 /* param_len */ datalen,
4041 /* sense_len */ SSD_FULL_SIZE,
4042 /* timeout */ timeout ? timeout : 5000);
4044 if (arglist & CAM_ARG_ERR_RECOVER)
4045 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4047 /* Disable freezing the device queue */
4048 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4050 if (((retval = cam_send_ccb(device, ccb)) < 0)
4051 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4052 if (arglist & CAM_ARG_VERBOSE) {
4053 cam_error_print(device, ccb, CAM_ESF_ALL,
4054 CAM_EPF_ALL, stderr);
4057 cam_close_device(device);
4060 err(1, "error sending mode select command");
4062 errx(1, "error sending mode select command");
4070 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4071 int retry_count, int timeout)
4073 int c, mode_page = -1, page_control = 0;
4074 int binary = 0, list = 0;
4076 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4082 arglist |= CAM_ARG_DBD;
4085 arglist |= CAM_ARG_MODE_EDIT;
4091 mode_page = strtol(optarg, NULL, 0);
4093 errx(1, "invalid mode page %d", mode_page);
4096 page_control = strtol(optarg, NULL, 0);
4097 if ((page_control < 0) || (page_control > 3))
4098 errx(1, "invalid page control field %d",
4100 arglist |= CAM_ARG_PAGE_CNTL;
4107 if (mode_page == -1 && list == 0)
4108 errx(1, "you must specify a mode page!");
4111 mode_list(device, page_control, arglist & CAM_ARG_DBD,
4112 retry_count, timeout);
4114 mode_edit(device, mode_page, page_control,
4115 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
4116 retry_count, timeout);
4121 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4122 int retry_count, int timeout)
4125 u_int32_t flags = CAM_DIR_NONE;
4126 u_int8_t *data_ptr = NULL;
4128 u_int8_t atacmd[12];
4129 struct get_hook hook;
4130 int c, data_bytes = 0;
4136 char *datastr = NULL, *tstr, *resstr = NULL;
4138 int fd_data = 0, fd_res = 0;
4141 ccb = cam_getccb(device);
4144 warnx("scsicmd: error allocating ccb");
4148 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4150 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4154 while (isspace(*tstr) && (*tstr != '\0'))
4156 hook.argc = argc - optind;
4157 hook.argv = argv + optind;
4159 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4162 * Increment optind by the number of arguments the
4163 * encoding routine processed. After each call to
4164 * getopt(3), optind points to the argument that
4165 * getopt should process _next_. In this case,
4166 * that means it points to the first command string
4167 * argument, if there is one. Once we increment
4168 * this, it should point to either the next command
4169 * line argument, or it should be past the end of
4176 while (isspace(*tstr) && (*tstr != '\0'))
4178 hook.argc = argc - optind;
4179 hook.argv = argv + optind;
4181 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4184 * Increment optind by the number of arguments the
4185 * encoding routine processed. After each call to
4186 * getopt(3), optind points to the argument that
4187 * getopt should process _next_. In this case,
4188 * that means it points to the first command string
4189 * argument, if there is one. Once we increment
4190 * this, it should point to either the next command
4191 * line argument, or it should be past the end of
4203 if (arglist & CAM_ARG_CMD_OUT) {
4204 warnx("command must either be "
4205 "read or write, not both");
4207 goto scsicmd_bailout;
4209 arglist |= CAM_ARG_CMD_IN;
4211 data_bytes = strtol(optarg, NULL, 0);
4212 if (data_bytes <= 0) {
4213 warnx("invalid number of input bytes %d",
4216 goto scsicmd_bailout;
4218 hook.argc = argc - optind;
4219 hook.argv = argv + optind;
4222 datastr = cget(&hook, NULL);
4224 * If the user supplied "-" instead of a format, he
4225 * wants the data to be written to stdout.
4227 if ((datastr != NULL)
4228 && (datastr[0] == '-'))
4231 data_ptr = (u_int8_t *)malloc(data_bytes);
4232 if (data_ptr == NULL) {
4233 warnx("can't malloc memory for data_ptr");
4235 goto scsicmd_bailout;
4239 if (arglist & CAM_ARG_CMD_IN) {
4240 warnx("command must either be "
4241 "read or write, not both");
4243 goto scsicmd_bailout;
4245 arglist |= CAM_ARG_CMD_OUT;
4246 flags = CAM_DIR_OUT;
4247 data_bytes = strtol(optarg, NULL, 0);
4248 if (data_bytes <= 0) {
4249 warnx("invalid number of output bytes %d",
4252 goto scsicmd_bailout;
4254 hook.argc = argc - optind;
4255 hook.argv = argv + optind;
4257 datastr = cget(&hook, NULL);
4258 data_ptr = (u_int8_t *)malloc(data_bytes);
4259 if (data_ptr == NULL) {
4260 warnx("can't malloc memory for data_ptr");
4262 goto scsicmd_bailout;
4264 bzero(data_ptr, data_bytes);
4266 * If the user supplied "-" instead of a format, he
4267 * wants the data to be read from stdin.
4269 if ((datastr != NULL)
4270 && (datastr[0] == '-'))
4273 buff_encode_visit(data_ptr, data_bytes, datastr,
4279 hook.argc = argc - optind;
4280 hook.argv = argv + optind;
4282 resstr = cget(&hook, NULL);
4283 if ((resstr != NULL) && (resstr[0] == '-'))
4293 * If fd_data is set, and we're writing to the device, we need to
4294 * read the data the user wants written from stdin.
4296 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4298 int amt_to_read = data_bytes;
4299 u_int8_t *buf_ptr = data_ptr;
4301 for (amt_read = 0; amt_to_read > 0;
4302 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4303 if (amt_read == -1) {
4304 warn("error reading data from stdin");
4306 goto scsicmd_bailout;
4308 amt_to_read -= amt_read;
4309 buf_ptr += amt_read;
4313 if (arglist & CAM_ARG_ERR_RECOVER)
4314 flags |= CAM_PASS_ERR_RECOVER;
4316 /* Disable freezing the device queue */
4317 flags |= CAM_DEV_QFRZDIS;
4321 * This is taken from the SCSI-3 draft spec.
4322 * (T10/1157D revision 0.3)
4323 * The top 3 bits of an opcode are the group code.
4324 * The next 5 bits are the command code.
4325 * Group 0: six byte commands
4326 * Group 1: ten byte commands
4327 * Group 2: ten byte commands
4329 * Group 4: sixteen byte commands
4330 * Group 5: twelve byte commands
4331 * Group 6: vendor specific
4332 * Group 7: vendor specific
4334 switch((cdb[0] >> 5) & 0x7) {
4345 /* computed by buff_encode_visit */
4356 * We should probably use csio_build_visit or something like that
4357 * here, but it's easier to encode arguments as you go. The
4358 * alternative would be skipping the CDB argument and then encoding
4359 * it here, since we've got the data buffer argument by now.
4361 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4363 cam_fill_csio(&ccb->csio,
4364 /*retries*/ retry_count,
4367 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4368 /*data_ptr*/ data_ptr,
4369 /*dxfer_len*/ data_bytes,
4370 /*sense_len*/ SSD_FULL_SIZE,
4371 /*cdb_len*/ cdb_len,
4372 /*timeout*/ timeout ? timeout : 5000);
4375 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4377 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4379 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4381 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4383 cam_fill_ataio(&ccb->ataio,
4384 /*retries*/ retry_count,
4388 /*data_ptr*/ data_ptr,
4389 /*dxfer_len*/ data_bytes,
4390 /*timeout*/ timeout ? timeout : 5000);
4393 if (((retval = cam_send_ccb(device, ccb)) < 0)
4394 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4395 const char warnstr[] = "error sending command";
4402 if (arglist & CAM_ARG_VERBOSE) {
4403 cam_error_print(device, ccb, CAM_ESF_ALL,
4404 CAM_EPF_ALL, stderr);
4408 goto scsicmd_bailout;
4411 if (atacmd_len && need_res) {
4413 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4415 fprintf(stdout, "\n");
4418 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4419 ccb->ataio.res.status,
4420 ccb->ataio.res.error,
4421 ccb->ataio.res.lba_low,
4422 ccb->ataio.res.lba_mid,
4423 ccb->ataio.res.lba_high,
4424 ccb->ataio.res.device,
4425 ccb->ataio.res.lba_low_exp,
4426 ccb->ataio.res.lba_mid_exp,
4427 ccb->ataio.res.lba_high_exp,
4428 ccb->ataio.res.sector_count,
4429 ccb->ataio.res.sector_count_exp);
4434 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4435 && (arglist & CAM_ARG_CMD_IN)
4436 && (data_bytes > 0)) {
4438 buff_decode_visit(data_ptr, data_bytes, datastr,
4440 fprintf(stdout, "\n");
4442 ssize_t amt_written;
4443 int amt_to_write = data_bytes;
4444 u_int8_t *buf_ptr = data_ptr;
4446 for (amt_written = 0; (amt_to_write > 0) &&
4447 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4448 amt_to_write -= amt_written;
4449 buf_ptr += amt_written;
4451 if (amt_written == -1) {
4452 warn("error writing data to stdout");
4454 goto scsicmd_bailout;
4455 } else if ((amt_written == 0)
4456 && (amt_to_write > 0)) {
4457 warnx("only wrote %u bytes out of %u",
4458 data_bytes - amt_to_write, data_bytes);
4465 if ((data_bytes > 0) && (data_ptr != NULL))
4474 camdebug(int argc, char **argv, char *combinedopt)
4477 path_id_t bus = CAM_BUS_WILDCARD;
4478 target_id_t target = CAM_TARGET_WILDCARD;
4479 lun_id_t lun = CAM_LUN_WILDCARD;
4480 char *tstr, *tmpstr = NULL;
4484 bzero(&ccb, sizeof(union ccb));
4486 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4489 arglist |= CAM_ARG_DEBUG_INFO;
4490 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4493 arglist |= CAM_ARG_DEBUG_PERIPH;
4494 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4497 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4498 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4501 arglist |= CAM_ARG_DEBUG_TRACE;
4502 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4505 arglist |= CAM_ARG_DEBUG_XPT;
4506 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4509 arglist |= CAM_ARG_DEBUG_CDB;
4510 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4513 arglist |= CAM_ARG_DEBUG_PROBE;
4514 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4521 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4522 warnx("error opening transport layer device %s", XPT_DEVICE);
4523 warn("%s", XPT_DEVICE);
4530 warnx("you must specify \"off\", \"all\" or a bus,");
4531 warnx("bus:target, or bus:target:lun");
4538 while (isspace(*tstr) && (*tstr != '\0'))
4541 if (strncmp(tstr, "off", 3) == 0) {
4542 ccb.cdbg.flags = CAM_DEBUG_NONE;
4543 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4544 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4545 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4546 } else if (strncmp(tstr, "all", 3) != 0) {
4547 tmpstr = (char *)strtok(tstr, ":");
4548 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4549 bus = strtol(tmpstr, NULL, 0);
4550 arglist |= CAM_ARG_BUS;
4551 tmpstr = (char *)strtok(NULL, ":");
4552 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4553 target = strtol(tmpstr, NULL, 0);
4554 arglist |= CAM_ARG_TARGET;
4555 tmpstr = (char *)strtok(NULL, ":");
4556 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4557 lun = strtol(tmpstr, NULL, 0);
4558 arglist |= CAM_ARG_LUN;
4563 warnx("you must specify \"all\", \"off\", or a bus,");
4564 warnx("bus:target, or bus:target:lun to debug");
4570 ccb.ccb_h.func_code = XPT_DEBUG;
4571 ccb.ccb_h.path_id = bus;
4572 ccb.ccb_h.target_id = target;
4573 ccb.ccb_h.target_lun = lun;
4575 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4576 warn("CAMIOCOMMAND ioctl failed");
4581 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4582 CAM_FUNC_NOTAVAIL) {
4583 warnx("CAM debugging not available");
4584 warnx("you need to put options CAMDEBUG in"
4585 " your kernel config file!");
4587 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4589 warnx("XPT_DEBUG CCB failed with status %#x",
4593 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4595 "Debugging turned off\n");
4598 "Debugging enabled for "
4600 bus, target, (uintmax_t)lun);
4611 tagcontrol(struct cam_device *device, int argc, char **argv,
4621 ccb = cam_getccb(device);
4624 warnx("tagcontrol: error allocating ccb");
4628 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4631 numtags = strtol(optarg, NULL, 0);
4633 warnx("tag count %d is < 0", numtags);
4635 goto tagcontrol_bailout;
4646 cam_path_string(device, pathstr, sizeof(pathstr));
4649 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4650 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4651 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4652 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4653 ccb->crs.openings = numtags;
4656 if (cam_send_ccb(device, ccb) < 0) {
4657 perror("error sending XPT_REL_SIMQ CCB");
4659 goto tagcontrol_bailout;
4662 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4663 warnx("XPT_REL_SIMQ CCB failed");
4664 cam_error_print(device, ccb, CAM_ESF_ALL,
4665 CAM_EPF_ALL, stderr);
4667 goto tagcontrol_bailout;
4672 fprintf(stdout, "%stagged openings now %d\n",
4673 pathstr, ccb->crs.openings);
4676 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4678 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4680 if (cam_send_ccb(device, ccb) < 0) {
4681 perror("error sending XPT_GDEV_STATS CCB");
4683 goto tagcontrol_bailout;
4686 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4687 warnx("XPT_GDEV_STATS CCB failed");
4688 cam_error_print(device, ccb, CAM_ESF_ALL,
4689 CAM_EPF_ALL, stderr);
4691 goto tagcontrol_bailout;
4694 if (arglist & CAM_ARG_VERBOSE) {
4695 fprintf(stdout, "%s", pathstr);
4696 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4697 fprintf(stdout, "%s", pathstr);
4698 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4699 fprintf(stdout, "%s", pathstr);
4700 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4701 fprintf(stdout, "%s", pathstr);
4702 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4703 fprintf(stdout, "%s", pathstr);
4704 fprintf(stdout, "held %d\n", ccb->cgds.held);
4705 fprintf(stdout, "%s", pathstr);
4706 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4707 fprintf(stdout, "%s", pathstr);
4708 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4711 fprintf(stdout, "%s", pathstr);
4712 fprintf(stdout, "device openings: ");
4714 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4715 ccb->cgds.dev_active);
4725 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4729 cam_path_string(device, pathstr, sizeof(pathstr));
4731 if (cts->transport == XPORT_SPI) {
4732 struct ccb_trans_settings_spi *spi =
4733 &cts->xport_specific.spi;
4735 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4737 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4740 if (spi->sync_offset != 0) {
4743 freq = scsi_calc_syncsrate(spi->sync_period);
4744 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4745 pathstr, freq / 1000, freq % 1000);
4749 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4750 fprintf(stdout, "%soffset: %d\n", pathstr,
4754 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4755 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4756 (0x01 << spi->bus_width) * 8);
4759 if (spi->valid & CTS_SPI_VALID_DISC) {
4760 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4761 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4762 "enabled" : "disabled");
4765 if (cts->transport == XPORT_FC) {
4766 struct ccb_trans_settings_fc *fc =
4767 &cts->xport_specific.fc;
4769 if (fc->valid & CTS_FC_VALID_WWNN)
4770 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4771 (long long) fc->wwnn);
4772 if (fc->valid & CTS_FC_VALID_WWPN)
4773 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4774 (long long) fc->wwpn);
4775 if (fc->valid & CTS_FC_VALID_PORT)
4776 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4777 if (fc->valid & CTS_FC_VALID_SPEED)
4778 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4779 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4781 if (cts->transport == XPORT_SAS) {
4782 struct ccb_trans_settings_sas *sas =
4783 &cts->xport_specific.sas;
4785 if (sas->valid & CTS_SAS_VALID_SPEED)
4786 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4787 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4789 if (cts->transport == XPORT_ATA) {
4790 struct ccb_trans_settings_pata *pata =
4791 &cts->xport_specific.ata;
4793 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4794 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4795 ata_mode2string(pata->mode));
4797 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4798 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4801 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4802 fprintf(stdout, "%sPIO transaction length: %d\n",
4803 pathstr, pata->bytecount);
4806 if (cts->transport == XPORT_SATA) {
4807 struct ccb_trans_settings_sata *sata =
4808 &cts->xport_specific.sata;
4810 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4811 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4814 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4815 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4816 ata_mode2string(sata->mode));
4818 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4819 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4822 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4823 fprintf(stdout, "%sPIO transaction length: %d\n",
4824 pathstr, sata->bytecount);
4826 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4827 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4830 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4831 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4834 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4835 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4839 if (cts->protocol == PROTO_ATA) {
4840 struct ccb_trans_settings_ata *ata=
4841 &cts->proto_specific.ata;
4843 if (ata->valid & CTS_ATA_VALID_TQ) {
4844 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4845 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4846 "enabled" : "disabled");
4849 if (cts->protocol == PROTO_SCSI) {
4850 struct ccb_trans_settings_scsi *scsi=
4851 &cts->proto_specific.scsi;
4853 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4854 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4855 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4856 "enabled" : "disabled");
4863 * Get a path inquiry CCB for the specified device.
4866 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4871 ccb = cam_getccb(device);
4873 warnx("get_cpi: couldn't allocate CCB");
4876 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
4877 ccb->ccb_h.func_code = XPT_PATH_INQ;
4878 if (cam_send_ccb(device, ccb) < 0) {
4879 warn("get_cpi: error sending Path Inquiry CCB");
4880 if (arglist & CAM_ARG_VERBOSE)
4881 cam_error_print(device, ccb, CAM_ESF_ALL,
4882 CAM_EPF_ALL, stderr);
4884 goto get_cpi_bailout;
4886 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4887 if (arglist & CAM_ARG_VERBOSE)
4888 cam_error_print(device, ccb, CAM_ESF_ALL,
4889 CAM_EPF_ALL, stderr);
4891 goto get_cpi_bailout;
4893 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4901 * Get a get device CCB for the specified device.
4904 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4909 ccb = cam_getccb(device);
4911 warnx("get_cgd: couldn't allocate CCB");
4914 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
4915 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4916 if (cam_send_ccb(device, ccb) < 0) {
4917 warn("get_cgd: error sending Path Inquiry CCB");
4918 if (arglist & CAM_ARG_VERBOSE)
4919 cam_error_print(device, ccb, CAM_ESF_ALL,
4920 CAM_EPF_ALL, stderr);
4922 goto get_cgd_bailout;
4924 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4925 if (arglist & CAM_ARG_VERBOSE)
4926 cam_error_print(device, ccb, CAM_ESF_ALL,
4927 CAM_EPF_ALL, stderr);
4929 goto get_cgd_bailout;
4931 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4939 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4943 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4944 int timeout, int verbosemode)
4946 union ccb *ccb = NULL;
4947 struct scsi_vpd_supported_page_list sup_pages;
4951 ccb = cam_getccb(dev);
4953 warn("Unable to allocate CCB");
4958 /* cam_getccb cleans up the header, caller has to zero the payload */
4959 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4961 bzero(&sup_pages, sizeof(sup_pages));
4963 scsi_inquiry(&ccb->csio,
4964 /*retries*/ retry_count,
4966 /* tag_action */ MSG_SIMPLE_Q_TAG,
4967 /* inq_buf */ (u_int8_t *)&sup_pages,
4968 /* inq_len */ sizeof(sup_pages),
4970 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
4971 /* sense_len */ SSD_FULL_SIZE,
4972 /* timeout */ timeout ? timeout : 5000);
4974 /* Disable freezing the device queue */
4975 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4977 if (retry_count != 0)
4978 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4980 if (cam_send_ccb(dev, ccb) < 0) {
4987 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4988 if (verbosemode != 0)
4989 cam_error_print(dev, ccb, CAM_ESF_ALL,
4990 CAM_EPF_ALL, stderr);
4995 for (i = 0; i < sup_pages.length; i++) {
4996 if (sup_pages.list[i] == page_id) {
5009 * devtype is filled in with the type of device.
5010 * Returns 0 for success, non-zero for failure.
5013 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5014 int verbosemode, camcontrol_devtype *devtype)
5016 struct ccb_getdev cgd;
5019 retval = get_cgd(dev, &cgd);
5023 switch (cgd.protocol) {
5029 *devtype = CC_DT_ATA;
5031 break; /*NOTREACHED*/
5033 *devtype = CC_DT_UNKNOWN;
5035 break; /*NOTREACHED*/
5039 * Check for the ATA Information VPD page (0x89). If this is an
5040 * ATA device behind a SCSI to ATA translation layer, this VPD page
5041 * should be present.
5043 * If that VPD page isn't present, or we get an error back from the
5044 * INQUIRY command, we'll just treat it as a normal SCSI device.
5046 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5047 timeout, verbosemode);
5049 *devtype = CC_DT_ATA_BEHIND_SCSI;
5051 *devtype = CC_DT_SCSI;
5060 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5061 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5062 uint16_t sector_count, uint64_t lba, uint8_t command, uint8_t *data_ptr,
5063 uint16_t dxfer_len, uint8_t sense_len, uint32_t timeout,
5064 int is48bit, camcontrol_devtype devtype)
5066 if (devtype == CC_DT_ATA) {
5067 cam_fill_ataio(&ccb->ataio,
5068 /*retries*/ retry_count,
5071 /*tag_action*/ tag_action,
5072 /*data_ptr*/ data_ptr,
5073 /*dxfer_len*/ dxfer_len,
5074 /*timeout*/ timeout);
5075 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5076 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5079 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5082 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5083 protocol |= AP_EXTEND;
5085 scsi_ata_pass_16(&ccb->csio,
5086 /*retries*/ retry_count,
5089 /*tag_action*/ tag_action,
5090 /*protocol*/ protocol,
5091 /*ata_flags*/ ata_flags,
5092 /*features*/ features,
5093 /*sector_count*/ sector_count,
5095 /*command*/ command,
5097 /*data_ptr*/ data_ptr,
5098 /*dxfer_len*/ dxfer_len,
5099 /*sense_len*/ sense_len,
5100 /*timeout*/ timeout);
5106 cpi_print(struct ccb_pathinq *cpi)
5108 char adapter_str[1024];
5111 snprintf(adapter_str, sizeof(adapter_str),
5112 "%s%d:", cpi->dev_name, cpi->unit_number);
5114 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5117 for (i = 1; i < 0xff; i = i << 1) {
5120 if ((i & cpi->hba_inquiry) == 0)
5123 fprintf(stdout, "%s supports ", adapter_str);
5127 str = "MDP message";
5130 str = "32 bit wide SCSI";
5133 str = "16 bit wide SCSI";
5136 str = "SDTR message";
5139 str = "linked CDBs";
5142 str = "tag queue messages";
5145 str = "soft reset alternative";
5148 str = "SATA Port Multiplier";
5151 str = "unknown PI bit set";
5154 fprintf(stdout, "%s\n", str);
5157 for (i = 1; i < 0xff; i = i << 1) {
5160 if ((i & cpi->hba_misc) == 0)
5163 fprintf(stdout, "%s ", adapter_str);
5167 str = "bus scans from high ID to low ID";
5170 str = "removable devices not included in scan";
5172 case PIM_NOINITIATOR:
5173 str = "initiator role not supported";
5175 case PIM_NOBUSRESET:
5176 str = "user has disabled initial BUS RESET or"
5177 " controller is in target/mixed mode";
5180 str = "do not send 6-byte commands";
5183 str = "scan bus sequentially";
5186 str = "unknown PIM bit set";
5189 fprintf(stdout, "%s\n", str);
5192 for (i = 1; i < 0xff; i = i << 1) {
5195 if ((i & cpi->target_sprt) == 0)
5198 fprintf(stdout, "%s supports ", adapter_str);
5201 str = "target mode processor mode";
5204 str = "target mode phase cog. mode";
5206 case PIT_DISCONNECT:
5207 str = "disconnects in target mode";
5210 str = "terminate I/O message in target mode";
5213 str = "group 6 commands in target mode";
5216 str = "group 7 commands in target mode";
5219 str = "unknown PIT bit set";
5223 fprintf(stdout, "%s\n", str);
5225 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5227 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5229 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5231 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5232 adapter_str, cpi->hpath_id);
5233 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5235 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5236 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5237 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5238 adapter_str, cpi->hba_vendor);
5239 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5240 adapter_str, cpi->hba_device);
5241 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5242 adapter_str, cpi->hba_subvendor);
5243 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5244 adapter_str, cpi->hba_subdevice);
5245 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5246 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5247 if (cpi->base_transfer_speed > 1000)
5248 fprintf(stdout, "%d.%03dMB/sec\n",
5249 cpi->base_transfer_speed / 1000,
5250 cpi->base_transfer_speed % 1000);
5252 fprintf(stdout, "%dKB/sec\n",
5253 (cpi->base_transfer_speed % 1000) * 1000);
5254 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5255 adapter_str, cpi->maxio);
5259 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5260 struct ccb_trans_settings *cts)
5266 ccb = cam_getccb(device);
5269 warnx("get_print_cts: error allocating ccb");
5273 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5275 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5277 if (user_settings == 0)
5278 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5280 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5282 if (cam_send_ccb(device, ccb) < 0) {
5283 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5284 if (arglist & CAM_ARG_VERBOSE)
5285 cam_error_print(device, ccb, CAM_ESF_ALL,
5286 CAM_EPF_ALL, stderr);
5288 goto get_print_cts_bailout;
5291 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5292 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5293 if (arglist & CAM_ARG_VERBOSE)
5294 cam_error_print(device, ccb, CAM_ESF_ALL,
5295 CAM_EPF_ALL, stderr);
5297 goto get_print_cts_bailout;
5301 cts_print(device, &ccb->cts);
5304 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5306 get_print_cts_bailout:
5314 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5315 int argc, char **argv, char *combinedopt)
5319 int user_settings = 0;
5321 int disc_enable = -1, tag_enable = -1;
5324 double syncrate = -1;
5327 int change_settings = 0, send_tur = 0;
5328 struct ccb_pathinq cpi;
5330 ccb = cam_getccb(device);
5332 warnx("ratecontrol: error allocating ccb");
5335 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5344 if (strncasecmp(optarg, "enable", 6) == 0)
5346 else if (strncasecmp(optarg, "disable", 7) == 0)
5349 warnx("-D argument \"%s\" is unknown", optarg);
5351 goto ratecontrol_bailout;
5353 change_settings = 1;
5356 mode = ata_string2mode(optarg);
5358 warnx("unknown mode '%s'", optarg);
5360 goto ratecontrol_bailout;
5362 change_settings = 1;
5365 offset = strtol(optarg, NULL, 0);
5367 warnx("offset value %d is < 0", offset);
5369 goto ratecontrol_bailout;
5371 change_settings = 1;
5377 syncrate = atof(optarg);
5379 warnx("sync rate %f is < 0", syncrate);
5381 goto ratecontrol_bailout;
5383 change_settings = 1;
5386 if (strncasecmp(optarg, "enable", 6) == 0)
5388 else if (strncasecmp(optarg, "disable", 7) == 0)
5391 warnx("-T argument \"%s\" is unknown", optarg);
5393 goto ratecontrol_bailout;
5395 change_settings = 1;
5401 bus_width = strtol(optarg, NULL, 0);
5402 if (bus_width < 0) {
5403 warnx("bus width %d is < 0", bus_width);
5405 goto ratecontrol_bailout;
5407 change_settings = 1;
5413 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5415 * Grab path inquiry information, so we can determine whether
5416 * or not the initiator is capable of the things that the user
5419 ccb->ccb_h.func_code = XPT_PATH_INQ;
5420 if (cam_send_ccb(device, ccb) < 0) {
5421 perror("error sending XPT_PATH_INQ CCB");
5422 if (arglist & CAM_ARG_VERBOSE) {
5423 cam_error_print(device, ccb, CAM_ESF_ALL,
5424 CAM_EPF_ALL, stderr);
5427 goto ratecontrol_bailout;
5429 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5430 warnx("XPT_PATH_INQ CCB failed");
5431 if (arglist & CAM_ARG_VERBOSE) {
5432 cam_error_print(device, ccb, CAM_ESF_ALL,
5433 CAM_EPF_ALL, stderr);
5436 goto ratecontrol_bailout;
5438 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5439 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5441 fprintf(stdout, "%s parameters:\n",
5442 user_settings ? "User" : "Current");
5444 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5446 goto ratecontrol_bailout;
5448 if (arglist & CAM_ARG_VERBOSE)
5451 if (change_settings) {
5452 int didsettings = 0;
5453 struct ccb_trans_settings_spi *spi = NULL;
5454 struct ccb_trans_settings_pata *pata = NULL;
5455 struct ccb_trans_settings_sata *sata = NULL;
5456 struct ccb_trans_settings_ata *ata = NULL;
5457 struct ccb_trans_settings_scsi *scsi = NULL;
5459 if (ccb->cts.transport == XPORT_SPI)
5460 spi = &ccb->cts.xport_specific.spi;
5461 if (ccb->cts.transport == XPORT_ATA)
5462 pata = &ccb->cts.xport_specific.ata;
5463 if (ccb->cts.transport == XPORT_SATA)
5464 sata = &ccb->cts.xport_specific.sata;
5465 if (ccb->cts.protocol == PROTO_ATA)
5466 ata = &ccb->cts.proto_specific.ata;
5467 if (ccb->cts.protocol == PROTO_SCSI)
5468 scsi = &ccb->cts.proto_specific.scsi;
5469 ccb->cts.xport_specific.valid = 0;
5470 ccb->cts.proto_specific.valid = 0;
5471 if (spi && disc_enable != -1) {
5472 spi->valid |= CTS_SPI_VALID_DISC;
5473 if (disc_enable == 0)
5474 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5476 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5479 if (tag_enable != -1) {
5480 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5481 warnx("HBA does not support tagged queueing, "
5482 "so you cannot modify tag settings");
5484 goto ratecontrol_bailout;
5487 ata->valid |= CTS_SCSI_VALID_TQ;
5488 if (tag_enable == 0)
5489 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5491 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5494 scsi->valid |= CTS_SCSI_VALID_TQ;
5495 if (tag_enable == 0)
5496 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5498 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5502 if (spi && offset != -1) {
5503 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5504 warnx("HBA is not capable of changing offset");
5506 goto ratecontrol_bailout;
5508 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5509 spi->sync_offset = offset;
5512 if (spi && syncrate != -1) {
5513 int prelim_sync_period;
5515 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5516 warnx("HBA is not capable of changing "
5519 goto ratecontrol_bailout;
5521 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5523 * The sync rate the user gives us is in MHz.
5524 * We need to translate it into KHz for this
5529 * Next, we calculate a "preliminary" sync period
5530 * in tenths of a nanosecond.
5533 prelim_sync_period = 0;
5535 prelim_sync_period = 10000000 / syncrate;
5537 scsi_calc_syncparam(prelim_sync_period);
5540 if (sata && syncrate != -1) {
5541 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5542 warnx("HBA is not capable of changing "
5545 goto ratecontrol_bailout;
5547 if (!user_settings) {
5548 warnx("You can modify only user rate "
5549 "settings for SATA");
5551 goto ratecontrol_bailout;
5553 sata->revision = ata_speed2revision(syncrate * 100);
5554 if (sata->revision < 0) {
5555 warnx("Invalid rate %f", syncrate);
5557 goto ratecontrol_bailout;
5559 sata->valid |= CTS_SATA_VALID_REVISION;
5562 if ((pata || sata) && mode != -1) {
5563 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5564 warnx("HBA is not capable of changing "
5567 goto ratecontrol_bailout;
5569 if (!user_settings) {
5570 warnx("You can modify only user mode "
5571 "settings for ATA/SATA");
5573 goto ratecontrol_bailout;
5577 pata->valid |= CTS_ATA_VALID_MODE;
5580 sata->valid |= CTS_SATA_VALID_MODE;
5585 * The bus_width argument goes like this:
5589 * Therefore, if you shift the number of bits given on the
5590 * command line right by 4, you should get the correct
5593 if (spi && bus_width != -1) {
5595 * We might as well validate things here with a
5596 * decipherable error message, rather than what
5597 * will probably be an indecipherable error message
5598 * by the time it gets back to us.
5600 if ((bus_width == 16)
5601 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5602 warnx("HBA does not support 16 bit bus width");
5604 goto ratecontrol_bailout;
5605 } else if ((bus_width == 32)
5606 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5607 warnx("HBA does not support 32 bit bus width");
5609 goto ratecontrol_bailout;
5610 } else if ((bus_width != 8)
5611 && (bus_width != 16)
5612 && (bus_width != 32)) {
5613 warnx("Invalid bus width %d", bus_width);
5615 goto ratecontrol_bailout;
5617 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5618 spi->bus_width = bus_width >> 4;
5621 if (didsettings == 0) {
5622 goto ratecontrol_bailout;
5624 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5625 if (cam_send_ccb(device, ccb) < 0) {
5626 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5627 if (arglist & CAM_ARG_VERBOSE) {
5628 cam_error_print(device, ccb, CAM_ESF_ALL,
5629 CAM_EPF_ALL, stderr);
5632 goto ratecontrol_bailout;
5634 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5635 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5636 if (arglist & CAM_ARG_VERBOSE) {
5637 cam_error_print(device, ccb, CAM_ESF_ALL,
5638 CAM_EPF_ALL, stderr);
5641 goto ratecontrol_bailout;
5645 retval = testunitready(device, retry_count, timeout,
5646 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5648 * If the TUR didn't succeed, just bail.
5652 fprintf(stderr, "Test Unit Ready failed\n");
5653 goto ratecontrol_bailout;
5656 if ((change_settings || send_tur) && !quiet &&
5657 (ccb->cts.transport == XPORT_ATA ||
5658 ccb->cts.transport == XPORT_SATA || send_tur)) {
5659 fprintf(stdout, "New parameters:\n");
5660 retval = get_print_cts(device, user_settings, 0, NULL);
5663 ratecontrol_bailout:
5669 scsiformat(struct cam_device *device, int argc, char **argv,
5670 char *combinedopt, int retry_count, int timeout)
5674 int ycount = 0, quiet = 0;
5675 int error = 0, retval = 0;
5676 int use_timeout = 10800 * 1000;
5678 struct format_defect_list_header fh;
5679 u_int8_t *data_ptr = NULL;
5680 u_int32_t dxfer_len = 0;
5682 int num_warnings = 0;
5685 ccb = cam_getccb(device);
5688 warnx("scsiformat: error allocating ccb");
5692 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5694 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5715 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5716 "following device:\n");
5718 error = scsidoinquiry(device, argc, argv, combinedopt,
5719 retry_count, timeout);
5722 warnx("scsiformat: error sending inquiry");
5723 goto scsiformat_bailout;
5728 if (!get_confirmation()) {
5730 goto scsiformat_bailout;
5735 use_timeout = timeout;
5738 fprintf(stdout, "Current format timeout is %d seconds\n",
5739 use_timeout / 1000);
5743 * If the user hasn't disabled questions and didn't specify a
5744 * timeout on the command line, ask them if they want the current
5748 && (timeout == 0)) {
5750 int new_timeout = 0;
5752 fprintf(stdout, "Enter new timeout in seconds or press\n"
5753 "return to keep the current timeout [%d] ",
5754 use_timeout / 1000);
5756 if (fgets(str, sizeof(str), stdin) != NULL) {
5758 new_timeout = atoi(str);
5761 if (new_timeout != 0) {
5762 use_timeout = new_timeout * 1000;
5763 fprintf(stdout, "Using new timeout value %d\n",
5764 use_timeout / 1000);
5769 * Keep this outside the if block below to silence any unused
5770 * variable warnings.
5772 bzero(&fh, sizeof(fh));
5775 * If we're in immediate mode, we've got to include the format
5778 if (immediate != 0) {
5779 fh.byte2 = FU_DLH_IMMED;
5780 data_ptr = (u_int8_t *)&fh;
5781 dxfer_len = sizeof(fh);
5782 byte2 = FU_FMT_DATA;
5783 } else if (quiet == 0) {
5784 fprintf(stdout, "Formatting...");
5788 scsi_format_unit(&ccb->csio,
5789 /* retries */ retry_count,
5791 /* tag_action */ MSG_SIMPLE_Q_TAG,
5794 /* data_ptr */ data_ptr,
5795 /* dxfer_len */ dxfer_len,
5796 /* sense_len */ SSD_FULL_SIZE,
5797 /* timeout */ use_timeout);
5799 /* Disable freezing the device queue */
5800 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5802 if (arglist & CAM_ARG_ERR_RECOVER)
5803 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5805 if (((retval = cam_send_ccb(device, ccb)) < 0)
5806 || ((immediate == 0)
5807 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5808 const char errstr[] = "error sending format command";
5815 if (arglist & CAM_ARG_VERBOSE) {
5816 cam_error_print(device, ccb, CAM_ESF_ALL,
5817 CAM_EPF_ALL, stderr);
5820 goto scsiformat_bailout;
5824 * If we ran in non-immediate mode, we already checked for errors
5825 * above and printed out any necessary information. If we're in
5826 * immediate mode, we need to loop through and get status
5827 * information periodically.
5829 if (immediate == 0) {
5831 fprintf(stdout, "Format Complete\n");
5833 goto scsiformat_bailout;
5840 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5843 * There's really no need to do error recovery or
5844 * retries here, since we're just going to sit in a
5845 * loop and wait for the device to finish formatting.
5847 scsi_test_unit_ready(&ccb->csio,
5850 /* tag_action */ MSG_SIMPLE_Q_TAG,
5851 /* sense_len */ SSD_FULL_SIZE,
5852 /* timeout */ 5000);
5854 /* Disable freezing the device queue */
5855 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5857 retval = cam_send_ccb(device, ccb);
5860 * If we get an error from the ioctl, bail out. SCSI
5861 * errors are expected.
5864 warn("error sending CAMIOCOMMAND ioctl");
5865 if (arglist & CAM_ARG_VERBOSE) {
5866 cam_error_print(device, ccb, CAM_ESF_ALL,
5867 CAM_EPF_ALL, stderr);
5870 goto scsiformat_bailout;
5873 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5875 if ((status != CAM_REQ_CMP)
5876 && (status == CAM_SCSI_STATUS_ERROR)
5877 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5878 struct scsi_sense_data *sense;
5879 int error_code, sense_key, asc, ascq;
5881 sense = &ccb->csio.sense_data;
5882 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5883 ccb->csio.sense_resid, &error_code, &sense_key,
5884 &asc, &ascq, /*show_errors*/ 1);
5887 * According to the SCSI-2 and SCSI-3 specs, a
5888 * drive that is in the middle of a format should
5889 * return NOT READY with an ASC of "logical unit
5890 * not ready, format in progress". The sense key
5891 * specific bytes will then be a progress indicator.
5893 if ((sense_key == SSD_KEY_NOT_READY)
5894 && (asc == 0x04) && (ascq == 0x04)) {
5897 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5898 ccb->csio.sense_resid, sks) == 0)
5901 u_int64_t percentage;
5903 val = scsi_2btoul(&sks[1]);
5904 percentage = 10000 * val;
5907 "\rFormatting: %ju.%02u %% "
5909 (uintmax_t)(percentage /
5911 (unsigned)((percentage /
5915 } else if ((quiet == 0)
5916 && (++num_warnings <= 1)) {
5917 warnx("Unexpected SCSI Sense Key "
5918 "Specific value returned "
5920 scsi_sense_print(device, &ccb->csio,
5922 warnx("Unable to print status "
5923 "information, but format will "
5925 warnx("will exit when format is "
5930 warnx("Unexpected SCSI error during format");
5931 cam_error_print(device, ccb, CAM_ESF_ALL,
5932 CAM_EPF_ALL, stderr);
5934 goto scsiformat_bailout;
5937 } else if (status != CAM_REQ_CMP) {
5938 warnx("Unexpected CAM status %#x", status);
5939 if (arglist & CAM_ARG_VERBOSE)
5940 cam_error_print(device, ccb, CAM_ESF_ALL,
5941 CAM_EPF_ALL, stderr);
5943 goto scsiformat_bailout;
5946 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5949 fprintf(stdout, "\nFormat Complete\n");
5959 scsisanitize(struct cam_device *device, int argc, char **argv,
5960 char *combinedopt, int retry_count, int timeout)
5963 u_int8_t action = 0;
5965 int ycount = 0, quiet = 0;
5966 int error = 0, retval = 0;
5967 int use_timeout = 10800 * 1000;
5973 const char *pattern = NULL;
5974 u_int8_t *data_ptr = NULL;
5975 u_int32_t dxfer_len = 0;
5977 int num_warnings = 0;
5980 ccb = cam_getccb(device);
5983 warnx("scsisanitize: error allocating ccb");
5987 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5989 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5992 if (strcasecmp(optarg, "overwrite") == 0)
5993 action = SSZ_SERVICE_ACTION_OVERWRITE;
5994 else if (strcasecmp(optarg, "block") == 0)
5995 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
5996 else if (strcasecmp(optarg, "crypto") == 0)
5997 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
5998 else if (strcasecmp(optarg, "exitfailure") == 0)
5999 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6001 warnx("invalid service operation \"%s\"",
6004 goto scsisanitize_bailout;
6008 passes = strtol(optarg, NULL, 0);
6009 if (passes < 1 || passes > 31) {
6010 warnx("invalid passes value %d", passes);
6012 goto scsisanitize_bailout;
6043 warnx("an action is required");
6045 goto scsisanitize_bailout;
6046 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6047 struct scsi_sanitize_parameter_list *pl;
6051 if (pattern == NULL) {
6052 warnx("overwrite action requires -P argument");
6054 goto scsisanitize_bailout;
6056 fd = open(pattern, O_RDONLY);
6058 warn("cannot open pattern file %s", pattern);
6060 goto scsisanitize_bailout;
6062 if (fstat(fd, &sb) < 0) {
6063 warn("cannot stat pattern file %s", pattern);
6065 goto scsisanitize_bailout;
6068 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6069 warnx("pattern file size exceeds maximum value %d",
6070 SSZPL_MAX_PATTERN_LENGTH);
6072 goto scsisanitize_bailout;
6074 dxfer_len = sizeof(*pl) + sz;
6075 data_ptr = calloc(1, dxfer_len);
6076 if (data_ptr == NULL) {
6077 warnx("cannot allocate parameter list buffer");
6079 goto scsisanitize_bailout;
6082 amt = read(fd, data_ptr + sizeof(*pl), sz);
6084 warn("cannot read pattern file");
6086 goto scsisanitize_bailout;
6087 } else if (amt != sz) {
6088 warnx("short pattern file read");
6090 goto scsisanitize_bailout;
6093 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6099 pl->byte1 |= SSZPL_INVERT;
6100 scsi_ulto2b(sz, pl->length);
6106 else if (invert != 0)
6108 else if (pattern != NULL)
6113 warnx("%s argument only valid with overwrite "
6116 goto scsisanitize_bailout;
6121 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6122 "following device:\n");
6124 error = scsidoinquiry(device, argc, argv, combinedopt,
6125 retry_count, timeout);
6128 warnx("scsisanitize: error sending inquiry");
6129 goto scsisanitize_bailout;
6134 if (!get_confirmation()) {
6136 goto scsisanitize_bailout;
6141 use_timeout = timeout;
6144 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6145 use_timeout / 1000);
6149 * If the user hasn't disabled questions and didn't specify a
6150 * timeout on the command line, ask them if they want the current
6154 && (timeout == 0)) {
6156 int new_timeout = 0;
6158 fprintf(stdout, "Enter new timeout in seconds or press\n"
6159 "return to keep the current timeout [%d] ",
6160 use_timeout / 1000);
6162 if (fgets(str, sizeof(str), stdin) != NULL) {
6164 new_timeout = atoi(str);
6167 if (new_timeout != 0) {
6168 use_timeout = new_timeout * 1000;
6169 fprintf(stdout, "Using new timeout value %d\n",
6170 use_timeout / 1000);
6176 byte2 |= SSZ_UNRESTRICTED_EXIT;
6180 scsi_sanitize(&ccb->csio,
6181 /* retries */ retry_count,
6183 /* tag_action */ MSG_SIMPLE_Q_TAG,
6186 /* data_ptr */ data_ptr,
6187 /* dxfer_len */ dxfer_len,
6188 /* sense_len */ SSD_FULL_SIZE,
6189 /* timeout */ use_timeout);
6191 /* Disable freezing the device queue */
6192 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6194 if (arglist & CAM_ARG_ERR_RECOVER)
6195 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6197 if (cam_send_ccb(device, ccb) < 0) {
6198 warn("error sending sanitize command");
6200 goto scsisanitize_bailout;
6203 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6204 struct scsi_sense_data *sense;
6205 int error_code, sense_key, asc, ascq;
6207 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6208 CAM_SCSI_STATUS_ERROR) {
6209 sense = &ccb->csio.sense_data;
6210 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6211 ccb->csio.sense_resid, &error_code, &sense_key,
6212 &asc, &ascq, /*show_errors*/ 1);
6214 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6215 asc == 0x20 && ascq == 0x00)
6216 warnx("sanitize is not supported by "
6219 warnx("error sanitizing this device");
6221 warnx("error sanitizing this device");
6223 if (arglist & CAM_ARG_VERBOSE) {
6224 cam_error_print(device, ccb, CAM_ESF_ALL,
6225 CAM_EPF_ALL, stderr);
6228 goto scsisanitize_bailout;
6232 * If we ran in non-immediate mode, we already checked for errors
6233 * above and printed out any necessary information. If we're in
6234 * immediate mode, we need to loop through and get status
6235 * information periodically.
6237 if (immediate == 0) {
6239 fprintf(stdout, "Sanitize Complete\n");
6241 goto scsisanitize_bailout;
6248 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6251 * There's really no need to do error recovery or
6252 * retries here, since we're just going to sit in a
6253 * loop and wait for the device to finish sanitizing.
6255 scsi_test_unit_ready(&ccb->csio,
6258 /* tag_action */ MSG_SIMPLE_Q_TAG,
6259 /* sense_len */ SSD_FULL_SIZE,
6260 /* timeout */ 5000);
6262 /* Disable freezing the device queue */
6263 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6265 retval = cam_send_ccb(device, ccb);
6268 * If we get an error from the ioctl, bail out. SCSI
6269 * errors are expected.
6272 warn("error sending CAMIOCOMMAND ioctl");
6273 if (arglist & CAM_ARG_VERBOSE) {
6274 cam_error_print(device, ccb, CAM_ESF_ALL,
6275 CAM_EPF_ALL, stderr);
6278 goto scsisanitize_bailout;
6281 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6283 if ((status != CAM_REQ_CMP)
6284 && (status == CAM_SCSI_STATUS_ERROR)
6285 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6286 struct scsi_sense_data *sense;
6287 int error_code, sense_key, asc, ascq;
6289 sense = &ccb->csio.sense_data;
6290 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6291 ccb->csio.sense_resid, &error_code, &sense_key,
6292 &asc, &ascq, /*show_errors*/ 1);
6295 * According to the SCSI-3 spec, a drive that is in the
6296 * middle of a sanitize should return NOT READY with an
6297 * ASC of "logical unit not ready, sanitize in
6298 * progress". The sense key specific bytes will then
6299 * be a progress indicator.
6301 if ((sense_key == SSD_KEY_NOT_READY)
6302 && (asc == 0x04) && (ascq == 0x1b)) {
6305 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6306 ccb->csio.sense_resid, sks) == 0)
6309 u_int64_t percentage;
6311 val = scsi_2btoul(&sks[1]);
6312 percentage = 10000 * val;
6315 "\rSanitizing: %ju.%02u %% "
6317 (uintmax_t)(percentage /
6319 (unsigned)((percentage /
6323 } else if ((quiet == 0)
6324 && (++num_warnings <= 1)) {
6325 warnx("Unexpected SCSI Sense Key "
6326 "Specific value returned "
6327 "during sanitize:");
6328 scsi_sense_print(device, &ccb->csio,
6330 warnx("Unable to print status "
6331 "information, but sanitze will "
6333 warnx("will exit when sanitize is "
6338 warnx("Unexpected SCSI error during sanitize");
6339 cam_error_print(device, ccb, CAM_ESF_ALL,
6340 CAM_EPF_ALL, stderr);
6342 goto scsisanitize_bailout;
6345 } else if (status != CAM_REQ_CMP) {
6346 warnx("Unexpected CAM status %#x", status);
6347 if (arglist & CAM_ARG_VERBOSE)
6348 cam_error_print(device, ccb, CAM_ESF_ALL,
6349 CAM_EPF_ALL, stderr);
6351 goto scsisanitize_bailout;
6353 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6356 fprintf(stdout, "\nSanitize Complete\n");
6358 scsisanitize_bailout:
6361 if (data_ptr != NULL)
6369 scsireportluns(struct cam_device *device, int argc, char **argv,
6370 char *combinedopt, int retry_count, int timeout)
6373 int c, countonly, lunsonly;
6374 struct scsi_report_luns_data *lundata;
6376 uint8_t report_type;
6377 uint32_t list_len, i, j;
6382 report_type = RPL_REPORT_DEFAULT;
6383 ccb = cam_getccb(device);
6386 warnx("%s: error allocating ccb", __func__);
6390 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6395 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6404 if (strcasecmp(optarg, "default") == 0)
6405 report_type = RPL_REPORT_DEFAULT;
6406 else if (strcasecmp(optarg, "wellknown") == 0)
6407 report_type = RPL_REPORT_WELLKNOWN;
6408 else if (strcasecmp(optarg, "all") == 0)
6409 report_type = RPL_REPORT_ALL;
6411 warnx("%s: invalid report type \"%s\"",
6422 if ((countonly != 0)
6423 && (lunsonly != 0)) {
6424 warnx("%s: you can only specify one of -c or -l", __func__);
6429 * According to SPC-4, the allocation length must be at least 16
6430 * bytes -- enough for the header and one LUN.
6432 alloc_len = sizeof(*lundata) + 8;
6436 lundata = malloc(alloc_len);
6438 if (lundata == NULL) {
6439 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6444 scsi_report_luns(&ccb->csio,
6445 /*retries*/ retry_count,
6447 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6448 /*select_report*/ report_type,
6449 /*rpl_buf*/ lundata,
6450 /*alloc_len*/ alloc_len,
6451 /*sense_len*/ SSD_FULL_SIZE,
6452 /*timeout*/ timeout ? timeout : 5000);
6454 /* Disable freezing the device queue */
6455 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6457 if (arglist & CAM_ARG_ERR_RECOVER)
6458 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6460 if (cam_send_ccb(device, ccb) < 0) {
6461 warn("error sending REPORT LUNS command");
6463 if (arglist & CAM_ARG_VERBOSE)
6464 cam_error_print(device, ccb, CAM_ESF_ALL,
6465 CAM_EPF_ALL, stderr);
6471 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6472 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6478 list_len = scsi_4btoul(lundata->length);
6481 * If we need to list the LUNs, and our allocation
6482 * length was too short, reallocate and retry.
6484 if ((countonly == 0)
6485 && (list_len > (alloc_len - sizeof(*lundata)))) {
6486 alloc_len = list_len + sizeof(*lundata);
6492 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6493 ((list_len / 8) > 1) ? "s" : "");
6498 for (i = 0; i < (list_len / 8); i++) {
6502 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6504 fprintf(stdout, ",");
6505 switch (lundata->luns[i].lundata[j] &
6506 RPL_LUNDATA_ATYP_MASK) {
6507 case RPL_LUNDATA_ATYP_PERIPH:
6508 if ((lundata->luns[i].lundata[j] &
6509 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6510 fprintf(stdout, "%d:",
6511 lundata->luns[i].lundata[j] &
6512 RPL_LUNDATA_PERIPH_BUS_MASK);
6514 && ((lundata->luns[i].lundata[j+2] &
6515 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6518 fprintf(stdout, "%d",
6519 lundata->luns[i].lundata[j+1]);
6521 case RPL_LUNDATA_ATYP_FLAT: {
6523 tmplun[0] = lundata->luns[i].lundata[j] &
6524 RPL_LUNDATA_FLAT_LUN_MASK;
6525 tmplun[1] = lundata->luns[i].lundata[j+1];
6527 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6531 case RPL_LUNDATA_ATYP_LUN:
6532 fprintf(stdout, "%d:%d:%d",
6533 (lundata->luns[i].lundata[j+1] &
6534 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6535 lundata->luns[i].lundata[j] &
6536 RPL_LUNDATA_LUN_TARG_MASK,
6537 lundata->luns[i].lundata[j+1] &
6538 RPL_LUNDATA_LUN_LUN_MASK);
6540 case RPL_LUNDATA_ATYP_EXTLUN: {
6541 int field_len_code, eam_code;
6543 eam_code = lundata->luns[i].lundata[j] &
6544 RPL_LUNDATA_EXT_EAM_MASK;
6545 field_len_code = (lundata->luns[i].lundata[j] &
6546 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6548 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6549 && (field_len_code == 0x00)) {
6550 fprintf(stdout, "%d",
6551 lundata->luns[i].lundata[j+1]);
6552 } else if ((eam_code ==
6553 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6554 && (field_len_code == 0x03)) {
6558 * This format takes up all 8 bytes.
6559 * If we aren't starting at offset 0,
6563 fprintf(stdout, "Invalid "
6566 "specified format", j);
6570 bzero(tmp_lun, sizeof(tmp_lun));
6571 bcopy(&lundata->luns[i].lundata[j+1],
6572 &tmp_lun[1], sizeof(tmp_lun) - 1);
6573 fprintf(stdout, "%#jx",
6574 (intmax_t)scsi_8btou64(tmp_lun));
6577 fprintf(stderr, "Unknown Extended LUN"
6578 "Address method %#x, length "
6579 "code %#x", eam_code,
6586 fprintf(stderr, "Unknown LUN address method "
6587 "%#x\n", lundata->luns[i].lundata[0] &
6588 RPL_LUNDATA_ATYP_MASK);
6592 * For the flat addressing method, there are no
6593 * other levels after it.
6598 fprintf(stdout, "\n");
6611 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6612 char *combinedopt, int retry_count, int timeout)
6615 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6616 struct scsi_read_capacity_data rcap;
6617 struct scsi_read_capacity_data_long rcaplong;
6631 ccb = cam_getccb(device);
6634 warnx("%s: error allocating ccb", __func__);
6638 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6640 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6667 if ((blocksizeonly != 0)
6668 && (numblocks != 0)) {
6669 warnx("%s: you can only specify one of -b or -N", __func__);
6674 if ((blocksizeonly != 0)
6675 && (sizeonly != 0)) {
6676 warnx("%s: you can only specify one of -b or -s", __func__);
6683 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6689 && (blocksizeonly != 0)) {
6690 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6695 scsi_read_capacity(&ccb->csio,
6696 /*retries*/ retry_count,
6698 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6701 /*timeout*/ timeout ? timeout : 5000);
6703 /* Disable freezing the device queue */
6704 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6706 if (arglist & CAM_ARG_ERR_RECOVER)
6707 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6709 if (cam_send_ccb(device, ccb) < 0) {
6710 warn("error sending READ CAPACITY command");
6712 if (arglist & CAM_ARG_VERBOSE)
6713 cam_error_print(device, ccb, CAM_ESF_ALL,
6714 CAM_EPF_ALL, stderr);
6720 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6721 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6726 maxsector = scsi_4btoul(rcap.addr);
6727 block_len = scsi_4btoul(rcap.length);
6730 * A last block of 2^32-1 means that the true capacity is over 2TB,
6731 * and we need to issue the long READ CAPACITY to get the real
6732 * capacity. Otherwise, we're all set.
6734 if (maxsector != 0xffffffff)
6737 scsi_read_capacity_16(&ccb->csio,
6738 /*retries*/ retry_count,
6740 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6744 /*rcap_buf*/ (uint8_t *)&rcaplong,
6745 /*rcap_buf_len*/ sizeof(rcaplong),
6746 /*sense_len*/ SSD_FULL_SIZE,
6747 /*timeout*/ timeout ? timeout : 5000);
6749 /* Disable freezing the device queue */
6750 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6752 if (arglist & CAM_ARG_ERR_RECOVER)
6753 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6755 if (cam_send_ccb(device, ccb) < 0) {
6756 warn("error sending READ CAPACITY (16) command");
6758 if (arglist & CAM_ARG_VERBOSE)
6759 cam_error_print(device, ccb, CAM_ESF_ALL,
6760 CAM_EPF_ALL, stderr);
6766 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6767 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6772 maxsector = scsi_8btou64(rcaplong.addr);
6773 block_len = scsi_4btoul(rcaplong.length);
6776 if (blocksizeonly == 0) {
6778 * Humanize implies !quiet, and also implies numblocks.
6780 if (humanize != 0) {
6785 tmpbytes = (maxsector + 1) * block_len;
6786 ret = humanize_number(tmpstr, sizeof(tmpstr),
6787 tmpbytes, "", HN_AUTOSCALE,
6790 HN_DIVISOR_1000 : 0));
6792 warnx("%s: humanize_number failed!", __func__);
6796 fprintf(stdout, "Device Size: %s%s", tmpstr,
6797 (sizeonly == 0) ? ", " : "\n");
6798 } else if (numblocks != 0) {
6799 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6800 "Blocks: " : "", (uintmax_t)maxsector + 1,
6801 (sizeonly == 0) ? ", " : "\n");
6803 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6804 "Last Block: " : "", (uintmax_t)maxsector,
6805 (sizeonly == 0) ? ", " : "\n");
6809 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6810 "Block Length: " : "", block_len, (quiet == 0) ?
6819 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6820 int retry_count, int timeout)
6824 uint8_t *smp_request = NULL, *smp_response = NULL;
6825 int request_size = 0, response_size = 0;
6826 int fd_request = 0, fd_response = 0;
6827 char *datastr = NULL;
6828 struct get_hook hook;
6833 * Note that at the moment we don't support sending SMP CCBs to
6834 * devices that aren't probed by CAM.
6836 ccb = cam_getccb(device);
6838 warnx("%s: error allocating CCB", __func__);
6842 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
6844 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6847 arglist |= CAM_ARG_CMD_IN;
6848 response_size = strtol(optarg, NULL, 0);
6849 if (response_size <= 0) {
6850 warnx("invalid number of response bytes %d",
6853 goto smpcmd_bailout;
6855 hook.argc = argc - optind;
6856 hook.argv = argv + optind;
6859 datastr = cget(&hook, NULL);
6861 * If the user supplied "-" instead of a format, he
6862 * wants the data to be written to stdout.
6864 if ((datastr != NULL)
6865 && (datastr[0] == '-'))
6868 smp_response = (u_int8_t *)malloc(response_size);
6869 if (smp_response == NULL) {
6870 warn("can't malloc memory for SMP response");
6872 goto smpcmd_bailout;
6876 arglist |= CAM_ARG_CMD_OUT;
6877 request_size = strtol(optarg, NULL, 0);
6878 if (request_size <= 0) {
6879 warnx("invalid number of request bytes %d",
6882 goto smpcmd_bailout;
6884 hook.argc = argc - optind;
6885 hook.argv = argv + optind;
6887 datastr = cget(&hook, NULL);
6888 smp_request = (u_int8_t *)malloc(request_size);
6889 if (smp_request == NULL) {
6890 warn("can't malloc memory for SMP request");
6892 goto smpcmd_bailout;
6894 bzero(smp_request, request_size);
6896 * If the user supplied "-" instead of a format, he
6897 * wants the data to be read from stdin.
6899 if ((datastr != NULL)
6900 && (datastr[0] == '-'))
6903 buff_encode_visit(smp_request, request_size,
6914 * If fd_data is set, and we're writing to the device, we need to
6915 * read the data the user wants written from stdin.
6917 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6919 int amt_to_read = request_size;
6920 u_int8_t *buf_ptr = smp_request;
6922 for (amt_read = 0; amt_to_read > 0;
6923 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6924 if (amt_read == -1) {
6925 warn("error reading data from stdin");
6927 goto smpcmd_bailout;
6929 amt_to_read -= amt_read;
6930 buf_ptr += amt_read;
6934 if (((arglist & CAM_ARG_CMD_IN) == 0)
6935 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6936 warnx("%s: need both the request (-r) and response (-R) "
6937 "arguments", __func__);
6939 goto smpcmd_bailout;
6942 flags |= CAM_DEV_QFRZDIS;
6944 cam_fill_smpio(&ccb->smpio,
6945 /*retries*/ retry_count,
6948 /*smp_request*/ smp_request,
6949 /*smp_request_len*/ request_size,
6950 /*smp_response*/ smp_response,
6951 /*smp_response_len*/ response_size,
6952 /*timeout*/ timeout ? timeout : 5000);
6954 ccb->smpio.flags = SMP_FLAG_NONE;
6956 if (((retval = cam_send_ccb(device, ccb)) < 0)
6957 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6958 const char warnstr[] = "error sending command";
6965 if (arglist & CAM_ARG_VERBOSE) {
6966 cam_error_print(device, ccb, CAM_ESF_ALL,
6967 CAM_EPF_ALL, stderr);
6971 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6972 && (response_size > 0)) {
6973 if (fd_response == 0) {
6974 buff_decode_visit(smp_response, response_size,
6975 datastr, arg_put, NULL);
6976 fprintf(stdout, "\n");
6978 ssize_t amt_written;
6979 int amt_to_write = response_size;
6980 u_int8_t *buf_ptr = smp_response;
6982 for (amt_written = 0; (amt_to_write > 0) &&
6983 (amt_written = write(STDOUT_FILENO, buf_ptr,
6984 amt_to_write)) > 0;){
6985 amt_to_write -= amt_written;
6986 buf_ptr += amt_written;
6988 if (amt_written == -1) {
6989 warn("error writing data to stdout");
6991 goto smpcmd_bailout;
6992 } else if ((amt_written == 0)
6993 && (amt_to_write > 0)) {
6994 warnx("only wrote %u bytes out of %u",
6995 response_size - amt_to_write,
7004 if (smp_request != NULL)
7007 if (smp_response != NULL)
7014 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7015 char *combinedopt, int retry_count, int timeout)
7018 struct smp_report_general_request *request = NULL;
7019 struct smp_report_general_response *response = NULL;
7020 struct sbuf *sb = NULL;
7022 int c, long_response = 0;
7026 * Note that at the moment we don't support sending SMP CCBs to
7027 * devices that aren't probed by CAM.
7029 ccb = cam_getccb(device);
7031 warnx("%s: error allocating CCB", __func__);
7035 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7037 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7046 request = malloc(sizeof(*request));
7047 if (request == NULL) {
7048 warn("%s: unable to allocate %zd bytes", __func__,
7054 response = malloc(sizeof(*response));
7055 if (response == NULL) {
7056 warn("%s: unable to allocate %zd bytes", __func__,
7063 smp_report_general(&ccb->smpio,
7067 /*request_len*/ sizeof(*request),
7068 (uint8_t *)response,
7069 /*response_len*/ sizeof(*response),
7070 /*long_response*/ long_response,
7073 if (((retval = cam_send_ccb(device, ccb)) < 0)
7074 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7075 const char warnstr[] = "error sending command";
7082 if (arglist & CAM_ARG_VERBOSE) {
7083 cam_error_print(device, ccb, CAM_ESF_ALL,
7084 CAM_EPF_ALL, stderr);
7091 * If the device supports the long response bit, try again and see
7092 * if we can get all of the data.
7094 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7095 && (long_response == 0)) {
7096 ccb->ccb_h.status = CAM_REQ_INPROG;
7097 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7103 * XXX KDM detect and decode SMP errors here.
7105 sb = sbuf_new_auto();
7107 warnx("%s: error allocating sbuf", __func__);
7111 smp_report_general_sbuf(response, sizeof(*response), sb);
7113 if (sbuf_finish(sb) != 0) {
7114 warnx("%s: sbuf_finish", __func__);
7118 printf("%s", sbuf_data(sb));
7124 if (request != NULL)
7127 if (response != NULL)
7136 static struct camcontrol_opts phy_ops[] = {
7137 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7138 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7139 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7140 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7141 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7142 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7143 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7144 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7145 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7150 smpphycontrol(struct cam_device *device, int argc, char **argv,
7151 char *combinedopt, int retry_count, int timeout)
7154 struct smp_phy_control_request *request = NULL;
7155 struct smp_phy_control_response *response = NULL;
7156 int long_response = 0;
7159 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7161 uint64_t attached_dev_name = 0;
7162 int dev_name_set = 0;
7163 uint32_t min_plr = 0, max_plr = 0;
7164 uint32_t pp_timeout_val = 0;
7165 int slumber_partial = 0;
7166 int set_pp_timeout_val = 0;
7170 * Note that at the moment we don't support sending SMP CCBs to
7171 * devices that aren't probed by CAM.
7173 ccb = cam_getccb(device);
7175 warnx("%s: error allocating CCB", __func__);
7179 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7181 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7189 if (strcasecmp(optarg, "enable") == 0)
7191 else if (strcasecmp(optarg, "disable") == 0)
7194 warnx("%s: Invalid argument %s", __func__,
7201 slumber_partial |= enable <<
7202 SMP_PC_SAS_SLUMBER_SHIFT;
7205 slumber_partial |= enable <<
7206 SMP_PC_SAS_PARTIAL_SHIFT;
7209 slumber_partial |= enable <<
7210 SMP_PC_SATA_SLUMBER_SHIFT;
7213 slumber_partial |= enable <<
7214 SMP_PC_SATA_PARTIAL_SHIFT;
7217 warnx("%s: programmer error", __func__);
7220 break; /*NOTREACHED*/
7225 attached_dev_name = (uintmax_t)strtoumax(optarg,
7234 * We don't do extensive checking here, so this
7235 * will continue to work when new speeds come out.
7237 min_plr = strtoul(optarg, NULL, 0);
7239 || (min_plr > 0xf)) {
7240 warnx("%s: invalid link rate %x",
7248 * We don't do extensive checking here, so this
7249 * will continue to work when new speeds come out.
7251 max_plr = strtoul(optarg, NULL, 0);
7253 || (max_plr > 0xf)) {
7254 warnx("%s: invalid link rate %x",
7261 camcontrol_optret optreturn;
7262 cam_argmask argnums;
7265 if (phy_op_set != 0) {
7266 warnx("%s: only one phy operation argument "
7267 "(-o) allowed", __func__);
7275 * Allow the user to specify the phy operation
7276 * numerically, as well as with a name. This will
7277 * future-proof it a bit, so options that are added
7278 * in future specs can be used.
7280 if (isdigit(optarg[0])) {
7281 phy_operation = strtoul(optarg, NULL, 0);
7282 if ((phy_operation == 0)
7283 || (phy_operation > 0xff)) {
7284 warnx("%s: invalid phy operation %#x",
7285 __func__, phy_operation);
7291 optreturn = getoption(phy_ops, optarg, &phy_operation,
7294 if (optreturn == CC_OR_AMBIGUOUS) {
7295 warnx("%s: ambiguous option %s", __func__,
7300 } else if (optreturn == CC_OR_NOT_FOUND) {
7301 warnx("%s: option %s not found", __func__,
7313 pp_timeout_val = strtoul(optarg, NULL, 0);
7314 if (pp_timeout_val > 15) {
7315 warnx("%s: invalid partial pathway timeout "
7316 "value %u, need a value less than 16",
7317 __func__, pp_timeout_val);
7321 set_pp_timeout_val = 1;
7329 warnx("%s: a PHY (-p phy) argument is required",__func__);
7334 if (((dev_name_set != 0)
7335 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7336 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7337 && (dev_name_set == 0))) {
7338 warnx("%s: -d name and -o setdevname arguments both "
7339 "required to set device name", __func__);
7344 request = malloc(sizeof(*request));
7345 if (request == NULL) {
7346 warn("%s: unable to allocate %zd bytes", __func__,
7352 response = malloc(sizeof(*response));
7353 if (response == NULL) {
7354 warn("%s: unable to allocate %zd bytes", __func__,
7360 smp_phy_control(&ccb->smpio,
7365 (uint8_t *)response,
7368 /*expected_exp_change_count*/ 0,
7371 (set_pp_timeout_val != 0) ? 1 : 0,
7379 if (((retval = cam_send_ccb(device, ccb)) < 0)
7380 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7381 const char warnstr[] = "error sending command";
7388 if (arglist & CAM_ARG_VERBOSE) {
7390 * Use CAM_EPF_NORMAL so we only get one line of
7391 * SMP command decoding.
7393 cam_error_print(device, ccb, CAM_ESF_ALL,
7394 CAM_EPF_NORMAL, stderr);
7400 /* XXX KDM print out something here for success? */
7405 if (request != NULL)
7408 if (response != NULL)
7415 smpmaninfo(struct cam_device *device, int argc, char **argv,
7416 char *combinedopt, int retry_count, int timeout)
7419 struct smp_report_manuf_info_request request;
7420 struct smp_report_manuf_info_response response;
7421 struct sbuf *sb = NULL;
7422 int long_response = 0;
7427 * Note that at the moment we don't support sending SMP CCBs to
7428 * devices that aren't probed by CAM.
7430 ccb = cam_getccb(device);
7432 warnx("%s: error allocating CCB", __func__);
7436 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7438 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7447 bzero(&request, sizeof(request));
7448 bzero(&response, sizeof(response));
7450 smp_report_manuf_info(&ccb->smpio,
7455 (uint8_t *)&response,
7460 if (((retval = cam_send_ccb(device, ccb)) < 0)
7461 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7462 const char warnstr[] = "error sending command";
7469 if (arglist & CAM_ARG_VERBOSE) {
7470 cam_error_print(device, ccb, CAM_ESF_ALL,
7471 CAM_EPF_ALL, stderr);
7477 sb = sbuf_new_auto();
7479 warnx("%s: error allocating sbuf", __func__);
7483 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7485 if (sbuf_finish(sb) != 0) {
7486 warnx("%s: sbuf_finish", __func__);
7490 printf("%s", sbuf_data(sb));
7504 getdevid(struct cam_devitem *item)
7507 union ccb *ccb = NULL;
7509 struct cam_device *dev;
7511 dev = cam_open_btl(item->dev_match.path_id,
7512 item->dev_match.target_id,
7513 item->dev_match.target_lun, O_RDWR, NULL);
7516 warnx("%s", cam_errbuf);
7521 item->device_id_len = 0;
7523 ccb = cam_getccb(dev);
7525 warnx("%s: error allocating CCB", __func__);
7530 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7533 * On the first try, we just probe for the size of the data, and
7534 * then allocate that much memory and try again.
7537 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7538 ccb->ccb_h.flags = CAM_DIR_IN;
7539 ccb->cdai.flags = CDAI_FLAG_NONE;
7540 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7541 ccb->cdai.bufsiz = item->device_id_len;
7542 if (item->device_id_len != 0)
7543 ccb->cdai.buf = (uint8_t *)item->device_id;
7545 if (cam_send_ccb(dev, ccb) < 0) {
7546 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7551 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7552 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7557 if (item->device_id_len == 0) {
7559 * This is our first time through. Allocate the buffer,
7560 * and then go back to get the data.
7562 if (ccb->cdai.provsiz == 0) {
7563 warnx("%s: invalid .provsiz field returned with "
7564 "XPT_GDEV_ADVINFO CCB", __func__);
7568 item->device_id_len = ccb->cdai.provsiz;
7569 item->device_id = malloc(item->device_id_len);
7570 if (item->device_id == NULL) {
7571 warn("%s: unable to allocate %d bytes", __func__,
7572 item->device_id_len);
7576 ccb->ccb_h.status = CAM_REQ_INPROG;
7582 cam_close_device(dev);
7591 * XXX KDM merge this code with getdevtree()?
7594 buildbusdevlist(struct cam_devlist *devlist)
7597 int bufsize, fd = -1;
7598 struct dev_match_pattern *patterns;
7599 struct cam_devitem *item = NULL;
7600 int skip_device = 0;
7603 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7604 warn("couldn't open %s", XPT_DEVICE);
7608 bzero(&ccb, sizeof(union ccb));
7610 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7611 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7612 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7614 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7615 bufsize = sizeof(struct dev_match_result) * 100;
7616 ccb.cdm.match_buf_len = bufsize;
7617 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7618 if (ccb.cdm.matches == NULL) {
7619 warnx("can't malloc memory for matches");
7623 ccb.cdm.num_matches = 0;
7624 ccb.cdm.num_patterns = 2;
7625 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7626 ccb.cdm.num_patterns;
7628 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7629 if (patterns == NULL) {
7630 warnx("can't malloc memory for patterns");
7635 ccb.cdm.patterns = patterns;
7636 bzero(patterns, ccb.cdm.pattern_buf_len);
7638 patterns[0].type = DEV_MATCH_DEVICE;
7639 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7640 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7641 patterns[1].type = DEV_MATCH_PERIPH;
7642 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7643 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7646 * We do the ioctl multiple times if necessary, in case there are
7647 * more than 100 nodes in the EDT.
7652 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7653 warn("error sending CAMIOCOMMAND ioctl");
7658 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7659 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7660 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7661 warnx("got CAM error %#x, CDM error %d\n",
7662 ccb.ccb_h.status, ccb.cdm.status);
7667 for (i = 0; i < ccb.cdm.num_matches; i++) {
7668 switch (ccb.cdm.matches[i].type) {
7669 case DEV_MATCH_DEVICE: {
7670 struct device_match_result *dev_result;
7673 &ccb.cdm.matches[i].result.device_result;
7675 if (dev_result->flags &
7676 DEV_RESULT_UNCONFIGURED) {
7682 item = malloc(sizeof(*item));
7684 warn("%s: unable to allocate %zd bytes",
7685 __func__, sizeof(*item));
7689 bzero(item, sizeof(*item));
7690 bcopy(dev_result, &item->dev_match,
7691 sizeof(*dev_result));
7692 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7695 if (getdevid(item) != 0) {
7701 case DEV_MATCH_PERIPH: {
7702 struct periph_match_result *periph_result;
7705 &ccb.cdm.matches[i].result.periph_result;
7707 if (skip_device != 0)
7709 item->num_periphs++;
7710 item->periph_matches = realloc(
7711 item->periph_matches,
7713 sizeof(struct periph_match_result));
7714 if (item->periph_matches == NULL) {
7715 warn("%s: error allocating periph "
7720 bcopy(periph_result, &item->periph_matches[
7721 item->num_periphs - 1],
7722 sizeof(*periph_result));
7726 fprintf(stderr, "%s: unexpected match "
7727 "type %d\n", __func__,
7728 ccb.cdm.matches[i].type);
7731 break; /*NOTREACHED*/
7734 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7735 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7743 free(ccb.cdm.matches);
7746 freebusdevlist(devlist);
7752 freebusdevlist(struct cam_devlist *devlist)
7754 struct cam_devitem *item, *item2;
7756 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7757 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7759 free(item->device_id);
7760 free(item->periph_matches);
7765 static struct cam_devitem *
7766 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7768 struct cam_devitem *item;
7770 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7771 struct scsi_vpd_id_descriptor *idd;
7774 * XXX KDM look for LUN IDs as well?
7776 idd = scsi_get_devid(item->device_id,
7777 item->device_id_len,
7778 scsi_devid_is_sas_target);
7782 if (scsi_8btou64(idd->identifier) == sasaddr)
7790 smpphylist(struct cam_device *device, int argc, char **argv,
7791 char *combinedopt, int retry_count, int timeout)
7793 struct smp_report_general_request *rgrequest = NULL;
7794 struct smp_report_general_response *rgresponse = NULL;
7795 struct smp_discover_request *disrequest = NULL;
7796 struct smp_discover_response *disresponse = NULL;
7797 struct cam_devlist devlist;
7799 int long_response = 0;
7806 * Note that at the moment we don't support sending SMP CCBs to
7807 * devices that aren't probed by CAM.
7809 ccb = cam_getccb(device);
7811 warnx("%s: error allocating CCB", __func__);
7815 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7816 STAILQ_INIT(&devlist.dev_queue);
7818 rgrequest = malloc(sizeof(*rgrequest));
7819 if (rgrequest == NULL) {
7820 warn("%s: unable to allocate %zd bytes", __func__,
7821 sizeof(*rgrequest));
7826 rgresponse = malloc(sizeof(*rgresponse));
7827 if (rgresponse == NULL) {
7828 warn("%s: unable to allocate %zd bytes", __func__,
7829 sizeof(*rgresponse));
7834 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7847 smp_report_general(&ccb->smpio,
7851 /*request_len*/ sizeof(*rgrequest),
7852 (uint8_t *)rgresponse,
7853 /*response_len*/ sizeof(*rgresponse),
7854 /*long_response*/ long_response,
7857 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7859 if (((retval = cam_send_ccb(device, ccb)) < 0)
7860 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7861 const char warnstr[] = "error sending command";
7868 if (arglist & CAM_ARG_VERBOSE) {
7869 cam_error_print(device, ccb, CAM_ESF_ALL,
7870 CAM_EPF_ALL, stderr);
7876 num_phys = rgresponse->num_phys;
7878 if (num_phys == 0) {
7880 fprintf(stdout, "%s: No Phys reported\n", __func__);
7885 devlist.path_id = device->path_id;
7887 retval = buildbusdevlist(&devlist);
7892 fprintf(stdout, "%d PHYs:\n", num_phys);
7893 fprintf(stdout, "PHY Attached SAS Address\n");
7896 disrequest = malloc(sizeof(*disrequest));
7897 if (disrequest == NULL) {
7898 warn("%s: unable to allocate %zd bytes", __func__,
7899 sizeof(*disrequest));
7904 disresponse = malloc(sizeof(*disresponse));
7905 if (disresponse == NULL) {
7906 warn("%s: unable to allocate %zd bytes", __func__,
7907 sizeof(*disresponse));
7912 for (i = 0; i < num_phys; i++) {
7913 struct cam_devitem *item;
7914 struct device_match_result *dev_match;
7915 char vendor[16], product[48], revision[16];
7919 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7921 ccb->ccb_h.status = CAM_REQ_INPROG;
7922 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7924 smp_discover(&ccb->smpio,
7928 sizeof(*disrequest),
7929 (uint8_t *)disresponse,
7930 sizeof(*disresponse),
7932 /*ignore_zone_group*/ 0,
7936 if (((retval = cam_send_ccb(device, ccb)) < 0)
7937 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7938 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7939 const char warnstr[] = "error sending command";
7946 if (arglist & CAM_ARG_VERBOSE) {
7947 cam_error_print(device, ccb, CAM_ESF_ALL,
7948 CAM_EPF_ALL, stderr);
7954 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7956 fprintf(stdout, "%3d <vacant>\n", i);
7960 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7963 item = findsasdevice(&devlist,
7964 scsi_8btou64(disresponse->attached_sas_address));
7968 || (item != NULL)) {
7969 fprintf(stdout, "%3d 0x%016jx", i,
7970 (uintmax_t)scsi_8btou64(
7971 disresponse->attached_sas_address));
7973 fprintf(stdout, "\n");
7976 } else if (quiet != 0)
7979 dev_match = &item->dev_match;
7981 if (dev_match->protocol == PROTO_SCSI) {
7982 cam_strvis(vendor, dev_match->inq_data.vendor,
7983 sizeof(dev_match->inq_data.vendor),
7985 cam_strvis(product, dev_match->inq_data.product,
7986 sizeof(dev_match->inq_data.product),
7988 cam_strvis(revision, dev_match->inq_data.revision,
7989 sizeof(dev_match->inq_data.revision),
7991 sprintf(tmpstr, "<%s %s %s>", vendor, product,
7993 } else if ((dev_match->protocol == PROTO_ATA)
7994 || (dev_match->protocol == PROTO_SATAPM)) {
7995 cam_strvis(product, dev_match->ident_data.model,
7996 sizeof(dev_match->ident_data.model),
7998 cam_strvis(revision, dev_match->ident_data.revision,
7999 sizeof(dev_match->ident_data.revision),
8001 sprintf(tmpstr, "<%s %s>", product, revision);
8003 sprintf(tmpstr, "<>");
8005 fprintf(stdout, " %-33s ", tmpstr);
8008 * If we have 0 periphs, that's a bug...
8010 if (item->num_periphs == 0) {
8011 fprintf(stdout, "\n");
8015 fprintf(stdout, "(");
8016 for (j = 0; j < item->num_periphs; j++) {
8018 fprintf(stdout, ",");
8020 fprintf(stdout, "%s%d",
8021 item->periph_matches[j].periph_name,
8022 item->periph_matches[j].unit_number);
8025 fprintf(stdout, ")\n");
8039 freebusdevlist(&devlist);
8045 atapm(struct cam_device *device, int argc, char **argv,
8046 char *combinedopt, int retry_count, int timeout)
8054 ccb = cam_getccb(device);
8057 warnx("%s: error allocating ccb", __func__);
8061 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8070 if (strcmp(argv[1], "idle") == 0) {
8072 cmd = ATA_IDLE_IMMEDIATE;
8075 } else if (strcmp(argv[1], "standby") == 0) {
8077 cmd = ATA_STANDBY_IMMEDIATE;
8079 cmd = ATA_STANDBY_CMD;
8087 else if (t <= (240 * 5))
8089 else if (t <= (252 * 5))
8090 /* special encoding for 21 minutes */
8092 else if (t <= (11 * 30 * 60))
8093 sc = (t - 1) / (30 * 60) + 241;
8097 retval = ata_do_28bit_cmd(device,
8099 /*retries*/retry_count,
8100 /*flags*/CAM_DIR_NONE,
8101 /*protocol*/AP_PROTO_NON_DATA,
8102 /*tag_action*/MSG_SIMPLE_Q_TAG,
8109 /*timeout*/timeout ? timeout : 30 * 1000,
8117 ataaxm(struct cam_device *device, int argc, char **argv,
8118 char *combinedopt, int retry_count, int timeout)
8126 ccb = cam_getccb(device);
8129 warnx("%s: error allocating ccb", __func__);
8133 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8143 if (strcmp(argv[1], "apm") == 0) {
8159 retval = ata_do_28bit_cmd(device,
8161 /*retries*/retry_count,
8162 /*flags*/CAM_DIR_NONE,
8163 /*protocol*/AP_PROTO_NON_DATA,
8164 /*tag_action*/MSG_SIMPLE_Q_TAG,
8165 /*command*/ATA_SETFEATURES,
8171 /*timeout*/timeout ? timeout : 30 * 1000,
8179 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8180 int show_sa_errors, int sa_set, int service_action,
8181 int timeout_desc, int retry_count, int timeout, int verbosemode,
8182 uint32_t *fill_len, uint8_t **data_ptr)
8184 union ccb *ccb = NULL;
8185 uint8_t *buf = NULL;
8186 uint32_t alloc_len = 0, num_opcodes;
8187 uint32_t valid_len = 0;
8188 uint32_t avail_len = 0;
8189 struct scsi_report_supported_opcodes_all *all_hdr;
8190 struct scsi_report_supported_opcodes_one *one;
8195 * Make it clear that we haven't yet allocated or filled anything.
8200 ccb = cam_getccb(device);
8202 warnx("couldn't allocate CCB");
8207 /* cam_getccb cleans up the header, caller has to zero the payload */
8208 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8210 if (opcode_set != 0) {
8211 options |= RSO_OPTIONS_OC;
8213 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8216 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8217 sizeof(struct scsi_report_supported_opcodes_descr));
8220 if (timeout_desc != 0) {
8221 options |= RSO_RCTD;
8222 alloc_len += num_opcodes *
8223 sizeof(struct scsi_report_supported_opcodes_timeout);
8227 options |= RSO_OPTIONS_OC_SA;
8228 if (show_sa_errors != 0)
8229 options &= ~RSO_OPTIONS_OC;
8238 buf = malloc(alloc_len);
8240 warn("Unable to allocate %u bytes", alloc_len);
8244 bzero(buf, alloc_len);
8246 scsi_report_supported_opcodes(&ccb->csio,
8247 /*retries*/ retry_count,
8249 /*tag_action*/ MSG_SIMPLE_Q_TAG,
8250 /*options*/ options,
8251 /*req_opcode*/ opcode,
8252 /*req_service_action*/ service_action,
8254 /*dxfer_len*/ alloc_len,
8255 /*sense_len*/ SSD_FULL_SIZE,
8256 /*timeout*/ timeout ? timeout : 10000);
8258 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8260 if (retry_count != 0)
8261 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8263 if (cam_send_ccb(device, ccb) < 0) {
8264 perror("error sending REPORT SUPPORTED OPERATION CODES");
8269 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8270 if (verbosemode != 0)
8271 cam_error_print(device, ccb, CAM_ESF_ALL,
8272 CAM_EPF_ALL, stderr);
8278 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8280 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8281 && (valid_len >= sizeof(*all_hdr))) {
8282 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8283 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8284 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8285 && (valid_len >= sizeof(*one))) {
8286 uint32_t cdb_length;
8288 one = (struct scsi_report_supported_opcodes_one *)buf;
8289 cdb_length = scsi_2btoul(one->cdb_length);
8290 avail_len = sizeof(*one) + cdb_length;
8291 if (one->support & RSO_ONE_CTDP) {
8292 struct scsi_report_supported_opcodes_timeout *td;
8294 td = (struct scsi_report_supported_opcodes_timeout *)
8296 if (valid_len >= (avail_len + sizeof(td->length))) {
8297 avail_len += scsi_2btoul(td->length) +
8300 avail_len += sizeof(*td);
8306 * avail_len could be zero if we didn't get enough data back from
8307 * thet target to determine
8309 if ((avail_len != 0)
8310 && (avail_len > valid_len)) {
8311 alloc_len = avail_len;
8315 *fill_len = valid_len;
8327 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8328 int req_sa, uint8_t *buf, uint32_t valid_len)
8330 struct scsi_report_supported_opcodes_one *one;
8331 struct scsi_report_supported_opcodes_timeout *td;
8332 uint32_t cdb_len = 0, td_len = 0;
8333 const char *op_desc = NULL;
8337 one = (struct scsi_report_supported_opcodes_one *)buf;
8340 * If we don't have the full single opcode descriptor, no point in
8343 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8345 warnx("Only %u bytes returned, not enough to verify support",
8351 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8353 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8356 printf(", SA 0x%x", req_sa);
8359 switch (one->support & RSO_ONE_SUP_MASK) {
8360 case RSO_ONE_SUP_UNAVAIL:
8361 printf("No command support information currently available\n");
8363 case RSO_ONE_SUP_NOT_SUP:
8364 printf("Command not supported\n");
8367 break; /*NOTREACHED*/
8368 case RSO_ONE_SUP_AVAIL:
8369 printf("Command is supported, complies with a SCSI standard\n");
8371 case RSO_ONE_SUP_VENDOR:
8372 printf("Command is supported, vendor-specific "
8373 "implementation\n");
8376 printf("Unknown command support flags 0x%#x\n",
8377 one->support & RSO_ONE_SUP_MASK);
8382 * If we don't have the CDB length, it isn't exactly an error, the
8383 * command probably isn't supported.
8385 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8389 cdb_len = scsi_2btoul(one->cdb_length);
8392 * If our valid data doesn't include the full reported length,
8393 * return. The caller should have detected this and adjusted his
8394 * allocation length to get all of the available data.
8396 if (valid_len < sizeof(*one) + cdb_len) {
8402 * If all we have is the opcode, there is no point in printing out
8410 printf("CDB usage bitmap:");
8411 for (i = 0; i < cdb_len; i++) {
8412 printf(" %02x", one->cdb_usage[i]);
8417 * If we don't have a timeout descriptor, we're done.
8419 if ((one->support & RSO_ONE_CTDP) == 0)
8423 * If we don't have enough valid length to include the timeout
8424 * descriptor length, we're done.
8426 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8429 td = (struct scsi_report_supported_opcodes_timeout *)
8430 &buf[sizeof(*one) + cdb_len];
8431 td_len = scsi_2btoul(td->length);
8432 td_len += sizeof(td->length);
8435 * If we don't have the full timeout descriptor, we're done.
8437 if (td_len < sizeof(*td))
8441 * If we don't have enough valid length to contain the full timeout
8442 * descriptor, we're done.
8444 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8447 printf("Timeout information:\n");
8448 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8449 printf("Nominal timeout: %u seconds\n",
8450 scsi_4btoul(td->nominal_time));
8451 printf("Recommended timeout: %u seconds\n",
8452 scsi_4btoul(td->recommended_time));
8459 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8462 struct scsi_report_supported_opcodes_all *hdr;
8463 struct scsi_report_supported_opcodes_descr *desc;
8464 uint32_t avail_len = 0, used_len = 0;
8468 if (valid_len < sizeof(*hdr)) {
8469 warnx("%s: not enough returned data (%u bytes) opcode list",
8470 __func__, valid_len);
8474 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8475 avail_len = scsi_4btoul(hdr->length);
8476 avail_len += sizeof(hdr->length);
8478 * Take the lesser of the amount of data the drive claims is
8479 * available, and the amount of data the HBA says was returned.
8481 avail_len = MIN(avail_len, valid_len);
8483 used_len = sizeof(hdr->length);
8485 printf("%-6s %4s %8s ",
8486 "Opcode", "SA", "CDB len" );
8489 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8490 printf(" Description\n");
8492 while ((avail_len - used_len) > sizeof(*desc)) {
8493 struct scsi_report_supported_opcodes_timeout *td;
8495 const char *op_desc = NULL;
8497 cur_ptr = &buf[used_len];
8498 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8500 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8501 if (op_desc == NULL)
8502 op_desc = "UNKNOWN";
8504 printf("0x%02x %#4x %8u ", desc->opcode,
8505 scsi_2btoul(desc->service_action),
8506 scsi_2btoul(desc->cdb_length));
8508 used_len += sizeof(*desc);
8510 if ((desc->flags & RSO_CTDP) == 0) {
8511 printf(" %s\n", op_desc);
8516 * If we don't have enough space to fit a timeout
8517 * descriptor, then we're done.
8519 if (avail_len - used_len < sizeof(*td)) {
8520 used_len = avail_len;
8521 printf(" %s\n", op_desc);
8524 cur_ptr = &buf[used_len];
8525 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8526 td_len = scsi_2btoul(td->length);
8527 td_len += sizeof(td->length);
8531 * If the given timeout descriptor length is less than what
8532 * we understand, skip it.
8534 if (td_len < sizeof(*td)) {
8535 printf(" %s\n", op_desc);
8539 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8540 scsi_4btoul(td->nominal_time),
8541 scsi_4btoul(td->recommended_time), op_desc);
8548 scsiopcodes(struct cam_device *device, int argc, char **argv,
8549 char *combinedopt, int retry_count, int timeout, int verbosemode)
8552 uint32_t opcode = 0, service_action = 0;
8553 int td_set = 0, opcode_set = 0, sa_set = 0;
8554 int show_sa_errors = 1;
8555 uint32_t valid_len = 0;
8556 uint8_t *buf = NULL;
8560 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8566 opcode = strtoul(optarg, &endptr, 0);
8567 if (*endptr != '\0') {
8568 warnx("Invalid opcode \"%s\", must be a number",
8573 if (opcode > 0xff) {
8574 warnx("Invalid opcode 0x%#x, must be between"
8575 "0 and 0xff inclusive", opcode);
8582 service_action = strtoul(optarg, &endptr, 0);
8583 if (*endptr != '\0') {
8584 warnx("Invalid service action \"%s\", must "
8585 "be a number", optarg);
8589 if (service_action > 0xffff) {
8590 warnx("Invalid service action 0x%#x, must "
8591 "be between 0 and 0xffff inclusive",
8606 && (opcode_set == 0)) {
8607 warnx("You must specify an opcode with -o if a service "
8612 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8613 sa_set, service_action, td_set, retry_count,
8614 timeout, verbosemode, &valid_len, &buf);
8618 if ((opcode_set != 0)
8620 retval = scsiprintoneopcode(device, opcode, sa_set,
8621 service_action, buf, valid_len);
8623 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8632 #endif /* MINIMALISTIC */
8635 scsireprobe(struct cam_device *device)
8640 ccb = cam_getccb(device);
8643 warnx("%s: error allocating ccb", __func__);
8647 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8649 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8651 if (cam_send_ccb(device, ccb) < 0) {
8652 warn("error sending XPT_REPROBE_LUN CCB");
8657 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8658 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8670 usage(int printlong)
8673 fprintf(printlong ? stdout : stderr,
8674 "usage: camcontrol <command> [device id][generic args][command args]\n"
8675 " camcontrol devlist [-b] [-v]\n"
8676 #ifndef MINIMALISTIC
8677 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8678 " camcontrol tur [dev_id][generic args]\n"
8679 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8680 " camcontrol identify [dev_id][generic args] [-v]\n"
8681 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8682 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8684 " camcontrol start [dev_id][generic args]\n"
8685 " camcontrol stop [dev_id][generic args]\n"
8686 " camcontrol load [dev_id][generic args]\n"
8687 " camcontrol eject [dev_id][generic args]\n"
8688 " camcontrol reprobe [dev_id][generic args]\n"
8689 #endif /* MINIMALISTIC */
8690 " camcontrol rescan <all | bus[:target:lun]>\n"
8691 " camcontrol reset <all | bus[:target:lun]>\n"
8692 #ifndef MINIMALISTIC
8693 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8694 " [-q][-s][-S offset][-X]\n"
8695 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8696 " [-P pagectl][-e | -b][-d]\n"
8697 " camcontrol cmd [dev_id][generic args]\n"
8698 " <-a cmd [args] | -c cmd [args]>\n"
8699 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8700 " camcontrol smpcmd [dev_id][generic args]\n"
8701 " <-r len fmt [args]> <-R len fmt [args]>\n"
8702 " camcontrol smprg [dev_id][generic args][-l]\n"
8703 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8704 " [-o operation][-d name][-m rate][-M rate]\n"
8705 " [-T pp_timeout][-a enable|disable]\n"
8706 " [-A enable|disable][-s enable|disable]\n"
8707 " [-S enable|disable]\n"
8708 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8709 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8710 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8711 " <all|bus[:target[:lun]]|off>\n"
8712 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8713 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8714 " [-D <enable|disable>][-M mode][-O offset]\n"
8715 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8716 " [-U][-W bus_width]\n"
8717 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8718 " camcontrol sanitize [dev_id][generic args]\n"
8719 " [-a overwrite|block|crypto|exitfailure]\n"
8720 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8722 " camcontrol idle [dev_id][generic args][-t time]\n"
8723 " camcontrol standby [dev_id][generic args][-t time]\n"
8724 " camcontrol sleep [dev_id][generic args]\n"
8725 " camcontrol apm [dev_id][generic args][-l level]\n"
8726 " camcontrol aam [dev_id][generic args][-l level]\n"
8727 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8729 " camcontrol security [dev_id][generic args]\n"
8730 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8731 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8732 " [-U <user|master>] [-y]\n"
8733 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8734 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8735 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8736 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8737 " [-s scope][-S][-T type][-U]\n"
8738 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8739 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8740 " [-p part][-s start][-T type][-V vol]\n"
8741 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8743 #endif /* MINIMALISTIC */
8744 " camcontrol help\n");
8747 #ifndef MINIMALISTIC
8749 "Specify one of the following options:\n"
8750 "devlist list all CAM devices\n"
8751 "periphlist list all CAM peripheral drivers attached to a device\n"
8752 "tur send a test unit ready to the named device\n"
8753 "inquiry send a SCSI inquiry command to the named device\n"
8754 "identify send a ATA identify command to the named device\n"
8755 "reportluns send a SCSI report luns command to the device\n"
8756 "readcap send a SCSI read capacity command to the device\n"
8757 "start send a Start Unit command to the device\n"
8758 "stop send a Stop Unit command to the device\n"
8759 "load send a Start Unit command to the device with the load bit set\n"
8760 "eject send a Stop Unit command to the device with the eject bit set\n"
8761 "reprobe update capacity information of the given device\n"
8762 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8763 "reset reset all busses, the given bus, or bus:target:lun\n"
8764 "defects read the defect list of the specified device\n"
8765 "modepage display or edit (-e) the given mode page\n"
8766 "cmd send the given SCSI command, may need -i or -o as well\n"
8767 "smpcmd send the given SMP command, requires -o and -i\n"
8768 "smprg send the SMP Report General command\n"
8769 "smppc send the SMP PHY Control command, requires -p\n"
8770 "smpphylist display phys attached to a SAS expander\n"
8771 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8772 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8773 "tags report or set the number of transaction slots for a device\n"
8774 "negotiate report or set device negotiation parameters\n"
8775 "format send the SCSI FORMAT UNIT command to the named device\n"
8776 "sanitize send the SCSI SANITIZE command to the named device\n"
8777 "idle send the ATA IDLE command to the named device\n"
8778 "standby send the ATA STANDBY command to the named device\n"
8779 "sleep send the ATA SLEEP command to the named device\n"
8780 "fwdownload program firmware of the named device with the given image\n"
8781 "security report or send ATA security commands to the named device\n"
8782 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8783 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8784 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8785 "help this message\n"
8786 "Device Identifiers:\n"
8787 "bus:target specify the bus and target, lun defaults to 0\n"
8788 "bus:target:lun specify the bus, target and lun\n"
8789 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8790 "Generic arguments:\n"
8791 "-v be verbose, print out sense information\n"
8792 "-t timeout command timeout in seconds, overrides default timeout\n"
8793 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8794 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8795 "-E have the kernel attempt to perform SCSI error recovery\n"
8796 "-C count specify the SCSI command retry count (needs -E to work)\n"
8797 "modepage arguments:\n"
8798 "-l list all available mode pages\n"
8799 "-m page specify the mode page to view or edit\n"
8800 "-e edit the specified mode page\n"
8801 "-b force view to binary mode\n"
8802 "-d disable block descriptors for mode sense\n"
8803 "-P pgctl page control field 0-3\n"
8804 "defects arguments:\n"
8805 "-f format specify defect list format (block, bfi or phys)\n"
8806 "-G get the grown defect list\n"
8807 "-P get the permanent defect list\n"
8808 "inquiry arguments:\n"
8809 "-D get the standard inquiry data\n"
8810 "-S get the serial number\n"
8811 "-R get the transfer rate, etc.\n"
8812 "reportluns arguments:\n"
8813 "-c only report a count of available LUNs\n"
8814 "-l only print out luns, and not a count\n"
8815 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
8816 "readcap arguments\n"
8817 "-b only report the blocksize\n"
8818 "-h human readable device size, base 2\n"
8819 "-H human readable device size, base 10\n"
8820 "-N print the number of blocks instead of last block\n"
8821 "-q quiet, print numbers only\n"
8822 "-s only report the last block/device size\n"
8824 "-c cdb [args] specify the SCSI CDB\n"
8825 "-i len fmt specify input data and input data format\n"
8826 "-o len fmt [args] specify output data and output data fmt\n"
8827 "smpcmd arguments:\n"
8828 "-r len fmt [args] specify the SMP command to be sent\n"
8829 "-R len fmt [args] specify SMP response format\n"
8830 "smprg arguments:\n"
8831 "-l specify the long response format\n"
8832 "smppc arguments:\n"
8833 "-p phy specify the PHY to operate on\n"
8834 "-l specify the long request/response format\n"
8835 "-o operation specify the phy control operation\n"
8836 "-d name set the attached device name\n"
8837 "-m rate set the minimum physical link rate\n"
8838 "-M rate set the maximum physical link rate\n"
8839 "-T pp_timeout set the partial pathway timeout value\n"
8840 "-a enable|disable enable or disable SATA slumber\n"
8841 "-A enable|disable enable or disable SATA partial phy power\n"
8842 "-s enable|disable enable or disable SAS slumber\n"
8843 "-S enable|disable enable or disable SAS partial phy power\n"
8844 "smpphylist arguments:\n"
8845 "-l specify the long response format\n"
8846 "-q only print phys with attached devices\n"
8847 "smpmaninfo arguments:\n"
8848 "-l specify the long response format\n"
8849 "debug arguments:\n"
8850 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
8851 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
8852 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
8853 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
8855 "-N tags specify the number of tags to use for this device\n"
8856 "-q be quiet, don't report the number of tags\n"
8857 "-v report a number of tag-related parameters\n"
8858 "negotiate arguments:\n"
8859 "-a send a test unit ready after negotiation\n"
8860 "-c report/set current negotiation settings\n"
8861 "-D <arg> \"enable\" or \"disable\" disconnection\n"
8862 "-M mode set ATA mode\n"
8863 "-O offset set command delay offset\n"
8864 "-q be quiet, don't report anything\n"
8865 "-R syncrate synchronization rate in MHz\n"
8866 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
8867 "-U report/set user negotiation settings\n"
8868 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
8869 "-v also print a Path Inquiry CCB for the controller\n"
8870 "format arguments:\n"
8871 "-q be quiet, don't print status messages\n"
8872 "-r run in report only mode\n"
8873 "-w don't send immediate format command\n"
8874 "-y don't ask any questions\n"
8875 "sanitize arguments:\n"
8876 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
8877 "-c passes overwrite passes to perform (1 to 31)\n"
8878 "-I invert overwrite pattern after each pass\n"
8879 "-P pattern path to overwrite pattern file\n"
8880 "-q be quiet, don't print status messages\n"
8881 "-r run in report only mode\n"
8882 "-U run operation in unrestricted completion exit mode\n"
8883 "-w don't send immediate sanitize command\n"
8884 "-y don't ask any questions\n"
8885 "idle/standby arguments:\n"
8886 "-t <arg> number of seconds before respective state.\n"
8887 "fwdownload arguments:\n"
8888 "-f fw_image path to firmware image file\n"
8889 "-q don't print informational messages, only errors\n"
8890 "-s run in simulation mode\n"
8891 "-v print info for every firmware segment sent to device\n"
8892 "-y don't ask any questions\n"
8893 "security arguments:\n"
8894 "-d pwd disable security using the given password for the selected\n"
8896 "-e pwd erase the device using the given pwd for the selected user\n"
8897 "-f freeze the security configuration of the specified device\n"
8898 "-h pwd enhanced erase the device using the given pwd for the\n"
8900 "-k pwd unlock the device using the given pwd for the selected\n"
8902 "-l <high|maximum> specifies which security level to set: high or maximum\n"
8903 "-q be quiet, do not print any status messages\n"
8904 "-s pwd password the device (enable security) using the given\n"
8905 " pwd for the selected user\n"
8906 "-T timeout overrides the timeout (seconds) used for erase operation\n"
8907 "-U <user|master> specifies which user to set: user or master\n"
8908 "-y don't ask any questions\n"
8910 "-f freeze the HPA configuration of the device\n"
8911 "-l lock the HPA configuration of the device\n"
8912 "-P make the HPA max sectors persist\n"
8913 "-p pwd Set the HPA configuration password required for unlock\n"
8915 "-q be quiet, do not print any status messages\n"
8916 "-s sectors configures the maximum user accessible sectors of the\n"
8918 "-U pwd unlock the HPA configuration of the device\n"
8919 "-y don't ask any questions\n"
8920 "persist arguments:\n"
8921 "-i action specify read_keys, read_reservation, report_cap, or\n"
8922 " read_full_status\n"
8923 "-o action specify register, register_ignore, reserve, release,\n"
8924 " clear, preempt, preempt_abort, register_move, replace_lost\n"
8925 "-a set the All Target Ports (ALL_TG_PT) bit\n"
8926 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
8927 "-k key specify the Reservation Key\n"
8928 "-K sa_key specify the Service Action Reservation Key\n"
8929 "-p set the Activate Persist Through Power Loss bit\n"
8930 "-R rtp specify the Relative Target Port\n"
8931 "-s scope specify the scope: lun, extent, element or a number\n"
8932 "-S specify Transport ID for register, requires -I\n"
8933 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
8934 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
8935 "-U unregister the current initiator for register_move\n"
8936 "attrib arguments:\n"
8937 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
8939 "-w attr specify an attribute to write, one -w argument per attr\n"
8940 "-a attr_num only display this attribute number\n"
8941 "-c get cached attributes\n"
8942 "-e elem_addr request attributes for the given element in a changer\n"
8943 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
8944 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
8945 " field_none, field_desc, field_num, field_size, field_rw\n"
8946 "-p partition request attributes for the given partition\n"
8947 "-s start_attr request attributes starting at the given number\n"
8948 "-T elem_type specify the element type (used with -e)\n"
8949 "-V logical_vol specify the logical volume ID\n"
8950 "opcodes arguments:\n"
8951 "-o opcode specify the individual opcode to list\n"
8952 "-s service_action specify the service action for the opcode\n"
8953 "-N do not return SCSI error for unsupported SA\n"
8954 "-T request nominal and recommended timeout values\n"
8956 #endif /* MINIMALISTIC */
8960 main(int argc, char **argv)
8963 char *device = NULL;
8965 struct cam_device *cam_dev = NULL;
8966 int timeout = 0, retry_count = 1;
8967 camcontrol_optret optreturn;
8969 const char *mainopt = "C:En:t:u:v";
8970 const char *subopt = NULL;
8971 char combinedopt[256];
8972 int error = 0, optstart = 2;
8974 #ifndef MINIMALISTIC
8978 #endif /* MINIMALISTIC */
8980 cmdlist = CAM_CMD_NONE;
8981 arglist = CAM_ARG_NONE;
8989 * Get the base option.
8991 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
8993 if (optreturn == CC_OR_AMBIGUOUS) {
8994 warnx("ambiguous option %s", argv[1]);
8997 } else if (optreturn == CC_OR_NOT_FOUND) {
8998 warnx("option %s not found", argv[1]);
9004 * Ahh, getopt(3) is a pain.
9006 * This is a gross hack. There really aren't many other good
9007 * options (excuse the pun) for parsing options in a situation like
9008 * this. getopt is kinda braindead, so you end up having to run
9009 * through the options twice, and give each invocation of getopt
9010 * the option string for the other invocation.
9012 * You would think that you could just have two groups of options.
9013 * The first group would get parsed by the first invocation of
9014 * getopt, and the second group would get parsed by the second
9015 * invocation of getopt. It doesn't quite work out that way. When
9016 * the first invocation of getopt finishes, it leaves optind pointing
9017 * to the argument _after_ the first argument in the second group.
9018 * So when the second invocation of getopt comes around, it doesn't
9019 * recognize the first argument it gets and then bails out.
9021 * A nice alternative would be to have a flag for getopt that says
9022 * "just keep parsing arguments even when you encounter an unknown
9023 * argument", but there isn't one. So there's no real clean way to
9024 * easily parse two sets of arguments without having one invocation
9025 * of getopt know about the other.
9027 * Without this hack, the first invocation of getopt would work as
9028 * long as the generic arguments are first, but the second invocation
9029 * (in the subfunction) would fail in one of two ways. In the case
9030 * where you don't set optreset, it would fail because optind may be
9031 * pointing to the argument after the one it should be pointing at.
9032 * In the case where you do set optreset, and reset optind, it would
9033 * fail because getopt would run into the first set of options, which
9034 * it doesn't understand.
9036 * All of this would "sort of" work if you could somehow figure out
9037 * whether optind had been incremented one option too far. The
9038 * mechanics of that, however, are more daunting than just giving
9039 * both invocations all of the expect options for either invocation.
9041 * Needless to say, I wouldn't mind if someone invented a better
9042 * (non-GPL!) command line parsing interface than getopt. I
9043 * wouldn't mind if someone added more knobs to getopt to make it
9044 * work better. Who knows, I may talk myself into doing it someday,
9045 * if the standards weenies let me. As it is, it just leads to
9046 * hackery like this and causes people to avoid it in some cases.
9048 * KDM, September 8th, 1998
9051 sprintf(combinedopt, "%s%s", mainopt, subopt);
9053 sprintf(combinedopt, "%s", mainopt);
9056 * For these options we do not parse optional device arguments and
9057 * we do not open a passthrough device.
9059 if ((cmdlist == CAM_CMD_RESCAN)
9060 || (cmdlist == CAM_CMD_RESET)
9061 || (cmdlist == CAM_CMD_DEVTREE)
9062 || (cmdlist == CAM_CMD_USAGE)
9063 || (cmdlist == CAM_CMD_DEBUG))
9066 #ifndef MINIMALISTIC
9068 && (argc > 2 && argv[2][0] != '-')) {
9072 if (isdigit(argv[2][0])) {
9073 /* device specified as bus:target[:lun] */
9074 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9076 errx(1, "numeric device specification must "
9077 "be either bus:target, or "
9079 /* default to 0 if lun was not specified */
9080 if ((arglist & CAM_ARG_LUN) == 0) {
9082 arglist |= CAM_ARG_LUN;
9086 if (cam_get_device(argv[2], name, sizeof name, &unit)
9088 errx(1, "%s", cam_errbuf);
9089 device = strdup(name);
9090 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9094 #endif /* MINIMALISTIC */
9096 * Start getopt processing at argv[2/3], since we've already
9097 * accepted argv[1..2] as the command name, and as a possible
9103 * Now we run through the argument list looking for generic
9104 * options, and ignoring options that possibly belong to
9107 while ((c = getopt(argc, argv, combinedopt))!= -1){
9110 retry_count = strtol(optarg, NULL, 0);
9111 if (retry_count < 0)
9112 errx(1, "retry count %d is < 0",
9114 arglist |= CAM_ARG_RETRIES;
9117 arglist |= CAM_ARG_ERR_RECOVER;
9120 arglist |= CAM_ARG_DEVICE;
9122 while (isspace(*tstr) && (*tstr != '\0'))
9124 device = (char *)strdup(tstr);
9127 timeout = strtol(optarg, NULL, 0);
9129 errx(1, "invalid timeout %d", timeout);
9130 /* Convert the timeout from seconds to ms */
9132 arglist |= CAM_ARG_TIMEOUT;
9135 arglist |= CAM_ARG_UNIT;
9136 unit = strtol(optarg, NULL, 0);
9139 arglist |= CAM_ARG_VERBOSE;
9146 #ifndef MINIMALISTIC
9148 * For most commands we'll want to open the passthrough device
9149 * associated with the specified device. In the case of the rescan
9150 * commands, we don't use a passthrough device at all, just the
9151 * transport layer device.
9154 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9155 && (((arglist & CAM_ARG_DEVICE) == 0)
9156 || ((arglist & CAM_ARG_UNIT) == 0))) {
9157 errx(1, "subcommand \"%s\" requires a valid device "
9158 "identifier", argv[1]);
9161 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9162 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9163 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9165 errx(1,"%s", cam_errbuf);
9167 #endif /* MINIMALISTIC */
9170 * Reset optind to 2, and reset getopt, so these routines can parse
9171 * the arguments again.
9177 #ifndef MINIMALISTIC
9178 case CAM_CMD_DEVLIST:
9179 error = getdevlist(cam_dev);
9182 error = atahpa(cam_dev, retry_count, timeout,
9183 argc, argv, combinedopt);
9185 #endif /* MINIMALISTIC */
9186 case CAM_CMD_DEVTREE:
9187 error = getdevtree(argc, argv, combinedopt);
9189 #ifndef MINIMALISTIC
9191 error = testunitready(cam_dev, retry_count, timeout, 0);
9193 case CAM_CMD_INQUIRY:
9194 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9195 retry_count, timeout);
9197 case CAM_CMD_IDENTIFY:
9198 error = ataidentify(cam_dev, retry_count, timeout);
9200 case CAM_CMD_STARTSTOP:
9201 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9202 arglist & CAM_ARG_EJECT, retry_count,
9205 #endif /* MINIMALISTIC */
9206 case CAM_CMD_RESCAN:
9207 error = dorescan_or_reset(argc, argv, 1);
9210 error = dorescan_or_reset(argc, argv, 0);
9212 #ifndef MINIMALISTIC
9213 case CAM_CMD_READ_DEFECTS:
9214 error = readdefects(cam_dev, argc, argv, combinedopt,
9215 retry_count, timeout);
9217 case CAM_CMD_MODE_PAGE:
9218 modepage(cam_dev, argc, argv, combinedopt,
9219 retry_count, timeout);
9221 case CAM_CMD_SCSI_CMD:
9222 error = scsicmd(cam_dev, argc, argv, combinedopt,
9223 retry_count, timeout);
9225 case CAM_CMD_SMP_CMD:
9226 error = smpcmd(cam_dev, argc, argv, combinedopt,
9227 retry_count, timeout);
9229 case CAM_CMD_SMP_RG:
9230 error = smpreportgeneral(cam_dev, argc, argv,
9231 combinedopt, retry_count,
9234 case CAM_CMD_SMP_PC:
9235 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9236 retry_count, timeout);
9238 case CAM_CMD_SMP_PHYLIST:
9239 error = smpphylist(cam_dev, argc, argv, combinedopt,
9240 retry_count, timeout);
9242 case CAM_CMD_SMP_MANINFO:
9243 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9244 retry_count, timeout);
9247 error = camdebug(argc, argv, combinedopt);
9250 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9253 error = ratecontrol(cam_dev, retry_count, timeout,
9254 argc, argv, combinedopt);
9256 case CAM_CMD_FORMAT:
9257 error = scsiformat(cam_dev, argc, argv,
9258 combinedopt, retry_count, timeout);
9260 case CAM_CMD_REPORTLUNS:
9261 error = scsireportluns(cam_dev, argc, argv,
9262 combinedopt, retry_count,
9265 case CAM_CMD_READCAP:
9266 error = scsireadcapacity(cam_dev, argc, argv,
9267 combinedopt, retry_count,
9271 case CAM_CMD_STANDBY:
9273 error = atapm(cam_dev, argc, argv,
9274 combinedopt, retry_count, timeout);
9278 error = ataaxm(cam_dev, argc, argv,
9279 combinedopt, retry_count, timeout);
9281 case CAM_CMD_SECURITY:
9282 error = atasecurity(cam_dev, retry_count, timeout,
9283 argc, argv, combinedopt);
9285 case CAM_CMD_DOWNLOAD_FW:
9286 error = fwdownload(cam_dev, argc, argv, combinedopt,
9287 arglist & CAM_ARG_VERBOSE, retry_count, timeout);
9289 case CAM_CMD_SANITIZE:
9290 error = scsisanitize(cam_dev, argc, argv,
9291 combinedopt, retry_count, timeout);
9293 case CAM_CMD_PERSIST:
9294 error = scsipersist(cam_dev, argc, argv, combinedopt,
9295 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9296 arglist & CAM_ARG_ERR_RECOVER);
9298 case CAM_CMD_ATTRIB:
9299 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9300 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9301 arglist & CAM_ARG_ERR_RECOVER);
9303 case CAM_CMD_OPCODES:
9304 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9305 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9307 case CAM_CMD_REPROBE:
9308 error = scsireprobe(cam_dev);
9311 #endif /* MINIMALISTIC */
9321 if (cam_dev != NULL)
9322 cam_close_device(cam_dev);