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_TIMEOUT = 0x00020000,
126 CAM_ARG_CMD_IN = 0x00040000,
127 CAM_ARG_CMD_OUT = 0x00080000,
128 CAM_ARG_ERR_RECOVER = 0x00200000,
129 CAM_ARG_RETRIES = 0x00400000,
130 CAM_ARG_START_UNIT = 0x00800000,
131 CAM_ARG_DEBUG_INFO = 0x01000000,
132 CAM_ARG_DEBUG_TRACE = 0x02000000,
133 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
134 CAM_ARG_DEBUG_CDB = 0x08000000,
135 CAM_ARG_DEBUG_XPT = 0x10000000,
136 CAM_ARG_DEBUG_PERIPH = 0x20000000,
137 CAM_ARG_DEBUG_PROBE = 0x40000000,
140 struct camcontrol_opts {
148 struct ata_res_pass16 {
149 u_int16_t reserved[5];
152 u_int8_t sector_count_exp;
153 u_int8_t sector_count;
154 u_int8_t lba_low_exp;
156 u_int8_t lba_mid_exp;
158 u_int8_t lba_high_exp;
164 struct ata_set_max_pwd
167 u_int8_t password[32];
168 u_int16_t reserved2[239];
171 static const char scsicmd_opts[] = "a:c:dfi:o:r";
172 static const char readdefect_opts[] = "f:GPqsS:X";
173 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
174 static const char smprg_opts[] = "l";
175 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
176 static const char smpphylist_opts[] = "lq";
180 static struct camcontrol_opts option_table[] = {
182 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
183 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
184 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
185 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
186 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
187 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
188 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
189 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
190 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
191 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
192 #endif /* MINIMALISTIC */
193 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
194 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
196 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
197 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
198 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
199 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
200 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
201 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
202 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
203 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
204 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
205 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
206 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
207 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
208 #endif /* MINIMALISTIC */
209 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
211 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
212 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
213 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
214 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
215 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
216 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
217 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
218 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
219 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
220 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
221 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
222 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
223 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
224 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
225 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
226 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
227 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
228 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
229 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
230 #endif /* MINIMALISTIC */
231 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
232 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
233 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
238 struct device_match_result dev_match;
240 struct periph_match_result *periph_matches;
241 struct scsi_vpd_device_id *device_id;
243 STAILQ_ENTRY(cam_devitem) links;
247 STAILQ_HEAD(, cam_devitem) dev_queue;
251 static cam_cmdmask cmdlist;
252 static cam_argmask arglist;
254 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
255 uint32_t *cmdnum, cam_argmask *argnum,
256 const char **subopt);
258 static int getdevlist(struct cam_device *device);
259 #endif /* MINIMALISTIC */
260 static int getdevtree(int argc, char **argv, char *combinedopt);
262 static int testunitready(struct cam_device *device, int retry_count,
263 int timeout, int quiet);
264 static int scsistart(struct cam_device *device, int startstop, int loadeject,
265 int retry_count, int timeout);
266 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
267 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
268 #endif /* MINIMALISTIC */
269 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
270 lun_id_t *lun, cam_argmask *arglst);
271 static int dorescan_or_reset(int argc, char **argv, int rescan);
272 static int rescan_or_reset_bus(path_id_t bus, int rescan);
273 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
274 lun_id_t lun, int scan);
276 static int readdefects(struct cam_device *device, int argc, char **argv,
277 char *combinedopt, int retry_count, int timeout);
278 static void modepage(struct cam_device *device, int argc, char **argv,
279 char *combinedopt, int retry_count, int timeout);
280 static int scsicmd(struct cam_device *device, int argc, char **argv,
281 char *combinedopt, int retry_count, int timeout);
282 static int smpcmd(struct cam_device *device, int argc, char **argv,
283 char *combinedopt, int retry_count, int timeout);
284 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
285 char *combinedopt, int retry_count, int timeout);
286 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
287 char *combinedopt, int retry_count, int timeout);
288 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
289 char *combinedopt, int retry_count, int timeout);
290 static int getdevid(struct cam_devitem *item);
291 static int buildbusdevlist(struct cam_devlist *devlist);
292 static void freebusdevlist(struct cam_devlist *devlist);
293 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
295 static int smpphylist(struct cam_device *device, int argc, char **argv,
296 char *combinedopt, int retry_count, int timeout);
297 static int tagcontrol(struct cam_device *device, int argc, char **argv,
299 static void cts_print(struct cam_device *device,
300 struct ccb_trans_settings *cts);
301 static void cpi_print(struct ccb_pathinq *cpi);
302 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
303 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
304 static int get_print_cts(struct cam_device *device, int user_settings,
305 int quiet, struct ccb_trans_settings *cts);
306 static int ratecontrol(struct cam_device *device, int retry_count,
307 int timeout, int argc, char **argv, char *combinedopt);
308 static int scsiformat(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int retry_count, int timeout);
310 static int scsisanitize(struct cam_device *device, int argc, char **argv,
311 char *combinedopt, int retry_count, int timeout);
312 static int scsireportluns(struct cam_device *device, int argc, char **argv,
313 char *combinedopt, int retry_count, int timeout);
314 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int retry_count, int timeout);
316 static int atapm(struct cam_device *device, int argc, char **argv,
317 char *combinedopt, int retry_count, int timeout);
318 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
319 int argc, char **argv, char *combinedopt);
320 static int atahpa(struct cam_device *device, int retry_count, int timeout,
321 int argc, char **argv, char *combinedopt);
322 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
323 int sa_set, int req_sa, uint8_t *buf,
325 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
327 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
328 char *combinedopt, int retry_count, int timeout,
330 static int scsireprobe(struct cam_device *device);
332 #endif /* MINIMALISTIC */
334 #define min(a,b) (((a)<(b))?(a):(b))
337 #define max(a,b) (((a)>(b))?(a):(b))
341 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
342 cam_argmask *argnum, const char **subopt)
344 struct camcontrol_opts *opts;
347 for (opts = table; (opts != NULL) && (opts->optname != NULL);
349 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
350 *cmdnum = opts->cmdnum;
351 *argnum = opts->argnum;
352 *subopt = opts->subopt;
353 if (++num_matches > 1)
354 return(CC_OR_AMBIGUOUS);
361 return(CC_OR_NOT_FOUND);
366 getdevlist(struct cam_device *device)
372 ccb = cam_getccb(device);
374 ccb->ccb_h.func_code = XPT_GDEVLIST;
375 ccb->ccb_h.flags = CAM_DIR_NONE;
376 ccb->ccb_h.retry_count = 1;
378 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
379 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
380 if (cam_send_ccb(device, ccb) < 0) {
381 perror("error getting device list");
388 switch (ccb->cgdl.status) {
389 case CAM_GDEVLIST_MORE_DEVS:
390 strcpy(status, "MORE");
392 case CAM_GDEVLIST_LAST_DEVICE:
393 strcpy(status, "LAST");
395 case CAM_GDEVLIST_LIST_CHANGED:
396 strcpy(status, "CHANGED");
398 case CAM_GDEVLIST_ERROR:
399 strcpy(status, "ERROR");
404 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
405 ccb->cgdl.periph_name,
406 ccb->cgdl.unit_number,
407 ccb->cgdl.generation,
412 * If the list has changed, we need to start over from the
415 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
423 #endif /* MINIMALISTIC */
426 getdevtree(int argc, char **argv, char *combinedopt)
437 while ((c = getopt(argc, argv, combinedopt)) != -1) {
440 if ((arglist & CAM_ARG_VERBOSE) == 0)
448 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
449 warn("couldn't open %s", XPT_DEVICE);
453 bzero(&ccb, sizeof(union ccb));
455 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
456 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
457 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
459 ccb.ccb_h.func_code = XPT_DEV_MATCH;
460 bufsize = sizeof(struct dev_match_result) * 100;
461 ccb.cdm.match_buf_len = bufsize;
462 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
463 if (ccb.cdm.matches == NULL) {
464 warnx("can't malloc memory for matches");
468 ccb.cdm.num_matches = 0;
471 * We fetch all nodes, since we display most of them in the default
472 * case, and all in the verbose case.
474 ccb.cdm.num_patterns = 0;
475 ccb.cdm.pattern_buf_len = 0;
478 * We do the ioctl multiple times if necessary, in case there are
479 * more than 100 nodes in the EDT.
482 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
483 warn("error sending CAMIOCOMMAND ioctl");
488 if ((ccb.ccb_h.status != CAM_REQ_CMP)
489 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
490 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
491 warnx("got CAM error %#x, CDM error %d\n",
492 ccb.ccb_h.status, ccb.cdm.status);
497 for (i = 0; i < ccb.cdm.num_matches; i++) {
498 switch (ccb.cdm.matches[i].type) {
499 case DEV_MATCH_BUS: {
500 struct bus_match_result *bus_result;
503 * Only print the bus information if the
504 * user turns on the verbose flag.
506 if ((busonly == 0) &&
507 (arglist & CAM_ARG_VERBOSE) == 0)
511 &ccb.cdm.matches[i].result.bus_result;
514 fprintf(stdout, ")\n");
518 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
520 bus_result->dev_name,
521 bus_result->unit_number,
523 (busonly ? "" : ":"));
526 case DEV_MATCH_DEVICE: {
527 struct device_match_result *dev_result;
528 char vendor[16], product[48], revision[16];
529 char fw[5], tmpstr[256];
535 &ccb.cdm.matches[i].result.device_result;
537 if ((dev_result->flags
538 & DEV_RESULT_UNCONFIGURED)
539 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
545 if (dev_result->protocol == PROTO_SCSI) {
546 cam_strvis(vendor, dev_result->inq_data.vendor,
547 sizeof(dev_result->inq_data.vendor),
550 dev_result->inq_data.product,
551 sizeof(dev_result->inq_data.product),
554 dev_result->inq_data.revision,
555 sizeof(dev_result->inq_data.revision),
557 sprintf(tmpstr, "<%s %s %s>", vendor, product,
559 } else if (dev_result->protocol == PROTO_ATA ||
560 dev_result->protocol == PROTO_SATAPM) {
562 dev_result->ident_data.model,
563 sizeof(dev_result->ident_data.model),
566 dev_result->ident_data.revision,
567 sizeof(dev_result->ident_data.revision),
569 sprintf(tmpstr, "<%s %s>", product,
571 } else if (dev_result->protocol == PROTO_SEMB) {
572 struct sep_identify_data *sid;
574 sid = (struct sep_identify_data *)
575 &dev_result->ident_data;
576 cam_strvis(vendor, sid->vendor_id,
577 sizeof(sid->vendor_id),
579 cam_strvis(product, sid->product_id,
580 sizeof(sid->product_id),
582 cam_strvis(revision, sid->product_rev,
583 sizeof(sid->product_rev),
585 cam_strvis(fw, sid->firmware_rev,
586 sizeof(sid->firmware_rev),
588 sprintf(tmpstr, "<%s %s %s %s>",
589 vendor, product, revision, fw);
591 sprintf(tmpstr, "<>");
594 fprintf(stdout, ")\n");
598 fprintf(stdout, "%-33s at scbus%d "
599 "target %d lun %jx (",
602 dev_result->target_id,
603 (uintmax_t)dev_result->target_lun);
609 case DEV_MATCH_PERIPH: {
610 struct periph_match_result *periph_result;
613 &ccb.cdm.matches[i].result.periph_result;
615 if (busonly || skip_device != 0)
619 fprintf(stdout, ",");
621 fprintf(stdout, "%s%d",
622 periph_result->periph_name,
623 periph_result->unit_number);
629 fprintf(stdout, "unknown match type\n");
634 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
635 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
638 fprintf(stdout, ")\n");
647 testunitready(struct cam_device *device, int retry_count, int timeout,
653 ccb = cam_getccb(device);
655 scsi_test_unit_ready(&ccb->csio,
656 /* retries */ retry_count,
658 /* tag_action */ MSG_SIMPLE_Q_TAG,
659 /* sense_len */ SSD_FULL_SIZE,
660 /* timeout */ timeout ? timeout : 5000);
662 /* Disable freezing the device queue */
663 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
665 if (arglist & CAM_ARG_ERR_RECOVER)
666 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
668 if (cam_send_ccb(device, ccb) < 0) {
670 perror("error sending test unit ready");
672 if (arglist & CAM_ARG_VERBOSE) {
673 cam_error_print(device, ccb, CAM_ESF_ALL,
674 CAM_EPF_ALL, stderr);
681 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
683 fprintf(stdout, "Unit is ready\n");
686 fprintf(stdout, "Unit is not ready\n");
689 if (arglist & CAM_ARG_VERBOSE) {
690 cam_error_print(device, ccb, CAM_ESF_ALL,
691 CAM_EPF_ALL, stderr);
701 scsistart(struct cam_device *device, int startstop, int loadeject,
702 int retry_count, int timeout)
707 ccb = cam_getccb(device);
710 * If we're stopping, send an ordered tag so the drive in question
711 * will finish any previously queued writes before stopping. If
712 * the device isn't capable of tagged queueing, or if tagged
713 * queueing is turned off, the tag action is a no-op.
715 scsi_start_stop(&ccb->csio,
716 /* retries */ retry_count,
718 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
720 /* start/stop */ startstop,
721 /* load_eject */ loadeject,
723 /* sense_len */ SSD_FULL_SIZE,
724 /* timeout */ timeout ? timeout : 120000);
726 /* Disable freezing the device queue */
727 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
729 if (arglist & CAM_ARG_ERR_RECOVER)
730 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
732 if (cam_send_ccb(device, ccb) < 0) {
733 perror("error sending start unit");
735 if (arglist & CAM_ARG_VERBOSE) {
736 cam_error_print(device, ccb, CAM_ESF_ALL,
737 CAM_EPF_ALL, stderr);
744 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
746 fprintf(stdout, "Unit started successfully");
748 fprintf(stdout,", Media loaded\n");
750 fprintf(stdout,"\n");
752 fprintf(stdout, "Unit stopped successfully");
754 fprintf(stdout, ", Media ejected\n");
756 fprintf(stdout, "\n");
762 "Error received from start unit command\n");
765 "Error received from stop unit command\n");
767 if (arglist & CAM_ARG_VERBOSE) {
768 cam_error_print(device, ccb, CAM_ESF_ALL,
769 CAM_EPF_ALL, stderr);
779 scsidoinquiry(struct cam_device *device, int argc, char **argv,
780 char *combinedopt, int retry_count, int timeout)
785 while ((c = getopt(argc, argv, combinedopt)) != -1) {
788 arglist |= CAM_ARG_GET_STDINQ;
791 arglist |= CAM_ARG_GET_XFERRATE;
794 arglist |= CAM_ARG_GET_SERIAL;
802 * If the user didn't specify any inquiry options, he wants all of
805 if ((arglist & CAM_ARG_INQ_MASK) == 0)
806 arglist |= CAM_ARG_INQ_MASK;
808 if (arglist & CAM_ARG_GET_STDINQ)
809 error = scsiinquiry(device, retry_count, timeout);
814 if (arglist & CAM_ARG_GET_SERIAL)
815 scsiserial(device, retry_count, timeout);
817 if (arglist & CAM_ARG_GET_XFERRATE)
818 error = camxferrate(device);
824 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
827 struct scsi_inquiry_data *inq_buf;
830 ccb = cam_getccb(device);
833 warnx("couldn't allocate CCB");
837 /* cam_getccb cleans up the header, caller has to zero the payload */
838 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
840 inq_buf = (struct scsi_inquiry_data *)malloc(
841 sizeof(struct scsi_inquiry_data));
843 if (inq_buf == NULL) {
845 warnx("can't malloc memory for inquiry\n");
848 bzero(inq_buf, sizeof(*inq_buf));
851 * Note that although the size of the inquiry buffer is the full
852 * 256 bytes specified in the SCSI spec, we only tell the device
853 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
854 * two reasons for this:
856 * - The SCSI spec says that when a length field is only 1 byte,
857 * a value of 0 will be interpreted as 256. Therefore
858 * scsi_inquiry() will convert an inq_len (which is passed in as
859 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
860 * to 0. Evidently, very few devices meet the spec in that
861 * regard. Some devices, like many Seagate disks, take the 0 as
862 * 0, and don't return any data. One Pioneer DVD-R drive
863 * returns more data than the command asked for.
865 * So, since there are numerous devices that just don't work
866 * right with the full inquiry size, we don't send the full size.
868 * - The second reason not to use the full inquiry data length is
869 * that we don't need it here. The only reason we issue a
870 * standard inquiry is to get the vendor name, device name,
871 * and revision so scsi_print_inquiry() can print them.
873 * If, at some point in the future, more inquiry data is needed for
874 * some reason, this code should use a procedure similar to the
875 * probe code. i.e., issue a short inquiry, and determine from
876 * the additional length passed back from the device how much
877 * inquiry data the device supports. Once the amount the device
878 * supports is determined, issue an inquiry for that amount and no
883 scsi_inquiry(&ccb->csio,
884 /* retries */ retry_count,
886 /* tag_action */ MSG_SIMPLE_Q_TAG,
887 /* inq_buf */ (u_int8_t *)inq_buf,
888 /* inq_len */ SHORT_INQUIRY_LENGTH,
891 /* sense_len */ SSD_FULL_SIZE,
892 /* timeout */ timeout ? timeout : 5000);
894 /* Disable freezing the device queue */
895 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
897 if (arglist & CAM_ARG_ERR_RECOVER)
898 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
900 if (cam_send_ccb(device, ccb) < 0) {
901 perror("error sending SCSI inquiry");
903 if (arglist & CAM_ARG_VERBOSE) {
904 cam_error_print(device, ccb, CAM_ESF_ALL,
905 CAM_EPF_ALL, stderr);
912 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
915 if (arglist & CAM_ARG_VERBOSE) {
916 cam_error_print(device, ccb, CAM_ESF_ALL,
917 CAM_EPF_ALL, stderr);
928 fprintf(stdout, "%s%d: ", device->device_name,
929 device->dev_unit_num);
930 scsi_print_inquiry(inq_buf);
938 scsiserial(struct cam_device *device, int retry_count, int timeout)
941 struct scsi_vpd_unit_serial_number *serial_buf;
942 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
945 ccb = cam_getccb(device);
948 warnx("couldn't allocate CCB");
952 /* cam_getccb cleans up the header, caller has to zero the payload */
953 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
955 serial_buf = (struct scsi_vpd_unit_serial_number *)
956 malloc(sizeof(*serial_buf));
958 if (serial_buf == NULL) {
960 warnx("can't malloc memory for serial number");
964 scsi_inquiry(&ccb->csio,
965 /*retries*/ retry_count,
967 /* tag_action */ MSG_SIMPLE_Q_TAG,
968 /* inq_buf */ (u_int8_t *)serial_buf,
969 /* inq_len */ sizeof(*serial_buf),
971 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
972 /* sense_len */ SSD_FULL_SIZE,
973 /* timeout */ timeout ? timeout : 5000);
975 /* Disable freezing the device queue */
976 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
978 if (arglist & CAM_ARG_ERR_RECOVER)
979 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
981 if (cam_send_ccb(device, ccb) < 0) {
982 warn("error getting serial number");
984 if (arglist & CAM_ARG_VERBOSE) {
985 cam_error_print(device, ccb, CAM_ESF_ALL,
986 CAM_EPF_ALL, stderr);
994 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
997 if (arglist & CAM_ARG_VERBOSE) {
998 cam_error_print(device, ccb, CAM_ESF_ALL,
999 CAM_EPF_ALL, stderr);
1010 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1011 serial_num[serial_buf->length] = '\0';
1013 if ((arglist & CAM_ARG_GET_STDINQ)
1014 || (arglist & CAM_ARG_GET_XFERRATE))
1015 fprintf(stdout, "%s%d: Serial Number ",
1016 device->device_name, device->dev_unit_num);
1018 fprintf(stdout, "%.60s\n", serial_num);
1026 camxferrate(struct cam_device *device)
1028 struct ccb_pathinq cpi;
1030 u_int32_t speed = 0;
1035 if ((retval = get_cpi(device, &cpi)) != 0)
1038 ccb = cam_getccb(device);
1041 warnx("couldn't allocate CCB");
1045 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1047 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1048 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1050 if (((retval = cam_send_ccb(device, ccb)) < 0)
1051 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1052 const char error_string[] = "error getting transfer settings";
1057 warnx(error_string);
1059 if (arglist & CAM_ARG_VERBOSE)
1060 cam_error_print(device, ccb, CAM_ESF_ALL,
1061 CAM_EPF_ALL, stderr);
1065 goto xferrate_bailout;
1069 speed = cpi.base_transfer_speed;
1071 if (ccb->cts.transport == XPORT_SPI) {
1072 struct ccb_trans_settings_spi *spi =
1073 &ccb->cts.xport_specific.spi;
1075 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1076 freq = scsi_calc_syncsrate(spi->sync_period);
1079 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1080 speed *= (0x01 << spi->bus_width);
1082 } else if (ccb->cts.transport == XPORT_FC) {
1083 struct ccb_trans_settings_fc *fc =
1084 &ccb->cts.xport_specific.fc;
1086 if (fc->valid & CTS_FC_VALID_SPEED)
1087 speed = fc->bitrate;
1088 } else if (ccb->cts.transport == XPORT_SAS) {
1089 struct ccb_trans_settings_sas *sas =
1090 &ccb->cts.xport_specific.sas;
1092 if (sas->valid & CTS_SAS_VALID_SPEED)
1093 speed = sas->bitrate;
1094 } else if (ccb->cts.transport == XPORT_ATA) {
1095 struct ccb_trans_settings_pata *pata =
1096 &ccb->cts.xport_specific.ata;
1098 if (pata->valid & CTS_ATA_VALID_MODE)
1099 speed = ata_mode2speed(pata->mode);
1100 } else if (ccb->cts.transport == XPORT_SATA) {
1101 struct ccb_trans_settings_sata *sata =
1102 &ccb->cts.xport_specific.sata;
1104 if (sata->valid & CTS_SATA_VALID_REVISION)
1105 speed = ata_revision2speed(sata->revision);
1110 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1111 device->device_name, device->dev_unit_num,
1114 fprintf(stdout, "%s%d: %dKB/s transfers",
1115 device->device_name, device->dev_unit_num,
1119 if (ccb->cts.transport == XPORT_SPI) {
1120 struct ccb_trans_settings_spi *spi =
1121 &ccb->cts.xport_specific.spi;
1123 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1124 && (spi->sync_offset != 0))
1125 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1126 freq % 1000, spi->sync_offset);
1128 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1129 && (spi->bus_width > 0)) {
1130 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1131 && (spi->sync_offset != 0)) {
1132 fprintf(stdout, ", ");
1134 fprintf(stdout, " (");
1136 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1137 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1138 && (spi->sync_offset != 0)) {
1139 fprintf(stdout, ")");
1141 } else if (ccb->cts.transport == XPORT_ATA) {
1142 struct ccb_trans_settings_pata *pata =
1143 &ccb->cts.xport_specific.ata;
1146 if (pata->valid & CTS_ATA_VALID_MODE)
1147 printf("%s, ", ata_mode2string(pata->mode));
1148 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1149 printf("ATAPI %dbytes, ", pata->atapi);
1150 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1151 printf("PIO %dbytes", pata->bytecount);
1153 } else if (ccb->cts.transport == XPORT_SATA) {
1154 struct ccb_trans_settings_sata *sata =
1155 &ccb->cts.xport_specific.sata;
1158 if (sata->valid & CTS_SATA_VALID_REVISION)
1159 printf("SATA %d.x, ", sata->revision);
1162 if (sata->valid & CTS_SATA_VALID_MODE)
1163 printf("%s, ", ata_mode2string(sata->mode));
1164 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1165 printf("ATAPI %dbytes, ", sata->atapi);
1166 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1167 printf("PIO %dbytes", sata->bytecount);
1171 if (ccb->cts.protocol == PROTO_SCSI) {
1172 struct ccb_trans_settings_scsi *scsi =
1173 &ccb->cts.proto_specific.scsi;
1174 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1175 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1176 fprintf(stdout, ", Command Queueing Enabled");
1181 fprintf(stdout, "\n");
1191 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1193 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1194 ((u_int32_t)parm->lba_size_2 << 16);
1196 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1197 ((u_int64_t)parm->lba_size48_2 << 16) |
1198 ((u_int64_t)parm->lba_size48_3 << 32) |
1199 ((u_int64_t)parm->lba_size48_4 << 48);
1203 "Support Enabled Value\n");
1206 printf("Host Protected Area (HPA) ");
1207 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1208 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1209 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1212 printf("HPA - Security ");
1213 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1223 atasata(struct ata_params *parm)
1227 if (parm->satacapabilities != 0xffff &&
1228 parm->satacapabilities != 0x0000)
1235 atacapprint(struct ata_params *parm)
1237 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1238 ((u_int32_t)parm->lba_size_2 << 16);
1240 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1241 ((u_int64_t)parm->lba_size48_2 << 16) |
1242 ((u_int64_t)parm->lba_size48_3 << 32) |
1243 ((u_int64_t)parm->lba_size48_4 << 48);
1246 printf("protocol ");
1247 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1248 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1249 if (parm->satacapabilities & ATA_SATA_GEN3)
1250 printf(" SATA 3.x\n");
1251 else if (parm->satacapabilities & ATA_SATA_GEN2)
1252 printf(" SATA 2.x\n");
1253 else if (parm->satacapabilities & ATA_SATA_GEN1)
1254 printf(" SATA 1.x\n");
1260 printf("device model %.40s\n", parm->model);
1261 printf("firmware revision %.8s\n", parm->revision);
1262 printf("serial number %.20s\n", parm->serial);
1263 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1264 printf("WWN %04x%04x%04x%04x\n",
1265 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1267 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1268 printf("media serial number %.30s\n",
1269 parm->media_serial);
1272 printf("cylinders %d\n", parm->cylinders);
1273 printf("heads %d\n", parm->heads);
1274 printf("sectors/track %d\n", parm->sectors);
1275 printf("sector size logical %u, physical %lu, offset %lu\n",
1276 ata_logical_sector_size(parm),
1277 (unsigned long)ata_physical_sector_size(parm),
1278 (unsigned long)ata_logical_sector_offset(parm));
1280 if (parm->config == ATA_PROTO_CFA ||
1281 (parm->support.command2 & ATA_SUPPORT_CFA))
1282 printf("CFA supported\n");
1284 printf("LBA%ssupported ",
1285 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1287 printf("%d sectors\n", lbasize);
1291 printf("LBA48%ssupported ",
1292 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1294 printf("%ju sectors\n", (uintmax_t)lbasize48);
1298 printf("PIO supported PIO");
1299 switch (ata_max_pmode(parm)) {
1315 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1316 printf(" w/o IORDY");
1319 printf("DMA%ssupported ",
1320 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1321 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1322 if (parm->mwdmamodes & 0xff) {
1324 if (parm->mwdmamodes & 0x04)
1326 else if (parm->mwdmamodes & 0x02)
1328 else if (parm->mwdmamodes & 0x01)
1332 if ((parm->atavalid & ATA_FLAG_88) &&
1333 (parm->udmamodes & 0xff)) {
1335 if (parm->udmamodes & 0x40)
1337 else if (parm->udmamodes & 0x20)
1339 else if (parm->udmamodes & 0x10)
1341 else if (parm->udmamodes & 0x08)
1343 else if (parm->udmamodes & 0x04)
1345 else if (parm->udmamodes & 0x02)
1347 else if (parm->udmamodes & 0x01)
1354 if (parm->media_rotation_rate == 1) {
1355 printf("media RPM non-rotating\n");
1356 } else if (parm->media_rotation_rate >= 0x0401 &&
1357 parm->media_rotation_rate <= 0xFFFE) {
1358 printf("media RPM %d\n",
1359 parm->media_rotation_rate);
1363 "Support Enabled Value Vendor\n");
1364 printf("read ahead %s %s\n",
1365 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1366 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1367 printf("write cache %s %s\n",
1368 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1369 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1370 printf("flush cache %s %s\n",
1371 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1372 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1373 printf("overlap %s\n",
1374 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1375 printf("Tagged Command Queuing (TCQ) %s %s",
1376 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1377 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1378 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1379 printf(" %d tags\n",
1380 ATA_QUEUE_LEN(parm->queue) + 1);
1383 printf("Native Command Queuing (NCQ) ");
1384 if (parm->satacapabilities != 0xffff &&
1385 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1386 printf("yes %d tags\n",
1387 ATA_QUEUE_LEN(parm->queue) + 1);
1391 printf("NCQ Queue Management %s\n", atasata(parm) &&
1392 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1394 printf("NCQ Streaming %s\n", atasata(parm) &&
1395 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1397 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1398 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1401 printf("SMART %s %s\n",
1402 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1403 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1404 printf("microcode download %s %s\n",
1405 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1406 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1407 printf("security %s %s\n",
1408 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1409 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1410 printf("power management %s %s\n",
1411 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1412 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1413 printf("advanced power management %s %s",
1414 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1415 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1416 if (parm->support.command2 & ATA_SUPPORT_APM) {
1417 printf(" %d/0x%02X\n",
1418 parm->apm_value & 0xff, parm->apm_value & 0xff);
1421 printf("automatic acoustic management %s %s",
1422 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1423 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1424 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1425 printf(" %d/0x%02X %d/0x%02X\n",
1426 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1427 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1428 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1429 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1432 printf("media status notification %s %s\n",
1433 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1434 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1435 printf("power-up in Standby %s %s\n",
1436 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1437 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1438 printf("write-read-verify %s %s",
1439 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1440 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1441 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1442 printf(" %d/0x%x\n",
1443 parm->wrv_mode, parm->wrv_mode);
1446 printf("unload %s %s\n",
1447 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1448 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1449 printf("general purpose logging %s %s\n",
1450 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1451 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1452 printf("free-fall %s %s\n",
1453 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1454 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1455 printf("Data Set Management (DSM/TRIM) ");
1456 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1458 printf("DSM - max 512byte blocks ");
1459 if (parm->max_dsm_blocks == 0x00)
1460 printf("yes not specified\n");
1463 parm->max_dsm_blocks);
1465 printf("DSM - deterministic read ");
1466 if (parm->support3 & ATA_SUPPORT_DRAT) {
1467 if (parm->support3 & ATA_SUPPORT_RZAT)
1468 printf("yes zeroed\n");
1470 printf("yes any value\n");
1480 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1482 struct ata_pass_16 *ata_pass_16;
1483 struct ata_cmd ata_cmd;
1485 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1486 ata_cmd.command = ata_pass_16->command;
1487 ata_cmd.control = ata_pass_16->control;
1488 ata_cmd.features = ata_pass_16->features;
1490 if (arglist & CAM_ARG_VERBOSE) {
1491 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1492 ata_op_string(&ata_cmd),
1493 ccb->csio.ccb_h.timeout);
1496 /* Disable freezing the device queue */
1497 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1499 if (arglist & CAM_ARG_ERR_RECOVER)
1500 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1502 if (cam_send_ccb(device, ccb) < 0) {
1503 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1504 warn("error sending ATA %s via pass_16",
1505 ata_op_string(&ata_cmd));
1508 if (arglist & CAM_ARG_VERBOSE) {
1509 cam_error_print(device, ccb, CAM_ESF_ALL,
1510 CAM_EPF_ALL, stderr);
1516 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1517 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1518 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1519 warnx("ATA %s via pass_16 failed",
1520 ata_op_string(&ata_cmd));
1522 if (arglist & CAM_ARG_VERBOSE) {
1523 cam_error_print(device, ccb, CAM_ESF_ALL,
1524 CAM_EPF_ALL, stderr);
1535 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1537 if (arglist & CAM_ARG_VERBOSE) {
1538 warnx("sending ATA %s with timeout of %u msecs",
1539 ata_op_string(&(ccb->ataio.cmd)),
1540 ccb->ataio.ccb_h.timeout);
1543 /* Disable freezing the device queue */
1544 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1546 if (arglist & CAM_ARG_ERR_RECOVER)
1547 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1549 if (cam_send_ccb(device, ccb) < 0) {
1550 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1551 warn("error sending ATA %s",
1552 ata_op_string(&(ccb->ataio.cmd)));
1555 if (arglist & CAM_ARG_VERBOSE) {
1556 cam_error_print(device, ccb, CAM_ESF_ALL,
1557 CAM_EPF_ALL, stderr);
1563 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1564 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1565 warnx("ATA %s failed: %d",
1566 ata_op_string(&(ccb->ataio.cmd)), quiet);
1569 if (arglist & CAM_ARG_VERBOSE) {
1570 cam_error_print(device, ccb, CAM_ESF_ALL,
1571 CAM_EPF_ALL, stderr);
1581 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1582 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1583 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1584 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1585 u_int16_t dxfer_len, int timeout, int quiet)
1587 if (data_ptr != NULL) {
1588 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1589 AP_FLAG_TLEN_SECT_CNT;
1590 if (flags & CAM_DIR_OUT)
1591 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1593 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1595 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1598 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1600 scsi_ata_pass_16(&ccb->csio,
1614 /*sense_len*/SSD_FULL_SIZE,
1617 return scsi_cam_pass_16_send(device, ccb, quiet);
1621 ata_try_pass_16(struct cam_device *device)
1623 struct ccb_pathinq cpi;
1625 if (get_cpi(device, &cpi) != 0) {
1626 warnx("couldn't get CPI");
1630 if (cpi.protocol == PROTO_SCSI) {
1631 /* possibly compatible with pass_16 */
1635 /* likely not compatible with pass_16 */
1640 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1641 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1642 u_int8_t command, u_int8_t features, u_int32_t lba,
1643 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1644 int timeout, int quiet)
1648 switch (ata_try_pass_16(device)) {
1652 /* Try using SCSI Passthrough */
1653 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1654 0, tag_action, command, features, lba,
1655 sector_count, data_ptr, dxfer_len,
1659 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1660 cam_fill_ataio(&ccb->ataio,
1669 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1670 return ata_cam_send(device, ccb, quiet);
1674 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1675 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1676 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1677 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1678 u_int16_t dxfer_len, int timeout, int force48bit)
1682 retval = ata_try_pass_16(device);
1689 /* Try using SCSI Passthrough */
1690 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1691 ata_flags, tag_action, command, features,
1692 lba, sector_count, data_ptr, dxfer_len,
1695 if (ata_flags & AP_FLAG_CHK_COND) {
1696 /* Decode ata_res from sense data */
1697 struct ata_res_pass16 *res_pass16;
1698 struct ata_res *res;
1702 /* sense_data is 4 byte aligned */
1703 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1704 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1705 ptr[i] = le16toh(ptr[i]);
1707 /* sense_data is 4 byte aligned */
1708 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1709 &ccb->csio.sense_data;
1710 res = &ccb->ataio.res;
1711 res->flags = res_pass16->flags;
1712 res->status = res_pass16->status;
1713 res->error = res_pass16->error;
1714 res->lba_low = res_pass16->lba_low;
1715 res->lba_mid = res_pass16->lba_mid;
1716 res->lba_high = res_pass16->lba_high;
1717 res->device = res_pass16->device;
1718 res->lba_low_exp = res_pass16->lba_low_exp;
1719 res->lba_mid_exp = res_pass16->lba_mid_exp;
1720 res->lba_high_exp = res_pass16->lba_high_exp;
1721 res->sector_count = res_pass16->sector_count;
1722 res->sector_count_exp = res_pass16->sector_count_exp;
1728 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1729 cam_fill_ataio(&ccb->ataio,
1738 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1739 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1741 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1743 if (ata_flags & AP_FLAG_CHK_COND)
1744 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1746 return ata_cam_send(device, ccb, 0);
1750 dump_data(uint16_t *ptr, uint32_t len)
1754 for (i = 0; i < len / 2; i++) {
1756 printf(" %3d: ", i);
1757 printf("%04hx ", ptr[i]);
1766 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1767 int is48bit, u_int64_t *hpasize)
1769 struct ata_res *res;
1771 res = &ccb->ataio.res;
1772 if (res->status & ATA_STATUS_ERROR) {
1773 if (arglist & CAM_ARG_VERBOSE) {
1774 cam_error_print(device, ccb, CAM_ESF_ALL,
1775 CAM_EPF_ALL, stderr);
1776 printf("error = 0x%02x, sector_count = 0x%04x, "
1777 "device = 0x%02x, status = 0x%02x\n",
1778 res->error, res->sector_count,
1779 res->device, res->status);
1782 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1783 warnx("Max address has already been set since "
1784 "last power-on or hardware reset");
1790 if (arglist & CAM_ARG_VERBOSE) {
1791 fprintf(stdout, "%s%d: Raw native max data:\n",
1792 device->device_name, device->dev_unit_num);
1793 /* res is 4 byte aligned */
1794 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1796 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1797 "status = 0x%02x\n", res->error, res->sector_count,
1798 res->device, res->status);
1801 if (hpasize != NULL) {
1803 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1804 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1805 ((res->lba_high << 16) | (res->lba_mid << 8) |
1808 *hpasize = (((res->device & 0x0f) << 24) |
1809 (res->lba_high << 16) | (res->lba_mid << 8) |
1818 ata_read_native_max(struct cam_device *device, int retry_count,
1819 u_int32_t timeout, union ccb *ccb,
1820 struct ata_params *parm, u_int64_t *hpasize)
1826 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1827 protocol = AP_PROTO_NON_DATA;
1830 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1831 protocol |= AP_EXTEND;
1833 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1836 error = ata_do_cmd(device,
1839 /*flags*/CAM_DIR_NONE,
1840 /*protocol*/protocol,
1841 /*ata_flags*/AP_FLAG_CHK_COND,
1842 /*tag_action*/MSG_SIMPLE_Q_TAG,
1849 timeout ? timeout : 1000,
1855 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1859 atahpa_set_max(struct cam_device *device, int retry_count,
1860 u_int32_t timeout, union ccb *ccb,
1861 int is48bit, u_int64_t maxsize, int persist)
1867 protocol = AP_PROTO_NON_DATA;
1870 cmd = ATA_SET_MAX_ADDRESS48;
1871 protocol |= AP_EXTEND;
1873 cmd = ATA_SET_MAX_ADDRESS;
1876 /* lba's are zero indexed so the max lba is requested max - 1 */
1880 error = ata_do_cmd(device,
1883 /*flags*/CAM_DIR_NONE,
1884 /*protocol*/protocol,
1885 /*ata_flags*/AP_FLAG_CHK_COND,
1886 /*tag_action*/MSG_SIMPLE_Q_TAG,
1888 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1890 /*sector_count*/persist,
1893 timeout ? timeout : 1000,
1899 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1903 atahpa_password(struct cam_device *device, int retry_count,
1904 u_int32_t timeout, union ccb *ccb,
1905 int is48bit, struct ata_set_max_pwd *pwd)
1911 protocol = AP_PROTO_PIO_OUT;
1912 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1914 error = ata_do_cmd(device,
1917 /*flags*/CAM_DIR_OUT,
1918 /*protocol*/protocol,
1919 /*ata_flags*/AP_FLAG_CHK_COND,
1920 /*tag_action*/MSG_SIMPLE_Q_TAG,
1922 /*features*/ATA_HPA_FEAT_SET_PWD,
1925 /*data_ptr*/(u_int8_t*)pwd,
1926 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1927 timeout ? timeout : 1000,
1933 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1937 atahpa_lock(struct cam_device *device, int retry_count,
1938 u_int32_t timeout, union ccb *ccb, int is48bit)
1944 protocol = AP_PROTO_NON_DATA;
1945 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1947 error = ata_do_cmd(device,
1950 /*flags*/CAM_DIR_NONE,
1951 /*protocol*/protocol,
1952 /*ata_flags*/AP_FLAG_CHK_COND,
1953 /*tag_action*/MSG_SIMPLE_Q_TAG,
1955 /*features*/ATA_HPA_FEAT_LOCK,
1960 timeout ? timeout : 1000,
1966 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1970 atahpa_unlock(struct cam_device *device, int retry_count,
1971 u_int32_t timeout, union ccb *ccb,
1972 int is48bit, struct ata_set_max_pwd *pwd)
1978 protocol = AP_PROTO_PIO_OUT;
1979 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1981 error = ata_do_cmd(device,
1984 /*flags*/CAM_DIR_OUT,
1985 /*protocol*/protocol,
1986 /*ata_flags*/AP_FLAG_CHK_COND,
1987 /*tag_action*/MSG_SIMPLE_Q_TAG,
1989 /*features*/ATA_HPA_FEAT_UNLOCK,
1992 /*data_ptr*/(u_int8_t*)pwd,
1993 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1994 timeout ? timeout : 1000,
2000 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2004 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2005 u_int32_t timeout, union ccb *ccb, int is48bit)
2011 protocol = AP_PROTO_NON_DATA;
2012 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2014 error = ata_do_cmd(device,
2017 /*flags*/CAM_DIR_NONE,
2018 /*protocol*/protocol,
2019 /*ata_flags*/AP_FLAG_CHK_COND,
2020 /*tag_action*/MSG_SIMPLE_Q_TAG,
2022 /*features*/ATA_HPA_FEAT_FREEZE,
2027 timeout ? timeout : 1000,
2033 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2038 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2039 union ccb *ccb, struct ata_params** ident_bufp)
2041 struct ata_params *ident_buf;
2042 struct ccb_pathinq cpi;
2043 struct ccb_getdev cgd;
2046 u_int8_t command, retry_command;
2048 if (get_cpi(device, &cpi) != 0) {
2049 warnx("couldn't get CPI");
2053 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2054 if (cpi.protocol == PROTO_ATA) {
2055 if (get_cgd(device, &cgd) != 0) {
2056 warnx("couldn't get CGD");
2060 command = (cgd.protocol == PROTO_ATA) ?
2061 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2064 /* We don't know which for sure so try both */
2065 command = ATA_ATA_IDENTIFY;
2066 retry_command = ATA_ATAPI_IDENTIFY;
2069 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2071 warnx("can't calloc memory for identify\n");
2075 error = ata_do_28bit_cmd(device,
2077 /*retries*/retry_count,
2078 /*flags*/CAM_DIR_IN,
2079 /*protocol*/AP_PROTO_PIO_IN,
2080 /*tag_action*/MSG_SIMPLE_Q_TAG,
2084 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2085 /*data_ptr*/(u_int8_t *)ptr,
2086 /*dxfer_len*/sizeof(struct ata_params),
2087 /*timeout*/timeout ? timeout : 30 * 1000,
2091 if (retry_command == 0) {
2095 error = ata_do_28bit_cmd(device,
2097 /*retries*/retry_count,
2098 /*flags*/CAM_DIR_IN,
2099 /*protocol*/AP_PROTO_PIO_IN,
2100 /*tag_action*/MSG_SIMPLE_Q_TAG,
2101 /*command*/retry_command,
2104 /*sector_count*/(u_int8_t)
2105 sizeof(struct ata_params),
2106 /*data_ptr*/(u_int8_t *)ptr,
2107 /*dxfer_len*/sizeof(struct ata_params),
2108 /*timeout*/timeout ? timeout : 30 * 1000,
2118 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2119 ptr[i] = le16toh(ptr[i]);
2124 if (arglist & CAM_ARG_VERBOSE) {
2125 fprintf(stdout, "%s%d: Raw identify data:\n",
2126 device->device_name, device->dev_unit_num);
2127 dump_data(ptr, sizeof(struct ata_params));
2130 /* check for invalid (all zero) response */
2132 warnx("Invalid identify response detected");
2137 ident_buf = (struct ata_params *)ptr;
2138 if (strncmp(ident_buf->model, "FX", 2) &&
2139 strncmp(ident_buf->model, "NEC", 3) &&
2140 strncmp(ident_buf->model, "Pioneer", 7) &&
2141 strncmp(ident_buf->model, "SHARP", 5)) {
2142 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2143 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2144 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2145 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2147 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2148 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2149 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2150 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2151 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2152 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2153 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2154 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2155 sizeof(ident_buf->media_serial));
2157 *ident_bufp = ident_buf;
2164 ataidentify(struct cam_device *device, int retry_count, int timeout)
2167 struct ata_params *ident_buf;
2170 if ((ccb = cam_getccb(device)) == NULL) {
2171 warnx("couldn't allocate CCB");
2175 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2180 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2181 if (ata_read_native_max(device, retry_count, timeout, ccb,
2182 ident_buf, &hpasize) != 0) {
2190 printf("%s%d: ", device->device_name, device->dev_unit_num);
2191 ata_print_ident(ident_buf);
2192 camxferrate(device);
2193 atacapprint(ident_buf);
2194 atahpa_print(ident_buf, hpasize, 0);
2201 #endif /* MINIMALISTIC */
2204 #ifndef MINIMALISTIC
2206 ATA_SECURITY_ACTION_PRINT,
2207 ATA_SECURITY_ACTION_FREEZE,
2208 ATA_SECURITY_ACTION_UNLOCK,
2209 ATA_SECURITY_ACTION_DISABLE,
2210 ATA_SECURITY_ACTION_ERASE,
2211 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2212 ATA_SECURITY_ACTION_SET_PASSWORD
2216 atasecurity_print_time(u_int16_t tw)
2220 printf("unspecified");
2222 printf("> 508 min");
2224 printf("%i min", 2 * tw);
2228 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2232 return 2 * 3600 * 1000; /* default: two hours */
2233 else if (timeout > 255)
2234 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2236 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2241 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2245 bzero(&cmd, sizeof(cmd));
2246 cmd.command = command;
2247 printf("Issuing %s", ata_op_string(&cmd));
2250 char pass[sizeof(pwd->password)+1];
2252 /* pwd->password may not be null terminated */
2253 pass[sizeof(pwd->password)] = '\0';
2254 strncpy(pass, pwd->password, sizeof(pwd->password));
2255 printf(" password='%s', user='%s'",
2257 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2260 if (command == ATA_SECURITY_SET_PASSWORD) {
2261 printf(", mode='%s'",
2262 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2263 "maximum" : "high");
2271 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2272 int retry_count, u_int32_t timeout, int quiet)
2276 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2278 return ata_do_28bit_cmd(device,
2281 /*flags*/CAM_DIR_NONE,
2282 /*protocol*/AP_PROTO_NON_DATA,
2283 /*tag_action*/MSG_SIMPLE_Q_TAG,
2284 /*command*/ATA_SECURITY_FREEZE_LOCK,
2295 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2296 int retry_count, u_int32_t timeout,
2297 struct ata_security_password *pwd, int quiet)
2301 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2303 return ata_do_28bit_cmd(device,
2306 /*flags*/CAM_DIR_OUT,
2307 /*protocol*/AP_PROTO_PIO_OUT,
2308 /*tag_action*/MSG_SIMPLE_Q_TAG,
2309 /*command*/ATA_SECURITY_UNLOCK,
2313 /*data_ptr*/(u_int8_t *)pwd,
2314 /*dxfer_len*/sizeof(*pwd),
2320 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2321 int retry_count, u_int32_t timeout,
2322 struct ata_security_password *pwd, int quiet)
2326 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2327 return ata_do_28bit_cmd(device,
2330 /*flags*/CAM_DIR_OUT,
2331 /*protocol*/AP_PROTO_PIO_OUT,
2332 /*tag_action*/MSG_SIMPLE_Q_TAG,
2333 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2337 /*data_ptr*/(u_int8_t *)pwd,
2338 /*dxfer_len*/sizeof(*pwd),
2345 atasecurity_erase_confirm(struct cam_device *device,
2346 struct ata_params* ident_buf)
2349 printf("\nYou are about to ERASE ALL DATA from the following"
2350 " device:\n%s%d,%s%d: ", device->device_name,
2351 device->dev_unit_num, device->given_dev_name,
2352 device->given_unit_number);
2353 ata_print_ident(ident_buf);
2357 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2359 if (fgets(str, sizeof(str), stdin) != NULL) {
2360 if (strncasecmp(str, "yes", 3) == 0) {
2362 } else if (strncasecmp(str, "no", 2) == 0) {
2365 printf("Please answer \"yes\" or "
2376 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2377 int retry_count, u_int32_t timeout,
2378 u_int32_t erase_timeout,
2379 struct ata_security_password *pwd, int quiet)
2384 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2386 error = ata_do_28bit_cmd(device,
2389 /*flags*/CAM_DIR_NONE,
2390 /*protocol*/AP_PROTO_NON_DATA,
2391 /*tag_action*/MSG_SIMPLE_Q_TAG,
2392 /*command*/ATA_SECURITY_ERASE_PREPARE,
2405 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2407 error = ata_do_28bit_cmd(device,
2410 /*flags*/CAM_DIR_OUT,
2411 /*protocol*/AP_PROTO_PIO_OUT,
2412 /*tag_action*/MSG_SIMPLE_Q_TAG,
2413 /*command*/ATA_SECURITY_ERASE_UNIT,
2417 /*data_ptr*/(u_int8_t *)pwd,
2418 /*dxfer_len*/sizeof(*pwd),
2419 /*timeout*/erase_timeout,
2422 if (error == 0 && quiet == 0)
2423 printf("\nErase Complete\n");
2429 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2430 int retry_count, u_int32_t timeout,
2431 struct ata_security_password *pwd, int quiet)
2435 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2437 return ata_do_28bit_cmd(device,
2440 /*flags*/CAM_DIR_OUT,
2441 /*protocol*/AP_PROTO_PIO_OUT,
2442 /*tag_action*/MSG_SIMPLE_Q_TAG,
2443 /*command*/ATA_SECURITY_SET_PASSWORD,
2447 /*data_ptr*/(u_int8_t *)pwd,
2448 /*dxfer_len*/sizeof(*pwd),
2454 atasecurity_print(struct ata_params *parm)
2457 printf("\nSecurity Option Value\n");
2458 if (arglist & CAM_ARG_VERBOSE) {
2459 printf("status %04x\n",
2460 parm->security_status);
2462 printf("supported %s\n",
2463 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2464 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2466 printf("enabled %s\n",
2467 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2468 printf("drive locked %s\n",
2469 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2470 printf("security config frozen %s\n",
2471 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2472 printf("count expired %s\n",
2473 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2474 printf("security level %s\n",
2475 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2476 printf("enhanced erase supported %s\n",
2477 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2478 printf("erase time ");
2479 atasecurity_print_time(parm->erase_time);
2481 printf("enhanced erase time ");
2482 atasecurity_print_time(parm->enhanced_erase_time);
2484 printf("master password rev %04x%s\n",
2485 parm->master_passwd_revision,
2486 parm->master_passwd_revision == 0x0000 ||
2487 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2491 * Validates and copies the password in optarg to the passed buffer.
2492 * If the password in optarg is the same length as the buffer then
2493 * the data will still be copied but no null termination will occur.
2496 ata_getpwd(u_int8_t *passwd, int max, char opt)
2500 len = strlen(optarg);
2502 warnx("-%c password is too long", opt);
2504 } else if (len == 0) {
2505 warnx("-%c password is missing", opt);
2507 } else if (optarg[0] == '-'){
2508 warnx("-%c password starts with '-' (generic arg?)", opt);
2510 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2511 warnx("-%c password conflicts with existing password from -%c",
2516 /* Callers pass in a buffer which does NOT need to be terminated */
2517 strncpy(passwd, optarg, max);
2524 ATA_HPA_ACTION_PRINT,
2525 ATA_HPA_ACTION_SET_MAX,
2526 ATA_HPA_ACTION_SET_PWD,
2527 ATA_HPA_ACTION_LOCK,
2528 ATA_HPA_ACTION_UNLOCK,
2529 ATA_HPA_ACTION_FREEZE_LOCK
2533 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2534 u_int64_t maxsize, int persist)
2536 printf("\nYou are about to configure HPA to limit the user accessible\n"
2537 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2538 persist ? "persistently" : "temporarily",
2539 device->device_name, device->dev_unit_num,
2540 device->given_dev_name, device->given_unit_number);
2541 ata_print_ident(ident_buf);
2545 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2547 if (NULL != fgets(str, sizeof(str), stdin)) {
2548 if (0 == strncasecmp(str, "yes", 3)) {
2550 } else if (0 == strncasecmp(str, "no", 2)) {
2553 printf("Please answer \"yes\" or "
2564 atahpa(struct cam_device *device, int retry_count, int timeout,
2565 int argc, char **argv, char *combinedopt)
2568 struct ata_params *ident_buf;
2569 struct ccb_getdev cgd;
2570 struct ata_set_max_pwd pwd;
2571 int error, confirm, quiet, c, action, actions, setpwd, persist;
2572 int security, is48bit, pwdsize;
2573 u_int64_t hpasize, maxsize;
2583 memset(&pwd, 0, sizeof(pwd));
2585 /* default action is to print hpa information */
2586 action = ATA_HPA_ACTION_PRINT;
2587 pwdsize = sizeof(pwd.password);
2589 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2592 action = ATA_HPA_ACTION_SET_MAX;
2593 maxsize = strtoumax(optarg, NULL, 0);
2598 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2600 action = ATA_HPA_ACTION_SET_PWD;
2606 action = ATA_HPA_ACTION_LOCK;
2612 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2614 action = ATA_HPA_ACTION_UNLOCK;
2620 action = ATA_HPA_ACTION_FREEZE_LOCK;
2640 warnx("too many hpa actions specified");
2644 if (get_cgd(device, &cgd) != 0) {
2645 warnx("couldn't get CGD");
2649 ccb = cam_getccb(device);
2651 warnx("couldn't allocate CCB");
2655 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2662 printf("%s%d: ", device->device_name, device->dev_unit_num);
2663 ata_print_ident(ident_buf);
2664 camxferrate(device);
2667 if (action == ATA_HPA_ACTION_PRINT) {
2668 error = ata_read_native_max(device, retry_count, timeout, ccb,
2669 ident_buf, &hpasize);
2671 atahpa_print(ident_buf, hpasize, 1);
2678 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2679 warnx("HPA is not supported by this device");
2685 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2686 warnx("HPA Security is not supported by this device");
2692 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2695 * The ATA spec requires:
2696 * 1. Read native max addr is called directly before set max addr
2697 * 2. Read native max addr is NOT called before any other set max call
2700 case ATA_HPA_ACTION_SET_MAX:
2702 atahpa_set_confirm(device, ident_buf, maxsize,
2709 error = ata_read_native_max(device, retry_count, timeout,
2710 ccb, ident_buf, &hpasize);
2712 error = atahpa_set_max(device, retry_count, timeout,
2713 ccb, is48bit, maxsize, persist);
2715 /* redo identify to get new lba values */
2716 error = ata_do_identify(device, retry_count,
2719 atahpa_print(ident_buf, hpasize, 1);
2724 case ATA_HPA_ACTION_SET_PWD:
2725 error = atahpa_password(device, retry_count, timeout,
2726 ccb, is48bit, &pwd);
2728 printf("HPA password has been set\n");
2731 case ATA_HPA_ACTION_LOCK:
2732 error = atahpa_lock(device, retry_count, timeout,
2735 printf("HPA has been locked\n");
2738 case ATA_HPA_ACTION_UNLOCK:
2739 error = atahpa_unlock(device, retry_count, timeout,
2740 ccb, is48bit, &pwd);
2742 printf("HPA has been unlocked\n");
2745 case ATA_HPA_ACTION_FREEZE_LOCK:
2746 error = atahpa_freeze_lock(device, retry_count, timeout,
2749 printf("HPA has been frozen\n");
2753 errx(1, "Option currently not supported");
2763 atasecurity(struct cam_device *device, int retry_count, int timeout,
2764 int argc, char **argv, char *combinedopt)
2767 struct ata_params *ident_buf;
2768 int error, confirm, quiet, c, action, actions, setpwd;
2769 int security_enabled, erase_timeout, pwdsize;
2770 struct ata_security_password pwd;
2778 memset(&pwd, 0, sizeof(pwd));
2780 /* default action is to print security information */
2781 action = ATA_SECURITY_ACTION_PRINT;
2783 /* user is master by default as its safer that way */
2784 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2785 pwdsize = sizeof(pwd.password);
2787 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2790 action = ATA_SECURITY_ACTION_FREEZE;
2795 if (strcasecmp(optarg, "user") == 0) {
2796 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2797 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2798 } else if (strcasecmp(optarg, "master") == 0) {
2799 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2800 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2802 warnx("-U argument '%s' is invalid (must be "
2803 "'user' or 'master')", optarg);
2809 if (strcasecmp(optarg, "high") == 0) {
2810 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2811 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2812 } else if (strcasecmp(optarg, "maximum") == 0) {
2813 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2814 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2816 warnx("-l argument '%s' is unknown (must be "
2817 "'high' or 'maximum')", optarg);
2823 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2825 action = ATA_SECURITY_ACTION_UNLOCK;
2830 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2832 action = ATA_SECURITY_ACTION_DISABLE;
2837 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2839 action = ATA_SECURITY_ACTION_ERASE;
2844 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2846 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2847 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2852 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2855 if (action == ATA_SECURITY_ACTION_PRINT)
2856 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2858 * Don't increment action as this can be combined
2859 * with other actions.
2872 erase_timeout = atoi(optarg) * 1000;
2878 warnx("too many security actions specified");
2882 if ((ccb = cam_getccb(device)) == NULL) {
2883 warnx("couldn't allocate CCB");
2887 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2894 printf("%s%d: ", device->device_name, device->dev_unit_num);
2895 ata_print_ident(ident_buf);
2896 camxferrate(device);
2899 if (action == ATA_SECURITY_ACTION_PRINT) {
2900 atasecurity_print(ident_buf);
2906 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2907 warnx("Security not supported");
2913 /* default timeout 15 seconds the same as linux hdparm */
2914 timeout = timeout ? timeout : 15 * 1000;
2916 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2918 /* first set the password if requested */
2920 /* confirm we can erase before setting the password if erasing */
2922 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2923 action == ATA_SECURITY_ACTION_ERASE) &&
2924 atasecurity_erase_confirm(device, ident_buf) == 0) {
2930 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2931 pwd.revision = ident_buf->master_passwd_revision;
2932 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2933 --pwd.revision == 0) {
2934 pwd.revision = 0xfffe;
2937 error = atasecurity_set_password(device, ccb, retry_count,
2938 timeout, &pwd, quiet);
2944 security_enabled = 1;
2948 case ATA_SECURITY_ACTION_FREEZE:
2949 error = atasecurity_freeze(device, ccb, retry_count,
2953 case ATA_SECURITY_ACTION_UNLOCK:
2954 if (security_enabled) {
2955 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2956 error = atasecurity_unlock(device, ccb,
2957 retry_count, timeout, &pwd, quiet);
2959 warnx("Can't unlock, drive is not locked");
2963 warnx("Can't unlock, security is disabled");
2968 case ATA_SECURITY_ACTION_DISABLE:
2969 if (security_enabled) {
2970 /* First unlock the drive if its locked */
2971 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2972 error = atasecurity_unlock(device, ccb,
2980 error = atasecurity_disable(device,
2988 warnx("Can't disable security (already disabled)");
2993 case ATA_SECURITY_ACTION_ERASE:
2994 if (security_enabled) {
2995 if (erase_timeout == 0) {
2996 erase_timeout = atasecurity_erase_timeout_msecs(
2997 ident_buf->erase_time);
3000 error = atasecurity_erase(device, ccb, retry_count,
3001 timeout, erase_timeout, &pwd,
3004 warnx("Can't secure erase (security is disabled)");
3009 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3010 if (security_enabled) {
3011 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3012 if (erase_timeout == 0) {
3014 atasecurity_erase_timeout_msecs(
3015 ident_buf->enhanced_erase_time);
3018 error = atasecurity_erase(device, ccb,
3019 retry_count, timeout,
3020 erase_timeout, &pwd,
3023 warnx("Enhanced erase is not supported");
3027 warnx("Can't secure erase (enhanced), "
3028 "(security is disabled)");
3039 #endif /* MINIMALISTIC */
3042 * Parse out a bus, or a bus, target and lun in the following
3048 * Returns the number of parsed components, or 0.
3051 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3052 cam_argmask *arglst)
3057 while (isspace(*tstr) && (*tstr != '\0'))
3060 tmpstr = (char *)strtok(tstr, ":");
3061 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3062 *bus = strtol(tmpstr, NULL, 0);
3063 *arglst |= CAM_ARG_BUS;
3065 tmpstr = (char *)strtok(NULL, ":");
3066 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3067 *target = strtol(tmpstr, NULL, 0);
3068 *arglst |= CAM_ARG_TARGET;
3070 tmpstr = (char *)strtok(NULL, ":");
3071 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3072 *lun = strtol(tmpstr, NULL, 0);
3073 *arglst |= CAM_ARG_LUN;
3083 dorescan_or_reset(int argc, char **argv, int rescan)
3085 static const char must[] =
3086 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3088 path_id_t bus = CAM_BUS_WILDCARD;
3089 target_id_t target = CAM_TARGET_WILDCARD;
3090 lun_id_t lun = CAM_LUN_WILDCARD;
3094 warnx(must, rescan? "rescan" : "reset");
3098 tstr = argv[optind];
3099 while (isspace(*tstr) && (*tstr != '\0'))
3101 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3102 arglist |= CAM_ARG_BUS;
3104 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3105 if (rv != 1 && rv != 3) {
3106 warnx(must, rescan? "rescan" : "reset");
3111 if ((arglist & CAM_ARG_BUS)
3112 && (arglist & CAM_ARG_TARGET)
3113 && (arglist & CAM_ARG_LUN))
3114 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3116 error = rescan_or_reset_bus(bus, rescan);
3122 rescan_or_reset_bus(path_id_t bus, int rescan)
3124 union ccb *ccb = NULL, *matchccb = NULL;
3125 int fd = -1, retval;
3130 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3131 warnx("error opening transport layer device %s", XPT_DEVICE);
3132 warn("%s", XPT_DEVICE);
3136 ccb = malloc(sizeof(*ccb));
3138 warn("failed to allocate CCB");
3142 bzero(ccb, sizeof(*ccb));
3144 if (bus != CAM_BUS_WILDCARD) {
3145 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3146 ccb->ccb_h.path_id = bus;
3147 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3148 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3149 ccb->crcn.flags = CAM_FLAG_NONE;
3151 /* run this at a low priority */
3152 ccb->ccb_h.pinfo.priority = 5;
3154 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3155 warn("CAMIOCOMMAND ioctl failed");
3160 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3161 fprintf(stdout, "%s of bus %d was successful\n",
3162 rescan ? "Re-scan" : "Reset", bus);
3164 fprintf(stdout, "%s of bus %d returned error %#x\n",
3165 rescan ? "Re-scan" : "Reset", bus,
3166 ccb->ccb_h.status & CAM_STATUS_MASK);
3175 * The right way to handle this is to modify the xpt so that it can
3176 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3177 * that isn't implemented, so instead we enumerate the busses and
3178 * send the rescan or reset to those busses in the case where the
3179 * given bus is -1 (wildcard). We don't send a rescan or reset
3180 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3181 * no-op, sending a rescan to the xpt bus would result in a status of
3184 matchccb = malloc(sizeof(*matchccb));
3185 if (matchccb == NULL) {
3186 warn("failed to allocate CCB");
3190 bzero(matchccb, sizeof(*matchccb));
3191 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3192 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3193 bufsize = sizeof(struct dev_match_result) * 20;
3194 matchccb->cdm.match_buf_len = bufsize;
3195 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3196 if (matchccb->cdm.matches == NULL) {
3197 warnx("can't malloc memory for matches");
3201 matchccb->cdm.num_matches = 0;
3203 matchccb->cdm.num_patterns = 1;
3204 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3206 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3207 matchccb->cdm.pattern_buf_len);
3208 if (matchccb->cdm.patterns == NULL) {
3209 warnx("can't malloc memory for patterns");
3213 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3214 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3219 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3220 warn("CAMIOCOMMAND ioctl failed");
3225 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3226 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3227 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3228 warnx("got CAM error %#x, CDM error %d\n",
3229 matchccb->ccb_h.status, matchccb->cdm.status);
3234 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3235 struct bus_match_result *bus_result;
3237 /* This shouldn't happen. */
3238 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3241 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3244 * We don't want to rescan or reset the xpt bus.
3247 if (bus_result->path_id == CAM_XPT_PATH_ID)
3250 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3252 ccb->ccb_h.path_id = bus_result->path_id;
3253 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3254 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3255 ccb->crcn.flags = CAM_FLAG_NONE;
3257 /* run this at a low priority */
3258 ccb->ccb_h.pinfo.priority = 5;
3260 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3261 warn("CAMIOCOMMAND ioctl failed");
3266 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3267 fprintf(stdout, "%s of bus %d was successful\n",
3268 rescan? "Re-scan" : "Reset",
3269 bus_result->path_id);
3272 * Don't bail out just yet, maybe the other
3273 * rescan or reset commands will complete
3276 fprintf(stderr, "%s of bus %d returned error "
3277 "%#x\n", rescan? "Re-scan" : "Reset",
3278 bus_result->path_id,
3279 ccb->ccb_h.status & CAM_STATUS_MASK);
3283 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3284 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3291 if (matchccb != NULL) {
3292 free(matchccb->cdm.patterns);
3293 free(matchccb->cdm.matches);
3302 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3305 struct cam_device *device;
3310 if (bus == CAM_BUS_WILDCARD) {
3311 warnx("invalid bus number %d", bus);
3315 if (target == CAM_TARGET_WILDCARD) {
3316 warnx("invalid target number %d", target);
3320 if (lun == CAM_LUN_WILDCARD) {
3321 warnx("invalid lun number %jx", (uintmax_t)lun);
3327 bzero(&ccb, sizeof(union ccb));
3330 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3331 warnx("error opening transport layer device %s\n",
3333 warn("%s", XPT_DEVICE);
3337 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3338 if (device == NULL) {
3339 warnx("%s", cam_errbuf);
3344 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3345 ccb.ccb_h.path_id = bus;
3346 ccb.ccb_h.target_id = target;
3347 ccb.ccb_h.target_lun = lun;
3348 ccb.ccb_h.timeout = 5000;
3349 ccb.crcn.flags = CAM_FLAG_NONE;
3351 /* run this at a low priority */
3352 ccb.ccb_h.pinfo.priority = 5;
3355 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3356 warn("CAMIOCOMMAND ioctl failed");
3361 if (cam_send_ccb(device, &ccb) < 0) {
3362 warn("error sending XPT_RESET_DEV CCB");
3363 cam_close_device(device);
3371 cam_close_device(device);
3374 * An error code of CAM_BDR_SENT is normal for a BDR request.
3376 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3378 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3379 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3380 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3383 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3384 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3385 ccb.ccb_h.status & CAM_STATUS_MASK);
3390 #ifndef MINIMALISTIC
3392 static struct scsi_nv defect_list_type_map[] = {
3393 { "block", SRDD10_BLOCK_FORMAT },
3394 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3395 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3396 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3397 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3398 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3402 readdefects(struct cam_device *device, int argc, char **argv,
3403 char *combinedopt, int retry_count, int timeout)
3405 union ccb *ccb = NULL;
3406 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3407 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3408 size_t hdr_size = 0, entry_size = 0;
3411 u_int8_t *defect_list = NULL;
3412 u_int8_t list_format = 0;
3413 int list_type_set = 0;
3414 u_int32_t dlist_length = 0;
3415 u_int32_t returned_length = 0, valid_len = 0;
3416 u_int32_t num_returned = 0, num_valid = 0;
3417 u_int32_t max_possible_size = 0, hdr_max = 0;
3418 u_int32_t starting_offset = 0;
3419 u_int8_t returned_format, returned_type;
3421 int summary = 0, quiet = 0;
3423 int lists_specified = 0;
3424 int get_length = 1, first_pass = 1;
3427 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3431 scsi_nv_status status;
3434 status = scsi_get_nv(defect_list_type_map,
3435 sizeof(defect_list_type_map) /
3436 sizeof(defect_list_type_map[0]), optarg,
3437 &entry_num, SCSI_NV_FLAG_IG_CASE);
3439 if (status == SCSI_NV_FOUND) {
3440 list_format = defect_list_type_map[
3444 warnx("%s: %s %s option %s", __func__,
3445 (status == SCSI_NV_AMBIGUOUS) ?
3446 "ambiguous" : "invalid", "defect list type",
3449 goto defect_bailout;
3454 arglist |= CAM_ARG_GLIST;
3457 arglist |= CAM_ARG_PLIST;
3468 starting_offset = strtoul(optarg, &endptr, 0);
3469 if (*endptr != '\0') {
3471 warnx("invalid starting offset %s", optarg);
3472 goto defect_bailout;
3484 if (list_type_set == 0) {
3486 warnx("no defect list format specified");
3487 goto defect_bailout;
3490 if (arglist & CAM_ARG_PLIST) {
3491 list_format |= SRDD10_PLIST;
3495 if (arglist & CAM_ARG_GLIST) {
3496 list_format |= SRDD10_GLIST;
3501 * This implies a summary, and was the previous behavior.
3503 if (lists_specified == 0)
3506 ccb = cam_getccb(device);
3511 * We start off asking for just the header to determine how much
3512 * defect data is available. Some Hitachi drives return an error
3513 * if you ask for more data than the drive has. Once we know the
3514 * length, we retry the command with the returned length.
3516 if (use_12byte == 0)
3517 dlist_length = sizeof(*hdr10);
3519 dlist_length = sizeof(*hdr12);
3522 if (defect_list != NULL) {
3526 defect_list = malloc(dlist_length);
3527 if (defect_list == NULL) {
3528 warnx("can't malloc memory for defect list");
3530 goto defect_bailout;
3534 bzero(defect_list, dlist_length);
3537 * cam_getccb() zeros the CCB header only. So we need to zero the
3538 * payload portion of the ccb.
3540 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3542 scsi_read_defects(&ccb->csio,
3543 /*retries*/ retry_count,
3545 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3546 /*list_format*/ list_format,
3547 /*addr_desc_index*/ starting_offset,
3548 /*data_ptr*/ defect_list,
3549 /*dxfer_len*/ dlist_length,
3550 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3551 /*sense_len*/ SSD_FULL_SIZE,
3552 /*timeout*/ timeout ? timeout : 5000);
3554 /* Disable freezing the device queue */
3555 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3557 if (cam_send_ccb(device, ccb) < 0) {
3558 perror("error reading defect list");
3560 if (arglist & CAM_ARG_VERBOSE) {
3561 cam_error_print(device, ccb, CAM_ESF_ALL,
3562 CAM_EPF_ALL, stderr);
3566 goto defect_bailout;
3569 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3571 if (use_12byte == 0) {
3572 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3573 hdr_size = sizeof(*hdr10);
3574 hdr_max = SRDDH10_MAX_LENGTH;
3576 if (valid_len >= hdr_size) {
3577 returned_length = scsi_2btoul(hdr10->length);
3578 returned_format = hdr10->format;
3580 returned_length = 0;
3581 returned_format = 0;
3584 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3585 hdr_size = sizeof(*hdr12);
3586 hdr_max = SRDDH12_MAX_LENGTH;
3588 if (valid_len >= hdr_size) {
3589 returned_length = scsi_4btoul(hdr12->length);
3590 returned_format = hdr12->format;
3592 returned_length = 0;
3593 returned_format = 0;
3597 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3598 switch (returned_type) {
3599 case SRDD10_BLOCK_FORMAT:
3600 entry_size = sizeof(struct scsi_defect_desc_block);
3602 case SRDD10_LONG_BLOCK_FORMAT:
3603 entry_size = sizeof(struct scsi_defect_desc_long_block);
3605 case SRDD10_EXT_PHYS_FORMAT:
3606 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3607 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3609 case SRDD10_EXT_BFI_FORMAT:
3610 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3611 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3614 warnx("Unknown defect format 0x%x\n", returned_type);
3616 goto defect_bailout;
3620 max_possible_size = (hdr_max / entry_size) * entry_size;
3621 num_returned = returned_length / entry_size;
3622 num_valid = min(returned_length, valid_len - hdr_size);
3623 num_valid /= entry_size;
3625 if (get_length != 0) {
3628 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3629 CAM_SCSI_STATUS_ERROR) {
3630 struct scsi_sense_data *sense;
3631 int error_code, sense_key, asc, ascq;
3633 sense = &ccb->csio.sense_data;
3634 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3635 ccb->csio.sense_resid, &error_code, &sense_key,
3636 &asc, &ascq, /*show_errors*/ 1);
3639 * If the drive is reporting that it just doesn't
3640 * support the defect list format, go ahead and use
3641 * the length it reported. Otherwise, the length
3642 * may not be valid, so use the maximum.
3644 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3645 && (asc == 0x1c) && (ascq == 0x00)
3646 && (returned_length > 0)) {
3647 if ((use_12byte == 0)
3648 && (returned_length >= max_possible_size)) {
3653 dlist_length = returned_length + hdr_size;
3654 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3655 && (asc == 0x1f) && (ascq == 0x00)
3656 && (returned_length > 0)) {
3657 /* Partial defect list transfer */
3659 * Hitachi drives return this error
3660 * along with a partial defect list if they
3661 * have more defects than the 10 byte
3662 * command can support. Retry with the 12
3665 if (use_12byte == 0) {
3670 dlist_length = returned_length + hdr_size;
3671 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3672 && (asc == 0x24) && (ascq == 0x00)) {
3673 /* Invalid field in CDB */
3675 * SBC-3 says that if the drive has more
3676 * defects than can be reported with the
3677 * 10 byte command, it should return this
3678 * error and no data. Retry with the 12
3681 if (use_12byte == 0) {
3686 dlist_length = returned_length + hdr_size;
3689 * If we got a SCSI error and no valid length,
3690 * just use the 10 byte maximum. The 12
3691 * byte maximum is too large.
3693 if (returned_length == 0)
3694 dlist_length = SRDD10_MAX_LENGTH;
3696 if ((use_12byte == 0)
3697 && (returned_length >=
3698 max_possible_size)) {
3703 dlist_length = returned_length +
3707 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3710 warnx("Error reading defect header");
3711 if (arglist & CAM_ARG_VERBOSE)
3712 cam_error_print(device, ccb, CAM_ESF_ALL,
3713 CAM_EPF_ALL, stderr);
3714 goto defect_bailout;
3716 if ((use_12byte == 0)
3717 && (returned_length >= max_possible_size)) {
3722 dlist_length = returned_length + hdr_size;
3725 fprintf(stdout, "%u", num_returned);
3727 fprintf(stdout, " defect%s",
3728 (num_returned != 1) ? "s" : "");
3730 fprintf(stdout, "\n");
3732 goto defect_bailout;
3736 * We always limit the list length to the 10-byte maximum
3737 * length (0xffff). The reason is that some controllers
3738 * can't handle larger I/Os, and we can transfer the entire
3739 * 10 byte list in one shot. For drives that support the 12
3740 * byte read defects command, we'll step through the list
3741 * by specifying a starting offset. For drives that don't
3742 * support the 12 byte command's starting offset, we'll
3743 * just display the first 64K.
3745 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3751 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3752 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3753 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3754 struct scsi_sense_data *sense;
3755 int error_code, sense_key, asc, ascq;
3757 sense = &ccb->csio.sense_data;
3758 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3759 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3760 &ascq, /*show_errors*/ 1);
3763 * According to the SCSI spec, if the disk doesn't support
3764 * the requested format, it will generally return a sense
3765 * key of RECOVERED ERROR, and an additional sense code
3766 * of "DEFECT LIST NOT FOUND". HGST drives also return
3767 * Primary/Grown defect list not found errors. So just
3768 * check for an ASC of 0x1c.
3770 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3772 const char *format_str;
3774 format_str = scsi_nv_to_str(defect_list_type_map,
3775 sizeof(defect_list_type_map) /
3776 sizeof(defect_list_type_map[0]),
3777 list_format & SRDD10_DLIST_FORMAT_MASK);
3778 warnx("requested defect format %s not available",
3779 format_str ? format_str : "unknown");
3781 format_str = scsi_nv_to_str(defect_list_type_map,
3782 sizeof(defect_list_type_map) /
3783 sizeof(defect_list_type_map[0]), returned_type);
3784 if (format_str != NULL) {
3785 warnx("Device returned %s format",
3789 warnx("Device returned unknown defect"
3790 " data format %#x", returned_type);
3791 goto defect_bailout;
3795 warnx("Error returned from read defect data command");
3796 if (arglist & CAM_ARG_VERBOSE)
3797 cam_error_print(device, ccb, CAM_ESF_ALL,
3798 CAM_EPF_ALL, stderr);
3799 goto defect_bailout;
3801 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3803 warnx("Error returned from read defect data command");
3804 if (arglist & CAM_ARG_VERBOSE)
3805 cam_error_print(device, ccb, CAM_ESF_ALL,
3806 CAM_EPF_ALL, stderr);
3807 goto defect_bailout;
3810 if (first_pass != 0) {
3811 fprintf(stderr, "Got %d defect", num_returned);
3813 if ((lists_specified == 0) || (num_returned == 0)) {
3814 fprintf(stderr, "s.\n");
3815 goto defect_bailout;
3816 } else if (num_returned == 1)
3817 fprintf(stderr, ":\n");
3819 fprintf(stderr, "s:\n");
3825 * XXX KDM I should probably clean up the printout format for the
3828 switch (returned_type) {
3829 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3830 case SRDD10_EXT_PHYS_FORMAT:
3832 struct scsi_defect_desc_phys_sector *dlist;
3834 dlist = (struct scsi_defect_desc_phys_sector *)
3835 (defect_list + hdr_size);
3837 for (i = 0; i < num_valid; i++) {
3840 sector = scsi_4btoul(dlist[i].sector);
3841 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3842 mads = (sector & SDD_EXT_PHYS_MADS) ?
3844 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3846 if (hex_format == 0)
3847 fprintf(stdout, "%d:%d:%d%s",
3848 scsi_3btoul(dlist[i].cylinder),
3850 scsi_4btoul(dlist[i].sector),
3851 mads ? " - " : "\n");
3853 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3854 scsi_3btoul(dlist[i].cylinder),
3856 scsi_4btoul(dlist[i].sector),
3857 mads ? " - " : "\n");
3860 if (num_valid < num_returned) {
3861 starting_offset += num_valid;
3866 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3867 case SRDD10_EXT_BFI_FORMAT:
3869 struct scsi_defect_desc_bytes_from_index *dlist;
3871 dlist = (struct scsi_defect_desc_bytes_from_index *)
3872 (defect_list + hdr_size);
3874 for (i = 0; i < num_valid; i++) {
3877 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3878 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3879 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3880 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3882 if (hex_format == 0)
3883 fprintf(stdout, "%d:%d:%d%s",
3884 scsi_3btoul(dlist[i].cylinder),
3886 scsi_4btoul(dlist[i].bytes_from_index),
3887 mads ? " - " : "\n");
3889 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3890 scsi_3btoul(dlist[i].cylinder),
3892 scsi_4btoul(dlist[i].bytes_from_index),
3893 mads ? " - " : "\n");
3897 if (num_valid < num_returned) {
3898 starting_offset += num_valid;
3903 case SRDDH10_BLOCK_FORMAT:
3905 struct scsi_defect_desc_block *dlist;
3907 dlist = (struct scsi_defect_desc_block *)
3908 (defect_list + hdr_size);
3910 for (i = 0; i < num_valid; i++) {
3911 if (hex_format == 0)
3912 fprintf(stdout, "%u\n",
3913 scsi_4btoul(dlist[i].address));
3915 fprintf(stdout, "0x%x\n",
3916 scsi_4btoul(dlist[i].address));
3919 if (num_valid < num_returned) {
3920 starting_offset += num_valid;
3926 case SRDD10_LONG_BLOCK_FORMAT:
3928 struct scsi_defect_desc_long_block *dlist;
3930 dlist = (struct scsi_defect_desc_long_block *)
3931 (defect_list + hdr_size);
3933 for (i = 0; i < num_valid; i++) {
3934 if (hex_format == 0)
3935 fprintf(stdout, "%ju\n",
3936 (uintmax_t)scsi_8btou64(
3939 fprintf(stdout, "0x%jx\n",
3940 (uintmax_t)scsi_8btou64(
3944 if (num_valid < num_returned) {
3945 starting_offset += num_valid;
3951 fprintf(stderr, "Unknown defect format 0x%x\n",
3958 if (defect_list != NULL)
3966 #endif /* MINIMALISTIC */
3970 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3974 ccb = cam_getccb(device);
3980 #ifndef MINIMALISTIC
3982 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
3983 int retry_count, int timeout, u_int8_t *data, int datalen)
3988 ccb = cam_getccb(device);
3991 errx(1, "mode_sense: couldn't allocate CCB");
3993 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3995 scsi_mode_sense_subpage(&ccb->csio,
3996 /* retries */ retry_count,
3998 /* tag_action */ MSG_SIMPLE_Q_TAG,
4002 /* subpage */ subpage,
4003 /* param_buf */ data,
4004 /* param_len */ datalen,
4005 /* minimum_cmd_size */ 0,
4006 /* sense_len */ SSD_FULL_SIZE,
4007 /* timeout */ timeout ? timeout : 5000);
4009 if (arglist & CAM_ARG_ERR_RECOVER)
4010 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4012 /* Disable freezing the device queue */
4013 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4015 if (((retval = cam_send_ccb(device, ccb)) < 0)
4016 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4017 if (arglist & CAM_ARG_VERBOSE) {
4018 cam_error_print(device, ccb, CAM_ESF_ALL,
4019 CAM_EPF_ALL, stderr);
4022 cam_close_device(device);
4024 err(1, "error sending mode sense command");
4026 errx(1, "error sending mode sense command");
4033 mode_select(struct cam_device *device, int save_pages, int retry_count,
4034 int timeout, u_int8_t *data, int datalen)
4039 ccb = cam_getccb(device);
4042 errx(1, "mode_select: couldn't allocate CCB");
4044 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4046 scsi_mode_select(&ccb->csio,
4047 /* retries */ retry_count,
4049 /* tag_action */ MSG_SIMPLE_Q_TAG,
4050 /* scsi_page_fmt */ 1,
4051 /* save_pages */ save_pages,
4052 /* param_buf */ data,
4053 /* param_len */ datalen,
4054 /* sense_len */ SSD_FULL_SIZE,
4055 /* timeout */ timeout ? timeout : 5000);
4057 if (arglist & CAM_ARG_ERR_RECOVER)
4058 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4060 /* Disable freezing the device queue */
4061 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4063 if (((retval = cam_send_ccb(device, ccb)) < 0)
4064 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4065 if (arglist & CAM_ARG_VERBOSE) {
4066 cam_error_print(device, ccb, CAM_ESF_ALL,
4067 CAM_EPF_ALL, stderr);
4070 cam_close_device(device);
4073 err(1, "error sending mode select command");
4075 errx(1, "error sending mode select command");
4083 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4084 int retry_count, int timeout)
4087 int c, page = -1, subpage = -1, pc = 0;
4088 int binary = 0, dbd = 0, edit = 0, list = 0;
4090 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4105 str_subpage = optarg;
4106 strsep(&str_subpage, ",");
4107 page = strtol(optarg, NULL, 0);
4109 subpage = strtol(str_subpage, NULL, 0);
4113 errx(1, "invalid mode page %d", page);
4115 errx(1, "invalid mode subpage %d", subpage);
4118 pc = strtol(optarg, NULL, 0);
4119 if ((pc < 0) || (pc > 3))
4120 errx(1, "invalid page control field %d", pc);
4127 if (page == -1 && list == 0)
4128 errx(1, "you must specify a mode page!");
4131 mode_list(device, dbd, pc, list > 1, retry_count, timeout);
4133 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4134 retry_count, timeout);
4139 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4140 int retry_count, int timeout)
4143 u_int32_t flags = CAM_DIR_NONE;
4144 u_int8_t *data_ptr = NULL;
4146 u_int8_t atacmd[12];
4147 struct get_hook hook;
4148 int c, data_bytes = 0;
4154 char *datastr = NULL, *tstr, *resstr = NULL;
4156 int fd_data = 0, fd_res = 0;
4159 ccb = cam_getccb(device);
4162 warnx("scsicmd: error allocating ccb");
4166 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4168 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4172 while (isspace(*tstr) && (*tstr != '\0'))
4174 hook.argc = argc - optind;
4175 hook.argv = argv + optind;
4177 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4180 * Increment optind by the number of arguments the
4181 * encoding routine processed. After each call to
4182 * getopt(3), optind points to the argument that
4183 * getopt should process _next_. In this case,
4184 * that means it points to the first command string
4185 * argument, if there is one. Once we increment
4186 * this, it should point to either the next command
4187 * line argument, or it should be past the end of
4194 while (isspace(*tstr) && (*tstr != '\0'))
4196 hook.argc = argc - optind;
4197 hook.argv = argv + optind;
4199 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4202 * Increment optind by the number of arguments the
4203 * encoding routine processed. After each call to
4204 * getopt(3), optind points to the argument that
4205 * getopt should process _next_. In this case,
4206 * that means it points to the first command string
4207 * argument, if there is one. Once we increment
4208 * this, it should point to either the next command
4209 * line argument, or it should be past the end of
4221 if (arglist & CAM_ARG_CMD_OUT) {
4222 warnx("command must either be "
4223 "read or write, not both");
4225 goto scsicmd_bailout;
4227 arglist |= CAM_ARG_CMD_IN;
4229 data_bytes = strtol(optarg, NULL, 0);
4230 if (data_bytes <= 0) {
4231 warnx("invalid number of input bytes %d",
4234 goto scsicmd_bailout;
4236 hook.argc = argc - optind;
4237 hook.argv = argv + optind;
4240 datastr = cget(&hook, NULL);
4242 * If the user supplied "-" instead of a format, he
4243 * wants the data to be written to stdout.
4245 if ((datastr != NULL)
4246 && (datastr[0] == '-'))
4249 data_ptr = (u_int8_t *)malloc(data_bytes);
4250 if (data_ptr == NULL) {
4251 warnx("can't malloc memory for data_ptr");
4253 goto scsicmd_bailout;
4257 if (arglist & CAM_ARG_CMD_IN) {
4258 warnx("command must either be "
4259 "read or write, not both");
4261 goto scsicmd_bailout;
4263 arglist |= CAM_ARG_CMD_OUT;
4264 flags = CAM_DIR_OUT;
4265 data_bytes = strtol(optarg, NULL, 0);
4266 if (data_bytes <= 0) {
4267 warnx("invalid number of output bytes %d",
4270 goto scsicmd_bailout;
4272 hook.argc = argc - optind;
4273 hook.argv = argv + optind;
4275 datastr = cget(&hook, NULL);
4276 data_ptr = (u_int8_t *)malloc(data_bytes);
4277 if (data_ptr == NULL) {
4278 warnx("can't malloc memory for data_ptr");
4280 goto scsicmd_bailout;
4282 bzero(data_ptr, data_bytes);
4284 * If the user supplied "-" instead of a format, he
4285 * wants the data to be read from stdin.
4287 if ((datastr != NULL)
4288 && (datastr[0] == '-'))
4291 buff_encode_visit(data_ptr, data_bytes, datastr,
4297 hook.argc = argc - optind;
4298 hook.argv = argv + optind;
4300 resstr = cget(&hook, NULL);
4301 if ((resstr != NULL) && (resstr[0] == '-'))
4311 * If fd_data is set, and we're writing to the device, we need to
4312 * read the data the user wants written from stdin.
4314 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4316 int amt_to_read = data_bytes;
4317 u_int8_t *buf_ptr = data_ptr;
4319 for (amt_read = 0; amt_to_read > 0;
4320 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4321 if (amt_read == -1) {
4322 warn("error reading data from stdin");
4324 goto scsicmd_bailout;
4326 amt_to_read -= amt_read;
4327 buf_ptr += amt_read;
4331 if (arglist & CAM_ARG_ERR_RECOVER)
4332 flags |= CAM_PASS_ERR_RECOVER;
4334 /* Disable freezing the device queue */
4335 flags |= CAM_DEV_QFRZDIS;
4339 * This is taken from the SCSI-3 draft spec.
4340 * (T10/1157D revision 0.3)
4341 * The top 3 bits of an opcode are the group code.
4342 * The next 5 bits are the command code.
4343 * Group 0: six byte commands
4344 * Group 1: ten byte commands
4345 * Group 2: ten byte commands
4347 * Group 4: sixteen byte commands
4348 * Group 5: twelve byte commands
4349 * Group 6: vendor specific
4350 * Group 7: vendor specific
4352 switch((cdb[0] >> 5) & 0x7) {
4363 /* computed by buff_encode_visit */
4374 * We should probably use csio_build_visit or something like that
4375 * here, but it's easier to encode arguments as you go. The
4376 * alternative would be skipping the CDB argument and then encoding
4377 * it here, since we've got the data buffer argument by now.
4379 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4381 cam_fill_csio(&ccb->csio,
4382 /*retries*/ retry_count,
4385 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4386 /*data_ptr*/ data_ptr,
4387 /*dxfer_len*/ data_bytes,
4388 /*sense_len*/ SSD_FULL_SIZE,
4389 /*cdb_len*/ cdb_len,
4390 /*timeout*/ timeout ? timeout : 5000);
4393 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4395 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4397 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4399 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4401 cam_fill_ataio(&ccb->ataio,
4402 /*retries*/ retry_count,
4406 /*data_ptr*/ data_ptr,
4407 /*dxfer_len*/ data_bytes,
4408 /*timeout*/ timeout ? timeout : 5000);
4411 if (((retval = cam_send_ccb(device, ccb)) < 0)
4412 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4413 const char warnstr[] = "error sending command";
4420 if (arglist & CAM_ARG_VERBOSE) {
4421 cam_error_print(device, ccb, CAM_ESF_ALL,
4422 CAM_EPF_ALL, stderr);
4426 goto scsicmd_bailout;
4429 if (atacmd_len && need_res) {
4431 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4433 fprintf(stdout, "\n");
4436 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4437 ccb->ataio.res.status,
4438 ccb->ataio.res.error,
4439 ccb->ataio.res.lba_low,
4440 ccb->ataio.res.lba_mid,
4441 ccb->ataio.res.lba_high,
4442 ccb->ataio.res.device,
4443 ccb->ataio.res.lba_low_exp,
4444 ccb->ataio.res.lba_mid_exp,
4445 ccb->ataio.res.lba_high_exp,
4446 ccb->ataio.res.sector_count,
4447 ccb->ataio.res.sector_count_exp);
4452 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4453 && (arglist & CAM_ARG_CMD_IN)
4454 && (data_bytes > 0)) {
4456 buff_decode_visit(data_ptr, data_bytes, datastr,
4458 fprintf(stdout, "\n");
4460 ssize_t amt_written;
4461 int amt_to_write = data_bytes;
4462 u_int8_t *buf_ptr = data_ptr;
4464 for (amt_written = 0; (amt_to_write > 0) &&
4465 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4466 amt_to_write -= amt_written;
4467 buf_ptr += amt_written;
4469 if (amt_written == -1) {
4470 warn("error writing data to stdout");
4472 goto scsicmd_bailout;
4473 } else if ((amt_written == 0)
4474 && (amt_to_write > 0)) {
4475 warnx("only wrote %u bytes out of %u",
4476 data_bytes - amt_to_write, data_bytes);
4483 if ((data_bytes > 0) && (data_ptr != NULL))
4492 camdebug(int argc, char **argv, char *combinedopt)
4495 path_id_t bus = CAM_BUS_WILDCARD;
4496 target_id_t target = CAM_TARGET_WILDCARD;
4497 lun_id_t lun = CAM_LUN_WILDCARD;
4498 char *tstr, *tmpstr = NULL;
4502 bzero(&ccb, sizeof(union ccb));
4504 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4507 arglist |= CAM_ARG_DEBUG_INFO;
4508 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4511 arglist |= CAM_ARG_DEBUG_PERIPH;
4512 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4515 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4516 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4519 arglist |= CAM_ARG_DEBUG_TRACE;
4520 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4523 arglist |= CAM_ARG_DEBUG_XPT;
4524 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4527 arglist |= CAM_ARG_DEBUG_CDB;
4528 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4531 arglist |= CAM_ARG_DEBUG_PROBE;
4532 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4539 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4540 warnx("error opening transport layer device %s", XPT_DEVICE);
4541 warn("%s", XPT_DEVICE);
4548 warnx("you must specify \"off\", \"all\" or a bus,");
4549 warnx("bus:target, or bus:target:lun");
4556 while (isspace(*tstr) && (*tstr != '\0'))
4559 if (strncmp(tstr, "off", 3) == 0) {
4560 ccb.cdbg.flags = CAM_DEBUG_NONE;
4561 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4562 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4563 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4564 } else if (strncmp(tstr, "all", 3) != 0) {
4565 tmpstr = (char *)strtok(tstr, ":");
4566 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4567 bus = strtol(tmpstr, NULL, 0);
4568 arglist |= CAM_ARG_BUS;
4569 tmpstr = (char *)strtok(NULL, ":");
4570 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4571 target = strtol(tmpstr, NULL, 0);
4572 arglist |= CAM_ARG_TARGET;
4573 tmpstr = (char *)strtok(NULL, ":");
4574 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4575 lun = strtol(tmpstr, NULL, 0);
4576 arglist |= CAM_ARG_LUN;
4581 warnx("you must specify \"all\", \"off\", or a bus,");
4582 warnx("bus:target, or bus:target:lun to debug");
4588 ccb.ccb_h.func_code = XPT_DEBUG;
4589 ccb.ccb_h.path_id = bus;
4590 ccb.ccb_h.target_id = target;
4591 ccb.ccb_h.target_lun = lun;
4593 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4594 warn("CAMIOCOMMAND ioctl failed");
4599 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4600 CAM_FUNC_NOTAVAIL) {
4601 warnx("CAM debugging not available");
4602 warnx("you need to put options CAMDEBUG in"
4603 " your kernel config file!");
4605 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4607 warnx("XPT_DEBUG CCB failed with status %#x",
4611 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4613 "Debugging turned off\n");
4616 "Debugging enabled for "
4618 bus, target, (uintmax_t)lun);
4629 tagcontrol(struct cam_device *device, int argc, char **argv,
4639 ccb = cam_getccb(device);
4642 warnx("tagcontrol: error allocating ccb");
4646 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4649 numtags = strtol(optarg, NULL, 0);
4651 warnx("tag count %d is < 0", numtags);
4653 goto tagcontrol_bailout;
4664 cam_path_string(device, pathstr, sizeof(pathstr));
4667 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4668 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4669 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4670 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4671 ccb->crs.openings = numtags;
4674 if (cam_send_ccb(device, ccb) < 0) {
4675 perror("error sending XPT_REL_SIMQ CCB");
4677 goto tagcontrol_bailout;
4680 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4681 warnx("XPT_REL_SIMQ CCB failed");
4682 cam_error_print(device, ccb, CAM_ESF_ALL,
4683 CAM_EPF_ALL, stderr);
4685 goto tagcontrol_bailout;
4690 fprintf(stdout, "%stagged openings now %d\n",
4691 pathstr, ccb->crs.openings);
4694 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4696 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4698 if (cam_send_ccb(device, ccb) < 0) {
4699 perror("error sending XPT_GDEV_STATS CCB");
4701 goto tagcontrol_bailout;
4704 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4705 warnx("XPT_GDEV_STATS CCB failed");
4706 cam_error_print(device, ccb, CAM_ESF_ALL,
4707 CAM_EPF_ALL, stderr);
4709 goto tagcontrol_bailout;
4712 if (arglist & CAM_ARG_VERBOSE) {
4713 fprintf(stdout, "%s", pathstr);
4714 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4715 fprintf(stdout, "%s", pathstr);
4716 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4717 fprintf(stdout, "%s", pathstr);
4718 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4719 fprintf(stdout, "%s", pathstr);
4720 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4721 fprintf(stdout, "%s", pathstr);
4722 fprintf(stdout, "held %d\n", ccb->cgds.held);
4723 fprintf(stdout, "%s", pathstr);
4724 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4725 fprintf(stdout, "%s", pathstr);
4726 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4729 fprintf(stdout, "%s", pathstr);
4730 fprintf(stdout, "device openings: ");
4732 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4733 ccb->cgds.dev_active);
4743 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4747 cam_path_string(device, pathstr, sizeof(pathstr));
4749 if (cts->transport == XPORT_SPI) {
4750 struct ccb_trans_settings_spi *spi =
4751 &cts->xport_specific.spi;
4753 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4755 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4758 if (spi->sync_offset != 0) {
4761 freq = scsi_calc_syncsrate(spi->sync_period);
4762 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4763 pathstr, freq / 1000, freq % 1000);
4767 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4768 fprintf(stdout, "%soffset: %d\n", pathstr,
4772 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4773 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4774 (0x01 << spi->bus_width) * 8);
4777 if (spi->valid & CTS_SPI_VALID_DISC) {
4778 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4779 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4780 "enabled" : "disabled");
4783 if (cts->transport == XPORT_FC) {
4784 struct ccb_trans_settings_fc *fc =
4785 &cts->xport_specific.fc;
4787 if (fc->valid & CTS_FC_VALID_WWNN)
4788 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4789 (long long) fc->wwnn);
4790 if (fc->valid & CTS_FC_VALID_WWPN)
4791 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4792 (long long) fc->wwpn);
4793 if (fc->valid & CTS_FC_VALID_PORT)
4794 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4795 if (fc->valid & CTS_FC_VALID_SPEED)
4796 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4797 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4799 if (cts->transport == XPORT_SAS) {
4800 struct ccb_trans_settings_sas *sas =
4801 &cts->xport_specific.sas;
4803 if (sas->valid & CTS_SAS_VALID_SPEED)
4804 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4805 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4807 if (cts->transport == XPORT_ATA) {
4808 struct ccb_trans_settings_pata *pata =
4809 &cts->xport_specific.ata;
4811 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4812 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4813 ata_mode2string(pata->mode));
4815 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4816 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4819 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4820 fprintf(stdout, "%sPIO transaction length: %d\n",
4821 pathstr, pata->bytecount);
4824 if (cts->transport == XPORT_SATA) {
4825 struct ccb_trans_settings_sata *sata =
4826 &cts->xport_specific.sata;
4828 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4829 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4832 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4833 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4834 ata_mode2string(sata->mode));
4836 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4837 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4840 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4841 fprintf(stdout, "%sPIO transaction length: %d\n",
4842 pathstr, sata->bytecount);
4844 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4845 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4848 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4849 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4852 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4853 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4857 if (cts->protocol == PROTO_ATA) {
4858 struct ccb_trans_settings_ata *ata=
4859 &cts->proto_specific.ata;
4861 if (ata->valid & CTS_ATA_VALID_TQ) {
4862 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4863 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4864 "enabled" : "disabled");
4867 if (cts->protocol == PROTO_SCSI) {
4868 struct ccb_trans_settings_scsi *scsi=
4869 &cts->proto_specific.scsi;
4871 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4872 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4873 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4874 "enabled" : "disabled");
4881 * Get a path inquiry CCB for the specified device.
4884 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4889 ccb = cam_getccb(device);
4891 warnx("get_cpi: couldn't allocate CCB");
4894 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
4895 ccb->ccb_h.func_code = XPT_PATH_INQ;
4896 if (cam_send_ccb(device, ccb) < 0) {
4897 warn("get_cpi: error sending Path Inquiry CCB");
4898 if (arglist & CAM_ARG_VERBOSE)
4899 cam_error_print(device, ccb, CAM_ESF_ALL,
4900 CAM_EPF_ALL, stderr);
4902 goto get_cpi_bailout;
4904 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4905 if (arglist & CAM_ARG_VERBOSE)
4906 cam_error_print(device, ccb, CAM_ESF_ALL,
4907 CAM_EPF_ALL, stderr);
4909 goto get_cpi_bailout;
4911 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4919 * Get a get device CCB for the specified device.
4922 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4927 ccb = cam_getccb(device);
4929 warnx("get_cgd: couldn't allocate CCB");
4932 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
4933 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4934 if (cam_send_ccb(device, ccb) < 0) {
4935 warn("get_cgd: error sending Path Inquiry CCB");
4936 if (arglist & CAM_ARG_VERBOSE)
4937 cam_error_print(device, ccb, CAM_ESF_ALL,
4938 CAM_EPF_ALL, stderr);
4940 goto get_cgd_bailout;
4942 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4943 if (arglist & CAM_ARG_VERBOSE)
4944 cam_error_print(device, ccb, CAM_ESF_ALL,
4945 CAM_EPF_ALL, stderr);
4947 goto get_cgd_bailout;
4949 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4957 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4961 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4962 int timeout, int verbosemode)
4964 union ccb *ccb = NULL;
4965 struct scsi_vpd_supported_page_list sup_pages;
4969 ccb = cam_getccb(dev);
4971 warn("Unable to allocate CCB");
4976 /* cam_getccb cleans up the header, caller has to zero the payload */
4977 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4979 bzero(&sup_pages, sizeof(sup_pages));
4981 scsi_inquiry(&ccb->csio,
4982 /*retries*/ retry_count,
4984 /* tag_action */ MSG_SIMPLE_Q_TAG,
4985 /* inq_buf */ (u_int8_t *)&sup_pages,
4986 /* inq_len */ sizeof(sup_pages),
4988 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
4989 /* sense_len */ SSD_FULL_SIZE,
4990 /* timeout */ timeout ? timeout : 5000);
4992 /* Disable freezing the device queue */
4993 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4995 if (retry_count != 0)
4996 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4998 if (cam_send_ccb(dev, ccb) < 0) {
5005 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5006 if (verbosemode != 0)
5007 cam_error_print(dev, ccb, CAM_ESF_ALL,
5008 CAM_EPF_ALL, stderr);
5013 for (i = 0; i < sup_pages.length; i++) {
5014 if (sup_pages.list[i] == page_id) {
5027 * devtype is filled in with the type of device.
5028 * Returns 0 for success, non-zero for failure.
5031 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5032 int verbosemode, camcontrol_devtype *devtype)
5034 struct ccb_getdev cgd;
5037 retval = get_cgd(dev, &cgd);
5041 switch (cgd.protocol) {
5047 *devtype = CC_DT_ATA;
5049 break; /*NOTREACHED*/
5051 *devtype = CC_DT_UNKNOWN;
5053 break; /*NOTREACHED*/
5057 * Check for the ATA Information VPD page (0x89). If this is an
5058 * ATA device behind a SCSI to ATA translation layer, this VPD page
5059 * should be present.
5061 * If that VPD page isn't present, or we get an error back from the
5062 * INQUIRY command, we'll just treat it as a normal SCSI device.
5064 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5065 timeout, verbosemode);
5067 *devtype = CC_DT_ATA_BEHIND_SCSI;
5069 *devtype = CC_DT_SCSI;
5078 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5079 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5080 uint16_t sector_count, uint64_t lba, uint8_t command, uint8_t *data_ptr,
5081 uint16_t dxfer_len, uint8_t sense_len, uint32_t timeout,
5082 int is48bit, camcontrol_devtype devtype)
5084 if (devtype == CC_DT_ATA) {
5085 cam_fill_ataio(&ccb->ataio,
5086 /*retries*/ retry_count,
5089 /*tag_action*/ tag_action,
5090 /*data_ptr*/ data_ptr,
5091 /*dxfer_len*/ dxfer_len,
5092 /*timeout*/ timeout);
5093 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5094 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5097 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5100 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5101 protocol |= AP_EXTEND;
5103 scsi_ata_pass_16(&ccb->csio,
5104 /*retries*/ retry_count,
5107 /*tag_action*/ tag_action,
5108 /*protocol*/ protocol,
5109 /*ata_flags*/ ata_flags,
5110 /*features*/ features,
5111 /*sector_count*/ sector_count,
5113 /*command*/ command,
5115 /*data_ptr*/ data_ptr,
5116 /*dxfer_len*/ dxfer_len,
5117 /*sense_len*/ sense_len,
5118 /*timeout*/ timeout);
5124 cpi_print(struct ccb_pathinq *cpi)
5126 char adapter_str[1024];
5129 snprintf(adapter_str, sizeof(adapter_str),
5130 "%s%d:", cpi->dev_name, cpi->unit_number);
5132 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5135 for (i = 1; i < 0xff; i = i << 1) {
5138 if ((i & cpi->hba_inquiry) == 0)
5141 fprintf(stdout, "%s supports ", adapter_str);
5145 str = "MDP message";
5148 str = "32 bit wide SCSI";
5151 str = "16 bit wide SCSI";
5154 str = "SDTR message";
5157 str = "linked CDBs";
5160 str = "tag queue messages";
5163 str = "soft reset alternative";
5166 str = "SATA Port Multiplier";
5169 str = "unknown PI bit set";
5172 fprintf(stdout, "%s\n", str);
5175 for (i = 1; i < 0xff; i = i << 1) {
5178 if ((i & cpi->hba_misc) == 0)
5181 fprintf(stdout, "%s ", adapter_str);
5185 str = "bus scans from high ID to low ID";
5188 str = "removable devices not included in scan";
5190 case PIM_NOINITIATOR:
5191 str = "initiator role not supported";
5193 case PIM_NOBUSRESET:
5194 str = "user has disabled initial BUS RESET or"
5195 " controller is in target/mixed mode";
5198 str = "do not send 6-byte commands";
5201 str = "scan bus sequentially";
5204 str = "unknown PIM bit set";
5207 fprintf(stdout, "%s\n", str);
5210 for (i = 1; i < 0xff; i = i << 1) {
5213 if ((i & cpi->target_sprt) == 0)
5216 fprintf(stdout, "%s supports ", adapter_str);
5219 str = "target mode processor mode";
5222 str = "target mode phase cog. mode";
5224 case PIT_DISCONNECT:
5225 str = "disconnects in target mode";
5228 str = "terminate I/O message in target mode";
5231 str = "group 6 commands in target mode";
5234 str = "group 7 commands in target mode";
5237 str = "unknown PIT bit set";
5241 fprintf(stdout, "%s\n", str);
5243 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5245 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5247 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5249 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5250 adapter_str, cpi->hpath_id);
5251 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5253 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5254 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5255 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5256 adapter_str, cpi->hba_vendor);
5257 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5258 adapter_str, cpi->hba_device);
5259 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5260 adapter_str, cpi->hba_subvendor);
5261 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5262 adapter_str, cpi->hba_subdevice);
5263 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5264 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5265 if (cpi->base_transfer_speed > 1000)
5266 fprintf(stdout, "%d.%03dMB/sec\n",
5267 cpi->base_transfer_speed / 1000,
5268 cpi->base_transfer_speed % 1000);
5270 fprintf(stdout, "%dKB/sec\n",
5271 (cpi->base_transfer_speed % 1000) * 1000);
5272 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5273 adapter_str, cpi->maxio);
5277 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5278 struct ccb_trans_settings *cts)
5284 ccb = cam_getccb(device);
5287 warnx("get_print_cts: error allocating ccb");
5291 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5293 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5295 if (user_settings == 0)
5296 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5298 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5300 if (cam_send_ccb(device, ccb) < 0) {
5301 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5302 if (arglist & CAM_ARG_VERBOSE)
5303 cam_error_print(device, ccb, CAM_ESF_ALL,
5304 CAM_EPF_ALL, stderr);
5306 goto get_print_cts_bailout;
5309 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5310 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5311 if (arglist & CAM_ARG_VERBOSE)
5312 cam_error_print(device, ccb, CAM_ESF_ALL,
5313 CAM_EPF_ALL, stderr);
5315 goto get_print_cts_bailout;
5319 cts_print(device, &ccb->cts);
5322 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5324 get_print_cts_bailout:
5332 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5333 int argc, char **argv, char *combinedopt)
5337 int user_settings = 0;
5339 int disc_enable = -1, tag_enable = -1;
5342 double syncrate = -1;
5345 int change_settings = 0, send_tur = 0;
5346 struct ccb_pathinq cpi;
5348 ccb = cam_getccb(device);
5350 warnx("ratecontrol: error allocating ccb");
5353 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5362 if (strncasecmp(optarg, "enable", 6) == 0)
5364 else if (strncasecmp(optarg, "disable", 7) == 0)
5367 warnx("-D argument \"%s\" is unknown", optarg);
5369 goto ratecontrol_bailout;
5371 change_settings = 1;
5374 mode = ata_string2mode(optarg);
5376 warnx("unknown mode '%s'", optarg);
5378 goto ratecontrol_bailout;
5380 change_settings = 1;
5383 offset = strtol(optarg, NULL, 0);
5385 warnx("offset value %d is < 0", offset);
5387 goto ratecontrol_bailout;
5389 change_settings = 1;
5395 syncrate = atof(optarg);
5397 warnx("sync rate %f is < 0", syncrate);
5399 goto ratecontrol_bailout;
5401 change_settings = 1;
5404 if (strncasecmp(optarg, "enable", 6) == 0)
5406 else if (strncasecmp(optarg, "disable", 7) == 0)
5409 warnx("-T argument \"%s\" is unknown", optarg);
5411 goto ratecontrol_bailout;
5413 change_settings = 1;
5419 bus_width = strtol(optarg, NULL, 0);
5420 if (bus_width < 0) {
5421 warnx("bus width %d is < 0", bus_width);
5423 goto ratecontrol_bailout;
5425 change_settings = 1;
5431 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5433 * Grab path inquiry information, so we can determine whether
5434 * or not the initiator is capable of the things that the user
5437 ccb->ccb_h.func_code = XPT_PATH_INQ;
5438 if (cam_send_ccb(device, ccb) < 0) {
5439 perror("error sending XPT_PATH_INQ CCB");
5440 if (arglist & CAM_ARG_VERBOSE) {
5441 cam_error_print(device, ccb, CAM_ESF_ALL,
5442 CAM_EPF_ALL, stderr);
5445 goto ratecontrol_bailout;
5447 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5448 warnx("XPT_PATH_INQ CCB failed");
5449 if (arglist & CAM_ARG_VERBOSE) {
5450 cam_error_print(device, ccb, CAM_ESF_ALL,
5451 CAM_EPF_ALL, stderr);
5454 goto ratecontrol_bailout;
5456 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5457 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5459 fprintf(stdout, "%s parameters:\n",
5460 user_settings ? "User" : "Current");
5462 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5464 goto ratecontrol_bailout;
5466 if (arglist & CAM_ARG_VERBOSE)
5469 if (change_settings) {
5470 int didsettings = 0;
5471 struct ccb_trans_settings_spi *spi = NULL;
5472 struct ccb_trans_settings_pata *pata = NULL;
5473 struct ccb_trans_settings_sata *sata = NULL;
5474 struct ccb_trans_settings_ata *ata = NULL;
5475 struct ccb_trans_settings_scsi *scsi = NULL;
5477 if (ccb->cts.transport == XPORT_SPI)
5478 spi = &ccb->cts.xport_specific.spi;
5479 if (ccb->cts.transport == XPORT_ATA)
5480 pata = &ccb->cts.xport_specific.ata;
5481 if (ccb->cts.transport == XPORT_SATA)
5482 sata = &ccb->cts.xport_specific.sata;
5483 if (ccb->cts.protocol == PROTO_ATA)
5484 ata = &ccb->cts.proto_specific.ata;
5485 if (ccb->cts.protocol == PROTO_SCSI)
5486 scsi = &ccb->cts.proto_specific.scsi;
5487 ccb->cts.xport_specific.valid = 0;
5488 ccb->cts.proto_specific.valid = 0;
5489 if (spi && disc_enable != -1) {
5490 spi->valid |= CTS_SPI_VALID_DISC;
5491 if (disc_enable == 0)
5492 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5494 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5497 if (tag_enable != -1) {
5498 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5499 warnx("HBA does not support tagged queueing, "
5500 "so you cannot modify tag settings");
5502 goto ratecontrol_bailout;
5505 ata->valid |= CTS_SCSI_VALID_TQ;
5506 if (tag_enable == 0)
5507 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5509 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5512 scsi->valid |= CTS_SCSI_VALID_TQ;
5513 if (tag_enable == 0)
5514 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5516 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5520 if (spi && offset != -1) {
5521 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5522 warnx("HBA is not capable of changing offset");
5524 goto ratecontrol_bailout;
5526 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5527 spi->sync_offset = offset;
5530 if (spi && syncrate != -1) {
5531 int prelim_sync_period;
5533 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5534 warnx("HBA is not capable of changing "
5537 goto ratecontrol_bailout;
5539 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5541 * The sync rate the user gives us is in MHz.
5542 * We need to translate it into KHz for this
5547 * Next, we calculate a "preliminary" sync period
5548 * in tenths of a nanosecond.
5551 prelim_sync_period = 0;
5553 prelim_sync_period = 10000000 / syncrate;
5555 scsi_calc_syncparam(prelim_sync_period);
5558 if (sata && syncrate != -1) {
5559 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5560 warnx("HBA is not capable of changing "
5563 goto ratecontrol_bailout;
5565 if (!user_settings) {
5566 warnx("You can modify only user rate "
5567 "settings for SATA");
5569 goto ratecontrol_bailout;
5571 sata->revision = ata_speed2revision(syncrate * 100);
5572 if (sata->revision < 0) {
5573 warnx("Invalid rate %f", syncrate);
5575 goto ratecontrol_bailout;
5577 sata->valid |= CTS_SATA_VALID_REVISION;
5580 if ((pata || sata) && mode != -1) {
5581 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5582 warnx("HBA is not capable of changing "
5585 goto ratecontrol_bailout;
5587 if (!user_settings) {
5588 warnx("You can modify only user mode "
5589 "settings for ATA/SATA");
5591 goto ratecontrol_bailout;
5595 pata->valid |= CTS_ATA_VALID_MODE;
5598 sata->valid |= CTS_SATA_VALID_MODE;
5603 * The bus_width argument goes like this:
5607 * Therefore, if you shift the number of bits given on the
5608 * command line right by 4, you should get the correct
5611 if (spi && bus_width != -1) {
5613 * We might as well validate things here with a
5614 * decipherable error message, rather than what
5615 * will probably be an indecipherable error message
5616 * by the time it gets back to us.
5618 if ((bus_width == 16)
5619 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5620 warnx("HBA does not support 16 bit bus width");
5622 goto ratecontrol_bailout;
5623 } else if ((bus_width == 32)
5624 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5625 warnx("HBA does not support 32 bit bus width");
5627 goto ratecontrol_bailout;
5628 } else if ((bus_width != 8)
5629 && (bus_width != 16)
5630 && (bus_width != 32)) {
5631 warnx("Invalid bus width %d", bus_width);
5633 goto ratecontrol_bailout;
5635 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5636 spi->bus_width = bus_width >> 4;
5639 if (didsettings == 0) {
5640 goto ratecontrol_bailout;
5642 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5643 if (cam_send_ccb(device, ccb) < 0) {
5644 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5645 if (arglist & CAM_ARG_VERBOSE) {
5646 cam_error_print(device, ccb, CAM_ESF_ALL,
5647 CAM_EPF_ALL, stderr);
5650 goto ratecontrol_bailout;
5652 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5653 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5654 if (arglist & CAM_ARG_VERBOSE) {
5655 cam_error_print(device, ccb, CAM_ESF_ALL,
5656 CAM_EPF_ALL, stderr);
5659 goto ratecontrol_bailout;
5663 retval = testunitready(device, retry_count, timeout,
5664 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5666 * If the TUR didn't succeed, just bail.
5670 fprintf(stderr, "Test Unit Ready failed\n");
5671 goto ratecontrol_bailout;
5674 if ((change_settings || send_tur) && !quiet &&
5675 (ccb->cts.transport == XPORT_ATA ||
5676 ccb->cts.transport == XPORT_SATA || send_tur)) {
5677 fprintf(stdout, "New parameters:\n");
5678 retval = get_print_cts(device, user_settings, 0, NULL);
5681 ratecontrol_bailout:
5687 scsiformat(struct cam_device *device, int argc, char **argv,
5688 char *combinedopt, int retry_count, int timeout)
5692 int ycount = 0, quiet = 0;
5693 int error = 0, retval = 0;
5694 int use_timeout = 10800 * 1000;
5696 struct format_defect_list_header fh;
5697 u_int8_t *data_ptr = NULL;
5698 u_int32_t dxfer_len = 0;
5700 int num_warnings = 0;
5703 ccb = cam_getccb(device);
5706 warnx("scsiformat: error allocating ccb");
5710 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5712 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5733 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5734 "following device:\n");
5736 error = scsidoinquiry(device, argc, argv, combinedopt,
5737 retry_count, timeout);
5740 warnx("scsiformat: error sending inquiry");
5741 goto scsiformat_bailout;
5746 if (!get_confirmation()) {
5748 goto scsiformat_bailout;
5753 use_timeout = timeout;
5756 fprintf(stdout, "Current format timeout is %d seconds\n",
5757 use_timeout / 1000);
5761 * If the user hasn't disabled questions and didn't specify a
5762 * timeout on the command line, ask them if they want the current
5766 && (timeout == 0)) {
5768 int new_timeout = 0;
5770 fprintf(stdout, "Enter new timeout in seconds or press\n"
5771 "return to keep the current timeout [%d] ",
5772 use_timeout / 1000);
5774 if (fgets(str, sizeof(str), stdin) != NULL) {
5776 new_timeout = atoi(str);
5779 if (new_timeout != 0) {
5780 use_timeout = new_timeout * 1000;
5781 fprintf(stdout, "Using new timeout value %d\n",
5782 use_timeout / 1000);
5787 * Keep this outside the if block below to silence any unused
5788 * variable warnings.
5790 bzero(&fh, sizeof(fh));
5793 * If we're in immediate mode, we've got to include the format
5796 if (immediate != 0) {
5797 fh.byte2 = FU_DLH_IMMED;
5798 data_ptr = (u_int8_t *)&fh;
5799 dxfer_len = sizeof(fh);
5800 byte2 = FU_FMT_DATA;
5801 } else if (quiet == 0) {
5802 fprintf(stdout, "Formatting...");
5806 scsi_format_unit(&ccb->csio,
5807 /* retries */ retry_count,
5809 /* tag_action */ MSG_SIMPLE_Q_TAG,
5812 /* data_ptr */ data_ptr,
5813 /* dxfer_len */ dxfer_len,
5814 /* sense_len */ SSD_FULL_SIZE,
5815 /* timeout */ use_timeout);
5817 /* Disable freezing the device queue */
5818 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5820 if (arglist & CAM_ARG_ERR_RECOVER)
5821 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5823 if (((retval = cam_send_ccb(device, ccb)) < 0)
5824 || ((immediate == 0)
5825 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5826 const char errstr[] = "error sending format command";
5833 if (arglist & CAM_ARG_VERBOSE) {
5834 cam_error_print(device, ccb, CAM_ESF_ALL,
5835 CAM_EPF_ALL, stderr);
5838 goto scsiformat_bailout;
5842 * If we ran in non-immediate mode, we already checked for errors
5843 * above and printed out any necessary information. If we're in
5844 * immediate mode, we need to loop through and get status
5845 * information periodically.
5847 if (immediate == 0) {
5849 fprintf(stdout, "Format Complete\n");
5851 goto scsiformat_bailout;
5858 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5861 * There's really no need to do error recovery or
5862 * retries here, since we're just going to sit in a
5863 * loop and wait for the device to finish formatting.
5865 scsi_test_unit_ready(&ccb->csio,
5868 /* tag_action */ MSG_SIMPLE_Q_TAG,
5869 /* sense_len */ SSD_FULL_SIZE,
5870 /* timeout */ 5000);
5872 /* Disable freezing the device queue */
5873 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5875 retval = cam_send_ccb(device, ccb);
5878 * If we get an error from the ioctl, bail out. SCSI
5879 * errors are expected.
5882 warn("error sending CAMIOCOMMAND ioctl");
5883 if (arglist & CAM_ARG_VERBOSE) {
5884 cam_error_print(device, ccb, CAM_ESF_ALL,
5885 CAM_EPF_ALL, stderr);
5888 goto scsiformat_bailout;
5891 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5893 if ((status != CAM_REQ_CMP)
5894 && (status == CAM_SCSI_STATUS_ERROR)
5895 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5896 struct scsi_sense_data *sense;
5897 int error_code, sense_key, asc, ascq;
5899 sense = &ccb->csio.sense_data;
5900 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5901 ccb->csio.sense_resid, &error_code, &sense_key,
5902 &asc, &ascq, /*show_errors*/ 1);
5905 * According to the SCSI-2 and SCSI-3 specs, a
5906 * drive that is in the middle of a format should
5907 * return NOT READY with an ASC of "logical unit
5908 * not ready, format in progress". The sense key
5909 * specific bytes will then be a progress indicator.
5911 if ((sense_key == SSD_KEY_NOT_READY)
5912 && (asc == 0x04) && (ascq == 0x04)) {
5915 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5916 ccb->csio.sense_resid, sks) == 0)
5919 u_int64_t percentage;
5921 val = scsi_2btoul(&sks[1]);
5922 percentage = 10000 * val;
5925 "\rFormatting: %ju.%02u %% "
5927 (uintmax_t)(percentage /
5929 (unsigned)((percentage /
5933 } else if ((quiet == 0)
5934 && (++num_warnings <= 1)) {
5935 warnx("Unexpected SCSI Sense Key "
5936 "Specific value returned "
5938 scsi_sense_print(device, &ccb->csio,
5940 warnx("Unable to print status "
5941 "information, but format will "
5943 warnx("will exit when format is "
5948 warnx("Unexpected SCSI error during format");
5949 cam_error_print(device, ccb, CAM_ESF_ALL,
5950 CAM_EPF_ALL, stderr);
5952 goto scsiformat_bailout;
5955 } else if (status != CAM_REQ_CMP) {
5956 warnx("Unexpected CAM status %#x", status);
5957 if (arglist & CAM_ARG_VERBOSE)
5958 cam_error_print(device, ccb, CAM_ESF_ALL,
5959 CAM_EPF_ALL, stderr);
5961 goto scsiformat_bailout;
5964 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5967 fprintf(stdout, "\nFormat Complete\n");
5977 scsisanitize(struct cam_device *device, int argc, char **argv,
5978 char *combinedopt, int retry_count, int timeout)
5981 u_int8_t action = 0;
5983 int ycount = 0, quiet = 0;
5984 int error = 0, retval = 0;
5985 int use_timeout = 10800 * 1000;
5991 const char *pattern = NULL;
5992 u_int8_t *data_ptr = NULL;
5993 u_int32_t dxfer_len = 0;
5995 int num_warnings = 0;
5998 ccb = cam_getccb(device);
6001 warnx("scsisanitize: error allocating ccb");
6005 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6007 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6010 if (strcasecmp(optarg, "overwrite") == 0)
6011 action = SSZ_SERVICE_ACTION_OVERWRITE;
6012 else if (strcasecmp(optarg, "block") == 0)
6013 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6014 else if (strcasecmp(optarg, "crypto") == 0)
6015 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6016 else if (strcasecmp(optarg, "exitfailure") == 0)
6017 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6019 warnx("invalid service operation \"%s\"",
6022 goto scsisanitize_bailout;
6026 passes = strtol(optarg, NULL, 0);
6027 if (passes < 1 || passes > 31) {
6028 warnx("invalid passes value %d", passes);
6030 goto scsisanitize_bailout;
6061 warnx("an action is required");
6063 goto scsisanitize_bailout;
6064 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6065 struct scsi_sanitize_parameter_list *pl;
6069 if (pattern == NULL) {
6070 warnx("overwrite action requires -P argument");
6072 goto scsisanitize_bailout;
6074 fd = open(pattern, O_RDONLY);
6076 warn("cannot open pattern file %s", pattern);
6078 goto scsisanitize_bailout;
6080 if (fstat(fd, &sb) < 0) {
6081 warn("cannot stat pattern file %s", pattern);
6083 goto scsisanitize_bailout;
6086 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6087 warnx("pattern file size exceeds maximum value %d",
6088 SSZPL_MAX_PATTERN_LENGTH);
6090 goto scsisanitize_bailout;
6092 dxfer_len = sizeof(*pl) + sz;
6093 data_ptr = calloc(1, dxfer_len);
6094 if (data_ptr == NULL) {
6095 warnx("cannot allocate parameter list buffer");
6097 goto scsisanitize_bailout;
6100 amt = read(fd, data_ptr + sizeof(*pl), sz);
6102 warn("cannot read pattern file");
6104 goto scsisanitize_bailout;
6105 } else if (amt != sz) {
6106 warnx("short pattern file read");
6108 goto scsisanitize_bailout;
6111 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6117 pl->byte1 |= SSZPL_INVERT;
6118 scsi_ulto2b(sz, pl->length);
6124 else if (invert != 0)
6126 else if (pattern != NULL)
6131 warnx("%s argument only valid with overwrite "
6134 goto scsisanitize_bailout;
6139 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6140 "following device:\n");
6142 error = scsidoinquiry(device, argc, argv, combinedopt,
6143 retry_count, timeout);
6146 warnx("scsisanitize: error sending inquiry");
6147 goto scsisanitize_bailout;
6152 if (!get_confirmation()) {
6154 goto scsisanitize_bailout;
6159 use_timeout = timeout;
6162 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6163 use_timeout / 1000);
6167 * If the user hasn't disabled questions and didn't specify a
6168 * timeout on the command line, ask them if they want the current
6172 && (timeout == 0)) {
6174 int new_timeout = 0;
6176 fprintf(stdout, "Enter new timeout in seconds or press\n"
6177 "return to keep the current timeout [%d] ",
6178 use_timeout / 1000);
6180 if (fgets(str, sizeof(str), stdin) != NULL) {
6182 new_timeout = atoi(str);
6185 if (new_timeout != 0) {
6186 use_timeout = new_timeout * 1000;
6187 fprintf(stdout, "Using new timeout value %d\n",
6188 use_timeout / 1000);
6194 byte2 |= SSZ_UNRESTRICTED_EXIT;
6198 scsi_sanitize(&ccb->csio,
6199 /* retries */ retry_count,
6201 /* tag_action */ MSG_SIMPLE_Q_TAG,
6204 /* data_ptr */ data_ptr,
6205 /* dxfer_len */ dxfer_len,
6206 /* sense_len */ SSD_FULL_SIZE,
6207 /* timeout */ use_timeout);
6209 /* Disable freezing the device queue */
6210 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6212 if (arglist & CAM_ARG_ERR_RECOVER)
6213 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6215 if (cam_send_ccb(device, ccb) < 0) {
6216 warn("error sending sanitize command");
6218 goto scsisanitize_bailout;
6221 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6222 struct scsi_sense_data *sense;
6223 int error_code, sense_key, asc, ascq;
6225 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6226 CAM_SCSI_STATUS_ERROR) {
6227 sense = &ccb->csio.sense_data;
6228 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6229 ccb->csio.sense_resid, &error_code, &sense_key,
6230 &asc, &ascq, /*show_errors*/ 1);
6232 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6233 asc == 0x20 && ascq == 0x00)
6234 warnx("sanitize is not supported by "
6237 warnx("error sanitizing this device");
6239 warnx("error sanitizing this device");
6241 if (arglist & CAM_ARG_VERBOSE) {
6242 cam_error_print(device, ccb, CAM_ESF_ALL,
6243 CAM_EPF_ALL, stderr);
6246 goto scsisanitize_bailout;
6250 * If we ran in non-immediate mode, we already checked for errors
6251 * above and printed out any necessary information. If we're in
6252 * immediate mode, we need to loop through and get status
6253 * information periodically.
6255 if (immediate == 0) {
6257 fprintf(stdout, "Sanitize Complete\n");
6259 goto scsisanitize_bailout;
6266 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6269 * There's really no need to do error recovery or
6270 * retries here, since we're just going to sit in a
6271 * loop and wait for the device to finish sanitizing.
6273 scsi_test_unit_ready(&ccb->csio,
6276 /* tag_action */ MSG_SIMPLE_Q_TAG,
6277 /* sense_len */ SSD_FULL_SIZE,
6278 /* timeout */ 5000);
6280 /* Disable freezing the device queue */
6281 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6283 retval = cam_send_ccb(device, ccb);
6286 * If we get an error from the ioctl, bail out. SCSI
6287 * errors are expected.
6290 warn("error sending CAMIOCOMMAND ioctl");
6291 if (arglist & CAM_ARG_VERBOSE) {
6292 cam_error_print(device, ccb, CAM_ESF_ALL,
6293 CAM_EPF_ALL, stderr);
6296 goto scsisanitize_bailout;
6299 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6301 if ((status != CAM_REQ_CMP)
6302 && (status == CAM_SCSI_STATUS_ERROR)
6303 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6304 struct scsi_sense_data *sense;
6305 int error_code, sense_key, asc, ascq;
6307 sense = &ccb->csio.sense_data;
6308 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6309 ccb->csio.sense_resid, &error_code, &sense_key,
6310 &asc, &ascq, /*show_errors*/ 1);
6313 * According to the SCSI-3 spec, a drive that is in the
6314 * middle of a sanitize should return NOT READY with an
6315 * ASC of "logical unit not ready, sanitize in
6316 * progress". The sense key specific bytes will then
6317 * be a progress indicator.
6319 if ((sense_key == SSD_KEY_NOT_READY)
6320 && (asc == 0x04) && (ascq == 0x1b)) {
6323 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6324 ccb->csio.sense_resid, sks) == 0)
6327 u_int64_t percentage;
6329 val = scsi_2btoul(&sks[1]);
6330 percentage = 10000 * val;
6333 "\rSanitizing: %ju.%02u %% "
6335 (uintmax_t)(percentage /
6337 (unsigned)((percentage /
6341 } else if ((quiet == 0)
6342 && (++num_warnings <= 1)) {
6343 warnx("Unexpected SCSI Sense Key "
6344 "Specific value returned "
6345 "during sanitize:");
6346 scsi_sense_print(device, &ccb->csio,
6348 warnx("Unable to print status "
6349 "information, but sanitze will "
6351 warnx("will exit when sanitize is "
6356 warnx("Unexpected SCSI error during sanitize");
6357 cam_error_print(device, ccb, CAM_ESF_ALL,
6358 CAM_EPF_ALL, stderr);
6360 goto scsisanitize_bailout;
6363 } else if (status != CAM_REQ_CMP) {
6364 warnx("Unexpected CAM status %#x", status);
6365 if (arglist & CAM_ARG_VERBOSE)
6366 cam_error_print(device, ccb, CAM_ESF_ALL,
6367 CAM_EPF_ALL, stderr);
6369 goto scsisanitize_bailout;
6371 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6374 fprintf(stdout, "\nSanitize Complete\n");
6376 scsisanitize_bailout:
6379 if (data_ptr != NULL)
6387 scsireportluns(struct cam_device *device, int argc, char **argv,
6388 char *combinedopt, int retry_count, int timeout)
6391 int c, countonly, lunsonly;
6392 struct scsi_report_luns_data *lundata;
6394 uint8_t report_type;
6395 uint32_t list_len, i, j;
6400 report_type = RPL_REPORT_DEFAULT;
6401 ccb = cam_getccb(device);
6404 warnx("%s: error allocating ccb", __func__);
6408 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6413 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6422 if (strcasecmp(optarg, "default") == 0)
6423 report_type = RPL_REPORT_DEFAULT;
6424 else if (strcasecmp(optarg, "wellknown") == 0)
6425 report_type = RPL_REPORT_WELLKNOWN;
6426 else if (strcasecmp(optarg, "all") == 0)
6427 report_type = RPL_REPORT_ALL;
6429 warnx("%s: invalid report type \"%s\"",
6440 if ((countonly != 0)
6441 && (lunsonly != 0)) {
6442 warnx("%s: you can only specify one of -c or -l", __func__);
6447 * According to SPC-4, the allocation length must be at least 16
6448 * bytes -- enough for the header and one LUN.
6450 alloc_len = sizeof(*lundata) + 8;
6454 lundata = malloc(alloc_len);
6456 if (lundata == NULL) {
6457 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6462 scsi_report_luns(&ccb->csio,
6463 /*retries*/ retry_count,
6465 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6466 /*select_report*/ report_type,
6467 /*rpl_buf*/ lundata,
6468 /*alloc_len*/ alloc_len,
6469 /*sense_len*/ SSD_FULL_SIZE,
6470 /*timeout*/ timeout ? timeout : 5000);
6472 /* Disable freezing the device queue */
6473 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6475 if (arglist & CAM_ARG_ERR_RECOVER)
6476 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6478 if (cam_send_ccb(device, ccb) < 0) {
6479 warn("error sending REPORT LUNS command");
6481 if (arglist & CAM_ARG_VERBOSE)
6482 cam_error_print(device, ccb, CAM_ESF_ALL,
6483 CAM_EPF_ALL, stderr);
6489 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6490 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6496 list_len = scsi_4btoul(lundata->length);
6499 * If we need to list the LUNs, and our allocation
6500 * length was too short, reallocate and retry.
6502 if ((countonly == 0)
6503 && (list_len > (alloc_len - sizeof(*lundata)))) {
6504 alloc_len = list_len + sizeof(*lundata);
6510 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6511 ((list_len / 8) > 1) ? "s" : "");
6516 for (i = 0; i < (list_len / 8); i++) {
6520 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6522 fprintf(stdout, ",");
6523 switch (lundata->luns[i].lundata[j] &
6524 RPL_LUNDATA_ATYP_MASK) {
6525 case RPL_LUNDATA_ATYP_PERIPH:
6526 if ((lundata->luns[i].lundata[j] &
6527 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6528 fprintf(stdout, "%d:",
6529 lundata->luns[i].lundata[j] &
6530 RPL_LUNDATA_PERIPH_BUS_MASK);
6532 && ((lundata->luns[i].lundata[j+2] &
6533 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6536 fprintf(stdout, "%d",
6537 lundata->luns[i].lundata[j+1]);
6539 case RPL_LUNDATA_ATYP_FLAT: {
6541 tmplun[0] = lundata->luns[i].lundata[j] &
6542 RPL_LUNDATA_FLAT_LUN_MASK;
6543 tmplun[1] = lundata->luns[i].lundata[j+1];
6545 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6549 case RPL_LUNDATA_ATYP_LUN:
6550 fprintf(stdout, "%d:%d:%d",
6551 (lundata->luns[i].lundata[j+1] &
6552 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6553 lundata->luns[i].lundata[j] &
6554 RPL_LUNDATA_LUN_TARG_MASK,
6555 lundata->luns[i].lundata[j+1] &
6556 RPL_LUNDATA_LUN_LUN_MASK);
6558 case RPL_LUNDATA_ATYP_EXTLUN: {
6559 int field_len_code, eam_code;
6561 eam_code = lundata->luns[i].lundata[j] &
6562 RPL_LUNDATA_EXT_EAM_MASK;
6563 field_len_code = (lundata->luns[i].lundata[j] &
6564 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6566 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6567 && (field_len_code == 0x00)) {
6568 fprintf(stdout, "%d",
6569 lundata->luns[i].lundata[j+1]);
6570 } else if ((eam_code ==
6571 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6572 && (field_len_code == 0x03)) {
6576 * This format takes up all 8 bytes.
6577 * If we aren't starting at offset 0,
6581 fprintf(stdout, "Invalid "
6584 "specified format", j);
6588 bzero(tmp_lun, sizeof(tmp_lun));
6589 bcopy(&lundata->luns[i].lundata[j+1],
6590 &tmp_lun[1], sizeof(tmp_lun) - 1);
6591 fprintf(stdout, "%#jx",
6592 (intmax_t)scsi_8btou64(tmp_lun));
6595 fprintf(stderr, "Unknown Extended LUN"
6596 "Address method %#x, length "
6597 "code %#x", eam_code,
6604 fprintf(stderr, "Unknown LUN address method "
6605 "%#x\n", lundata->luns[i].lundata[0] &
6606 RPL_LUNDATA_ATYP_MASK);
6610 * For the flat addressing method, there are no
6611 * other levels after it.
6616 fprintf(stdout, "\n");
6629 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6630 char *combinedopt, int retry_count, int timeout)
6633 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6634 struct scsi_read_capacity_data rcap;
6635 struct scsi_read_capacity_data_long rcaplong;
6649 ccb = cam_getccb(device);
6652 warnx("%s: error allocating ccb", __func__);
6656 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6658 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6685 if ((blocksizeonly != 0)
6686 && (numblocks != 0)) {
6687 warnx("%s: you can only specify one of -b or -N", __func__);
6692 if ((blocksizeonly != 0)
6693 && (sizeonly != 0)) {
6694 warnx("%s: you can only specify one of -b or -s", __func__);
6701 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6707 && (blocksizeonly != 0)) {
6708 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6713 scsi_read_capacity(&ccb->csio,
6714 /*retries*/ retry_count,
6716 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6719 /*timeout*/ timeout ? timeout : 5000);
6721 /* Disable freezing the device queue */
6722 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6724 if (arglist & CAM_ARG_ERR_RECOVER)
6725 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6727 if (cam_send_ccb(device, ccb) < 0) {
6728 warn("error sending READ CAPACITY command");
6730 if (arglist & CAM_ARG_VERBOSE)
6731 cam_error_print(device, ccb, CAM_ESF_ALL,
6732 CAM_EPF_ALL, stderr);
6738 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6739 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6744 maxsector = scsi_4btoul(rcap.addr);
6745 block_len = scsi_4btoul(rcap.length);
6748 * A last block of 2^32-1 means that the true capacity is over 2TB,
6749 * and we need to issue the long READ CAPACITY to get the real
6750 * capacity. Otherwise, we're all set.
6752 if (maxsector != 0xffffffff)
6755 scsi_read_capacity_16(&ccb->csio,
6756 /*retries*/ retry_count,
6758 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6762 /*rcap_buf*/ (uint8_t *)&rcaplong,
6763 /*rcap_buf_len*/ sizeof(rcaplong),
6764 /*sense_len*/ SSD_FULL_SIZE,
6765 /*timeout*/ timeout ? timeout : 5000);
6767 /* Disable freezing the device queue */
6768 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6770 if (arglist & CAM_ARG_ERR_RECOVER)
6771 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6773 if (cam_send_ccb(device, ccb) < 0) {
6774 warn("error sending READ CAPACITY (16) command");
6776 if (arglist & CAM_ARG_VERBOSE)
6777 cam_error_print(device, ccb, CAM_ESF_ALL,
6778 CAM_EPF_ALL, stderr);
6784 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6785 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6790 maxsector = scsi_8btou64(rcaplong.addr);
6791 block_len = scsi_4btoul(rcaplong.length);
6794 if (blocksizeonly == 0) {
6796 * Humanize implies !quiet, and also implies numblocks.
6798 if (humanize != 0) {
6803 tmpbytes = (maxsector + 1) * block_len;
6804 ret = humanize_number(tmpstr, sizeof(tmpstr),
6805 tmpbytes, "", HN_AUTOSCALE,
6808 HN_DIVISOR_1000 : 0));
6810 warnx("%s: humanize_number failed!", __func__);
6814 fprintf(stdout, "Device Size: %s%s", tmpstr,
6815 (sizeonly == 0) ? ", " : "\n");
6816 } else if (numblocks != 0) {
6817 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6818 "Blocks: " : "", (uintmax_t)maxsector + 1,
6819 (sizeonly == 0) ? ", " : "\n");
6821 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6822 "Last Block: " : "", (uintmax_t)maxsector,
6823 (sizeonly == 0) ? ", " : "\n");
6827 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6828 "Block Length: " : "", block_len, (quiet == 0) ?
6837 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6838 int retry_count, int timeout)
6842 uint8_t *smp_request = NULL, *smp_response = NULL;
6843 int request_size = 0, response_size = 0;
6844 int fd_request = 0, fd_response = 0;
6845 char *datastr = NULL;
6846 struct get_hook hook;
6851 * Note that at the moment we don't support sending SMP CCBs to
6852 * devices that aren't probed by CAM.
6854 ccb = cam_getccb(device);
6856 warnx("%s: error allocating CCB", __func__);
6860 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
6862 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6865 arglist |= CAM_ARG_CMD_IN;
6866 response_size = strtol(optarg, NULL, 0);
6867 if (response_size <= 0) {
6868 warnx("invalid number of response bytes %d",
6871 goto smpcmd_bailout;
6873 hook.argc = argc - optind;
6874 hook.argv = argv + optind;
6877 datastr = cget(&hook, NULL);
6879 * If the user supplied "-" instead of a format, he
6880 * wants the data to be written to stdout.
6882 if ((datastr != NULL)
6883 && (datastr[0] == '-'))
6886 smp_response = (u_int8_t *)malloc(response_size);
6887 if (smp_response == NULL) {
6888 warn("can't malloc memory for SMP response");
6890 goto smpcmd_bailout;
6894 arglist |= CAM_ARG_CMD_OUT;
6895 request_size = strtol(optarg, NULL, 0);
6896 if (request_size <= 0) {
6897 warnx("invalid number of request bytes %d",
6900 goto smpcmd_bailout;
6902 hook.argc = argc - optind;
6903 hook.argv = argv + optind;
6905 datastr = cget(&hook, NULL);
6906 smp_request = (u_int8_t *)malloc(request_size);
6907 if (smp_request == NULL) {
6908 warn("can't malloc memory for SMP request");
6910 goto smpcmd_bailout;
6912 bzero(smp_request, request_size);
6914 * If the user supplied "-" instead of a format, he
6915 * wants the data to be read from stdin.
6917 if ((datastr != NULL)
6918 && (datastr[0] == '-'))
6921 buff_encode_visit(smp_request, request_size,
6932 * If fd_data is set, and we're writing to the device, we need to
6933 * read the data the user wants written from stdin.
6935 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6937 int amt_to_read = request_size;
6938 u_int8_t *buf_ptr = smp_request;
6940 for (amt_read = 0; amt_to_read > 0;
6941 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6942 if (amt_read == -1) {
6943 warn("error reading data from stdin");
6945 goto smpcmd_bailout;
6947 amt_to_read -= amt_read;
6948 buf_ptr += amt_read;
6952 if (((arglist & CAM_ARG_CMD_IN) == 0)
6953 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6954 warnx("%s: need both the request (-r) and response (-R) "
6955 "arguments", __func__);
6957 goto smpcmd_bailout;
6960 flags |= CAM_DEV_QFRZDIS;
6962 cam_fill_smpio(&ccb->smpio,
6963 /*retries*/ retry_count,
6966 /*smp_request*/ smp_request,
6967 /*smp_request_len*/ request_size,
6968 /*smp_response*/ smp_response,
6969 /*smp_response_len*/ response_size,
6970 /*timeout*/ timeout ? timeout : 5000);
6972 ccb->smpio.flags = SMP_FLAG_NONE;
6974 if (((retval = cam_send_ccb(device, ccb)) < 0)
6975 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6976 const char warnstr[] = "error sending command";
6983 if (arglist & CAM_ARG_VERBOSE) {
6984 cam_error_print(device, ccb, CAM_ESF_ALL,
6985 CAM_EPF_ALL, stderr);
6989 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6990 && (response_size > 0)) {
6991 if (fd_response == 0) {
6992 buff_decode_visit(smp_response, response_size,
6993 datastr, arg_put, NULL);
6994 fprintf(stdout, "\n");
6996 ssize_t amt_written;
6997 int amt_to_write = response_size;
6998 u_int8_t *buf_ptr = smp_response;
7000 for (amt_written = 0; (amt_to_write > 0) &&
7001 (amt_written = write(STDOUT_FILENO, buf_ptr,
7002 amt_to_write)) > 0;){
7003 amt_to_write -= amt_written;
7004 buf_ptr += amt_written;
7006 if (amt_written == -1) {
7007 warn("error writing data to stdout");
7009 goto smpcmd_bailout;
7010 } else if ((amt_written == 0)
7011 && (amt_to_write > 0)) {
7012 warnx("only wrote %u bytes out of %u",
7013 response_size - amt_to_write,
7022 if (smp_request != NULL)
7025 if (smp_response != NULL)
7032 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7033 char *combinedopt, int retry_count, int timeout)
7036 struct smp_report_general_request *request = NULL;
7037 struct smp_report_general_response *response = NULL;
7038 struct sbuf *sb = NULL;
7040 int c, long_response = 0;
7044 * Note that at the moment we don't support sending SMP CCBs to
7045 * devices that aren't probed by CAM.
7047 ccb = cam_getccb(device);
7049 warnx("%s: error allocating CCB", __func__);
7053 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7055 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7064 request = malloc(sizeof(*request));
7065 if (request == NULL) {
7066 warn("%s: unable to allocate %zd bytes", __func__,
7072 response = malloc(sizeof(*response));
7073 if (response == NULL) {
7074 warn("%s: unable to allocate %zd bytes", __func__,
7081 smp_report_general(&ccb->smpio,
7085 /*request_len*/ sizeof(*request),
7086 (uint8_t *)response,
7087 /*response_len*/ sizeof(*response),
7088 /*long_response*/ long_response,
7091 if (((retval = cam_send_ccb(device, ccb)) < 0)
7092 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7093 const char warnstr[] = "error sending command";
7100 if (arglist & CAM_ARG_VERBOSE) {
7101 cam_error_print(device, ccb, CAM_ESF_ALL,
7102 CAM_EPF_ALL, stderr);
7109 * If the device supports the long response bit, try again and see
7110 * if we can get all of the data.
7112 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7113 && (long_response == 0)) {
7114 ccb->ccb_h.status = CAM_REQ_INPROG;
7115 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7121 * XXX KDM detect and decode SMP errors here.
7123 sb = sbuf_new_auto();
7125 warnx("%s: error allocating sbuf", __func__);
7129 smp_report_general_sbuf(response, sizeof(*response), sb);
7131 if (sbuf_finish(sb) != 0) {
7132 warnx("%s: sbuf_finish", __func__);
7136 printf("%s", sbuf_data(sb));
7142 if (request != NULL)
7145 if (response != NULL)
7154 static struct camcontrol_opts phy_ops[] = {
7155 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7156 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7157 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7158 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7159 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7160 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7161 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7162 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7163 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7168 smpphycontrol(struct cam_device *device, int argc, char **argv,
7169 char *combinedopt, int retry_count, int timeout)
7172 struct smp_phy_control_request *request = NULL;
7173 struct smp_phy_control_response *response = NULL;
7174 int long_response = 0;
7177 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7179 uint64_t attached_dev_name = 0;
7180 int dev_name_set = 0;
7181 uint32_t min_plr = 0, max_plr = 0;
7182 uint32_t pp_timeout_val = 0;
7183 int slumber_partial = 0;
7184 int set_pp_timeout_val = 0;
7188 * Note that at the moment we don't support sending SMP CCBs to
7189 * devices that aren't probed by CAM.
7191 ccb = cam_getccb(device);
7193 warnx("%s: error allocating CCB", __func__);
7197 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7199 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7207 if (strcasecmp(optarg, "enable") == 0)
7209 else if (strcasecmp(optarg, "disable") == 0)
7212 warnx("%s: Invalid argument %s", __func__,
7219 slumber_partial |= enable <<
7220 SMP_PC_SAS_SLUMBER_SHIFT;
7223 slumber_partial |= enable <<
7224 SMP_PC_SAS_PARTIAL_SHIFT;
7227 slumber_partial |= enable <<
7228 SMP_PC_SATA_SLUMBER_SHIFT;
7231 slumber_partial |= enable <<
7232 SMP_PC_SATA_PARTIAL_SHIFT;
7235 warnx("%s: programmer error", __func__);
7238 break; /*NOTREACHED*/
7243 attached_dev_name = (uintmax_t)strtoumax(optarg,
7252 * We don't do extensive checking here, so this
7253 * will continue to work when new speeds come out.
7255 min_plr = strtoul(optarg, NULL, 0);
7257 || (min_plr > 0xf)) {
7258 warnx("%s: invalid link rate %x",
7266 * We don't do extensive checking here, so this
7267 * will continue to work when new speeds come out.
7269 max_plr = strtoul(optarg, NULL, 0);
7271 || (max_plr > 0xf)) {
7272 warnx("%s: invalid link rate %x",
7279 camcontrol_optret optreturn;
7280 cam_argmask argnums;
7283 if (phy_op_set != 0) {
7284 warnx("%s: only one phy operation argument "
7285 "(-o) allowed", __func__);
7293 * Allow the user to specify the phy operation
7294 * numerically, as well as with a name. This will
7295 * future-proof it a bit, so options that are added
7296 * in future specs can be used.
7298 if (isdigit(optarg[0])) {
7299 phy_operation = strtoul(optarg, NULL, 0);
7300 if ((phy_operation == 0)
7301 || (phy_operation > 0xff)) {
7302 warnx("%s: invalid phy operation %#x",
7303 __func__, phy_operation);
7309 optreturn = getoption(phy_ops, optarg, &phy_operation,
7312 if (optreturn == CC_OR_AMBIGUOUS) {
7313 warnx("%s: ambiguous option %s", __func__,
7318 } else if (optreturn == CC_OR_NOT_FOUND) {
7319 warnx("%s: option %s not found", __func__,
7331 pp_timeout_val = strtoul(optarg, NULL, 0);
7332 if (pp_timeout_val > 15) {
7333 warnx("%s: invalid partial pathway timeout "
7334 "value %u, need a value less than 16",
7335 __func__, pp_timeout_val);
7339 set_pp_timeout_val = 1;
7347 warnx("%s: a PHY (-p phy) argument is required",__func__);
7352 if (((dev_name_set != 0)
7353 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7354 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7355 && (dev_name_set == 0))) {
7356 warnx("%s: -d name and -o setdevname arguments both "
7357 "required to set device name", __func__);
7362 request = malloc(sizeof(*request));
7363 if (request == NULL) {
7364 warn("%s: unable to allocate %zd bytes", __func__,
7370 response = malloc(sizeof(*response));
7371 if (response == NULL) {
7372 warn("%s: unable to allocate %zd bytes", __func__,
7378 smp_phy_control(&ccb->smpio,
7383 (uint8_t *)response,
7386 /*expected_exp_change_count*/ 0,
7389 (set_pp_timeout_val != 0) ? 1 : 0,
7397 if (((retval = cam_send_ccb(device, ccb)) < 0)
7398 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7399 const char warnstr[] = "error sending command";
7406 if (arglist & CAM_ARG_VERBOSE) {
7408 * Use CAM_EPF_NORMAL so we only get one line of
7409 * SMP command decoding.
7411 cam_error_print(device, ccb, CAM_ESF_ALL,
7412 CAM_EPF_NORMAL, stderr);
7418 /* XXX KDM print out something here for success? */
7423 if (request != NULL)
7426 if (response != NULL)
7433 smpmaninfo(struct cam_device *device, int argc, char **argv,
7434 char *combinedopt, int retry_count, int timeout)
7437 struct smp_report_manuf_info_request request;
7438 struct smp_report_manuf_info_response response;
7439 struct sbuf *sb = NULL;
7440 int long_response = 0;
7445 * Note that at the moment we don't support sending SMP CCBs to
7446 * devices that aren't probed by CAM.
7448 ccb = cam_getccb(device);
7450 warnx("%s: error allocating CCB", __func__);
7454 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7456 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7465 bzero(&request, sizeof(request));
7466 bzero(&response, sizeof(response));
7468 smp_report_manuf_info(&ccb->smpio,
7473 (uint8_t *)&response,
7478 if (((retval = cam_send_ccb(device, ccb)) < 0)
7479 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7480 const char warnstr[] = "error sending command";
7487 if (arglist & CAM_ARG_VERBOSE) {
7488 cam_error_print(device, ccb, CAM_ESF_ALL,
7489 CAM_EPF_ALL, stderr);
7495 sb = sbuf_new_auto();
7497 warnx("%s: error allocating sbuf", __func__);
7501 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7503 if (sbuf_finish(sb) != 0) {
7504 warnx("%s: sbuf_finish", __func__);
7508 printf("%s", sbuf_data(sb));
7522 getdevid(struct cam_devitem *item)
7525 union ccb *ccb = NULL;
7527 struct cam_device *dev;
7529 dev = cam_open_btl(item->dev_match.path_id,
7530 item->dev_match.target_id,
7531 item->dev_match.target_lun, O_RDWR, NULL);
7534 warnx("%s", cam_errbuf);
7539 item->device_id_len = 0;
7541 ccb = cam_getccb(dev);
7543 warnx("%s: error allocating CCB", __func__);
7548 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7551 * On the first try, we just probe for the size of the data, and
7552 * then allocate that much memory and try again.
7555 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7556 ccb->ccb_h.flags = CAM_DIR_IN;
7557 ccb->cdai.flags = CDAI_FLAG_NONE;
7558 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7559 ccb->cdai.bufsiz = item->device_id_len;
7560 if (item->device_id_len != 0)
7561 ccb->cdai.buf = (uint8_t *)item->device_id;
7563 if (cam_send_ccb(dev, ccb) < 0) {
7564 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7569 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7570 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7575 if (item->device_id_len == 0) {
7577 * This is our first time through. Allocate the buffer,
7578 * and then go back to get the data.
7580 if (ccb->cdai.provsiz == 0) {
7581 warnx("%s: invalid .provsiz field returned with "
7582 "XPT_GDEV_ADVINFO CCB", __func__);
7586 item->device_id_len = ccb->cdai.provsiz;
7587 item->device_id = malloc(item->device_id_len);
7588 if (item->device_id == NULL) {
7589 warn("%s: unable to allocate %d bytes", __func__,
7590 item->device_id_len);
7594 ccb->ccb_h.status = CAM_REQ_INPROG;
7600 cam_close_device(dev);
7609 * XXX KDM merge this code with getdevtree()?
7612 buildbusdevlist(struct cam_devlist *devlist)
7615 int bufsize, fd = -1;
7616 struct dev_match_pattern *patterns;
7617 struct cam_devitem *item = NULL;
7618 int skip_device = 0;
7621 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7622 warn("couldn't open %s", XPT_DEVICE);
7626 bzero(&ccb, sizeof(union ccb));
7628 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7629 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7630 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7632 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7633 bufsize = sizeof(struct dev_match_result) * 100;
7634 ccb.cdm.match_buf_len = bufsize;
7635 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7636 if (ccb.cdm.matches == NULL) {
7637 warnx("can't malloc memory for matches");
7641 ccb.cdm.num_matches = 0;
7642 ccb.cdm.num_patterns = 2;
7643 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7644 ccb.cdm.num_patterns;
7646 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7647 if (patterns == NULL) {
7648 warnx("can't malloc memory for patterns");
7653 ccb.cdm.patterns = patterns;
7654 bzero(patterns, ccb.cdm.pattern_buf_len);
7656 patterns[0].type = DEV_MATCH_DEVICE;
7657 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7658 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7659 patterns[1].type = DEV_MATCH_PERIPH;
7660 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7661 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7664 * We do the ioctl multiple times if necessary, in case there are
7665 * more than 100 nodes in the EDT.
7670 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7671 warn("error sending CAMIOCOMMAND ioctl");
7676 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7677 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7678 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7679 warnx("got CAM error %#x, CDM error %d\n",
7680 ccb.ccb_h.status, ccb.cdm.status);
7685 for (i = 0; i < ccb.cdm.num_matches; i++) {
7686 switch (ccb.cdm.matches[i].type) {
7687 case DEV_MATCH_DEVICE: {
7688 struct device_match_result *dev_result;
7691 &ccb.cdm.matches[i].result.device_result;
7693 if (dev_result->flags &
7694 DEV_RESULT_UNCONFIGURED) {
7700 item = malloc(sizeof(*item));
7702 warn("%s: unable to allocate %zd bytes",
7703 __func__, sizeof(*item));
7707 bzero(item, sizeof(*item));
7708 bcopy(dev_result, &item->dev_match,
7709 sizeof(*dev_result));
7710 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7713 if (getdevid(item) != 0) {
7719 case DEV_MATCH_PERIPH: {
7720 struct periph_match_result *periph_result;
7723 &ccb.cdm.matches[i].result.periph_result;
7725 if (skip_device != 0)
7727 item->num_periphs++;
7728 item->periph_matches = realloc(
7729 item->periph_matches,
7731 sizeof(struct periph_match_result));
7732 if (item->periph_matches == NULL) {
7733 warn("%s: error allocating periph "
7738 bcopy(periph_result, &item->periph_matches[
7739 item->num_periphs - 1],
7740 sizeof(*periph_result));
7744 fprintf(stderr, "%s: unexpected match "
7745 "type %d\n", __func__,
7746 ccb.cdm.matches[i].type);
7749 break; /*NOTREACHED*/
7752 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7753 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7761 free(ccb.cdm.matches);
7764 freebusdevlist(devlist);
7770 freebusdevlist(struct cam_devlist *devlist)
7772 struct cam_devitem *item, *item2;
7774 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7775 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7777 free(item->device_id);
7778 free(item->periph_matches);
7783 static struct cam_devitem *
7784 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7786 struct cam_devitem *item;
7788 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7789 struct scsi_vpd_id_descriptor *idd;
7792 * XXX KDM look for LUN IDs as well?
7794 idd = scsi_get_devid(item->device_id,
7795 item->device_id_len,
7796 scsi_devid_is_sas_target);
7800 if (scsi_8btou64(idd->identifier) == sasaddr)
7808 smpphylist(struct cam_device *device, int argc, char **argv,
7809 char *combinedopt, int retry_count, int timeout)
7811 struct smp_report_general_request *rgrequest = NULL;
7812 struct smp_report_general_response *rgresponse = NULL;
7813 struct smp_discover_request *disrequest = NULL;
7814 struct smp_discover_response *disresponse = NULL;
7815 struct cam_devlist devlist;
7817 int long_response = 0;
7824 * Note that at the moment we don't support sending SMP CCBs to
7825 * devices that aren't probed by CAM.
7827 ccb = cam_getccb(device);
7829 warnx("%s: error allocating CCB", __func__);
7833 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7834 STAILQ_INIT(&devlist.dev_queue);
7836 rgrequest = malloc(sizeof(*rgrequest));
7837 if (rgrequest == NULL) {
7838 warn("%s: unable to allocate %zd bytes", __func__,
7839 sizeof(*rgrequest));
7844 rgresponse = malloc(sizeof(*rgresponse));
7845 if (rgresponse == NULL) {
7846 warn("%s: unable to allocate %zd bytes", __func__,
7847 sizeof(*rgresponse));
7852 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7865 smp_report_general(&ccb->smpio,
7869 /*request_len*/ sizeof(*rgrequest),
7870 (uint8_t *)rgresponse,
7871 /*response_len*/ sizeof(*rgresponse),
7872 /*long_response*/ long_response,
7875 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7877 if (((retval = cam_send_ccb(device, ccb)) < 0)
7878 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7879 const char warnstr[] = "error sending command";
7886 if (arglist & CAM_ARG_VERBOSE) {
7887 cam_error_print(device, ccb, CAM_ESF_ALL,
7888 CAM_EPF_ALL, stderr);
7894 num_phys = rgresponse->num_phys;
7896 if (num_phys == 0) {
7898 fprintf(stdout, "%s: No Phys reported\n", __func__);
7903 devlist.path_id = device->path_id;
7905 retval = buildbusdevlist(&devlist);
7910 fprintf(stdout, "%d PHYs:\n", num_phys);
7911 fprintf(stdout, "PHY Attached SAS Address\n");
7914 disrequest = malloc(sizeof(*disrequest));
7915 if (disrequest == NULL) {
7916 warn("%s: unable to allocate %zd bytes", __func__,
7917 sizeof(*disrequest));
7922 disresponse = malloc(sizeof(*disresponse));
7923 if (disresponse == NULL) {
7924 warn("%s: unable to allocate %zd bytes", __func__,
7925 sizeof(*disresponse));
7930 for (i = 0; i < num_phys; i++) {
7931 struct cam_devitem *item;
7932 struct device_match_result *dev_match;
7933 char vendor[16], product[48], revision[16];
7937 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7939 ccb->ccb_h.status = CAM_REQ_INPROG;
7940 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7942 smp_discover(&ccb->smpio,
7946 sizeof(*disrequest),
7947 (uint8_t *)disresponse,
7948 sizeof(*disresponse),
7950 /*ignore_zone_group*/ 0,
7954 if (((retval = cam_send_ccb(device, ccb)) < 0)
7955 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7956 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7957 const char warnstr[] = "error sending command";
7964 if (arglist & CAM_ARG_VERBOSE) {
7965 cam_error_print(device, ccb, CAM_ESF_ALL,
7966 CAM_EPF_ALL, stderr);
7972 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7974 fprintf(stdout, "%3d <vacant>\n", i);
7978 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7981 item = findsasdevice(&devlist,
7982 scsi_8btou64(disresponse->attached_sas_address));
7986 || (item != NULL)) {
7987 fprintf(stdout, "%3d 0x%016jx", i,
7988 (uintmax_t)scsi_8btou64(
7989 disresponse->attached_sas_address));
7991 fprintf(stdout, "\n");
7994 } else if (quiet != 0)
7997 dev_match = &item->dev_match;
7999 if (dev_match->protocol == PROTO_SCSI) {
8000 cam_strvis(vendor, dev_match->inq_data.vendor,
8001 sizeof(dev_match->inq_data.vendor),
8003 cam_strvis(product, dev_match->inq_data.product,
8004 sizeof(dev_match->inq_data.product),
8006 cam_strvis(revision, dev_match->inq_data.revision,
8007 sizeof(dev_match->inq_data.revision),
8009 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8011 } else if ((dev_match->protocol == PROTO_ATA)
8012 || (dev_match->protocol == PROTO_SATAPM)) {
8013 cam_strvis(product, dev_match->ident_data.model,
8014 sizeof(dev_match->ident_data.model),
8016 cam_strvis(revision, dev_match->ident_data.revision,
8017 sizeof(dev_match->ident_data.revision),
8019 sprintf(tmpstr, "<%s %s>", product, revision);
8021 sprintf(tmpstr, "<>");
8023 fprintf(stdout, " %-33s ", tmpstr);
8026 * If we have 0 periphs, that's a bug...
8028 if (item->num_periphs == 0) {
8029 fprintf(stdout, "\n");
8033 fprintf(stdout, "(");
8034 for (j = 0; j < item->num_periphs; j++) {
8036 fprintf(stdout, ",");
8038 fprintf(stdout, "%s%d",
8039 item->periph_matches[j].periph_name,
8040 item->periph_matches[j].unit_number);
8043 fprintf(stdout, ")\n");
8057 freebusdevlist(&devlist);
8063 atapm(struct cam_device *device, int argc, char **argv,
8064 char *combinedopt, int retry_count, int timeout)
8072 ccb = cam_getccb(device);
8075 warnx("%s: error allocating ccb", __func__);
8079 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8088 if (strcmp(argv[1], "idle") == 0) {
8090 cmd = ATA_IDLE_IMMEDIATE;
8093 } else if (strcmp(argv[1], "standby") == 0) {
8095 cmd = ATA_STANDBY_IMMEDIATE;
8097 cmd = ATA_STANDBY_CMD;
8105 else if (t <= (240 * 5))
8107 else if (t <= (252 * 5))
8108 /* special encoding for 21 minutes */
8110 else if (t <= (11 * 30 * 60))
8111 sc = (t - 1) / (30 * 60) + 241;
8115 retval = ata_do_28bit_cmd(device,
8117 /*retries*/retry_count,
8118 /*flags*/CAM_DIR_NONE,
8119 /*protocol*/AP_PROTO_NON_DATA,
8120 /*tag_action*/MSG_SIMPLE_Q_TAG,
8127 /*timeout*/timeout ? timeout : 30 * 1000,
8135 ataaxm(struct cam_device *device, int argc, char **argv,
8136 char *combinedopt, int retry_count, int timeout)
8144 ccb = cam_getccb(device);
8147 warnx("%s: error allocating ccb", __func__);
8151 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8161 if (strcmp(argv[1], "apm") == 0) {
8177 retval = ata_do_28bit_cmd(device,
8179 /*retries*/retry_count,
8180 /*flags*/CAM_DIR_NONE,
8181 /*protocol*/AP_PROTO_NON_DATA,
8182 /*tag_action*/MSG_SIMPLE_Q_TAG,
8183 /*command*/ATA_SETFEATURES,
8189 /*timeout*/timeout ? timeout : 30 * 1000,
8197 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8198 int show_sa_errors, int sa_set, int service_action,
8199 int timeout_desc, int retry_count, int timeout, int verbosemode,
8200 uint32_t *fill_len, uint8_t **data_ptr)
8202 union ccb *ccb = NULL;
8203 uint8_t *buf = NULL;
8204 uint32_t alloc_len = 0, num_opcodes;
8205 uint32_t valid_len = 0;
8206 uint32_t avail_len = 0;
8207 struct scsi_report_supported_opcodes_all *all_hdr;
8208 struct scsi_report_supported_opcodes_one *one;
8213 * Make it clear that we haven't yet allocated or filled anything.
8218 ccb = cam_getccb(device);
8220 warnx("couldn't allocate CCB");
8225 /* cam_getccb cleans up the header, caller has to zero the payload */
8226 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8228 if (opcode_set != 0) {
8229 options |= RSO_OPTIONS_OC;
8231 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8234 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8235 sizeof(struct scsi_report_supported_opcodes_descr));
8238 if (timeout_desc != 0) {
8239 options |= RSO_RCTD;
8240 alloc_len += num_opcodes *
8241 sizeof(struct scsi_report_supported_opcodes_timeout);
8245 options |= RSO_OPTIONS_OC_SA;
8246 if (show_sa_errors != 0)
8247 options &= ~RSO_OPTIONS_OC;
8256 buf = malloc(alloc_len);
8258 warn("Unable to allocate %u bytes", alloc_len);
8262 bzero(buf, alloc_len);
8264 scsi_report_supported_opcodes(&ccb->csio,
8265 /*retries*/ retry_count,
8267 /*tag_action*/ MSG_SIMPLE_Q_TAG,
8268 /*options*/ options,
8269 /*req_opcode*/ opcode,
8270 /*req_service_action*/ service_action,
8272 /*dxfer_len*/ alloc_len,
8273 /*sense_len*/ SSD_FULL_SIZE,
8274 /*timeout*/ timeout ? timeout : 10000);
8276 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8278 if (retry_count != 0)
8279 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8281 if (cam_send_ccb(device, ccb) < 0) {
8282 perror("error sending REPORT SUPPORTED OPERATION CODES");
8287 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8288 if (verbosemode != 0)
8289 cam_error_print(device, ccb, CAM_ESF_ALL,
8290 CAM_EPF_ALL, stderr);
8296 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8298 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8299 && (valid_len >= sizeof(*all_hdr))) {
8300 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8301 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8302 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8303 && (valid_len >= sizeof(*one))) {
8304 uint32_t cdb_length;
8306 one = (struct scsi_report_supported_opcodes_one *)buf;
8307 cdb_length = scsi_2btoul(one->cdb_length);
8308 avail_len = sizeof(*one) + cdb_length;
8309 if (one->support & RSO_ONE_CTDP) {
8310 struct scsi_report_supported_opcodes_timeout *td;
8312 td = (struct scsi_report_supported_opcodes_timeout *)
8314 if (valid_len >= (avail_len + sizeof(td->length))) {
8315 avail_len += scsi_2btoul(td->length) +
8318 avail_len += sizeof(*td);
8324 * avail_len could be zero if we didn't get enough data back from
8325 * thet target to determine
8327 if ((avail_len != 0)
8328 && (avail_len > valid_len)) {
8329 alloc_len = avail_len;
8333 *fill_len = valid_len;
8345 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8346 int req_sa, uint8_t *buf, uint32_t valid_len)
8348 struct scsi_report_supported_opcodes_one *one;
8349 struct scsi_report_supported_opcodes_timeout *td;
8350 uint32_t cdb_len = 0, td_len = 0;
8351 const char *op_desc = NULL;
8355 one = (struct scsi_report_supported_opcodes_one *)buf;
8358 * If we don't have the full single opcode descriptor, no point in
8361 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8363 warnx("Only %u bytes returned, not enough to verify support",
8369 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8371 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8374 printf(", SA 0x%x", req_sa);
8377 switch (one->support & RSO_ONE_SUP_MASK) {
8378 case RSO_ONE_SUP_UNAVAIL:
8379 printf("No command support information currently available\n");
8381 case RSO_ONE_SUP_NOT_SUP:
8382 printf("Command not supported\n");
8385 break; /*NOTREACHED*/
8386 case RSO_ONE_SUP_AVAIL:
8387 printf("Command is supported, complies with a SCSI standard\n");
8389 case RSO_ONE_SUP_VENDOR:
8390 printf("Command is supported, vendor-specific "
8391 "implementation\n");
8394 printf("Unknown command support flags 0x%#x\n",
8395 one->support & RSO_ONE_SUP_MASK);
8400 * If we don't have the CDB length, it isn't exactly an error, the
8401 * command probably isn't supported.
8403 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8407 cdb_len = scsi_2btoul(one->cdb_length);
8410 * If our valid data doesn't include the full reported length,
8411 * return. The caller should have detected this and adjusted his
8412 * allocation length to get all of the available data.
8414 if (valid_len < sizeof(*one) + cdb_len) {
8420 * If all we have is the opcode, there is no point in printing out
8428 printf("CDB usage bitmap:");
8429 for (i = 0; i < cdb_len; i++) {
8430 printf(" %02x", one->cdb_usage[i]);
8435 * If we don't have a timeout descriptor, we're done.
8437 if ((one->support & RSO_ONE_CTDP) == 0)
8441 * If we don't have enough valid length to include the timeout
8442 * descriptor length, we're done.
8444 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8447 td = (struct scsi_report_supported_opcodes_timeout *)
8448 &buf[sizeof(*one) + cdb_len];
8449 td_len = scsi_2btoul(td->length);
8450 td_len += sizeof(td->length);
8453 * If we don't have the full timeout descriptor, we're done.
8455 if (td_len < sizeof(*td))
8459 * If we don't have enough valid length to contain the full timeout
8460 * descriptor, we're done.
8462 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8465 printf("Timeout information:\n");
8466 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8467 printf("Nominal timeout: %u seconds\n",
8468 scsi_4btoul(td->nominal_time));
8469 printf("Recommended timeout: %u seconds\n",
8470 scsi_4btoul(td->recommended_time));
8477 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8480 struct scsi_report_supported_opcodes_all *hdr;
8481 struct scsi_report_supported_opcodes_descr *desc;
8482 uint32_t avail_len = 0, used_len = 0;
8486 if (valid_len < sizeof(*hdr)) {
8487 warnx("%s: not enough returned data (%u bytes) opcode list",
8488 __func__, valid_len);
8492 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8493 avail_len = scsi_4btoul(hdr->length);
8494 avail_len += sizeof(hdr->length);
8496 * Take the lesser of the amount of data the drive claims is
8497 * available, and the amount of data the HBA says was returned.
8499 avail_len = MIN(avail_len, valid_len);
8501 used_len = sizeof(hdr->length);
8503 printf("%-6s %4s %8s ",
8504 "Opcode", "SA", "CDB len" );
8507 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8508 printf(" Description\n");
8510 while ((avail_len - used_len) > sizeof(*desc)) {
8511 struct scsi_report_supported_opcodes_timeout *td;
8513 const char *op_desc = NULL;
8515 cur_ptr = &buf[used_len];
8516 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8518 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8519 if (op_desc == NULL)
8520 op_desc = "UNKNOWN";
8522 printf("0x%02x %#4x %8u ", desc->opcode,
8523 scsi_2btoul(desc->service_action),
8524 scsi_2btoul(desc->cdb_length));
8526 used_len += sizeof(*desc);
8528 if ((desc->flags & RSO_CTDP) == 0) {
8529 printf(" %s\n", op_desc);
8534 * If we don't have enough space to fit a timeout
8535 * descriptor, then we're done.
8537 if (avail_len - used_len < sizeof(*td)) {
8538 used_len = avail_len;
8539 printf(" %s\n", op_desc);
8542 cur_ptr = &buf[used_len];
8543 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8544 td_len = scsi_2btoul(td->length);
8545 td_len += sizeof(td->length);
8549 * If the given timeout descriptor length is less than what
8550 * we understand, skip it.
8552 if (td_len < sizeof(*td)) {
8553 printf(" %s\n", op_desc);
8557 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8558 scsi_4btoul(td->nominal_time),
8559 scsi_4btoul(td->recommended_time), op_desc);
8566 scsiopcodes(struct cam_device *device, int argc, char **argv,
8567 char *combinedopt, int retry_count, int timeout, int verbosemode)
8570 uint32_t opcode = 0, service_action = 0;
8571 int td_set = 0, opcode_set = 0, sa_set = 0;
8572 int show_sa_errors = 1;
8573 uint32_t valid_len = 0;
8574 uint8_t *buf = NULL;
8578 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8584 opcode = strtoul(optarg, &endptr, 0);
8585 if (*endptr != '\0') {
8586 warnx("Invalid opcode \"%s\", must be a number",
8591 if (opcode > 0xff) {
8592 warnx("Invalid opcode 0x%#x, must be between"
8593 "0 and 0xff inclusive", opcode);
8600 service_action = strtoul(optarg, &endptr, 0);
8601 if (*endptr != '\0') {
8602 warnx("Invalid service action \"%s\", must "
8603 "be a number", optarg);
8607 if (service_action > 0xffff) {
8608 warnx("Invalid service action 0x%#x, must "
8609 "be between 0 and 0xffff inclusive",
8624 && (opcode_set == 0)) {
8625 warnx("You must specify an opcode with -o if a service "
8630 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8631 sa_set, service_action, td_set, retry_count,
8632 timeout, verbosemode, &valid_len, &buf);
8636 if ((opcode_set != 0)
8638 retval = scsiprintoneopcode(device, opcode, sa_set,
8639 service_action, buf, valid_len);
8641 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8650 #endif /* MINIMALISTIC */
8653 scsireprobe(struct cam_device *device)
8658 ccb = cam_getccb(device);
8661 warnx("%s: error allocating ccb", __func__);
8665 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8667 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8669 if (cam_send_ccb(device, ccb) < 0) {
8670 warn("error sending XPT_REPROBE_LUN CCB");
8675 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8676 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8688 usage(int printlong)
8691 fprintf(printlong ? stdout : stderr,
8692 "usage: camcontrol <command> [device id][generic args][command args]\n"
8693 " camcontrol devlist [-b] [-v]\n"
8694 #ifndef MINIMALISTIC
8695 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8696 " camcontrol tur [dev_id][generic args]\n"
8697 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8698 " camcontrol identify [dev_id][generic args] [-v]\n"
8699 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8700 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8702 " camcontrol start [dev_id][generic args]\n"
8703 " camcontrol stop [dev_id][generic args]\n"
8704 " camcontrol load [dev_id][generic args]\n"
8705 " camcontrol eject [dev_id][generic args]\n"
8706 " camcontrol reprobe [dev_id][generic args]\n"
8707 #endif /* MINIMALISTIC */
8708 " camcontrol rescan <all | bus[:target:lun]>\n"
8709 " camcontrol reset <all | bus[:target:lun]>\n"
8710 #ifndef MINIMALISTIC
8711 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8712 " [-q][-s][-S offset][-X]\n"
8713 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8714 " [-P pagectl][-e | -b][-d]\n"
8715 " camcontrol cmd [dev_id][generic args]\n"
8716 " <-a cmd [args] | -c cmd [args]>\n"
8717 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8718 " camcontrol smpcmd [dev_id][generic args]\n"
8719 " <-r len fmt [args]> <-R len fmt [args]>\n"
8720 " camcontrol smprg [dev_id][generic args][-l]\n"
8721 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8722 " [-o operation][-d name][-m rate][-M rate]\n"
8723 " [-T pp_timeout][-a enable|disable]\n"
8724 " [-A enable|disable][-s enable|disable]\n"
8725 " [-S enable|disable]\n"
8726 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8727 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8728 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8729 " <all|bus[:target[:lun]]|off>\n"
8730 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8731 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8732 " [-D <enable|disable>][-M mode][-O offset]\n"
8733 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8734 " [-U][-W bus_width]\n"
8735 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8736 " camcontrol sanitize [dev_id][generic args]\n"
8737 " [-a overwrite|block|crypto|exitfailure]\n"
8738 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8740 " camcontrol idle [dev_id][generic args][-t time]\n"
8741 " camcontrol standby [dev_id][generic args][-t time]\n"
8742 " camcontrol sleep [dev_id][generic args]\n"
8743 " camcontrol apm [dev_id][generic args][-l level]\n"
8744 " camcontrol aam [dev_id][generic args][-l level]\n"
8745 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8747 " camcontrol security [dev_id][generic args]\n"
8748 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8749 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8750 " [-U <user|master>] [-y]\n"
8751 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8752 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8753 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8754 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8755 " [-s scope][-S][-T type][-U]\n"
8756 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8757 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8758 " [-p part][-s start][-T type][-V vol]\n"
8759 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8761 #endif /* MINIMALISTIC */
8762 " camcontrol help\n");
8765 #ifndef MINIMALISTIC
8767 "Specify one of the following options:\n"
8768 "devlist list all CAM devices\n"
8769 "periphlist list all CAM peripheral drivers attached to a device\n"
8770 "tur send a test unit ready to the named device\n"
8771 "inquiry send a SCSI inquiry command to the named device\n"
8772 "identify send a ATA identify command to the named device\n"
8773 "reportluns send a SCSI report luns command to the device\n"
8774 "readcap send a SCSI read capacity command to the device\n"
8775 "start send a Start Unit command to the device\n"
8776 "stop send a Stop Unit command to the device\n"
8777 "load send a Start Unit command to the device with the load bit set\n"
8778 "eject send a Stop Unit command to the device with the eject bit set\n"
8779 "reprobe update capacity information of the given device\n"
8780 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8781 "reset reset all busses, the given bus, or bus:target:lun\n"
8782 "defects read the defect list of the specified device\n"
8783 "modepage display or edit (-e) the given mode page\n"
8784 "cmd send the given SCSI command, may need -i or -o as well\n"
8785 "smpcmd send the given SMP command, requires -o and -i\n"
8786 "smprg send the SMP Report General command\n"
8787 "smppc send the SMP PHY Control command, requires -p\n"
8788 "smpphylist display phys attached to a SAS expander\n"
8789 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8790 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8791 "tags report or set the number of transaction slots for a device\n"
8792 "negotiate report or set device negotiation parameters\n"
8793 "format send the SCSI FORMAT UNIT command to the named device\n"
8794 "sanitize send the SCSI SANITIZE command to the named device\n"
8795 "idle send the ATA IDLE command to the named device\n"
8796 "standby send the ATA STANDBY command to the named device\n"
8797 "sleep send the ATA SLEEP command to the named device\n"
8798 "fwdownload program firmware of the named device with the given image\n"
8799 "security report or send ATA security commands to the named device\n"
8800 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8801 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8802 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8803 "help this message\n"
8804 "Device Identifiers:\n"
8805 "bus:target specify the bus and target, lun defaults to 0\n"
8806 "bus:target:lun specify the bus, target and lun\n"
8807 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8808 "Generic arguments:\n"
8809 "-v be verbose, print out sense information\n"
8810 "-t timeout command timeout in seconds, overrides default timeout\n"
8811 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8812 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8813 "-E have the kernel attempt to perform SCSI error recovery\n"
8814 "-C count specify the SCSI command retry count (needs -E to work)\n"
8815 "modepage arguments:\n"
8816 "-l list all available mode pages\n"
8817 "-m page specify the mode page to view or edit\n"
8818 "-e edit the specified mode page\n"
8819 "-b force view to binary mode\n"
8820 "-d disable block descriptors for mode sense\n"
8821 "-P pgctl page control field 0-3\n"
8822 "defects arguments:\n"
8823 "-f format specify defect list format (block, bfi or phys)\n"
8824 "-G get the grown defect list\n"
8825 "-P get the permanent defect list\n"
8826 "inquiry arguments:\n"
8827 "-D get the standard inquiry data\n"
8828 "-S get the serial number\n"
8829 "-R get the transfer rate, etc.\n"
8830 "reportluns arguments:\n"
8831 "-c only report a count of available LUNs\n"
8832 "-l only print out luns, and not a count\n"
8833 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
8834 "readcap arguments\n"
8835 "-b only report the blocksize\n"
8836 "-h human readable device size, base 2\n"
8837 "-H human readable device size, base 10\n"
8838 "-N print the number of blocks instead of last block\n"
8839 "-q quiet, print numbers only\n"
8840 "-s only report the last block/device size\n"
8842 "-c cdb [args] specify the SCSI CDB\n"
8843 "-i len fmt specify input data and input data format\n"
8844 "-o len fmt [args] specify output data and output data fmt\n"
8845 "smpcmd arguments:\n"
8846 "-r len fmt [args] specify the SMP command to be sent\n"
8847 "-R len fmt [args] specify SMP response format\n"
8848 "smprg arguments:\n"
8849 "-l specify the long response format\n"
8850 "smppc arguments:\n"
8851 "-p phy specify the PHY to operate on\n"
8852 "-l specify the long request/response format\n"
8853 "-o operation specify the phy control operation\n"
8854 "-d name set the attached device name\n"
8855 "-m rate set the minimum physical link rate\n"
8856 "-M rate set the maximum physical link rate\n"
8857 "-T pp_timeout set the partial pathway timeout value\n"
8858 "-a enable|disable enable or disable SATA slumber\n"
8859 "-A enable|disable enable or disable SATA partial phy power\n"
8860 "-s enable|disable enable or disable SAS slumber\n"
8861 "-S enable|disable enable or disable SAS partial phy power\n"
8862 "smpphylist arguments:\n"
8863 "-l specify the long response format\n"
8864 "-q only print phys with attached devices\n"
8865 "smpmaninfo arguments:\n"
8866 "-l specify the long response format\n"
8867 "debug arguments:\n"
8868 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
8869 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
8870 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
8871 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
8873 "-N tags specify the number of tags to use for this device\n"
8874 "-q be quiet, don't report the number of tags\n"
8875 "-v report a number of tag-related parameters\n"
8876 "negotiate arguments:\n"
8877 "-a send a test unit ready after negotiation\n"
8878 "-c report/set current negotiation settings\n"
8879 "-D <arg> \"enable\" or \"disable\" disconnection\n"
8880 "-M mode set ATA mode\n"
8881 "-O offset set command delay offset\n"
8882 "-q be quiet, don't report anything\n"
8883 "-R syncrate synchronization rate in MHz\n"
8884 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
8885 "-U report/set user negotiation settings\n"
8886 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
8887 "-v also print a Path Inquiry CCB for the controller\n"
8888 "format arguments:\n"
8889 "-q be quiet, don't print status messages\n"
8890 "-r run in report only mode\n"
8891 "-w don't send immediate format command\n"
8892 "-y don't ask any questions\n"
8893 "sanitize arguments:\n"
8894 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
8895 "-c passes overwrite passes to perform (1 to 31)\n"
8896 "-I invert overwrite pattern after each pass\n"
8897 "-P pattern path to overwrite pattern file\n"
8898 "-q be quiet, don't print status messages\n"
8899 "-r run in report only mode\n"
8900 "-U run operation in unrestricted completion exit mode\n"
8901 "-w don't send immediate sanitize command\n"
8902 "-y don't ask any questions\n"
8903 "idle/standby arguments:\n"
8904 "-t <arg> number of seconds before respective state.\n"
8905 "fwdownload arguments:\n"
8906 "-f fw_image path to firmware image file\n"
8907 "-q don't print informational messages, only errors\n"
8908 "-s run in simulation mode\n"
8909 "-v print info for every firmware segment sent to device\n"
8910 "-y don't ask any questions\n"
8911 "security arguments:\n"
8912 "-d pwd disable security using the given password for the selected\n"
8914 "-e pwd erase the device using the given pwd for the selected user\n"
8915 "-f freeze the security configuration of the specified device\n"
8916 "-h pwd enhanced erase the device using the given pwd for the\n"
8918 "-k pwd unlock the device using the given pwd for the selected\n"
8920 "-l <high|maximum> specifies which security level to set: high or maximum\n"
8921 "-q be quiet, do not print any status messages\n"
8922 "-s pwd password the device (enable security) using the given\n"
8923 " pwd for the selected user\n"
8924 "-T timeout overrides the timeout (seconds) used for erase operation\n"
8925 "-U <user|master> specifies which user to set: user or master\n"
8926 "-y don't ask any questions\n"
8928 "-f freeze the HPA configuration of the device\n"
8929 "-l lock the HPA configuration of the device\n"
8930 "-P make the HPA max sectors persist\n"
8931 "-p pwd Set the HPA configuration password required for unlock\n"
8933 "-q be quiet, do not print any status messages\n"
8934 "-s sectors configures the maximum user accessible sectors of the\n"
8936 "-U pwd unlock the HPA configuration of the device\n"
8937 "-y don't ask any questions\n"
8938 "persist arguments:\n"
8939 "-i action specify read_keys, read_reservation, report_cap, or\n"
8940 " read_full_status\n"
8941 "-o action specify register, register_ignore, reserve, release,\n"
8942 " clear, preempt, preempt_abort, register_move, replace_lost\n"
8943 "-a set the All Target Ports (ALL_TG_PT) bit\n"
8944 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
8945 "-k key specify the Reservation Key\n"
8946 "-K sa_key specify the Service Action Reservation Key\n"
8947 "-p set the Activate Persist Through Power Loss bit\n"
8948 "-R rtp specify the Relative Target Port\n"
8949 "-s scope specify the scope: lun, extent, element or a number\n"
8950 "-S specify Transport ID for register, requires -I\n"
8951 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
8952 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
8953 "-U unregister the current initiator for register_move\n"
8954 "attrib arguments:\n"
8955 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
8957 "-w attr specify an attribute to write, one -w argument per attr\n"
8958 "-a attr_num only display this attribute number\n"
8959 "-c get cached attributes\n"
8960 "-e elem_addr request attributes for the given element in a changer\n"
8961 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
8962 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
8963 " field_none, field_desc, field_num, field_size, field_rw\n"
8964 "-p partition request attributes for the given partition\n"
8965 "-s start_attr request attributes starting at the given number\n"
8966 "-T elem_type specify the element type (used with -e)\n"
8967 "-V logical_vol specify the logical volume ID\n"
8968 "opcodes arguments:\n"
8969 "-o opcode specify the individual opcode to list\n"
8970 "-s service_action specify the service action for the opcode\n"
8971 "-N do not return SCSI error for unsupported SA\n"
8972 "-T request nominal and recommended timeout values\n"
8974 #endif /* MINIMALISTIC */
8978 main(int argc, char **argv)
8981 char *device = NULL;
8983 struct cam_device *cam_dev = NULL;
8984 int timeout = 0, retry_count = 1;
8985 camcontrol_optret optreturn;
8987 const char *mainopt = "C:En:t:u:v";
8988 const char *subopt = NULL;
8989 char combinedopt[256];
8990 int error = 0, optstart = 2;
8992 #ifndef MINIMALISTIC
8996 #endif /* MINIMALISTIC */
8998 cmdlist = CAM_CMD_NONE;
8999 arglist = CAM_ARG_NONE;
9007 * Get the base option.
9009 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9011 if (optreturn == CC_OR_AMBIGUOUS) {
9012 warnx("ambiguous option %s", argv[1]);
9015 } else if (optreturn == CC_OR_NOT_FOUND) {
9016 warnx("option %s not found", argv[1]);
9022 * Ahh, getopt(3) is a pain.
9024 * This is a gross hack. There really aren't many other good
9025 * options (excuse the pun) for parsing options in a situation like
9026 * this. getopt is kinda braindead, so you end up having to run
9027 * through the options twice, and give each invocation of getopt
9028 * the option string for the other invocation.
9030 * You would think that you could just have two groups of options.
9031 * The first group would get parsed by the first invocation of
9032 * getopt, and the second group would get parsed by the second
9033 * invocation of getopt. It doesn't quite work out that way. When
9034 * the first invocation of getopt finishes, it leaves optind pointing
9035 * to the argument _after_ the first argument in the second group.
9036 * So when the second invocation of getopt comes around, it doesn't
9037 * recognize the first argument it gets and then bails out.
9039 * A nice alternative would be to have a flag for getopt that says
9040 * "just keep parsing arguments even when you encounter an unknown
9041 * argument", but there isn't one. So there's no real clean way to
9042 * easily parse two sets of arguments without having one invocation
9043 * of getopt know about the other.
9045 * Without this hack, the first invocation of getopt would work as
9046 * long as the generic arguments are first, but the second invocation
9047 * (in the subfunction) would fail in one of two ways. In the case
9048 * where you don't set optreset, it would fail because optind may be
9049 * pointing to the argument after the one it should be pointing at.
9050 * In the case where you do set optreset, and reset optind, it would
9051 * fail because getopt would run into the first set of options, which
9052 * it doesn't understand.
9054 * All of this would "sort of" work if you could somehow figure out
9055 * whether optind had been incremented one option too far. The
9056 * mechanics of that, however, are more daunting than just giving
9057 * both invocations all of the expect options for either invocation.
9059 * Needless to say, I wouldn't mind if someone invented a better
9060 * (non-GPL!) command line parsing interface than getopt. I
9061 * wouldn't mind if someone added more knobs to getopt to make it
9062 * work better. Who knows, I may talk myself into doing it someday,
9063 * if the standards weenies let me. As it is, it just leads to
9064 * hackery like this and causes people to avoid it in some cases.
9066 * KDM, September 8th, 1998
9069 sprintf(combinedopt, "%s%s", mainopt, subopt);
9071 sprintf(combinedopt, "%s", mainopt);
9074 * For these options we do not parse optional device arguments and
9075 * we do not open a passthrough device.
9077 if ((cmdlist == CAM_CMD_RESCAN)
9078 || (cmdlist == CAM_CMD_RESET)
9079 || (cmdlist == CAM_CMD_DEVTREE)
9080 || (cmdlist == CAM_CMD_USAGE)
9081 || (cmdlist == CAM_CMD_DEBUG))
9084 #ifndef MINIMALISTIC
9086 && (argc > 2 && argv[2][0] != '-')) {
9090 if (isdigit(argv[2][0])) {
9091 /* device specified as bus:target[:lun] */
9092 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9094 errx(1, "numeric device specification must "
9095 "be either bus:target, or "
9097 /* default to 0 if lun was not specified */
9098 if ((arglist & CAM_ARG_LUN) == 0) {
9100 arglist |= CAM_ARG_LUN;
9104 if (cam_get_device(argv[2], name, sizeof name, &unit)
9106 errx(1, "%s", cam_errbuf);
9107 device = strdup(name);
9108 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9112 #endif /* MINIMALISTIC */
9114 * Start getopt processing at argv[2/3], since we've already
9115 * accepted argv[1..2] as the command name, and as a possible
9121 * Now we run through the argument list looking for generic
9122 * options, and ignoring options that possibly belong to
9125 while ((c = getopt(argc, argv, combinedopt))!= -1){
9128 retry_count = strtol(optarg, NULL, 0);
9129 if (retry_count < 0)
9130 errx(1, "retry count %d is < 0",
9132 arglist |= CAM_ARG_RETRIES;
9135 arglist |= CAM_ARG_ERR_RECOVER;
9138 arglist |= CAM_ARG_DEVICE;
9140 while (isspace(*tstr) && (*tstr != '\0'))
9142 device = (char *)strdup(tstr);
9145 timeout = strtol(optarg, NULL, 0);
9147 errx(1, "invalid timeout %d", timeout);
9148 /* Convert the timeout from seconds to ms */
9150 arglist |= CAM_ARG_TIMEOUT;
9153 arglist |= CAM_ARG_UNIT;
9154 unit = strtol(optarg, NULL, 0);
9157 arglist |= CAM_ARG_VERBOSE;
9164 #ifndef MINIMALISTIC
9166 * For most commands we'll want to open the passthrough device
9167 * associated with the specified device. In the case of the rescan
9168 * commands, we don't use a passthrough device at all, just the
9169 * transport layer device.
9172 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9173 && (((arglist & CAM_ARG_DEVICE) == 0)
9174 || ((arglist & CAM_ARG_UNIT) == 0))) {
9175 errx(1, "subcommand \"%s\" requires a valid device "
9176 "identifier", argv[1]);
9179 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9180 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9181 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9183 errx(1,"%s", cam_errbuf);
9185 #endif /* MINIMALISTIC */
9188 * Reset optind to 2, and reset getopt, so these routines can parse
9189 * the arguments again.
9195 #ifndef MINIMALISTIC
9196 case CAM_CMD_DEVLIST:
9197 error = getdevlist(cam_dev);
9200 error = atahpa(cam_dev, retry_count, timeout,
9201 argc, argv, combinedopt);
9203 #endif /* MINIMALISTIC */
9204 case CAM_CMD_DEVTREE:
9205 error = getdevtree(argc, argv, combinedopt);
9207 #ifndef MINIMALISTIC
9209 error = testunitready(cam_dev, retry_count, timeout, 0);
9211 case CAM_CMD_INQUIRY:
9212 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9213 retry_count, timeout);
9215 case CAM_CMD_IDENTIFY:
9216 error = ataidentify(cam_dev, retry_count, timeout);
9218 case CAM_CMD_STARTSTOP:
9219 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9220 arglist & CAM_ARG_EJECT, retry_count,
9223 #endif /* MINIMALISTIC */
9224 case CAM_CMD_RESCAN:
9225 error = dorescan_or_reset(argc, argv, 1);
9228 error = dorescan_or_reset(argc, argv, 0);
9230 #ifndef MINIMALISTIC
9231 case CAM_CMD_READ_DEFECTS:
9232 error = readdefects(cam_dev, argc, argv, combinedopt,
9233 retry_count, timeout);
9235 case CAM_CMD_MODE_PAGE:
9236 modepage(cam_dev, argc, argv, combinedopt,
9237 retry_count, timeout);
9239 case CAM_CMD_SCSI_CMD:
9240 error = scsicmd(cam_dev, argc, argv, combinedopt,
9241 retry_count, timeout);
9243 case CAM_CMD_SMP_CMD:
9244 error = smpcmd(cam_dev, argc, argv, combinedopt,
9245 retry_count, timeout);
9247 case CAM_CMD_SMP_RG:
9248 error = smpreportgeneral(cam_dev, argc, argv,
9249 combinedopt, retry_count,
9252 case CAM_CMD_SMP_PC:
9253 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9254 retry_count, timeout);
9256 case CAM_CMD_SMP_PHYLIST:
9257 error = smpphylist(cam_dev, argc, argv, combinedopt,
9258 retry_count, timeout);
9260 case CAM_CMD_SMP_MANINFO:
9261 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9262 retry_count, timeout);
9265 error = camdebug(argc, argv, combinedopt);
9268 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9271 error = ratecontrol(cam_dev, retry_count, timeout,
9272 argc, argv, combinedopt);
9274 case CAM_CMD_FORMAT:
9275 error = scsiformat(cam_dev, argc, argv,
9276 combinedopt, retry_count, timeout);
9278 case CAM_CMD_REPORTLUNS:
9279 error = scsireportluns(cam_dev, argc, argv,
9280 combinedopt, retry_count,
9283 case CAM_CMD_READCAP:
9284 error = scsireadcapacity(cam_dev, argc, argv,
9285 combinedopt, retry_count,
9289 case CAM_CMD_STANDBY:
9291 error = atapm(cam_dev, argc, argv,
9292 combinedopt, retry_count, timeout);
9296 error = ataaxm(cam_dev, argc, argv,
9297 combinedopt, retry_count, timeout);
9299 case CAM_CMD_SECURITY:
9300 error = atasecurity(cam_dev, retry_count, timeout,
9301 argc, argv, combinedopt);
9303 case CAM_CMD_DOWNLOAD_FW:
9304 error = fwdownload(cam_dev, argc, argv, combinedopt,
9305 arglist & CAM_ARG_VERBOSE, retry_count, timeout);
9307 case CAM_CMD_SANITIZE:
9308 error = scsisanitize(cam_dev, argc, argv,
9309 combinedopt, retry_count, timeout);
9311 case CAM_CMD_PERSIST:
9312 error = scsipersist(cam_dev, argc, argv, combinedopt,
9313 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9314 arglist & CAM_ARG_ERR_RECOVER);
9316 case CAM_CMD_ATTRIB:
9317 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9318 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9319 arglist & CAM_ARG_ERR_RECOVER);
9321 case CAM_CMD_OPCODES:
9322 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9323 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9325 case CAM_CMD_REPROBE:
9326 error = scsireprobe(cam_dev);
9329 #endif /* MINIMALISTIC */
9339 if (cam_dev != NULL)
9340 cam_close_device(cam_dev);