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, valid_bytes;
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);
4453 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4455 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4456 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4457 && (arglist & CAM_ARG_CMD_IN)
4458 && (valid_bytes > 0)) {
4460 buff_decode_visit(data_ptr, valid_bytes, datastr,
4462 fprintf(stdout, "\n");
4464 ssize_t amt_written;
4465 int amt_to_write = valid_bytes;
4466 u_int8_t *buf_ptr = data_ptr;
4468 for (amt_written = 0; (amt_to_write > 0) &&
4469 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4470 amt_to_write -= amt_written;
4471 buf_ptr += amt_written;
4473 if (amt_written == -1) {
4474 warn("error writing data to stdout");
4476 goto scsicmd_bailout;
4477 } else if ((amt_written == 0)
4478 && (amt_to_write > 0)) {
4479 warnx("only wrote %u bytes out of %u",
4480 valid_bytes - amt_to_write, valid_bytes);
4487 if ((data_bytes > 0) && (data_ptr != NULL))
4496 camdebug(int argc, char **argv, char *combinedopt)
4499 path_id_t bus = CAM_BUS_WILDCARD;
4500 target_id_t target = CAM_TARGET_WILDCARD;
4501 lun_id_t lun = CAM_LUN_WILDCARD;
4502 char *tstr, *tmpstr = NULL;
4506 bzero(&ccb, sizeof(union ccb));
4508 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4511 arglist |= CAM_ARG_DEBUG_INFO;
4512 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4515 arglist |= CAM_ARG_DEBUG_PERIPH;
4516 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4519 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4520 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4523 arglist |= CAM_ARG_DEBUG_TRACE;
4524 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4527 arglist |= CAM_ARG_DEBUG_XPT;
4528 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4531 arglist |= CAM_ARG_DEBUG_CDB;
4532 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4535 arglist |= CAM_ARG_DEBUG_PROBE;
4536 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4543 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4544 warnx("error opening transport layer device %s", XPT_DEVICE);
4545 warn("%s", XPT_DEVICE);
4552 warnx("you must specify \"off\", \"all\" or a bus,");
4553 warnx("bus:target, or bus:target:lun");
4560 while (isspace(*tstr) && (*tstr != '\0'))
4563 if (strncmp(tstr, "off", 3) == 0) {
4564 ccb.cdbg.flags = CAM_DEBUG_NONE;
4565 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4566 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4567 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4568 } else if (strncmp(tstr, "all", 3) != 0) {
4569 tmpstr = (char *)strtok(tstr, ":");
4570 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4571 bus = strtol(tmpstr, NULL, 0);
4572 arglist |= CAM_ARG_BUS;
4573 tmpstr = (char *)strtok(NULL, ":");
4574 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4575 target = strtol(tmpstr, NULL, 0);
4576 arglist |= CAM_ARG_TARGET;
4577 tmpstr = (char *)strtok(NULL, ":");
4578 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4579 lun = strtol(tmpstr, NULL, 0);
4580 arglist |= CAM_ARG_LUN;
4585 warnx("you must specify \"all\", \"off\", or a bus,");
4586 warnx("bus:target, or bus:target:lun to debug");
4592 ccb.ccb_h.func_code = XPT_DEBUG;
4593 ccb.ccb_h.path_id = bus;
4594 ccb.ccb_h.target_id = target;
4595 ccb.ccb_h.target_lun = lun;
4597 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4598 warn("CAMIOCOMMAND ioctl failed");
4603 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4604 CAM_FUNC_NOTAVAIL) {
4605 warnx("CAM debugging not available");
4606 warnx("you need to put options CAMDEBUG in"
4607 " your kernel config file!");
4609 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4611 warnx("XPT_DEBUG CCB failed with status %#x",
4615 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4617 "Debugging turned off\n");
4620 "Debugging enabled for "
4622 bus, target, (uintmax_t)lun);
4633 tagcontrol(struct cam_device *device, int argc, char **argv,
4643 ccb = cam_getccb(device);
4646 warnx("tagcontrol: error allocating ccb");
4650 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4653 numtags = strtol(optarg, NULL, 0);
4655 warnx("tag count %d is < 0", numtags);
4657 goto tagcontrol_bailout;
4668 cam_path_string(device, pathstr, sizeof(pathstr));
4671 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4672 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4673 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4674 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4675 ccb->crs.openings = numtags;
4678 if (cam_send_ccb(device, ccb) < 0) {
4679 perror("error sending XPT_REL_SIMQ CCB");
4681 goto tagcontrol_bailout;
4684 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4685 warnx("XPT_REL_SIMQ CCB failed");
4686 cam_error_print(device, ccb, CAM_ESF_ALL,
4687 CAM_EPF_ALL, stderr);
4689 goto tagcontrol_bailout;
4694 fprintf(stdout, "%stagged openings now %d\n",
4695 pathstr, ccb->crs.openings);
4698 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4700 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4702 if (cam_send_ccb(device, ccb) < 0) {
4703 perror("error sending XPT_GDEV_STATS CCB");
4705 goto tagcontrol_bailout;
4708 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4709 warnx("XPT_GDEV_STATS CCB failed");
4710 cam_error_print(device, ccb, CAM_ESF_ALL,
4711 CAM_EPF_ALL, stderr);
4713 goto tagcontrol_bailout;
4716 if (arglist & CAM_ARG_VERBOSE) {
4717 fprintf(stdout, "%s", pathstr);
4718 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4719 fprintf(stdout, "%s", pathstr);
4720 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4721 fprintf(stdout, "%s", pathstr);
4722 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4723 fprintf(stdout, "%s", pathstr);
4724 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4725 fprintf(stdout, "%s", pathstr);
4726 fprintf(stdout, "held %d\n", ccb->cgds.held);
4727 fprintf(stdout, "%s", pathstr);
4728 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4729 fprintf(stdout, "%s", pathstr);
4730 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4733 fprintf(stdout, "%s", pathstr);
4734 fprintf(stdout, "device openings: ");
4736 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4737 ccb->cgds.dev_active);
4747 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4751 cam_path_string(device, pathstr, sizeof(pathstr));
4753 if (cts->transport == XPORT_SPI) {
4754 struct ccb_trans_settings_spi *spi =
4755 &cts->xport_specific.spi;
4757 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4759 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4762 if (spi->sync_offset != 0) {
4765 freq = scsi_calc_syncsrate(spi->sync_period);
4766 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4767 pathstr, freq / 1000, freq % 1000);
4771 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4772 fprintf(stdout, "%soffset: %d\n", pathstr,
4776 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4777 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4778 (0x01 << spi->bus_width) * 8);
4781 if (spi->valid & CTS_SPI_VALID_DISC) {
4782 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4783 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4784 "enabled" : "disabled");
4787 if (cts->transport == XPORT_FC) {
4788 struct ccb_trans_settings_fc *fc =
4789 &cts->xport_specific.fc;
4791 if (fc->valid & CTS_FC_VALID_WWNN)
4792 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4793 (long long) fc->wwnn);
4794 if (fc->valid & CTS_FC_VALID_WWPN)
4795 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4796 (long long) fc->wwpn);
4797 if (fc->valid & CTS_FC_VALID_PORT)
4798 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4799 if (fc->valid & CTS_FC_VALID_SPEED)
4800 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4801 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4803 if (cts->transport == XPORT_SAS) {
4804 struct ccb_trans_settings_sas *sas =
4805 &cts->xport_specific.sas;
4807 if (sas->valid & CTS_SAS_VALID_SPEED)
4808 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4809 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4811 if (cts->transport == XPORT_ATA) {
4812 struct ccb_trans_settings_pata *pata =
4813 &cts->xport_specific.ata;
4815 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4816 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4817 ata_mode2string(pata->mode));
4819 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4820 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4823 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4824 fprintf(stdout, "%sPIO transaction length: %d\n",
4825 pathstr, pata->bytecount);
4828 if (cts->transport == XPORT_SATA) {
4829 struct ccb_trans_settings_sata *sata =
4830 &cts->xport_specific.sata;
4832 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4833 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4836 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4837 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4838 ata_mode2string(sata->mode));
4840 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4841 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4844 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4845 fprintf(stdout, "%sPIO transaction length: %d\n",
4846 pathstr, sata->bytecount);
4848 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4849 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4852 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4853 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4856 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4857 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4861 if (cts->protocol == PROTO_ATA) {
4862 struct ccb_trans_settings_ata *ata=
4863 &cts->proto_specific.ata;
4865 if (ata->valid & CTS_ATA_VALID_TQ) {
4866 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4867 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4868 "enabled" : "disabled");
4871 if (cts->protocol == PROTO_SCSI) {
4872 struct ccb_trans_settings_scsi *scsi=
4873 &cts->proto_specific.scsi;
4875 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4876 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4877 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4878 "enabled" : "disabled");
4885 * Get a path inquiry CCB for the specified device.
4888 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4893 ccb = cam_getccb(device);
4895 warnx("get_cpi: couldn't allocate CCB");
4898 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
4899 ccb->ccb_h.func_code = XPT_PATH_INQ;
4900 if (cam_send_ccb(device, ccb) < 0) {
4901 warn("get_cpi: error sending Path Inquiry CCB");
4902 if (arglist & CAM_ARG_VERBOSE)
4903 cam_error_print(device, ccb, CAM_ESF_ALL,
4904 CAM_EPF_ALL, stderr);
4906 goto get_cpi_bailout;
4908 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4909 if (arglist & CAM_ARG_VERBOSE)
4910 cam_error_print(device, ccb, CAM_ESF_ALL,
4911 CAM_EPF_ALL, stderr);
4913 goto get_cpi_bailout;
4915 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4923 * Get a get device CCB for the specified device.
4926 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4931 ccb = cam_getccb(device);
4933 warnx("get_cgd: couldn't allocate CCB");
4936 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
4937 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4938 if (cam_send_ccb(device, ccb) < 0) {
4939 warn("get_cgd: error sending Path Inquiry CCB");
4940 if (arglist & CAM_ARG_VERBOSE)
4941 cam_error_print(device, ccb, CAM_ESF_ALL,
4942 CAM_EPF_ALL, stderr);
4944 goto get_cgd_bailout;
4946 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4947 if (arglist & CAM_ARG_VERBOSE)
4948 cam_error_print(device, ccb, CAM_ESF_ALL,
4949 CAM_EPF_ALL, stderr);
4951 goto get_cgd_bailout;
4953 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4961 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4965 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4966 int timeout, int verbosemode)
4968 union ccb *ccb = NULL;
4969 struct scsi_vpd_supported_page_list sup_pages;
4973 ccb = cam_getccb(dev);
4975 warn("Unable to allocate CCB");
4980 /* cam_getccb cleans up the header, caller has to zero the payload */
4981 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4983 bzero(&sup_pages, sizeof(sup_pages));
4985 scsi_inquiry(&ccb->csio,
4986 /*retries*/ retry_count,
4988 /* tag_action */ MSG_SIMPLE_Q_TAG,
4989 /* inq_buf */ (u_int8_t *)&sup_pages,
4990 /* inq_len */ sizeof(sup_pages),
4992 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
4993 /* sense_len */ SSD_FULL_SIZE,
4994 /* timeout */ timeout ? timeout : 5000);
4996 /* Disable freezing the device queue */
4997 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4999 if (retry_count != 0)
5000 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5002 if (cam_send_ccb(dev, ccb) < 0) {
5009 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5010 if (verbosemode != 0)
5011 cam_error_print(dev, ccb, CAM_ESF_ALL,
5012 CAM_EPF_ALL, stderr);
5017 for (i = 0; i < sup_pages.length; i++) {
5018 if (sup_pages.list[i] == page_id) {
5031 * devtype is filled in with the type of device.
5032 * Returns 0 for success, non-zero for failure.
5035 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5036 int verbosemode, camcontrol_devtype *devtype)
5038 struct ccb_getdev cgd;
5041 retval = get_cgd(dev, &cgd);
5045 switch (cgd.protocol) {
5051 *devtype = CC_DT_ATA;
5053 break; /*NOTREACHED*/
5055 *devtype = CC_DT_UNKNOWN;
5057 break; /*NOTREACHED*/
5061 * Check for the ATA Information VPD page (0x89). If this is an
5062 * ATA device behind a SCSI to ATA translation layer, this VPD page
5063 * should be present.
5065 * If that VPD page isn't present, or we get an error back from the
5066 * INQUIRY command, we'll just treat it as a normal SCSI device.
5068 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5069 timeout, verbosemode);
5071 *devtype = CC_DT_ATA_BEHIND_SCSI;
5073 *devtype = CC_DT_SCSI;
5082 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5083 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5084 uint16_t sector_count, uint64_t lba, uint8_t command, uint8_t *data_ptr,
5085 uint16_t dxfer_len, uint8_t sense_len, uint32_t timeout,
5086 int is48bit, camcontrol_devtype devtype)
5088 if (devtype == CC_DT_ATA) {
5089 cam_fill_ataio(&ccb->ataio,
5090 /*retries*/ retry_count,
5093 /*tag_action*/ tag_action,
5094 /*data_ptr*/ data_ptr,
5095 /*dxfer_len*/ dxfer_len,
5096 /*timeout*/ timeout);
5097 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5098 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5101 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5104 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5105 protocol |= AP_EXTEND;
5107 scsi_ata_pass_16(&ccb->csio,
5108 /*retries*/ retry_count,
5111 /*tag_action*/ tag_action,
5112 /*protocol*/ protocol,
5113 /*ata_flags*/ ata_flags,
5114 /*features*/ features,
5115 /*sector_count*/ sector_count,
5117 /*command*/ command,
5119 /*data_ptr*/ data_ptr,
5120 /*dxfer_len*/ dxfer_len,
5121 /*sense_len*/ sense_len,
5122 /*timeout*/ timeout);
5128 cpi_print(struct ccb_pathinq *cpi)
5130 char adapter_str[1024];
5133 snprintf(adapter_str, sizeof(adapter_str),
5134 "%s%d:", cpi->dev_name, cpi->unit_number);
5136 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5139 for (i = 1; i < 0xff; i = i << 1) {
5142 if ((i & cpi->hba_inquiry) == 0)
5145 fprintf(stdout, "%s supports ", adapter_str);
5149 str = "MDP message";
5152 str = "32 bit wide SCSI";
5155 str = "16 bit wide SCSI";
5158 str = "SDTR message";
5161 str = "linked CDBs";
5164 str = "tag queue messages";
5167 str = "soft reset alternative";
5170 str = "SATA Port Multiplier";
5173 str = "unknown PI bit set";
5176 fprintf(stdout, "%s\n", str);
5179 for (i = 1; i < 0xff; i = i << 1) {
5182 if ((i & cpi->hba_misc) == 0)
5185 fprintf(stdout, "%s ", adapter_str);
5189 str = "bus scans from high ID to low ID";
5192 str = "removable devices not included in scan";
5194 case PIM_NOINITIATOR:
5195 str = "initiator role not supported";
5197 case PIM_NOBUSRESET:
5198 str = "user has disabled initial BUS RESET or"
5199 " controller is in target/mixed mode";
5202 str = "do not send 6-byte commands";
5205 str = "scan bus sequentially";
5208 str = "unknown PIM bit set";
5211 fprintf(stdout, "%s\n", str);
5214 for (i = 1; i < 0xff; i = i << 1) {
5217 if ((i & cpi->target_sprt) == 0)
5220 fprintf(stdout, "%s supports ", adapter_str);
5223 str = "target mode processor mode";
5226 str = "target mode phase cog. mode";
5228 case PIT_DISCONNECT:
5229 str = "disconnects in target mode";
5232 str = "terminate I/O message in target mode";
5235 str = "group 6 commands in target mode";
5238 str = "group 7 commands in target mode";
5241 str = "unknown PIT bit set";
5245 fprintf(stdout, "%s\n", str);
5247 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5249 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5251 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5253 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5254 adapter_str, cpi->hpath_id);
5255 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5257 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5258 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5259 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5260 adapter_str, cpi->hba_vendor);
5261 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5262 adapter_str, cpi->hba_device);
5263 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5264 adapter_str, cpi->hba_subvendor);
5265 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5266 adapter_str, cpi->hba_subdevice);
5267 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5268 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5269 if (cpi->base_transfer_speed > 1000)
5270 fprintf(stdout, "%d.%03dMB/sec\n",
5271 cpi->base_transfer_speed / 1000,
5272 cpi->base_transfer_speed % 1000);
5274 fprintf(stdout, "%dKB/sec\n",
5275 (cpi->base_transfer_speed % 1000) * 1000);
5276 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5277 adapter_str, cpi->maxio);
5281 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5282 struct ccb_trans_settings *cts)
5288 ccb = cam_getccb(device);
5291 warnx("get_print_cts: error allocating ccb");
5295 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5297 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5299 if (user_settings == 0)
5300 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5302 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5304 if (cam_send_ccb(device, ccb) < 0) {
5305 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5306 if (arglist & CAM_ARG_VERBOSE)
5307 cam_error_print(device, ccb, CAM_ESF_ALL,
5308 CAM_EPF_ALL, stderr);
5310 goto get_print_cts_bailout;
5313 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5314 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5315 if (arglist & CAM_ARG_VERBOSE)
5316 cam_error_print(device, ccb, CAM_ESF_ALL,
5317 CAM_EPF_ALL, stderr);
5319 goto get_print_cts_bailout;
5323 cts_print(device, &ccb->cts);
5326 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5328 get_print_cts_bailout:
5336 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5337 int argc, char **argv, char *combinedopt)
5341 int user_settings = 0;
5343 int disc_enable = -1, tag_enable = -1;
5346 double syncrate = -1;
5349 int change_settings = 0, send_tur = 0;
5350 struct ccb_pathinq cpi;
5352 ccb = cam_getccb(device);
5354 warnx("ratecontrol: error allocating ccb");
5357 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5366 if (strncasecmp(optarg, "enable", 6) == 0)
5368 else if (strncasecmp(optarg, "disable", 7) == 0)
5371 warnx("-D argument \"%s\" is unknown", optarg);
5373 goto ratecontrol_bailout;
5375 change_settings = 1;
5378 mode = ata_string2mode(optarg);
5380 warnx("unknown mode '%s'", optarg);
5382 goto ratecontrol_bailout;
5384 change_settings = 1;
5387 offset = strtol(optarg, NULL, 0);
5389 warnx("offset value %d is < 0", offset);
5391 goto ratecontrol_bailout;
5393 change_settings = 1;
5399 syncrate = atof(optarg);
5401 warnx("sync rate %f is < 0", syncrate);
5403 goto ratecontrol_bailout;
5405 change_settings = 1;
5408 if (strncasecmp(optarg, "enable", 6) == 0)
5410 else if (strncasecmp(optarg, "disable", 7) == 0)
5413 warnx("-T argument \"%s\" is unknown", optarg);
5415 goto ratecontrol_bailout;
5417 change_settings = 1;
5423 bus_width = strtol(optarg, NULL, 0);
5424 if (bus_width < 0) {
5425 warnx("bus width %d is < 0", bus_width);
5427 goto ratecontrol_bailout;
5429 change_settings = 1;
5435 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5437 * Grab path inquiry information, so we can determine whether
5438 * or not the initiator is capable of the things that the user
5441 ccb->ccb_h.func_code = XPT_PATH_INQ;
5442 if (cam_send_ccb(device, ccb) < 0) {
5443 perror("error sending XPT_PATH_INQ CCB");
5444 if (arglist & CAM_ARG_VERBOSE) {
5445 cam_error_print(device, ccb, CAM_ESF_ALL,
5446 CAM_EPF_ALL, stderr);
5449 goto ratecontrol_bailout;
5451 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5452 warnx("XPT_PATH_INQ CCB failed");
5453 if (arglist & CAM_ARG_VERBOSE) {
5454 cam_error_print(device, ccb, CAM_ESF_ALL,
5455 CAM_EPF_ALL, stderr);
5458 goto ratecontrol_bailout;
5460 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5461 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5463 fprintf(stdout, "%s parameters:\n",
5464 user_settings ? "User" : "Current");
5466 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5468 goto ratecontrol_bailout;
5470 if (arglist & CAM_ARG_VERBOSE)
5473 if (change_settings) {
5474 int didsettings = 0;
5475 struct ccb_trans_settings_spi *spi = NULL;
5476 struct ccb_trans_settings_pata *pata = NULL;
5477 struct ccb_trans_settings_sata *sata = NULL;
5478 struct ccb_trans_settings_ata *ata = NULL;
5479 struct ccb_trans_settings_scsi *scsi = NULL;
5481 if (ccb->cts.transport == XPORT_SPI)
5482 spi = &ccb->cts.xport_specific.spi;
5483 if (ccb->cts.transport == XPORT_ATA)
5484 pata = &ccb->cts.xport_specific.ata;
5485 if (ccb->cts.transport == XPORT_SATA)
5486 sata = &ccb->cts.xport_specific.sata;
5487 if (ccb->cts.protocol == PROTO_ATA)
5488 ata = &ccb->cts.proto_specific.ata;
5489 if (ccb->cts.protocol == PROTO_SCSI)
5490 scsi = &ccb->cts.proto_specific.scsi;
5491 ccb->cts.xport_specific.valid = 0;
5492 ccb->cts.proto_specific.valid = 0;
5493 if (spi && disc_enable != -1) {
5494 spi->valid |= CTS_SPI_VALID_DISC;
5495 if (disc_enable == 0)
5496 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5498 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5501 if (tag_enable != -1) {
5502 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5503 warnx("HBA does not support tagged queueing, "
5504 "so you cannot modify tag settings");
5506 goto ratecontrol_bailout;
5509 ata->valid |= CTS_SCSI_VALID_TQ;
5510 if (tag_enable == 0)
5511 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5513 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5516 scsi->valid |= CTS_SCSI_VALID_TQ;
5517 if (tag_enable == 0)
5518 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5520 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5524 if (spi && offset != -1) {
5525 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5526 warnx("HBA is not capable of changing offset");
5528 goto ratecontrol_bailout;
5530 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5531 spi->sync_offset = offset;
5534 if (spi && syncrate != -1) {
5535 int prelim_sync_period;
5537 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5538 warnx("HBA is not capable of changing "
5541 goto ratecontrol_bailout;
5543 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5545 * The sync rate the user gives us is in MHz.
5546 * We need to translate it into KHz for this
5551 * Next, we calculate a "preliminary" sync period
5552 * in tenths of a nanosecond.
5555 prelim_sync_period = 0;
5557 prelim_sync_period = 10000000 / syncrate;
5559 scsi_calc_syncparam(prelim_sync_period);
5562 if (sata && syncrate != -1) {
5563 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5564 warnx("HBA is not capable of changing "
5567 goto ratecontrol_bailout;
5569 if (!user_settings) {
5570 warnx("You can modify only user rate "
5571 "settings for SATA");
5573 goto ratecontrol_bailout;
5575 sata->revision = ata_speed2revision(syncrate * 100);
5576 if (sata->revision < 0) {
5577 warnx("Invalid rate %f", syncrate);
5579 goto ratecontrol_bailout;
5581 sata->valid |= CTS_SATA_VALID_REVISION;
5584 if ((pata || sata) && mode != -1) {
5585 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5586 warnx("HBA is not capable of changing "
5589 goto ratecontrol_bailout;
5591 if (!user_settings) {
5592 warnx("You can modify only user mode "
5593 "settings for ATA/SATA");
5595 goto ratecontrol_bailout;
5599 pata->valid |= CTS_ATA_VALID_MODE;
5602 sata->valid |= CTS_SATA_VALID_MODE;
5607 * The bus_width argument goes like this:
5611 * Therefore, if you shift the number of bits given on the
5612 * command line right by 4, you should get the correct
5615 if (spi && bus_width != -1) {
5617 * We might as well validate things here with a
5618 * decipherable error message, rather than what
5619 * will probably be an indecipherable error message
5620 * by the time it gets back to us.
5622 if ((bus_width == 16)
5623 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5624 warnx("HBA does not support 16 bit bus width");
5626 goto ratecontrol_bailout;
5627 } else if ((bus_width == 32)
5628 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5629 warnx("HBA does not support 32 bit bus width");
5631 goto ratecontrol_bailout;
5632 } else if ((bus_width != 8)
5633 && (bus_width != 16)
5634 && (bus_width != 32)) {
5635 warnx("Invalid bus width %d", bus_width);
5637 goto ratecontrol_bailout;
5639 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5640 spi->bus_width = bus_width >> 4;
5643 if (didsettings == 0) {
5644 goto ratecontrol_bailout;
5646 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5647 if (cam_send_ccb(device, ccb) < 0) {
5648 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5649 if (arglist & CAM_ARG_VERBOSE) {
5650 cam_error_print(device, ccb, CAM_ESF_ALL,
5651 CAM_EPF_ALL, stderr);
5654 goto ratecontrol_bailout;
5656 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5657 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5658 if (arglist & CAM_ARG_VERBOSE) {
5659 cam_error_print(device, ccb, CAM_ESF_ALL,
5660 CAM_EPF_ALL, stderr);
5663 goto ratecontrol_bailout;
5667 retval = testunitready(device, retry_count, timeout,
5668 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5670 * If the TUR didn't succeed, just bail.
5674 fprintf(stderr, "Test Unit Ready failed\n");
5675 goto ratecontrol_bailout;
5678 if ((change_settings || send_tur) && !quiet &&
5679 (ccb->cts.transport == XPORT_ATA ||
5680 ccb->cts.transport == XPORT_SATA || send_tur)) {
5681 fprintf(stdout, "New parameters:\n");
5682 retval = get_print_cts(device, user_settings, 0, NULL);
5685 ratecontrol_bailout:
5691 scsiformat(struct cam_device *device, int argc, char **argv,
5692 char *combinedopt, int retry_count, int timeout)
5696 int ycount = 0, quiet = 0;
5697 int error = 0, retval = 0;
5698 int use_timeout = 10800 * 1000;
5700 struct format_defect_list_header fh;
5701 u_int8_t *data_ptr = NULL;
5702 u_int32_t dxfer_len = 0;
5704 int num_warnings = 0;
5707 ccb = cam_getccb(device);
5710 warnx("scsiformat: error allocating ccb");
5714 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5716 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5737 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5738 "following device:\n");
5740 error = scsidoinquiry(device, argc, argv, combinedopt,
5741 retry_count, timeout);
5744 warnx("scsiformat: error sending inquiry");
5745 goto scsiformat_bailout;
5750 if (!get_confirmation()) {
5752 goto scsiformat_bailout;
5757 use_timeout = timeout;
5760 fprintf(stdout, "Current format timeout is %d seconds\n",
5761 use_timeout / 1000);
5765 * If the user hasn't disabled questions and didn't specify a
5766 * timeout on the command line, ask them if they want the current
5770 && (timeout == 0)) {
5772 int new_timeout = 0;
5774 fprintf(stdout, "Enter new timeout in seconds or press\n"
5775 "return to keep the current timeout [%d] ",
5776 use_timeout / 1000);
5778 if (fgets(str, sizeof(str), stdin) != NULL) {
5780 new_timeout = atoi(str);
5783 if (new_timeout != 0) {
5784 use_timeout = new_timeout * 1000;
5785 fprintf(stdout, "Using new timeout value %d\n",
5786 use_timeout / 1000);
5791 * Keep this outside the if block below to silence any unused
5792 * variable warnings.
5794 bzero(&fh, sizeof(fh));
5797 * If we're in immediate mode, we've got to include the format
5800 if (immediate != 0) {
5801 fh.byte2 = FU_DLH_IMMED;
5802 data_ptr = (u_int8_t *)&fh;
5803 dxfer_len = sizeof(fh);
5804 byte2 = FU_FMT_DATA;
5805 } else if (quiet == 0) {
5806 fprintf(stdout, "Formatting...");
5810 scsi_format_unit(&ccb->csio,
5811 /* retries */ retry_count,
5813 /* tag_action */ MSG_SIMPLE_Q_TAG,
5816 /* data_ptr */ data_ptr,
5817 /* dxfer_len */ dxfer_len,
5818 /* sense_len */ SSD_FULL_SIZE,
5819 /* timeout */ use_timeout);
5821 /* Disable freezing the device queue */
5822 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5824 if (arglist & CAM_ARG_ERR_RECOVER)
5825 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5827 if (((retval = cam_send_ccb(device, ccb)) < 0)
5828 || ((immediate == 0)
5829 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5830 const char errstr[] = "error sending format command";
5837 if (arglist & CAM_ARG_VERBOSE) {
5838 cam_error_print(device, ccb, CAM_ESF_ALL,
5839 CAM_EPF_ALL, stderr);
5842 goto scsiformat_bailout;
5846 * If we ran in non-immediate mode, we already checked for errors
5847 * above and printed out any necessary information. If we're in
5848 * immediate mode, we need to loop through and get status
5849 * information periodically.
5851 if (immediate == 0) {
5853 fprintf(stdout, "Format Complete\n");
5855 goto scsiformat_bailout;
5862 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5865 * There's really no need to do error recovery or
5866 * retries here, since we're just going to sit in a
5867 * loop and wait for the device to finish formatting.
5869 scsi_test_unit_ready(&ccb->csio,
5872 /* tag_action */ MSG_SIMPLE_Q_TAG,
5873 /* sense_len */ SSD_FULL_SIZE,
5874 /* timeout */ 5000);
5876 /* Disable freezing the device queue */
5877 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5879 retval = cam_send_ccb(device, ccb);
5882 * If we get an error from the ioctl, bail out. SCSI
5883 * errors are expected.
5886 warn("error sending CAMIOCOMMAND ioctl");
5887 if (arglist & CAM_ARG_VERBOSE) {
5888 cam_error_print(device, ccb, CAM_ESF_ALL,
5889 CAM_EPF_ALL, stderr);
5892 goto scsiformat_bailout;
5895 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5897 if ((status != CAM_REQ_CMP)
5898 && (status == CAM_SCSI_STATUS_ERROR)
5899 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5900 struct scsi_sense_data *sense;
5901 int error_code, sense_key, asc, ascq;
5903 sense = &ccb->csio.sense_data;
5904 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5905 ccb->csio.sense_resid, &error_code, &sense_key,
5906 &asc, &ascq, /*show_errors*/ 1);
5909 * According to the SCSI-2 and SCSI-3 specs, a
5910 * drive that is in the middle of a format should
5911 * return NOT READY with an ASC of "logical unit
5912 * not ready, format in progress". The sense key
5913 * specific bytes will then be a progress indicator.
5915 if ((sense_key == SSD_KEY_NOT_READY)
5916 && (asc == 0x04) && (ascq == 0x04)) {
5919 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5920 ccb->csio.sense_resid, sks) == 0)
5923 u_int64_t percentage;
5925 val = scsi_2btoul(&sks[1]);
5926 percentage = 10000 * val;
5929 "\rFormatting: %ju.%02u %% "
5931 (uintmax_t)(percentage /
5933 (unsigned)((percentage /
5937 } else if ((quiet == 0)
5938 && (++num_warnings <= 1)) {
5939 warnx("Unexpected SCSI Sense Key "
5940 "Specific value returned "
5942 scsi_sense_print(device, &ccb->csio,
5944 warnx("Unable to print status "
5945 "information, but format will "
5947 warnx("will exit when format is "
5952 warnx("Unexpected SCSI error during format");
5953 cam_error_print(device, ccb, CAM_ESF_ALL,
5954 CAM_EPF_ALL, stderr);
5956 goto scsiformat_bailout;
5959 } else if (status != CAM_REQ_CMP) {
5960 warnx("Unexpected CAM status %#x", status);
5961 if (arglist & CAM_ARG_VERBOSE)
5962 cam_error_print(device, ccb, CAM_ESF_ALL,
5963 CAM_EPF_ALL, stderr);
5965 goto scsiformat_bailout;
5968 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5971 fprintf(stdout, "\nFormat Complete\n");
5981 scsisanitize(struct cam_device *device, int argc, char **argv,
5982 char *combinedopt, int retry_count, int timeout)
5985 u_int8_t action = 0;
5987 int ycount = 0, quiet = 0;
5988 int error = 0, retval = 0;
5989 int use_timeout = 10800 * 1000;
5995 const char *pattern = NULL;
5996 u_int8_t *data_ptr = NULL;
5997 u_int32_t dxfer_len = 0;
5999 int num_warnings = 0;
6002 ccb = cam_getccb(device);
6005 warnx("scsisanitize: error allocating ccb");
6009 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6011 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6014 if (strcasecmp(optarg, "overwrite") == 0)
6015 action = SSZ_SERVICE_ACTION_OVERWRITE;
6016 else if (strcasecmp(optarg, "block") == 0)
6017 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6018 else if (strcasecmp(optarg, "crypto") == 0)
6019 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6020 else if (strcasecmp(optarg, "exitfailure") == 0)
6021 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6023 warnx("invalid service operation \"%s\"",
6026 goto scsisanitize_bailout;
6030 passes = strtol(optarg, NULL, 0);
6031 if (passes < 1 || passes > 31) {
6032 warnx("invalid passes value %d", passes);
6034 goto scsisanitize_bailout;
6065 warnx("an action is required");
6067 goto scsisanitize_bailout;
6068 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6069 struct scsi_sanitize_parameter_list *pl;
6073 if (pattern == NULL) {
6074 warnx("overwrite action requires -P argument");
6076 goto scsisanitize_bailout;
6078 fd = open(pattern, O_RDONLY);
6080 warn("cannot open pattern file %s", pattern);
6082 goto scsisanitize_bailout;
6084 if (fstat(fd, &sb) < 0) {
6085 warn("cannot stat pattern file %s", pattern);
6087 goto scsisanitize_bailout;
6090 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6091 warnx("pattern file size exceeds maximum value %d",
6092 SSZPL_MAX_PATTERN_LENGTH);
6094 goto scsisanitize_bailout;
6096 dxfer_len = sizeof(*pl) + sz;
6097 data_ptr = calloc(1, dxfer_len);
6098 if (data_ptr == NULL) {
6099 warnx("cannot allocate parameter list buffer");
6101 goto scsisanitize_bailout;
6104 amt = read(fd, data_ptr + sizeof(*pl), sz);
6106 warn("cannot read pattern file");
6108 goto scsisanitize_bailout;
6109 } else if (amt != sz) {
6110 warnx("short pattern file read");
6112 goto scsisanitize_bailout;
6115 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6121 pl->byte1 |= SSZPL_INVERT;
6122 scsi_ulto2b(sz, pl->length);
6128 else if (invert != 0)
6130 else if (pattern != NULL)
6135 warnx("%s argument only valid with overwrite "
6138 goto scsisanitize_bailout;
6143 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6144 "following device:\n");
6146 error = scsidoinquiry(device, argc, argv, combinedopt,
6147 retry_count, timeout);
6150 warnx("scsisanitize: error sending inquiry");
6151 goto scsisanitize_bailout;
6156 if (!get_confirmation()) {
6158 goto scsisanitize_bailout;
6163 use_timeout = timeout;
6166 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6167 use_timeout / 1000);
6171 * If the user hasn't disabled questions and didn't specify a
6172 * timeout on the command line, ask them if they want the current
6176 && (timeout == 0)) {
6178 int new_timeout = 0;
6180 fprintf(stdout, "Enter new timeout in seconds or press\n"
6181 "return to keep the current timeout [%d] ",
6182 use_timeout / 1000);
6184 if (fgets(str, sizeof(str), stdin) != NULL) {
6186 new_timeout = atoi(str);
6189 if (new_timeout != 0) {
6190 use_timeout = new_timeout * 1000;
6191 fprintf(stdout, "Using new timeout value %d\n",
6192 use_timeout / 1000);
6198 byte2 |= SSZ_UNRESTRICTED_EXIT;
6202 scsi_sanitize(&ccb->csio,
6203 /* retries */ retry_count,
6205 /* tag_action */ MSG_SIMPLE_Q_TAG,
6208 /* data_ptr */ data_ptr,
6209 /* dxfer_len */ dxfer_len,
6210 /* sense_len */ SSD_FULL_SIZE,
6211 /* timeout */ use_timeout);
6213 /* Disable freezing the device queue */
6214 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6216 if (arglist & CAM_ARG_ERR_RECOVER)
6217 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6219 if (cam_send_ccb(device, ccb) < 0) {
6220 warn("error sending sanitize command");
6222 goto scsisanitize_bailout;
6225 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6226 struct scsi_sense_data *sense;
6227 int error_code, sense_key, asc, ascq;
6229 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6230 CAM_SCSI_STATUS_ERROR) {
6231 sense = &ccb->csio.sense_data;
6232 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6233 ccb->csio.sense_resid, &error_code, &sense_key,
6234 &asc, &ascq, /*show_errors*/ 1);
6236 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6237 asc == 0x20 && ascq == 0x00)
6238 warnx("sanitize is not supported by "
6241 warnx("error sanitizing this device");
6243 warnx("error sanitizing this device");
6245 if (arglist & CAM_ARG_VERBOSE) {
6246 cam_error_print(device, ccb, CAM_ESF_ALL,
6247 CAM_EPF_ALL, stderr);
6250 goto scsisanitize_bailout;
6254 * If we ran in non-immediate mode, we already checked for errors
6255 * above and printed out any necessary information. If we're in
6256 * immediate mode, we need to loop through and get status
6257 * information periodically.
6259 if (immediate == 0) {
6261 fprintf(stdout, "Sanitize Complete\n");
6263 goto scsisanitize_bailout;
6270 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6273 * There's really no need to do error recovery or
6274 * retries here, since we're just going to sit in a
6275 * loop and wait for the device to finish sanitizing.
6277 scsi_test_unit_ready(&ccb->csio,
6280 /* tag_action */ MSG_SIMPLE_Q_TAG,
6281 /* sense_len */ SSD_FULL_SIZE,
6282 /* timeout */ 5000);
6284 /* Disable freezing the device queue */
6285 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6287 retval = cam_send_ccb(device, ccb);
6290 * If we get an error from the ioctl, bail out. SCSI
6291 * errors are expected.
6294 warn("error sending CAMIOCOMMAND ioctl");
6295 if (arglist & CAM_ARG_VERBOSE) {
6296 cam_error_print(device, ccb, CAM_ESF_ALL,
6297 CAM_EPF_ALL, stderr);
6300 goto scsisanitize_bailout;
6303 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6305 if ((status != CAM_REQ_CMP)
6306 && (status == CAM_SCSI_STATUS_ERROR)
6307 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6308 struct scsi_sense_data *sense;
6309 int error_code, sense_key, asc, ascq;
6311 sense = &ccb->csio.sense_data;
6312 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6313 ccb->csio.sense_resid, &error_code, &sense_key,
6314 &asc, &ascq, /*show_errors*/ 1);
6317 * According to the SCSI-3 spec, a drive that is in the
6318 * middle of a sanitize should return NOT READY with an
6319 * ASC of "logical unit not ready, sanitize in
6320 * progress". The sense key specific bytes will then
6321 * be a progress indicator.
6323 if ((sense_key == SSD_KEY_NOT_READY)
6324 && (asc == 0x04) && (ascq == 0x1b)) {
6327 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6328 ccb->csio.sense_resid, sks) == 0)
6331 u_int64_t percentage;
6333 val = scsi_2btoul(&sks[1]);
6334 percentage = 10000 * val;
6337 "\rSanitizing: %ju.%02u %% "
6339 (uintmax_t)(percentage /
6341 (unsigned)((percentage /
6345 } else if ((quiet == 0)
6346 && (++num_warnings <= 1)) {
6347 warnx("Unexpected SCSI Sense Key "
6348 "Specific value returned "
6349 "during sanitize:");
6350 scsi_sense_print(device, &ccb->csio,
6352 warnx("Unable to print status "
6353 "information, but sanitze will "
6355 warnx("will exit when sanitize is "
6360 warnx("Unexpected SCSI error during sanitize");
6361 cam_error_print(device, ccb, CAM_ESF_ALL,
6362 CAM_EPF_ALL, stderr);
6364 goto scsisanitize_bailout;
6367 } else if (status != CAM_REQ_CMP) {
6368 warnx("Unexpected CAM status %#x", status);
6369 if (arglist & CAM_ARG_VERBOSE)
6370 cam_error_print(device, ccb, CAM_ESF_ALL,
6371 CAM_EPF_ALL, stderr);
6373 goto scsisanitize_bailout;
6375 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6378 fprintf(stdout, "\nSanitize Complete\n");
6380 scsisanitize_bailout:
6383 if (data_ptr != NULL)
6391 scsireportluns(struct cam_device *device, int argc, char **argv,
6392 char *combinedopt, int retry_count, int timeout)
6395 int c, countonly, lunsonly;
6396 struct scsi_report_luns_data *lundata;
6398 uint8_t report_type;
6399 uint32_t list_len, i, j;
6404 report_type = RPL_REPORT_DEFAULT;
6405 ccb = cam_getccb(device);
6408 warnx("%s: error allocating ccb", __func__);
6412 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6417 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6426 if (strcasecmp(optarg, "default") == 0)
6427 report_type = RPL_REPORT_DEFAULT;
6428 else if (strcasecmp(optarg, "wellknown") == 0)
6429 report_type = RPL_REPORT_WELLKNOWN;
6430 else if (strcasecmp(optarg, "all") == 0)
6431 report_type = RPL_REPORT_ALL;
6433 warnx("%s: invalid report type \"%s\"",
6444 if ((countonly != 0)
6445 && (lunsonly != 0)) {
6446 warnx("%s: you can only specify one of -c or -l", __func__);
6451 * According to SPC-4, the allocation length must be at least 16
6452 * bytes -- enough for the header and one LUN.
6454 alloc_len = sizeof(*lundata) + 8;
6458 lundata = malloc(alloc_len);
6460 if (lundata == NULL) {
6461 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6466 scsi_report_luns(&ccb->csio,
6467 /*retries*/ retry_count,
6469 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6470 /*select_report*/ report_type,
6471 /*rpl_buf*/ lundata,
6472 /*alloc_len*/ alloc_len,
6473 /*sense_len*/ SSD_FULL_SIZE,
6474 /*timeout*/ timeout ? timeout : 5000);
6476 /* Disable freezing the device queue */
6477 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6479 if (arglist & CAM_ARG_ERR_RECOVER)
6480 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6482 if (cam_send_ccb(device, ccb) < 0) {
6483 warn("error sending REPORT LUNS command");
6485 if (arglist & CAM_ARG_VERBOSE)
6486 cam_error_print(device, ccb, CAM_ESF_ALL,
6487 CAM_EPF_ALL, stderr);
6493 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6494 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6500 list_len = scsi_4btoul(lundata->length);
6503 * If we need to list the LUNs, and our allocation
6504 * length was too short, reallocate and retry.
6506 if ((countonly == 0)
6507 && (list_len > (alloc_len - sizeof(*lundata)))) {
6508 alloc_len = list_len + sizeof(*lundata);
6514 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6515 ((list_len / 8) > 1) ? "s" : "");
6520 for (i = 0; i < (list_len / 8); i++) {
6524 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6526 fprintf(stdout, ",");
6527 switch (lundata->luns[i].lundata[j] &
6528 RPL_LUNDATA_ATYP_MASK) {
6529 case RPL_LUNDATA_ATYP_PERIPH:
6530 if ((lundata->luns[i].lundata[j] &
6531 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6532 fprintf(stdout, "%d:",
6533 lundata->luns[i].lundata[j] &
6534 RPL_LUNDATA_PERIPH_BUS_MASK);
6536 && ((lundata->luns[i].lundata[j+2] &
6537 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6540 fprintf(stdout, "%d",
6541 lundata->luns[i].lundata[j+1]);
6543 case RPL_LUNDATA_ATYP_FLAT: {
6545 tmplun[0] = lundata->luns[i].lundata[j] &
6546 RPL_LUNDATA_FLAT_LUN_MASK;
6547 tmplun[1] = lundata->luns[i].lundata[j+1];
6549 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6553 case RPL_LUNDATA_ATYP_LUN:
6554 fprintf(stdout, "%d:%d:%d",
6555 (lundata->luns[i].lundata[j+1] &
6556 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6557 lundata->luns[i].lundata[j] &
6558 RPL_LUNDATA_LUN_TARG_MASK,
6559 lundata->luns[i].lundata[j+1] &
6560 RPL_LUNDATA_LUN_LUN_MASK);
6562 case RPL_LUNDATA_ATYP_EXTLUN: {
6563 int field_len_code, eam_code;
6565 eam_code = lundata->luns[i].lundata[j] &
6566 RPL_LUNDATA_EXT_EAM_MASK;
6567 field_len_code = (lundata->luns[i].lundata[j] &
6568 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6570 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6571 && (field_len_code == 0x00)) {
6572 fprintf(stdout, "%d",
6573 lundata->luns[i].lundata[j+1]);
6574 } else if ((eam_code ==
6575 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6576 && (field_len_code == 0x03)) {
6580 * This format takes up all 8 bytes.
6581 * If we aren't starting at offset 0,
6585 fprintf(stdout, "Invalid "
6588 "specified format", j);
6592 bzero(tmp_lun, sizeof(tmp_lun));
6593 bcopy(&lundata->luns[i].lundata[j+1],
6594 &tmp_lun[1], sizeof(tmp_lun) - 1);
6595 fprintf(stdout, "%#jx",
6596 (intmax_t)scsi_8btou64(tmp_lun));
6599 fprintf(stderr, "Unknown Extended LUN"
6600 "Address method %#x, length "
6601 "code %#x", eam_code,
6608 fprintf(stderr, "Unknown LUN address method "
6609 "%#x\n", lundata->luns[i].lundata[0] &
6610 RPL_LUNDATA_ATYP_MASK);
6614 * For the flat addressing method, there are no
6615 * other levels after it.
6620 fprintf(stdout, "\n");
6633 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6634 char *combinedopt, int retry_count, int timeout)
6637 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6638 struct scsi_read_capacity_data rcap;
6639 struct scsi_read_capacity_data_long rcaplong;
6653 ccb = cam_getccb(device);
6656 warnx("%s: error allocating ccb", __func__);
6660 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6662 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6689 if ((blocksizeonly != 0)
6690 && (numblocks != 0)) {
6691 warnx("%s: you can only specify one of -b or -N", __func__);
6696 if ((blocksizeonly != 0)
6697 && (sizeonly != 0)) {
6698 warnx("%s: you can only specify one of -b or -s", __func__);
6705 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6711 && (blocksizeonly != 0)) {
6712 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6717 scsi_read_capacity(&ccb->csio,
6718 /*retries*/ retry_count,
6720 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6723 /*timeout*/ timeout ? timeout : 5000);
6725 /* Disable freezing the device queue */
6726 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6728 if (arglist & CAM_ARG_ERR_RECOVER)
6729 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6731 if (cam_send_ccb(device, ccb) < 0) {
6732 warn("error sending READ CAPACITY command");
6734 if (arglist & CAM_ARG_VERBOSE)
6735 cam_error_print(device, ccb, CAM_ESF_ALL,
6736 CAM_EPF_ALL, stderr);
6742 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6743 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6748 maxsector = scsi_4btoul(rcap.addr);
6749 block_len = scsi_4btoul(rcap.length);
6752 * A last block of 2^32-1 means that the true capacity is over 2TB,
6753 * and we need to issue the long READ CAPACITY to get the real
6754 * capacity. Otherwise, we're all set.
6756 if (maxsector != 0xffffffff)
6759 scsi_read_capacity_16(&ccb->csio,
6760 /*retries*/ retry_count,
6762 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6766 /*rcap_buf*/ (uint8_t *)&rcaplong,
6767 /*rcap_buf_len*/ sizeof(rcaplong),
6768 /*sense_len*/ SSD_FULL_SIZE,
6769 /*timeout*/ timeout ? timeout : 5000);
6771 /* Disable freezing the device queue */
6772 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6774 if (arglist & CAM_ARG_ERR_RECOVER)
6775 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6777 if (cam_send_ccb(device, ccb) < 0) {
6778 warn("error sending READ CAPACITY (16) command");
6780 if (arglist & CAM_ARG_VERBOSE)
6781 cam_error_print(device, ccb, CAM_ESF_ALL,
6782 CAM_EPF_ALL, stderr);
6788 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6789 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6794 maxsector = scsi_8btou64(rcaplong.addr);
6795 block_len = scsi_4btoul(rcaplong.length);
6798 if (blocksizeonly == 0) {
6800 * Humanize implies !quiet, and also implies numblocks.
6802 if (humanize != 0) {
6807 tmpbytes = (maxsector + 1) * block_len;
6808 ret = humanize_number(tmpstr, sizeof(tmpstr),
6809 tmpbytes, "", HN_AUTOSCALE,
6812 HN_DIVISOR_1000 : 0));
6814 warnx("%s: humanize_number failed!", __func__);
6818 fprintf(stdout, "Device Size: %s%s", tmpstr,
6819 (sizeonly == 0) ? ", " : "\n");
6820 } else if (numblocks != 0) {
6821 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6822 "Blocks: " : "", (uintmax_t)maxsector + 1,
6823 (sizeonly == 0) ? ", " : "\n");
6825 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6826 "Last Block: " : "", (uintmax_t)maxsector,
6827 (sizeonly == 0) ? ", " : "\n");
6831 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6832 "Block Length: " : "", block_len, (quiet == 0) ?
6841 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6842 int retry_count, int timeout)
6846 uint8_t *smp_request = NULL, *smp_response = NULL;
6847 int request_size = 0, response_size = 0;
6848 int fd_request = 0, fd_response = 0;
6849 char *datastr = NULL;
6850 struct get_hook hook;
6855 * Note that at the moment we don't support sending SMP CCBs to
6856 * devices that aren't probed by CAM.
6858 ccb = cam_getccb(device);
6860 warnx("%s: error allocating CCB", __func__);
6864 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
6866 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6869 arglist |= CAM_ARG_CMD_IN;
6870 response_size = strtol(optarg, NULL, 0);
6871 if (response_size <= 0) {
6872 warnx("invalid number of response bytes %d",
6875 goto smpcmd_bailout;
6877 hook.argc = argc - optind;
6878 hook.argv = argv + optind;
6881 datastr = cget(&hook, NULL);
6883 * If the user supplied "-" instead of a format, he
6884 * wants the data to be written to stdout.
6886 if ((datastr != NULL)
6887 && (datastr[0] == '-'))
6890 smp_response = (u_int8_t *)malloc(response_size);
6891 if (smp_response == NULL) {
6892 warn("can't malloc memory for SMP response");
6894 goto smpcmd_bailout;
6898 arglist |= CAM_ARG_CMD_OUT;
6899 request_size = strtol(optarg, NULL, 0);
6900 if (request_size <= 0) {
6901 warnx("invalid number of request bytes %d",
6904 goto smpcmd_bailout;
6906 hook.argc = argc - optind;
6907 hook.argv = argv + optind;
6909 datastr = cget(&hook, NULL);
6910 smp_request = (u_int8_t *)malloc(request_size);
6911 if (smp_request == NULL) {
6912 warn("can't malloc memory for SMP request");
6914 goto smpcmd_bailout;
6916 bzero(smp_request, request_size);
6918 * If the user supplied "-" instead of a format, he
6919 * wants the data to be read from stdin.
6921 if ((datastr != NULL)
6922 && (datastr[0] == '-'))
6925 buff_encode_visit(smp_request, request_size,
6936 * If fd_data is set, and we're writing to the device, we need to
6937 * read the data the user wants written from stdin.
6939 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6941 int amt_to_read = request_size;
6942 u_int8_t *buf_ptr = smp_request;
6944 for (amt_read = 0; amt_to_read > 0;
6945 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6946 if (amt_read == -1) {
6947 warn("error reading data from stdin");
6949 goto smpcmd_bailout;
6951 amt_to_read -= amt_read;
6952 buf_ptr += amt_read;
6956 if (((arglist & CAM_ARG_CMD_IN) == 0)
6957 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6958 warnx("%s: need both the request (-r) and response (-R) "
6959 "arguments", __func__);
6961 goto smpcmd_bailout;
6964 flags |= CAM_DEV_QFRZDIS;
6966 cam_fill_smpio(&ccb->smpio,
6967 /*retries*/ retry_count,
6970 /*smp_request*/ smp_request,
6971 /*smp_request_len*/ request_size,
6972 /*smp_response*/ smp_response,
6973 /*smp_response_len*/ response_size,
6974 /*timeout*/ timeout ? timeout : 5000);
6976 ccb->smpio.flags = SMP_FLAG_NONE;
6978 if (((retval = cam_send_ccb(device, ccb)) < 0)
6979 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6980 const char warnstr[] = "error sending command";
6987 if (arglist & CAM_ARG_VERBOSE) {
6988 cam_error_print(device, ccb, CAM_ESF_ALL,
6989 CAM_EPF_ALL, stderr);
6993 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6994 && (response_size > 0)) {
6995 if (fd_response == 0) {
6996 buff_decode_visit(smp_response, response_size,
6997 datastr, arg_put, NULL);
6998 fprintf(stdout, "\n");
7000 ssize_t amt_written;
7001 int amt_to_write = response_size;
7002 u_int8_t *buf_ptr = smp_response;
7004 for (amt_written = 0; (amt_to_write > 0) &&
7005 (amt_written = write(STDOUT_FILENO, buf_ptr,
7006 amt_to_write)) > 0;){
7007 amt_to_write -= amt_written;
7008 buf_ptr += amt_written;
7010 if (amt_written == -1) {
7011 warn("error writing data to stdout");
7013 goto smpcmd_bailout;
7014 } else if ((amt_written == 0)
7015 && (amt_to_write > 0)) {
7016 warnx("only wrote %u bytes out of %u",
7017 response_size - amt_to_write,
7026 if (smp_request != NULL)
7029 if (smp_response != NULL)
7036 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7037 char *combinedopt, int retry_count, int timeout)
7040 struct smp_report_general_request *request = NULL;
7041 struct smp_report_general_response *response = NULL;
7042 struct sbuf *sb = NULL;
7044 int c, long_response = 0;
7048 * Note that at the moment we don't support sending SMP CCBs to
7049 * devices that aren't probed by CAM.
7051 ccb = cam_getccb(device);
7053 warnx("%s: error allocating CCB", __func__);
7057 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7059 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7068 request = malloc(sizeof(*request));
7069 if (request == NULL) {
7070 warn("%s: unable to allocate %zd bytes", __func__,
7076 response = malloc(sizeof(*response));
7077 if (response == NULL) {
7078 warn("%s: unable to allocate %zd bytes", __func__,
7085 smp_report_general(&ccb->smpio,
7089 /*request_len*/ sizeof(*request),
7090 (uint8_t *)response,
7091 /*response_len*/ sizeof(*response),
7092 /*long_response*/ long_response,
7095 if (((retval = cam_send_ccb(device, ccb)) < 0)
7096 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7097 const char warnstr[] = "error sending command";
7104 if (arglist & CAM_ARG_VERBOSE) {
7105 cam_error_print(device, ccb, CAM_ESF_ALL,
7106 CAM_EPF_ALL, stderr);
7113 * If the device supports the long response bit, try again and see
7114 * if we can get all of the data.
7116 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7117 && (long_response == 0)) {
7118 ccb->ccb_h.status = CAM_REQ_INPROG;
7119 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7125 * XXX KDM detect and decode SMP errors here.
7127 sb = sbuf_new_auto();
7129 warnx("%s: error allocating sbuf", __func__);
7133 smp_report_general_sbuf(response, sizeof(*response), sb);
7135 if (sbuf_finish(sb) != 0) {
7136 warnx("%s: sbuf_finish", __func__);
7140 printf("%s", sbuf_data(sb));
7146 if (request != NULL)
7149 if (response != NULL)
7158 static struct camcontrol_opts phy_ops[] = {
7159 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7160 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7161 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7162 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7163 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7164 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7165 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7166 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7167 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7172 smpphycontrol(struct cam_device *device, int argc, char **argv,
7173 char *combinedopt, int retry_count, int timeout)
7176 struct smp_phy_control_request *request = NULL;
7177 struct smp_phy_control_response *response = NULL;
7178 int long_response = 0;
7181 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7183 uint64_t attached_dev_name = 0;
7184 int dev_name_set = 0;
7185 uint32_t min_plr = 0, max_plr = 0;
7186 uint32_t pp_timeout_val = 0;
7187 int slumber_partial = 0;
7188 int set_pp_timeout_val = 0;
7192 * Note that at the moment we don't support sending SMP CCBs to
7193 * devices that aren't probed by CAM.
7195 ccb = cam_getccb(device);
7197 warnx("%s: error allocating CCB", __func__);
7201 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7203 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7211 if (strcasecmp(optarg, "enable") == 0)
7213 else if (strcasecmp(optarg, "disable") == 0)
7216 warnx("%s: Invalid argument %s", __func__,
7223 slumber_partial |= enable <<
7224 SMP_PC_SAS_SLUMBER_SHIFT;
7227 slumber_partial |= enable <<
7228 SMP_PC_SAS_PARTIAL_SHIFT;
7231 slumber_partial |= enable <<
7232 SMP_PC_SATA_SLUMBER_SHIFT;
7235 slumber_partial |= enable <<
7236 SMP_PC_SATA_PARTIAL_SHIFT;
7239 warnx("%s: programmer error", __func__);
7242 break; /*NOTREACHED*/
7247 attached_dev_name = (uintmax_t)strtoumax(optarg,
7256 * We don't do extensive checking here, so this
7257 * will continue to work when new speeds come out.
7259 min_plr = strtoul(optarg, NULL, 0);
7261 || (min_plr > 0xf)) {
7262 warnx("%s: invalid link rate %x",
7270 * We don't do extensive checking here, so this
7271 * will continue to work when new speeds come out.
7273 max_plr = strtoul(optarg, NULL, 0);
7275 || (max_plr > 0xf)) {
7276 warnx("%s: invalid link rate %x",
7283 camcontrol_optret optreturn;
7284 cam_argmask argnums;
7287 if (phy_op_set != 0) {
7288 warnx("%s: only one phy operation argument "
7289 "(-o) allowed", __func__);
7297 * Allow the user to specify the phy operation
7298 * numerically, as well as with a name. This will
7299 * future-proof it a bit, so options that are added
7300 * in future specs can be used.
7302 if (isdigit(optarg[0])) {
7303 phy_operation = strtoul(optarg, NULL, 0);
7304 if ((phy_operation == 0)
7305 || (phy_operation > 0xff)) {
7306 warnx("%s: invalid phy operation %#x",
7307 __func__, phy_operation);
7313 optreturn = getoption(phy_ops, optarg, &phy_operation,
7316 if (optreturn == CC_OR_AMBIGUOUS) {
7317 warnx("%s: ambiguous option %s", __func__,
7322 } else if (optreturn == CC_OR_NOT_FOUND) {
7323 warnx("%s: option %s not found", __func__,
7335 pp_timeout_val = strtoul(optarg, NULL, 0);
7336 if (pp_timeout_val > 15) {
7337 warnx("%s: invalid partial pathway timeout "
7338 "value %u, need a value less than 16",
7339 __func__, pp_timeout_val);
7343 set_pp_timeout_val = 1;
7351 warnx("%s: a PHY (-p phy) argument is required",__func__);
7356 if (((dev_name_set != 0)
7357 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7358 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7359 && (dev_name_set == 0))) {
7360 warnx("%s: -d name and -o setdevname arguments both "
7361 "required to set device name", __func__);
7366 request = malloc(sizeof(*request));
7367 if (request == NULL) {
7368 warn("%s: unable to allocate %zd bytes", __func__,
7374 response = malloc(sizeof(*response));
7375 if (response == NULL) {
7376 warn("%s: unable to allocate %zd bytes", __func__,
7382 smp_phy_control(&ccb->smpio,
7387 (uint8_t *)response,
7390 /*expected_exp_change_count*/ 0,
7393 (set_pp_timeout_val != 0) ? 1 : 0,
7401 if (((retval = cam_send_ccb(device, ccb)) < 0)
7402 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7403 const char warnstr[] = "error sending command";
7410 if (arglist & CAM_ARG_VERBOSE) {
7412 * Use CAM_EPF_NORMAL so we only get one line of
7413 * SMP command decoding.
7415 cam_error_print(device, ccb, CAM_ESF_ALL,
7416 CAM_EPF_NORMAL, stderr);
7422 /* XXX KDM print out something here for success? */
7427 if (request != NULL)
7430 if (response != NULL)
7437 smpmaninfo(struct cam_device *device, int argc, char **argv,
7438 char *combinedopt, int retry_count, int timeout)
7441 struct smp_report_manuf_info_request request;
7442 struct smp_report_manuf_info_response response;
7443 struct sbuf *sb = NULL;
7444 int long_response = 0;
7449 * Note that at the moment we don't support sending SMP CCBs to
7450 * devices that aren't probed by CAM.
7452 ccb = cam_getccb(device);
7454 warnx("%s: error allocating CCB", __func__);
7458 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7460 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7469 bzero(&request, sizeof(request));
7470 bzero(&response, sizeof(response));
7472 smp_report_manuf_info(&ccb->smpio,
7477 (uint8_t *)&response,
7482 if (((retval = cam_send_ccb(device, ccb)) < 0)
7483 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7484 const char warnstr[] = "error sending command";
7491 if (arglist & CAM_ARG_VERBOSE) {
7492 cam_error_print(device, ccb, CAM_ESF_ALL,
7493 CAM_EPF_ALL, stderr);
7499 sb = sbuf_new_auto();
7501 warnx("%s: error allocating sbuf", __func__);
7505 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7507 if (sbuf_finish(sb) != 0) {
7508 warnx("%s: sbuf_finish", __func__);
7512 printf("%s", sbuf_data(sb));
7526 getdevid(struct cam_devitem *item)
7529 union ccb *ccb = NULL;
7531 struct cam_device *dev;
7533 dev = cam_open_btl(item->dev_match.path_id,
7534 item->dev_match.target_id,
7535 item->dev_match.target_lun, O_RDWR, NULL);
7538 warnx("%s", cam_errbuf);
7543 item->device_id_len = 0;
7545 ccb = cam_getccb(dev);
7547 warnx("%s: error allocating CCB", __func__);
7552 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7555 * On the first try, we just probe for the size of the data, and
7556 * then allocate that much memory and try again.
7559 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7560 ccb->ccb_h.flags = CAM_DIR_IN;
7561 ccb->cdai.flags = CDAI_FLAG_NONE;
7562 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7563 ccb->cdai.bufsiz = item->device_id_len;
7564 if (item->device_id_len != 0)
7565 ccb->cdai.buf = (uint8_t *)item->device_id;
7567 if (cam_send_ccb(dev, ccb) < 0) {
7568 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7573 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7574 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7579 if (item->device_id_len == 0) {
7581 * This is our first time through. Allocate the buffer,
7582 * and then go back to get the data.
7584 if (ccb->cdai.provsiz == 0) {
7585 warnx("%s: invalid .provsiz field returned with "
7586 "XPT_GDEV_ADVINFO CCB", __func__);
7590 item->device_id_len = ccb->cdai.provsiz;
7591 item->device_id = malloc(item->device_id_len);
7592 if (item->device_id == NULL) {
7593 warn("%s: unable to allocate %d bytes", __func__,
7594 item->device_id_len);
7598 ccb->ccb_h.status = CAM_REQ_INPROG;
7604 cam_close_device(dev);
7613 * XXX KDM merge this code with getdevtree()?
7616 buildbusdevlist(struct cam_devlist *devlist)
7619 int bufsize, fd = -1;
7620 struct dev_match_pattern *patterns;
7621 struct cam_devitem *item = NULL;
7622 int skip_device = 0;
7625 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7626 warn("couldn't open %s", XPT_DEVICE);
7630 bzero(&ccb, sizeof(union ccb));
7632 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7633 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7634 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7636 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7637 bufsize = sizeof(struct dev_match_result) * 100;
7638 ccb.cdm.match_buf_len = bufsize;
7639 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7640 if (ccb.cdm.matches == NULL) {
7641 warnx("can't malloc memory for matches");
7645 ccb.cdm.num_matches = 0;
7646 ccb.cdm.num_patterns = 2;
7647 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7648 ccb.cdm.num_patterns;
7650 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7651 if (patterns == NULL) {
7652 warnx("can't malloc memory for patterns");
7657 ccb.cdm.patterns = patterns;
7658 bzero(patterns, ccb.cdm.pattern_buf_len);
7660 patterns[0].type = DEV_MATCH_DEVICE;
7661 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7662 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7663 patterns[1].type = DEV_MATCH_PERIPH;
7664 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7665 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7668 * We do the ioctl multiple times if necessary, in case there are
7669 * more than 100 nodes in the EDT.
7674 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7675 warn("error sending CAMIOCOMMAND ioctl");
7680 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7681 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7682 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7683 warnx("got CAM error %#x, CDM error %d\n",
7684 ccb.ccb_h.status, ccb.cdm.status);
7689 for (i = 0; i < ccb.cdm.num_matches; i++) {
7690 switch (ccb.cdm.matches[i].type) {
7691 case DEV_MATCH_DEVICE: {
7692 struct device_match_result *dev_result;
7695 &ccb.cdm.matches[i].result.device_result;
7697 if (dev_result->flags &
7698 DEV_RESULT_UNCONFIGURED) {
7704 item = malloc(sizeof(*item));
7706 warn("%s: unable to allocate %zd bytes",
7707 __func__, sizeof(*item));
7711 bzero(item, sizeof(*item));
7712 bcopy(dev_result, &item->dev_match,
7713 sizeof(*dev_result));
7714 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7717 if (getdevid(item) != 0) {
7723 case DEV_MATCH_PERIPH: {
7724 struct periph_match_result *periph_result;
7727 &ccb.cdm.matches[i].result.periph_result;
7729 if (skip_device != 0)
7731 item->num_periphs++;
7732 item->periph_matches = realloc(
7733 item->periph_matches,
7735 sizeof(struct periph_match_result));
7736 if (item->periph_matches == NULL) {
7737 warn("%s: error allocating periph "
7742 bcopy(periph_result, &item->periph_matches[
7743 item->num_periphs - 1],
7744 sizeof(*periph_result));
7748 fprintf(stderr, "%s: unexpected match "
7749 "type %d\n", __func__,
7750 ccb.cdm.matches[i].type);
7753 break; /*NOTREACHED*/
7756 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7757 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7765 free(ccb.cdm.matches);
7768 freebusdevlist(devlist);
7774 freebusdevlist(struct cam_devlist *devlist)
7776 struct cam_devitem *item, *item2;
7778 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7779 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7781 free(item->device_id);
7782 free(item->periph_matches);
7787 static struct cam_devitem *
7788 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7790 struct cam_devitem *item;
7792 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7793 struct scsi_vpd_id_descriptor *idd;
7796 * XXX KDM look for LUN IDs as well?
7798 idd = scsi_get_devid(item->device_id,
7799 item->device_id_len,
7800 scsi_devid_is_sas_target);
7804 if (scsi_8btou64(idd->identifier) == sasaddr)
7812 smpphylist(struct cam_device *device, int argc, char **argv,
7813 char *combinedopt, int retry_count, int timeout)
7815 struct smp_report_general_request *rgrequest = NULL;
7816 struct smp_report_general_response *rgresponse = NULL;
7817 struct smp_discover_request *disrequest = NULL;
7818 struct smp_discover_response *disresponse = NULL;
7819 struct cam_devlist devlist;
7821 int long_response = 0;
7828 * Note that at the moment we don't support sending SMP CCBs to
7829 * devices that aren't probed by CAM.
7831 ccb = cam_getccb(device);
7833 warnx("%s: error allocating CCB", __func__);
7837 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7838 STAILQ_INIT(&devlist.dev_queue);
7840 rgrequest = malloc(sizeof(*rgrequest));
7841 if (rgrequest == NULL) {
7842 warn("%s: unable to allocate %zd bytes", __func__,
7843 sizeof(*rgrequest));
7848 rgresponse = malloc(sizeof(*rgresponse));
7849 if (rgresponse == NULL) {
7850 warn("%s: unable to allocate %zd bytes", __func__,
7851 sizeof(*rgresponse));
7856 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7869 smp_report_general(&ccb->smpio,
7873 /*request_len*/ sizeof(*rgrequest),
7874 (uint8_t *)rgresponse,
7875 /*response_len*/ sizeof(*rgresponse),
7876 /*long_response*/ long_response,
7879 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7881 if (((retval = cam_send_ccb(device, ccb)) < 0)
7882 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7883 const char warnstr[] = "error sending command";
7890 if (arglist & CAM_ARG_VERBOSE) {
7891 cam_error_print(device, ccb, CAM_ESF_ALL,
7892 CAM_EPF_ALL, stderr);
7898 num_phys = rgresponse->num_phys;
7900 if (num_phys == 0) {
7902 fprintf(stdout, "%s: No Phys reported\n", __func__);
7907 devlist.path_id = device->path_id;
7909 retval = buildbusdevlist(&devlist);
7914 fprintf(stdout, "%d PHYs:\n", num_phys);
7915 fprintf(stdout, "PHY Attached SAS Address\n");
7918 disrequest = malloc(sizeof(*disrequest));
7919 if (disrequest == NULL) {
7920 warn("%s: unable to allocate %zd bytes", __func__,
7921 sizeof(*disrequest));
7926 disresponse = malloc(sizeof(*disresponse));
7927 if (disresponse == NULL) {
7928 warn("%s: unable to allocate %zd bytes", __func__,
7929 sizeof(*disresponse));
7934 for (i = 0; i < num_phys; i++) {
7935 struct cam_devitem *item;
7936 struct device_match_result *dev_match;
7937 char vendor[16], product[48], revision[16];
7941 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7943 ccb->ccb_h.status = CAM_REQ_INPROG;
7944 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7946 smp_discover(&ccb->smpio,
7950 sizeof(*disrequest),
7951 (uint8_t *)disresponse,
7952 sizeof(*disresponse),
7954 /*ignore_zone_group*/ 0,
7958 if (((retval = cam_send_ccb(device, ccb)) < 0)
7959 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7960 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7961 const char warnstr[] = "error sending command";
7968 if (arglist & CAM_ARG_VERBOSE) {
7969 cam_error_print(device, ccb, CAM_ESF_ALL,
7970 CAM_EPF_ALL, stderr);
7976 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7978 fprintf(stdout, "%3d <vacant>\n", i);
7982 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7985 item = findsasdevice(&devlist,
7986 scsi_8btou64(disresponse->attached_sas_address));
7990 || (item != NULL)) {
7991 fprintf(stdout, "%3d 0x%016jx", i,
7992 (uintmax_t)scsi_8btou64(
7993 disresponse->attached_sas_address));
7995 fprintf(stdout, "\n");
7998 } else if (quiet != 0)
8001 dev_match = &item->dev_match;
8003 if (dev_match->protocol == PROTO_SCSI) {
8004 cam_strvis(vendor, dev_match->inq_data.vendor,
8005 sizeof(dev_match->inq_data.vendor),
8007 cam_strvis(product, dev_match->inq_data.product,
8008 sizeof(dev_match->inq_data.product),
8010 cam_strvis(revision, dev_match->inq_data.revision,
8011 sizeof(dev_match->inq_data.revision),
8013 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8015 } else if ((dev_match->protocol == PROTO_ATA)
8016 || (dev_match->protocol == PROTO_SATAPM)) {
8017 cam_strvis(product, dev_match->ident_data.model,
8018 sizeof(dev_match->ident_data.model),
8020 cam_strvis(revision, dev_match->ident_data.revision,
8021 sizeof(dev_match->ident_data.revision),
8023 sprintf(tmpstr, "<%s %s>", product, revision);
8025 sprintf(tmpstr, "<>");
8027 fprintf(stdout, " %-33s ", tmpstr);
8030 * If we have 0 periphs, that's a bug...
8032 if (item->num_periphs == 0) {
8033 fprintf(stdout, "\n");
8037 fprintf(stdout, "(");
8038 for (j = 0; j < item->num_periphs; j++) {
8040 fprintf(stdout, ",");
8042 fprintf(stdout, "%s%d",
8043 item->periph_matches[j].periph_name,
8044 item->periph_matches[j].unit_number);
8047 fprintf(stdout, ")\n");
8061 freebusdevlist(&devlist);
8067 atapm(struct cam_device *device, int argc, char **argv,
8068 char *combinedopt, int retry_count, int timeout)
8076 ccb = cam_getccb(device);
8079 warnx("%s: error allocating ccb", __func__);
8083 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8092 if (strcmp(argv[1], "idle") == 0) {
8094 cmd = ATA_IDLE_IMMEDIATE;
8097 } else if (strcmp(argv[1], "standby") == 0) {
8099 cmd = ATA_STANDBY_IMMEDIATE;
8101 cmd = ATA_STANDBY_CMD;
8109 else if (t <= (240 * 5))
8111 else if (t <= (252 * 5))
8112 /* special encoding for 21 minutes */
8114 else if (t <= (11 * 30 * 60))
8115 sc = (t - 1) / (30 * 60) + 241;
8119 retval = ata_do_28bit_cmd(device,
8121 /*retries*/retry_count,
8122 /*flags*/CAM_DIR_NONE,
8123 /*protocol*/AP_PROTO_NON_DATA,
8124 /*tag_action*/MSG_SIMPLE_Q_TAG,
8131 /*timeout*/timeout ? timeout : 30 * 1000,
8139 ataaxm(struct cam_device *device, int argc, char **argv,
8140 char *combinedopt, int retry_count, int timeout)
8148 ccb = cam_getccb(device);
8151 warnx("%s: error allocating ccb", __func__);
8155 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8165 if (strcmp(argv[1], "apm") == 0) {
8181 retval = ata_do_28bit_cmd(device,
8183 /*retries*/retry_count,
8184 /*flags*/CAM_DIR_NONE,
8185 /*protocol*/AP_PROTO_NON_DATA,
8186 /*tag_action*/MSG_SIMPLE_Q_TAG,
8187 /*command*/ATA_SETFEATURES,
8193 /*timeout*/timeout ? timeout : 30 * 1000,
8201 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8202 int show_sa_errors, int sa_set, int service_action,
8203 int timeout_desc, int retry_count, int timeout, int verbosemode,
8204 uint32_t *fill_len, uint8_t **data_ptr)
8206 union ccb *ccb = NULL;
8207 uint8_t *buf = NULL;
8208 uint32_t alloc_len = 0, num_opcodes;
8209 uint32_t valid_len = 0;
8210 uint32_t avail_len = 0;
8211 struct scsi_report_supported_opcodes_all *all_hdr;
8212 struct scsi_report_supported_opcodes_one *one;
8217 * Make it clear that we haven't yet allocated or filled anything.
8222 ccb = cam_getccb(device);
8224 warnx("couldn't allocate CCB");
8229 /* cam_getccb cleans up the header, caller has to zero the payload */
8230 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8232 if (opcode_set != 0) {
8233 options |= RSO_OPTIONS_OC;
8235 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8238 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8239 sizeof(struct scsi_report_supported_opcodes_descr));
8242 if (timeout_desc != 0) {
8243 options |= RSO_RCTD;
8244 alloc_len += num_opcodes *
8245 sizeof(struct scsi_report_supported_opcodes_timeout);
8249 options |= RSO_OPTIONS_OC_SA;
8250 if (show_sa_errors != 0)
8251 options &= ~RSO_OPTIONS_OC;
8260 buf = malloc(alloc_len);
8262 warn("Unable to allocate %u bytes", alloc_len);
8266 bzero(buf, alloc_len);
8268 scsi_report_supported_opcodes(&ccb->csio,
8269 /*retries*/ retry_count,
8271 /*tag_action*/ MSG_SIMPLE_Q_TAG,
8272 /*options*/ options,
8273 /*req_opcode*/ opcode,
8274 /*req_service_action*/ service_action,
8276 /*dxfer_len*/ alloc_len,
8277 /*sense_len*/ SSD_FULL_SIZE,
8278 /*timeout*/ timeout ? timeout : 10000);
8280 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8282 if (retry_count != 0)
8283 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8285 if (cam_send_ccb(device, ccb) < 0) {
8286 perror("error sending REPORT SUPPORTED OPERATION CODES");
8291 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8292 if (verbosemode != 0)
8293 cam_error_print(device, ccb, CAM_ESF_ALL,
8294 CAM_EPF_ALL, stderr);
8300 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8302 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8303 && (valid_len >= sizeof(*all_hdr))) {
8304 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8305 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8306 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8307 && (valid_len >= sizeof(*one))) {
8308 uint32_t cdb_length;
8310 one = (struct scsi_report_supported_opcodes_one *)buf;
8311 cdb_length = scsi_2btoul(one->cdb_length);
8312 avail_len = sizeof(*one) + cdb_length;
8313 if (one->support & RSO_ONE_CTDP) {
8314 struct scsi_report_supported_opcodes_timeout *td;
8316 td = (struct scsi_report_supported_opcodes_timeout *)
8318 if (valid_len >= (avail_len + sizeof(td->length))) {
8319 avail_len += scsi_2btoul(td->length) +
8322 avail_len += sizeof(*td);
8328 * avail_len could be zero if we didn't get enough data back from
8329 * thet target to determine
8331 if ((avail_len != 0)
8332 && (avail_len > valid_len)) {
8333 alloc_len = avail_len;
8337 *fill_len = valid_len;
8349 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8350 int req_sa, uint8_t *buf, uint32_t valid_len)
8352 struct scsi_report_supported_opcodes_one *one;
8353 struct scsi_report_supported_opcodes_timeout *td;
8354 uint32_t cdb_len = 0, td_len = 0;
8355 const char *op_desc = NULL;
8359 one = (struct scsi_report_supported_opcodes_one *)buf;
8362 * If we don't have the full single opcode descriptor, no point in
8365 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8367 warnx("Only %u bytes returned, not enough to verify support",
8373 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8375 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8378 printf(", SA 0x%x", req_sa);
8381 switch (one->support & RSO_ONE_SUP_MASK) {
8382 case RSO_ONE_SUP_UNAVAIL:
8383 printf("No command support information currently available\n");
8385 case RSO_ONE_SUP_NOT_SUP:
8386 printf("Command not supported\n");
8389 break; /*NOTREACHED*/
8390 case RSO_ONE_SUP_AVAIL:
8391 printf("Command is supported, complies with a SCSI standard\n");
8393 case RSO_ONE_SUP_VENDOR:
8394 printf("Command is supported, vendor-specific "
8395 "implementation\n");
8398 printf("Unknown command support flags 0x%#x\n",
8399 one->support & RSO_ONE_SUP_MASK);
8404 * If we don't have the CDB length, it isn't exactly an error, the
8405 * command probably isn't supported.
8407 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8411 cdb_len = scsi_2btoul(one->cdb_length);
8414 * If our valid data doesn't include the full reported length,
8415 * return. The caller should have detected this and adjusted his
8416 * allocation length to get all of the available data.
8418 if (valid_len < sizeof(*one) + cdb_len) {
8424 * If all we have is the opcode, there is no point in printing out
8432 printf("CDB usage bitmap:");
8433 for (i = 0; i < cdb_len; i++) {
8434 printf(" %02x", one->cdb_usage[i]);
8439 * If we don't have a timeout descriptor, we're done.
8441 if ((one->support & RSO_ONE_CTDP) == 0)
8445 * If we don't have enough valid length to include the timeout
8446 * descriptor length, we're done.
8448 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8451 td = (struct scsi_report_supported_opcodes_timeout *)
8452 &buf[sizeof(*one) + cdb_len];
8453 td_len = scsi_2btoul(td->length);
8454 td_len += sizeof(td->length);
8457 * If we don't have the full timeout descriptor, we're done.
8459 if (td_len < sizeof(*td))
8463 * If we don't have enough valid length to contain the full timeout
8464 * descriptor, we're done.
8466 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8469 printf("Timeout information:\n");
8470 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8471 printf("Nominal timeout: %u seconds\n",
8472 scsi_4btoul(td->nominal_time));
8473 printf("Recommended timeout: %u seconds\n",
8474 scsi_4btoul(td->recommended_time));
8481 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8484 struct scsi_report_supported_opcodes_all *hdr;
8485 struct scsi_report_supported_opcodes_descr *desc;
8486 uint32_t avail_len = 0, used_len = 0;
8490 if (valid_len < sizeof(*hdr)) {
8491 warnx("%s: not enough returned data (%u bytes) opcode list",
8492 __func__, valid_len);
8496 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8497 avail_len = scsi_4btoul(hdr->length);
8498 avail_len += sizeof(hdr->length);
8500 * Take the lesser of the amount of data the drive claims is
8501 * available, and the amount of data the HBA says was returned.
8503 avail_len = MIN(avail_len, valid_len);
8505 used_len = sizeof(hdr->length);
8507 printf("%-6s %4s %8s ",
8508 "Opcode", "SA", "CDB len" );
8511 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8512 printf(" Description\n");
8514 while ((avail_len - used_len) > sizeof(*desc)) {
8515 struct scsi_report_supported_opcodes_timeout *td;
8517 const char *op_desc = NULL;
8519 cur_ptr = &buf[used_len];
8520 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8522 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8523 if (op_desc == NULL)
8524 op_desc = "UNKNOWN";
8526 printf("0x%02x %#4x %8u ", desc->opcode,
8527 scsi_2btoul(desc->service_action),
8528 scsi_2btoul(desc->cdb_length));
8530 used_len += sizeof(*desc);
8532 if ((desc->flags & RSO_CTDP) == 0) {
8533 printf(" %s\n", op_desc);
8538 * If we don't have enough space to fit a timeout
8539 * descriptor, then we're done.
8541 if (avail_len - used_len < sizeof(*td)) {
8542 used_len = avail_len;
8543 printf(" %s\n", op_desc);
8546 cur_ptr = &buf[used_len];
8547 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8548 td_len = scsi_2btoul(td->length);
8549 td_len += sizeof(td->length);
8553 * If the given timeout descriptor length is less than what
8554 * we understand, skip it.
8556 if (td_len < sizeof(*td)) {
8557 printf(" %s\n", op_desc);
8561 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8562 scsi_4btoul(td->nominal_time),
8563 scsi_4btoul(td->recommended_time), op_desc);
8570 scsiopcodes(struct cam_device *device, int argc, char **argv,
8571 char *combinedopt, int retry_count, int timeout, int verbosemode)
8574 uint32_t opcode = 0, service_action = 0;
8575 int td_set = 0, opcode_set = 0, sa_set = 0;
8576 int show_sa_errors = 1;
8577 uint32_t valid_len = 0;
8578 uint8_t *buf = NULL;
8582 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8588 opcode = strtoul(optarg, &endptr, 0);
8589 if (*endptr != '\0') {
8590 warnx("Invalid opcode \"%s\", must be a number",
8595 if (opcode > 0xff) {
8596 warnx("Invalid opcode 0x%#x, must be between"
8597 "0 and 0xff inclusive", opcode);
8604 service_action = strtoul(optarg, &endptr, 0);
8605 if (*endptr != '\0') {
8606 warnx("Invalid service action \"%s\", must "
8607 "be a number", optarg);
8611 if (service_action > 0xffff) {
8612 warnx("Invalid service action 0x%#x, must "
8613 "be between 0 and 0xffff inclusive",
8628 && (opcode_set == 0)) {
8629 warnx("You must specify an opcode with -o if a service "
8634 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8635 sa_set, service_action, td_set, retry_count,
8636 timeout, verbosemode, &valid_len, &buf);
8640 if ((opcode_set != 0)
8642 retval = scsiprintoneopcode(device, opcode, sa_set,
8643 service_action, buf, valid_len);
8645 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8654 #endif /* MINIMALISTIC */
8657 scsireprobe(struct cam_device *device)
8662 ccb = cam_getccb(device);
8665 warnx("%s: error allocating ccb", __func__);
8669 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8671 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8673 if (cam_send_ccb(device, ccb) < 0) {
8674 warn("error sending XPT_REPROBE_LUN CCB");
8679 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8680 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8692 usage(int printlong)
8695 fprintf(printlong ? stdout : stderr,
8696 "usage: camcontrol <command> [device id][generic args][command args]\n"
8697 " camcontrol devlist [-b] [-v]\n"
8698 #ifndef MINIMALISTIC
8699 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8700 " camcontrol tur [dev_id][generic args]\n"
8701 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8702 " camcontrol identify [dev_id][generic args] [-v]\n"
8703 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8704 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8706 " camcontrol start [dev_id][generic args]\n"
8707 " camcontrol stop [dev_id][generic args]\n"
8708 " camcontrol load [dev_id][generic args]\n"
8709 " camcontrol eject [dev_id][generic args]\n"
8710 " camcontrol reprobe [dev_id][generic args]\n"
8711 #endif /* MINIMALISTIC */
8712 " camcontrol rescan <all | bus[:target:lun]>\n"
8713 " camcontrol reset <all | bus[:target:lun]>\n"
8714 #ifndef MINIMALISTIC
8715 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8716 " [-q][-s][-S offset][-X]\n"
8717 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8718 " [-P pagectl][-e | -b][-d]\n"
8719 " camcontrol cmd [dev_id][generic args]\n"
8720 " <-a cmd [args] | -c cmd [args]>\n"
8721 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8722 " camcontrol smpcmd [dev_id][generic args]\n"
8723 " <-r len fmt [args]> <-R len fmt [args]>\n"
8724 " camcontrol smprg [dev_id][generic args][-l]\n"
8725 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8726 " [-o operation][-d name][-m rate][-M rate]\n"
8727 " [-T pp_timeout][-a enable|disable]\n"
8728 " [-A enable|disable][-s enable|disable]\n"
8729 " [-S enable|disable]\n"
8730 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8731 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8732 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8733 " <all|bus[:target[:lun]]|off>\n"
8734 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8735 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8736 " [-D <enable|disable>][-M mode][-O offset]\n"
8737 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8738 " [-U][-W bus_width]\n"
8739 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8740 " camcontrol sanitize [dev_id][generic args]\n"
8741 " [-a overwrite|block|crypto|exitfailure]\n"
8742 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8744 " camcontrol idle [dev_id][generic args][-t time]\n"
8745 " camcontrol standby [dev_id][generic args][-t time]\n"
8746 " camcontrol sleep [dev_id][generic args]\n"
8747 " camcontrol apm [dev_id][generic args][-l level]\n"
8748 " camcontrol aam [dev_id][generic args][-l level]\n"
8749 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8751 " camcontrol security [dev_id][generic args]\n"
8752 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8753 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8754 " [-U <user|master>] [-y]\n"
8755 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8756 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8757 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8758 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8759 " [-s scope][-S][-T type][-U]\n"
8760 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8761 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8762 " [-p part][-s start][-T type][-V vol]\n"
8763 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8765 #endif /* MINIMALISTIC */
8766 " camcontrol help\n");
8769 #ifndef MINIMALISTIC
8771 "Specify one of the following options:\n"
8772 "devlist list all CAM devices\n"
8773 "periphlist list all CAM peripheral drivers attached to a device\n"
8774 "tur send a test unit ready to the named device\n"
8775 "inquiry send a SCSI inquiry command to the named device\n"
8776 "identify send a ATA identify command to the named device\n"
8777 "reportluns send a SCSI report luns command to the device\n"
8778 "readcap send a SCSI read capacity command to the device\n"
8779 "start send a Start Unit command to the device\n"
8780 "stop send a Stop Unit command to the device\n"
8781 "load send a Start Unit command to the device with the load bit set\n"
8782 "eject send a Stop Unit command to the device with the eject bit set\n"
8783 "reprobe update capacity information of the given device\n"
8784 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8785 "reset reset all busses, the given bus, or bus:target:lun\n"
8786 "defects read the defect list of the specified device\n"
8787 "modepage display or edit (-e) the given mode page\n"
8788 "cmd send the given SCSI command, may need -i or -o as well\n"
8789 "smpcmd send the given SMP command, requires -o and -i\n"
8790 "smprg send the SMP Report General command\n"
8791 "smppc send the SMP PHY Control command, requires -p\n"
8792 "smpphylist display phys attached to a SAS expander\n"
8793 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8794 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8795 "tags report or set the number of transaction slots for a device\n"
8796 "negotiate report or set device negotiation parameters\n"
8797 "format send the SCSI FORMAT UNIT command to the named device\n"
8798 "sanitize send the SCSI SANITIZE command to the named device\n"
8799 "idle send the ATA IDLE command to the named device\n"
8800 "standby send the ATA STANDBY command to the named device\n"
8801 "sleep send the ATA SLEEP command to the named device\n"
8802 "fwdownload program firmware of the named device with the given image\n"
8803 "security report or send ATA security commands to the named device\n"
8804 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8805 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8806 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8807 "help this message\n"
8808 "Device Identifiers:\n"
8809 "bus:target specify the bus and target, lun defaults to 0\n"
8810 "bus:target:lun specify the bus, target and lun\n"
8811 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8812 "Generic arguments:\n"
8813 "-v be verbose, print out sense information\n"
8814 "-t timeout command timeout in seconds, overrides default timeout\n"
8815 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8816 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8817 "-E have the kernel attempt to perform SCSI error recovery\n"
8818 "-C count specify the SCSI command retry count (needs -E to work)\n"
8819 "modepage arguments:\n"
8820 "-l list all available mode pages\n"
8821 "-m page specify the mode page to view or edit\n"
8822 "-e edit the specified mode page\n"
8823 "-b force view to binary mode\n"
8824 "-d disable block descriptors for mode sense\n"
8825 "-P pgctl page control field 0-3\n"
8826 "defects arguments:\n"
8827 "-f format specify defect list format (block, bfi or phys)\n"
8828 "-G get the grown defect list\n"
8829 "-P get the permanent defect list\n"
8830 "inquiry arguments:\n"
8831 "-D get the standard inquiry data\n"
8832 "-S get the serial number\n"
8833 "-R get the transfer rate, etc.\n"
8834 "reportluns arguments:\n"
8835 "-c only report a count of available LUNs\n"
8836 "-l only print out luns, and not a count\n"
8837 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
8838 "readcap arguments\n"
8839 "-b only report the blocksize\n"
8840 "-h human readable device size, base 2\n"
8841 "-H human readable device size, base 10\n"
8842 "-N print the number of blocks instead of last block\n"
8843 "-q quiet, print numbers only\n"
8844 "-s only report the last block/device size\n"
8846 "-c cdb [args] specify the SCSI CDB\n"
8847 "-i len fmt specify input data and input data format\n"
8848 "-o len fmt [args] specify output data and output data fmt\n"
8849 "smpcmd arguments:\n"
8850 "-r len fmt [args] specify the SMP command to be sent\n"
8851 "-R len fmt [args] specify SMP response format\n"
8852 "smprg arguments:\n"
8853 "-l specify the long response format\n"
8854 "smppc arguments:\n"
8855 "-p phy specify the PHY to operate on\n"
8856 "-l specify the long request/response format\n"
8857 "-o operation specify the phy control operation\n"
8858 "-d name set the attached device name\n"
8859 "-m rate set the minimum physical link rate\n"
8860 "-M rate set the maximum physical link rate\n"
8861 "-T pp_timeout set the partial pathway timeout value\n"
8862 "-a enable|disable enable or disable SATA slumber\n"
8863 "-A enable|disable enable or disable SATA partial phy power\n"
8864 "-s enable|disable enable or disable SAS slumber\n"
8865 "-S enable|disable enable or disable SAS partial phy power\n"
8866 "smpphylist arguments:\n"
8867 "-l specify the long response format\n"
8868 "-q only print phys with attached devices\n"
8869 "smpmaninfo arguments:\n"
8870 "-l specify the long response format\n"
8871 "debug arguments:\n"
8872 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
8873 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
8874 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
8875 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
8877 "-N tags specify the number of tags to use for this device\n"
8878 "-q be quiet, don't report the number of tags\n"
8879 "-v report a number of tag-related parameters\n"
8880 "negotiate arguments:\n"
8881 "-a send a test unit ready after negotiation\n"
8882 "-c report/set current negotiation settings\n"
8883 "-D <arg> \"enable\" or \"disable\" disconnection\n"
8884 "-M mode set ATA mode\n"
8885 "-O offset set command delay offset\n"
8886 "-q be quiet, don't report anything\n"
8887 "-R syncrate synchronization rate in MHz\n"
8888 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
8889 "-U report/set user negotiation settings\n"
8890 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
8891 "-v also print a Path Inquiry CCB for the controller\n"
8892 "format arguments:\n"
8893 "-q be quiet, don't print status messages\n"
8894 "-r run in report only mode\n"
8895 "-w don't send immediate format command\n"
8896 "-y don't ask any questions\n"
8897 "sanitize arguments:\n"
8898 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
8899 "-c passes overwrite passes to perform (1 to 31)\n"
8900 "-I invert overwrite pattern after each pass\n"
8901 "-P pattern path to overwrite pattern file\n"
8902 "-q be quiet, don't print status messages\n"
8903 "-r run in report only mode\n"
8904 "-U run operation in unrestricted completion exit mode\n"
8905 "-w don't send immediate sanitize command\n"
8906 "-y don't ask any questions\n"
8907 "idle/standby arguments:\n"
8908 "-t <arg> number of seconds before respective state.\n"
8909 "fwdownload arguments:\n"
8910 "-f fw_image path to firmware image file\n"
8911 "-q don't print informational messages, only errors\n"
8912 "-s run in simulation mode\n"
8913 "-v print info for every firmware segment sent to device\n"
8914 "-y don't ask any questions\n"
8915 "security arguments:\n"
8916 "-d pwd disable security using the given password for the selected\n"
8918 "-e pwd erase the device using the given pwd for the selected user\n"
8919 "-f freeze the security configuration of the specified device\n"
8920 "-h pwd enhanced erase the device using the given pwd for the\n"
8922 "-k pwd unlock the device using the given pwd for the selected\n"
8924 "-l <high|maximum> specifies which security level to set: high or maximum\n"
8925 "-q be quiet, do not print any status messages\n"
8926 "-s pwd password the device (enable security) using the given\n"
8927 " pwd for the selected user\n"
8928 "-T timeout overrides the timeout (seconds) used for erase operation\n"
8929 "-U <user|master> specifies which user to set: user or master\n"
8930 "-y don't ask any questions\n"
8932 "-f freeze the HPA configuration of the device\n"
8933 "-l lock the HPA configuration of the device\n"
8934 "-P make the HPA max sectors persist\n"
8935 "-p pwd Set the HPA configuration password required for unlock\n"
8937 "-q be quiet, do not print any status messages\n"
8938 "-s sectors configures the maximum user accessible sectors of the\n"
8940 "-U pwd unlock the HPA configuration of the device\n"
8941 "-y don't ask any questions\n"
8942 "persist arguments:\n"
8943 "-i action specify read_keys, read_reservation, report_cap, or\n"
8944 " read_full_status\n"
8945 "-o action specify register, register_ignore, reserve, release,\n"
8946 " clear, preempt, preempt_abort, register_move, replace_lost\n"
8947 "-a set the All Target Ports (ALL_TG_PT) bit\n"
8948 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
8949 "-k key specify the Reservation Key\n"
8950 "-K sa_key specify the Service Action Reservation Key\n"
8951 "-p set the Activate Persist Through Power Loss bit\n"
8952 "-R rtp specify the Relative Target Port\n"
8953 "-s scope specify the scope: lun, extent, element or a number\n"
8954 "-S specify Transport ID for register, requires -I\n"
8955 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
8956 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
8957 "-U unregister the current initiator for register_move\n"
8958 "attrib arguments:\n"
8959 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
8961 "-w attr specify an attribute to write, one -w argument per attr\n"
8962 "-a attr_num only display this attribute number\n"
8963 "-c get cached attributes\n"
8964 "-e elem_addr request attributes for the given element in a changer\n"
8965 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
8966 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
8967 " field_none, field_desc, field_num, field_size, field_rw\n"
8968 "-p partition request attributes for the given partition\n"
8969 "-s start_attr request attributes starting at the given number\n"
8970 "-T elem_type specify the element type (used with -e)\n"
8971 "-V logical_vol specify the logical volume ID\n"
8972 "opcodes arguments:\n"
8973 "-o opcode specify the individual opcode to list\n"
8974 "-s service_action specify the service action for the opcode\n"
8975 "-N do not return SCSI error for unsupported SA\n"
8976 "-T request nominal and recommended timeout values\n"
8978 #endif /* MINIMALISTIC */
8982 main(int argc, char **argv)
8985 char *device = NULL;
8987 struct cam_device *cam_dev = NULL;
8988 int timeout = 0, retry_count = 1;
8989 camcontrol_optret optreturn;
8991 const char *mainopt = "C:En:t:u:v";
8992 const char *subopt = NULL;
8993 char combinedopt[256];
8994 int error = 0, optstart = 2;
8996 #ifndef MINIMALISTIC
9000 #endif /* MINIMALISTIC */
9002 cmdlist = CAM_CMD_NONE;
9003 arglist = CAM_ARG_NONE;
9011 * Get the base option.
9013 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9015 if (optreturn == CC_OR_AMBIGUOUS) {
9016 warnx("ambiguous option %s", argv[1]);
9019 } else if (optreturn == CC_OR_NOT_FOUND) {
9020 warnx("option %s not found", argv[1]);
9026 * Ahh, getopt(3) is a pain.
9028 * This is a gross hack. There really aren't many other good
9029 * options (excuse the pun) for parsing options in a situation like
9030 * this. getopt is kinda braindead, so you end up having to run
9031 * through the options twice, and give each invocation of getopt
9032 * the option string for the other invocation.
9034 * You would think that you could just have two groups of options.
9035 * The first group would get parsed by the first invocation of
9036 * getopt, and the second group would get parsed by the second
9037 * invocation of getopt. It doesn't quite work out that way. When
9038 * the first invocation of getopt finishes, it leaves optind pointing
9039 * to the argument _after_ the first argument in the second group.
9040 * So when the second invocation of getopt comes around, it doesn't
9041 * recognize the first argument it gets and then bails out.
9043 * A nice alternative would be to have a flag for getopt that says
9044 * "just keep parsing arguments even when you encounter an unknown
9045 * argument", but there isn't one. So there's no real clean way to
9046 * easily parse two sets of arguments without having one invocation
9047 * of getopt know about the other.
9049 * Without this hack, the first invocation of getopt would work as
9050 * long as the generic arguments are first, but the second invocation
9051 * (in the subfunction) would fail in one of two ways. In the case
9052 * where you don't set optreset, it would fail because optind may be
9053 * pointing to the argument after the one it should be pointing at.
9054 * In the case where you do set optreset, and reset optind, it would
9055 * fail because getopt would run into the first set of options, which
9056 * it doesn't understand.
9058 * All of this would "sort of" work if you could somehow figure out
9059 * whether optind had been incremented one option too far. The
9060 * mechanics of that, however, are more daunting than just giving
9061 * both invocations all of the expect options for either invocation.
9063 * Needless to say, I wouldn't mind if someone invented a better
9064 * (non-GPL!) command line parsing interface than getopt. I
9065 * wouldn't mind if someone added more knobs to getopt to make it
9066 * work better. Who knows, I may talk myself into doing it someday,
9067 * if the standards weenies let me. As it is, it just leads to
9068 * hackery like this and causes people to avoid it in some cases.
9070 * KDM, September 8th, 1998
9073 sprintf(combinedopt, "%s%s", mainopt, subopt);
9075 sprintf(combinedopt, "%s", mainopt);
9078 * For these options we do not parse optional device arguments and
9079 * we do not open a passthrough device.
9081 if ((cmdlist == CAM_CMD_RESCAN)
9082 || (cmdlist == CAM_CMD_RESET)
9083 || (cmdlist == CAM_CMD_DEVTREE)
9084 || (cmdlist == CAM_CMD_USAGE)
9085 || (cmdlist == CAM_CMD_DEBUG))
9088 #ifndef MINIMALISTIC
9090 && (argc > 2 && argv[2][0] != '-')) {
9094 if (isdigit(argv[2][0])) {
9095 /* device specified as bus:target[:lun] */
9096 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9098 errx(1, "numeric device specification must "
9099 "be either bus:target, or "
9101 /* default to 0 if lun was not specified */
9102 if ((arglist & CAM_ARG_LUN) == 0) {
9104 arglist |= CAM_ARG_LUN;
9108 if (cam_get_device(argv[2], name, sizeof name, &unit)
9110 errx(1, "%s", cam_errbuf);
9111 device = strdup(name);
9112 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9116 #endif /* MINIMALISTIC */
9118 * Start getopt processing at argv[2/3], since we've already
9119 * accepted argv[1..2] as the command name, and as a possible
9125 * Now we run through the argument list looking for generic
9126 * options, and ignoring options that possibly belong to
9129 while ((c = getopt(argc, argv, combinedopt))!= -1){
9132 retry_count = strtol(optarg, NULL, 0);
9133 if (retry_count < 0)
9134 errx(1, "retry count %d is < 0",
9136 arglist |= CAM_ARG_RETRIES;
9139 arglist |= CAM_ARG_ERR_RECOVER;
9142 arglist |= CAM_ARG_DEVICE;
9144 while (isspace(*tstr) && (*tstr != '\0'))
9146 device = (char *)strdup(tstr);
9149 timeout = strtol(optarg, NULL, 0);
9151 errx(1, "invalid timeout %d", timeout);
9152 /* Convert the timeout from seconds to ms */
9154 arglist |= CAM_ARG_TIMEOUT;
9157 arglist |= CAM_ARG_UNIT;
9158 unit = strtol(optarg, NULL, 0);
9161 arglist |= CAM_ARG_VERBOSE;
9168 #ifndef MINIMALISTIC
9170 * For most commands we'll want to open the passthrough device
9171 * associated with the specified device. In the case of the rescan
9172 * commands, we don't use a passthrough device at all, just the
9173 * transport layer device.
9176 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9177 && (((arglist & CAM_ARG_DEVICE) == 0)
9178 || ((arglist & CAM_ARG_UNIT) == 0))) {
9179 errx(1, "subcommand \"%s\" requires a valid device "
9180 "identifier", argv[1]);
9183 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9184 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9185 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9187 errx(1,"%s", cam_errbuf);
9189 #endif /* MINIMALISTIC */
9192 * Reset optind to 2, and reset getopt, so these routines can parse
9193 * the arguments again.
9199 #ifndef MINIMALISTIC
9200 case CAM_CMD_DEVLIST:
9201 error = getdevlist(cam_dev);
9204 error = atahpa(cam_dev, retry_count, timeout,
9205 argc, argv, combinedopt);
9207 #endif /* MINIMALISTIC */
9208 case CAM_CMD_DEVTREE:
9209 error = getdevtree(argc, argv, combinedopt);
9211 #ifndef MINIMALISTIC
9213 error = testunitready(cam_dev, retry_count, timeout, 0);
9215 case CAM_CMD_INQUIRY:
9216 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9217 retry_count, timeout);
9219 case CAM_CMD_IDENTIFY:
9220 error = ataidentify(cam_dev, retry_count, timeout);
9222 case CAM_CMD_STARTSTOP:
9223 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9224 arglist & CAM_ARG_EJECT, retry_count,
9227 #endif /* MINIMALISTIC */
9228 case CAM_CMD_RESCAN:
9229 error = dorescan_or_reset(argc, argv, 1);
9232 error = dorescan_or_reset(argc, argv, 0);
9234 #ifndef MINIMALISTIC
9235 case CAM_CMD_READ_DEFECTS:
9236 error = readdefects(cam_dev, argc, argv, combinedopt,
9237 retry_count, timeout);
9239 case CAM_CMD_MODE_PAGE:
9240 modepage(cam_dev, argc, argv, combinedopt,
9241 retry_count, timeout);
9243 case CAM_CMD_SCSI_CMD:
9244 error = scsicmd(cam_dev, argc, argv, combinedopt,
9245 retry_count, timeout);
9247 case CAM_CMD_SMP_CMD:
9248 error = smpcmd(cam_dev, argc, argv, combinedopt,
9249 retry_count, timeout);
9251 case CAM_CMD_SMP_RG:
9252 error = smpreportgeneral(cam_dev, argc, argv,
9253 combinedopt, retry_count,
9256 case CAM_CMD_SMP_PC:
9257 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9258 retry_count, timeout);
9260 case CAM_CMD_SMP_PHYLIST:
9261 error = smpphylist(cam_dev, argc, argv, combinedopt,
9262 retry_count, timeout);
9264 case CAM_CMD_SMP_MANINFO:
9265 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9266 retry_count, timeout);
9269 error = camdebug(argc, argv, combinedopt);
9272 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9275 error = ratecontrol(cam_dev, retry_count, timeout,
9276 argc, argv, combinedopt);
9278 case CAM_CMD_FORMAT:
9279 error = scsiformat(cam_dev, argc, argv,
9280 combinedopt, retry_count, timeout);
9282 case CAM_CMD_REPORTLUNS:
9283 error = scsireportluns(cam_dev, argc, argv,
9284 combinedopt, retry_count,
9287 case CAM_CMD_READCAP:
9288 error = scsireadcapacity(cam_dev, argc, argv,
9289 combinedopt, retry_count,
9293 case CAM_CMD_STANDBY:
9295 error = atapm(cam_dev, argc, argv,
9296 combinedopt, retry_count, timeout);
9300 error = ataaxm(cam_dev, argc, argv,
9301 combinedopt, retry_count, timeout);
9303 case CAM_CMD_SECURITY:
9304 error = atasecurity(cam_dev, retry_count, timeout,
9305 argc, argv, combinedopt);
9307 case CAM_CMD_DOWNLOAD_FW:
9308 error = fwdownload(cam_dev, argc, argv, combinedopt,
9309 arglist & CAM_ARG_VERBOSE, retry_count, timeout);
9311 case CAM_CMD_SANITIZE:
9312 error = scsisanitize(cam_dev, argc, argv,
9313 combinedopt, retry_count, timeout);
9315 case CAM_CMD_PERSIST:
9316 error = scsipersist(cam_dev, argc, argv, combinedopt,
9317 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9318 arglist & CAM_ARG_ERR_RECOVER);
9320 case CAM_CMD_ATTRIB:
9321 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9322 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9323 arglist & CAM_ARG_ERR_RECOVER);
9325 case CAM_CMD_OPCODES:
9326 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9327 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9329 case CAM_CMD_REPROBE:
9330 error = scsireprobe(cam_dev);
9333 #endif /* MINIMALISTIC */
9343 if (cam_dev != NULL)
9344 cam_close_device(cam_dev);