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
107 CAM_ARG_NONE = 0x00000000,
108 CAM_ARG_VERBOSE = 0x00000001,
109 CAM_ARG_DEVICE = 0x00000002,
110 CAM_ARG_BUS = 0x00000004,
111 CAM_ARG_TARGET = 0x00000008,
112 CAM_ARG_LUN = 0x00000010,
113 CAM_ARG_EJECT = 0x00000020,
114 CAM_ARG_UNIT = 0x00000040,
115 CAM_ARG_FORMAT_BLOCK = 0x00000080,
116 CAM_ARG_FORMAT_BFI = 0x00000100,
117 CAM_ARG_FORMAT_PHYS = 0x00000200,
118 CAM_ARG_PLIST = 0x00000400,
119 CAM_ARG_GLIST = 0x00000800,
120 CAM_ARG_GET_SERIAL = 0x00001000,
121 CAM_ARG_GET_STDINQ = 0x00002000,
122 CAM_ARG_GET_XFERRATE = 0x00004000,
123 CAM_ARG_INQ_MASK = 0x00007000,
124 CAM_ARG_MODE_EDIT = 0x00008000,
125 CAM_ARG_PAGE_CNTL = 0x00010000,
126 CAM_ARG_TIMEOUT = 0x00020000,
127 CAM_ARG_CMD_IN = 0x00040000,
128 CAM_ARG_CMD_OUT = 0x00080000,
129 CAM_ARG_DBD = 0x00100000,
130 CAM_ARG_ERR_RECOVER = 0x00200000,
131 CAM_ARG_RETRIES = 0x00400000,
132 CAM_ARG_START_UNIT = 0x00800000,
133 CAM_ARG_DEBUG_INFO = 0x01000000,
134 CAM_ARG_DEBUG_TRACE = 0x02000000,
135 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
136 CAM_ARG_DEBUG_CDB = 0x08000000,
137 CAM_ARG_DEBUG_XPT = 0x10000000,
138 CAM_ARG_DEBUG_PERIPH = 0x20000000,
139 CAM_ARG_DEBUG_PROBE = 0x40000000,
142 struct camcontrol_opts {
150 struct ata_res_pass16 {
151 u_int16_t reserved[5];
154 u_int8_t sector_count_exp;
155 u_int8_t sector_count;
156 u_int8_t lba_low_exp;
158 u_int8_t lba_mid_exp;
160 u_int8_t lba_high_exp;
166 struct ata_set_max_pwd
169 u_int8_t password[32];
170 u_int16_t reserved2[239];
173 static const char scsicmd_opts[] = "a:c:dfi:o:r";
174 static const char readdefect_opts[] = "f:GPqsS:X";
175 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
176 static const char smprg_opts[] = "l";
177 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
178 static const char smpphylist_opts[] = "lq";
182 static struct camcontrol_opts option_table[] = {
184 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
185 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
186 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
187 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
188 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
189 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
190 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
191 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
192 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
193 #endif /* MINIMALISTIC */
194 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
195 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
197 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
198 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
199 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
200 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
201 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
202 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
203 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
204 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
205 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
206 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
207 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
208 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
209 #endif /* MINIMALISTIC */
210 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
212 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
213 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
214 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
215 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
216 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
217 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
218 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
219 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
220 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
221 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
222 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
223 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
224 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
225 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
226 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
227 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
228 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
229 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
230 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
231 #endif /* MINIMALISTIC */
232 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
233 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
234 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
239 struct device_match_result dev_match;
241 struct periph_match_result *periph_matches;
242 struct scsi_vpd_device_id *device_id;
244 STAILQ_ENTRY(cam_devitem) links;
248 STAILQ_HEAD(, cam_devitem) dev_queue;
252 static cam_cmdmask cmdlist;
253 static cam_argmask arglist;
255 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
256 uint32_t *cmdnum, cam_argmask *argnum,
257 const char **subopt);
259 static int getdevlist(struct cam_device *device);
260 #endif /* MINIMALISTIC */
261 static int getdevtree(int argc, char **argv, char *combinedopt);
263 static int testunitready(struct cam_device *device, int retry_count,
264 int timeout, int quiet);
265 static int scsistart(struct cam_device *device, int startstop, int loadeject,
266 int retry_count, int timeout);
267 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
268 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
269 #endif /* MINIMALISTIC */
270 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
271 lun_id_t *lun, cam_argmask *arglst);
272 static int dorescan_or_reset(int argc, char **argv, int rescan);
273 static int rescan_or_reset_bus(path_id_t bus, int rescan);
274 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
275 lun_id_t lun, int scan);
277 static int readdefects(struct cam_device *device, int argc, char **argv,
278 char *combinedopt, int retry_count, int timeout);
279 static void modepage(struct cam_device *device, int argc, char **argv,
280 char *combinedopt, int retry_count, int timeout);
281 static int scsicmd(struct cam_device *device, int argc, char **argv,
282 char *combinedopt, int retry_count, int timeout);
283 static int smpcmd(struct cam_device *device, int argc, char **argv,
284 char *combinedopt, int retry_count, int timeout);
285 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
286 char *combinedopt, int retry_count, int timeout);
287 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
288 char *combinedopt, int retry_count, int timeout);
289 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
290 char *combinedopt, int retry_count, int timeout);
291 static int getdevid(struct cam_devitem *item);
292 static int buildbusdevlist(struct cam_devlist *devlist);
293 static void freebusdevlist(struct cam_devlist *devlist);
294 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
296 static int smpphylist(struct cam_device *device, int argc, char **argv,
297 char *combinedopt, int retry_count, int timeout);
298 static int tagcontrol(struct cam_device *device, int argc, char **argv,
300 static void cts_print(struct cam_device *device,
301 struct ccb_trans_settings *cts);
302 static void cpi_print(struct ccb_pathinq *cpi);
303 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
304 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
305 static int get_print_cts(struct cam_device *device, int user_settings,
306 int quiet, struct ccb_trans_settings *cts);
307 static int ratecontrol(struct cam_device *device, int retry_count,
308 int timeout, int argc, char **argv, char *combinedopt);
309 static int scsiformat(struct cam_device *device, int argc, char **argv,
310 char *combinedopt, int retry_count, int timeout);
311 static int scsisanitize(struct cam_device *device, int argc, char **argv,
312 char *combinedopt, int retry_count, int timeout);
313 static int scsireportluns(struct cam_device *device, int argc, char **argv,
314 char *combinedopt, int retry_count, int timeout);
315 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
316 char *combinedopt, int retry_count, int timeout);
317 static int atapm(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
320 int argc, char **argv, char *combinedopt);
321 static int atahpa(struct cam_device *device, int retry_count, int timeout,
322 int argc, char **argv, char *combinedopt);
323 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
324 int sa_set, int req_sa, uint8_t *buf,
326 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
328 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
329 char *combinedopt, int retry_count, int timeout,
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);
820 if (arglist & CAM_ARG_GET_XFERRATE)
821 error = camxferrate(device);
827 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
830 struct scsi_inquiry_data *inq_buf;
833 ccb = cam_getccb(device);
836 warnx("couldn't allocate CCB");
840 /* cam_getccb cleans up the header, caller has to zero the payload */
841 bzero(&(&ccb->ccb_h)[1],
842 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
844 inq_buf = (struct scsi_inquiry_data *)malloc(
845 sizeof(struct scsi_inquiry_data));
847 if (inq_buf == NULL) {
849 warnx("can't malloc memory for inquiry\n");
852 bzero(inq_buf, sizeof(*inq_buf));
855 * Note that although the size of the inquiry buffer is the full
856 * 256 bytes specified in the SCSI spec, we only tell the device
857 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
858 * two reasons for this:
860 * - The SCSI spec says that when a length field is only 1 byte,
861 * a value of 0 will be interpreted as 256. Therefore
862 * scsi_inquiry() will convert an inq_len (which is passed in as
863 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
864 * to 0. Evidently, very few devices meet the spec in that
865 * regard. Some devices, like many Seagate disks, take the 0 as
866 * 0, and don't return any data. One Pioneer DVD-R drive
867 * returns more data than the command asked for.
869 * So, since there are numerous devices that just don't work
870 * right with the full inquiry size, we don't send the full size.
872 * - The second reason not to use the full inquiry data length is
873 * that we don't need it here. The only reason we issue a
874 * standard inquiry is to get the vendor name, device name,
875 * and revision so scsi_print_inquiry() can print them.
877 * If, at some point in the future, more inquiry data is needed for
878 * some reason, this code should use a procedure similar to the
879 * probe code. i.e., issue a short inquiry, and determine from
880 * the additional length passed back from the device how much
881 * inquiry data the device supports. Once the amount the device
882 * supports is determined, issue an inquiry for that amount and no
887 scsi_inquiry(&ccb->csio,
888 /* retries */ retry_count,
890 /* tag_action */ MSG_SIMPLE_Q_TAG,
891 /* inq_buf */ (u_int8_t *)inq_buf,
892 /* inq_len */ SHORT_INQUIRY_LENGTH,
895 /* sense_len */ SSD_FULL_SIZE,
896 /* timeout */ timeout ? timeout : 5000);
898 /* Disable freezing the device queue */
899 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
901 if (arglist & CAM_ARG_ERR_RECOVER)
902 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
904 if (cam_send_ccb(device, ccb) < 0) {
905 perror("error sending SCSI inquiry");
907 if (arglist & CAM_ARG_VERBOSE) {
908 cam_error_print(device, ccb, CAM_ESF_ALL,
909 CAM_EPF_ALL, stderr);
916 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
919 if (arglist & CAM_ARG_VERBOSE) {
920 cam_error_print(device, ccb, CAM_ESF_ALL,
921 CAM_EPF_ALL, stderr);
932 fprintf(stdout, "%s%d: ", device->device_name,
933 device->dev_unit_num);
934 scsi_print_inquiry(inq_buf);
942 scsiserial(struct cam_device *device, int retry_count, int timeout)
945 struct scsi_vpd_unit_serial_number *serial_buf;
946 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
949 ccb = cam_getccb(device);
952 warnx("couldn't allocate CCB");
956 /* cam_getccb cleans up the header, caller has to zero the payload */
957 bzero(&(&ccb->ccb_h)[1],
958 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
960 serial_buf = (struct scsi_vpd_unit_serial_number *)
961 malloc(sizeof(*serial_buf));
963 if (serial_buf == NULL) {
965 warnx("can't malloc memory for serial number");
969 scsi_inquiry(&ccb->csio,
970 /*retries*/ retry_count,
972 /* tag_action */ MSG_SIMPLE_Q_TAG,
973 /* inq_buf */ (u_int8_t *)serial_buf,
974 /* inq_len */ sizeof(*serial_buf),
976 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
977 /* sense_len */ SSD_FULL_SIZE,
978 /* timeout */ timeout ? timeout : 5000);
980 /* Disable freezing the device queue */
981 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
983 if (arglist & CAM_ARG_ERR_RECOVER)
984 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
986 if (cam_send_ccb(device, ccb) < 0) {
987 warn("error getting serial number");
989 if (arglist & CAM_ARG_VERBOSE) {
990 cam_error_print(device, ccb, CAM_ESF_ALL,
991 CAM_EPF_ALL, stderr);
999 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1002 if (arglist & CAM_ARG_VERBOSE) {
1003 cam_error_print(device, ccb, CAM_ESF_ALL,
1004 CAM_EPF_ALL, stderr);
1015 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1016 serial_num[serial_buf->length] = '\0';
1018 if ((arglist & CAM_ARG_GET_STDINQ)
1019 || (arglist & CAM_ARG_GET_XFERRATE))
1020 fprintf(stdout, "%s%d: Serial Number ",
1021 device->device_name, device->dev_unit_num);
1023 fprintf(stdout, "%.60s\n", serial_num);
1031 camxferrate(struct cam_device *device)
1033 struct ccb_pathinq cpi;
1035 u_int32_t speed = 0;
1040 if ((retval = get_cpi(device, &cpi)) != 0)
1043 ccb = cam_getccb(device);
1046 warnx("couldn't allocate CCB");
1050 bzero(&(&ccb->ccb_h)[1],
1051 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
1053 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1054 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1056 if (((retval = cam_send_ccb(device, ccb)) < 0)
1057 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1058 const char error_string[] = "error getting transfer settings";
1063 warnx(error_string);
1065 if (arglist & CAM_ARG_VERBOSE)
1066 cam_error_print(device, ccb, CAM_ESF_ALL,
1067 CAM_EPF_ALL, stderr);
1071 goto xferrate_bailout;
1075 speed = cpi.base_transfer_speed;
1077 if (ccb->cts.transport == XPORT_SPI) {
1078 struct ccb_trans_settings_spi *spi =
1079 &ccb->cts.xport_specific.spi;
1081 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1082 freq = scsi_calc_syncsrate(spi->sync_period);
1085 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1086 speed *= (0x01 << spi->bus_width);
1088 } else if (ccb->cts.transport == XPORT_FC) {
1089 struct ccb_trans_settings_fc *fc =
1090 &ccb->cts.xport_specific.fc;
1092 if (fc->valid & CTS_FC_VALID_SPEED)
1093 speed = fc->bitrate;
1094 } else if (ccb->cts.transport == XPORT_SAS) {
1095 struct ccb_trans_settings_sas *sas =
1096 &ccb->cts.xport_specific.sas;
1098 if (sas->valid & CTS_SAS_VALID_SPEED)
1099 speed = sas->bitrate;
1100 } else if (ccb->cts.transport == XPORT_ATA) {
1101 struct ccb_trans_settings_pata *pata =
1102 &ccb->cts.xport_specific.ata;
1104 if (pata->valid & CTS_ATA_VALID_MODE)
1105 speed = ata_mode2speed(pata->mode);
1106 } else if (ccb->cts.transport == XPORT_SATA) {
1107 struct ccb_trans_settings_sata *sata =
1108 &ccb->cts.xport_specific.sata;
1110 if (sata->valid & CTS_SATA_VALID_REVISION)
1111 speed = ata_revision2speed(sata->revision);
1116 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1117 device->device_name, device->dev_unit_num,
1120 fprintf(stdout, "%s%d: %dKB/s transfers",
1121 device->device_name, device->dev_unit_num,
1125 if (ccb->cts.transport == XPORT_SPI) {
1126 struct ccb_trans_settings_spi *spi =
1127 &ccb->cts.xport_specific.spi;
1129 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1130 && (spi->sync_offset != 0))
1131 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1132 freq % 1000, spi->sync_offset);
1134 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1135 && (spi->bus_width > 0)) {
1136 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1137 && (spi->sync_offset != 0)) {
1138 fprintf(stdout, ", ");
1140 fprintf(stdout, " (");
1142 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1143 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1144 && (spi->sync_offset != 0)) {
1145 fprintf(stdout, ")");
1147 } else if (ccb->cts.transport == XPORT_ATA) {
1148 struct ccb_trans_settings_pata *pata =
1149 &ccb->cts.xport_specific.ata;
1152 if (pata->valid & CTS_ATA_VALID_MODE)
1153 printf("%s, ", ata_mode2string(pata->mode));
1154 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1155 printf("ATAPI %dbytes, ", pata->atapi);
1156 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1157 printf("PIO %dbytes", pata->bytecount);
1159 } else if (ccb->cts.transport == XPORT_SATA) {
1160 struct ccb_trans_settings_sata *sata =
1161 &ccb->cts.xport_specific.sata;
1164 if (sata->valid & CTS_SATA_VALID_REVISION)
1165 printf("SATA %d.x, ", sata->revision);
1168 if (sata->valid & CTS_SATA_VALID_MODE)
1169 printf("%s, ", ata_mode2string(sata->mode));
1170 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1171 printf("ATAPI %dbytes, ", sata->atapi);
1172 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1173 printf("PIO %dbytes", sata->bytecount);
1177 if (ccb->cts.protocol == PROTO_SCSI) {
1178 struct ccb_trans_settings_scsi *scsi =
1179 &ccb->cts.proto_specific.scsi;
1180 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1181 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1182 fprintf(stdout, ", Command Queueing Enabled");
1187 fprintf(stdout, "\n");
1197 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1199 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1200 ((u_int32_t)parm->lba_size_2 << 16);
1202 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1203 ((u_int64_t)parm->lba_size48_2 << 16) |
1204 ((u_int64_t)parm->lba_size48_3 << 32) |
1205 ((u_int64_t)parm->lba_size48_4 << 48);
1209 "Support Enabled Value\n");
1212 printf("Host Protected Area (HPA) ");
1213 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1214 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1215 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1218 printf("HPA - Security ");
1219 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1229 atasata(struct ata_params *parm)
1233 if (parm->satacapabilities != 0xffff &&
1234 parm->satacapabilities != 0x0000)
1241 atacapprint(struct ata_params *parm)
1243 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1244 ((u_int32_t)parm->lba_size_2 << 16);
1246 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1247 ((u_int64_t)parm->lba_size48_2 << 16) |
1248 ((u_int64_t)parm->lba_size48_3 << 32) |
1249 ((u_int64_t)parm->lba_size48_4 << 48);
1252 printf("protocol ");
1253 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1254 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1255 if (parm->satacapabilities & ATA_SATA_GEN3)
1256 printf(" SATA 3.x\n");
1257 else if (parm->satacapabilities & ATA_SATA_GEN2)
1258 printf(" SATA 2.x\n");
1259 else if (parm->satacapabilities & ATA_SATA_GEN1)
1260 printf(" SATA 1.x\n");
1266 printf("device model %.40s\n", parm->model);
1267 printf("firmware revision %.8s\n", parm->revision);
1268 printf("serial number %.20s\n", parm->serial);
1269 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1270 printf("WWN %04x%04x%04x%04x\n",
1271 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1273 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1274 printf("media serial number %.30s\n",
1275 parm->media_serial);
1278 printf("cylinders %d\n", parm->cylinders);
1279 printf("heads %d\n", parm->heads);
1280 printf("sectors/track %d\n", parm->sectors);
1281 printf("sector size logical %u, physical %lu, offset %lu\n",
1282 ata_logical_sector_size(parm),
1283 (unsigned long)ata_physical_sector_size(parm),
1284 (unsigned long)ata_logical_sector_offset(parm));
1286 if (parm->config == ATA_PROTO_CFA ||
1287 (parm->support.command2 & ATA_SUPPORT_CFA))
1288 printf("CFA supported\n");
1290 printf("LBA%ssupported ",
1291 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1293 printf("%d sectors\n", lbasize);
1297 printf("LBA48%ssupported ",
1298 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1300 printf("%ju sectors\n", (uintmax_t)lbasize48);
1304 printf("PIO supported PIO");
1305 switch (ata_max_pmode(parm)) {
1321 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1322 printf(" w/o IORDY");
1325 printf("DMA%ssupported ",
1326 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1327 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1328 if (parm->mwdmamodes & 0xff) {
1330 if (parm->mwdmamodes & 0x04)
1332 else if (parm->mwdmamodes & 0x02)
1334 else if (parm->mwdmamodes & 0x01)
1338 if ((parm->atavalid & ATA_FLAG_88) &&
1339 (parm->udmamodes & 0xff)) {
1341 if (parm->udmamodes & 0x40)
1343 else if (parm->udmamodes & 0x20)
1345 else if (parm->udmamodes & 0x10)
1347 else if (parm->udmamodes & 0x08)
1349 else if (parm->udmamodes & 0x04)
1351 else if (parm->udmamodes & 0x02)
1353 else if (parm->udmamodes & 0x01)
1360 if (parm->media_rotation_rate == 1) {
1361 printf("media RPM non-rotating\n");
1362 } else if (parm->media_rotation_rate >= 0x0401 &&
1363 parm->media_rotation_rate <= 0xFFFE) {
1364 printf("media RPM %d\n",
1365 parm->media_rotation_rate);
1369 "Support Enabled Value Vendor\n");
1370 printf("read ahead %s %s\n",
1371 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1372 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1373 printf("write cache %s %s\n",
1374 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1375 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1376 printf("flush cache %s %s\n",
1377 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1378 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1379 printf("overlap %s\n",
1380 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1381 printf("Tagged Command Queuing (TCQ) %s %s",
1382 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1383 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1384 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1385 printf(" %d tags\n",
1386 ATA_QUEUE_LEN(parm->queue) + 1);
1389 printf("Native Command Queuing (NCQ) ");
1390 if (parm->satacapabilities != 0xffff &&
1391 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1392 printf("yes %d tags\n",
1393 ATA_QUEUE_LEN(parm->queue) + 1);
1397 printf("NCQ Queue Management %s\n", atasata(parm) &&
1398 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1400 printf("NCQ Streaming %s\n", atasata(parm) &&
1401 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1403 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1404 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1407 printf("SMART %s %s\n",
1408 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1409 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1410 printf("microcode download %s %s\n",
1411 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1412 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1413 printf("security %s %s\n",
1414 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1415 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1416 printf("power management %s %s\n",
1417 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1418 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1419 printf("advanced power management %s %s",
1420 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1421 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1422 if (parm->support.command2 & ATA_SUPPORT_APM) {
1423 printf(" %d/0x%02X\n",
1424 parm->apm_value & 0xff, parm->apm_value & 0xff);
1427 printf("automatic acoustic management %s %s",
1428 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1429 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1430 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1431 printf(" %d/0x%02X %d/0x%02X\n",
1432 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1433 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1434 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1435 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1438 printf("media status notification %s %s\n",
1439 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1440 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1441 printf("power-up in Standby %s %s\n",
1442 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1443 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1444 printf("write-read-verify %s %s",
1445 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1446 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1447 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1448 printf(" %d/0x%x\n",
1449 parm->wrv_mode, parm->wrv_mode);
1452 printf("unload %s %s\n",
1453 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1454 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1455 printf("general purpose logging %s %s\n",
1456 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1457 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1458 printf("free-fall %s %s\n",
1459 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1460 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1461 printf("Data Set Management (DSM/TRIM) ");
1462 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1464 printf("DSM - max 512byte blocks ");
1465 if (parm->max_dsm_blocks == 0x00)
1466 printf("yes not specified\n");
1469 parm->max_dsm_blocks);
1471 printf("DSM - deterministic read ");
1472 if (parm->support3 & ATA_SUPPORT_DRAT) {
1473 if (parm->support3 & ATA_SUPPORT_RZAT)
1474 printf("yes zeroed\n");
1476 printf("yes any value\n");
1486 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1488 struct ata_pass_16 *ata_pass_16;
1489 struct ata_cmd ata_cmd;
1491 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1492 ata_cmd.command = ata_pass_16->command;
1493 ata_cmd.control = ata_pass_16->control;
1494 ata_cmd.features = ata_pass_16->features;
1496 if (arglist & CAM_ARG_VERBOSE) {
1497 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1498 ata_op_string(&ata_cmd),
1499 ccb->csio.ccb_h.timeout);
1502 /* Disable freezing the device queue */
1503 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1505 if (arglist & CAM_ARG_ERR_RECOVER)
1506 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1508 if (cam_send_ccb(device, ccb) < 0) {
1509 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1510 warn("error sending ATA %s via pass_16",
1511 ata_op_string(&ata_cmd));
1514 if (arglist & CAM_ARG_VERBOSE) {
1515 cam_error_print(device, ccb, CAM_ESF_ALL,
1516 CAM_EPF_ALL, stderr);
1522 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1523 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1524 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1525 warnx("ATA %s via pass_16 failed",
1526 ata_op_string(&ata_cmd));
1528 if (arglist & CAM_ARG_VERBOSE) {
1529 cam_error_print(device, ccb, CAM_ESF_ALL,
1530 CAM_EPF_ALL, stderr);
1541 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1543 if (arglist & CAM_ARG_VERBOSE) {
1544 warnx("sending ATA %s with timeout of %u msecs",
1545 ata_op_string(&(ccb->ataio.cmd)),
1546 ccb->ataio.ccb_h.timeout);
1549 /* Disable freezing the device queue */
1550 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1552 if (arglist & CAM_ARG_ERR_RECOVER)
1553 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1555 if (cam_send_ccb(device, ccb) < 0) {
1556 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1557 warn("error sending ATA %s",
1558 ata_op_string(&(ccb->ataio.cmd)));
1561 if (arglist & CAM_ARG_VERBOSE) {
1562 cam_error_print(device, ccb, CAM_ESF_ALL,
1563 CAM_EPF_ALL, stderr);
1569 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1570 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1571 warnx("ATA %s failed: %d",
1572 ata_op_string(&(ccb->ataio.cmd)), quiet);
1575 if (arglist & CAM_ARG_VERBOSE) {
1576 cam_error_print(device, ccb, CAM_ESF_ALL,
1577 CAM_EPF_ALL, stderr);
1587 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1588 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1589 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1590 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1591 u_int16_t dxfer_len, int timeout, int quiet)
1593 if (data_ptr != NULL) {
1594 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1595 AP_FLAG_TLEN_SECT_CNT;
1596 if (flags & CAM_DIR_OUT)
1597 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1599 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1601 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1604 bzero(&(&ccb->ccb_h)[1],
1605 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1607 scsi_ata_pass_16(&ccb->csio,
1621 /*sense_len*/SSD_FULL_SIZE,
1624 return scsi_cam_pass_16_send(device, ccb, quiet);
1628 ata_try_pass_16(struct cam_device *device)
1630 struct ccb_pathinq cpi;
1632 if (get_cpi(device, &cpi) != 0) {
1633 warnx("couldn't get CPI");
1637 if (cpi.protocol == PROTO_SCSI) {
1638 /* possibly compatible with pass_16 */
1642 /* likely not compatible with pass_16 */
1647 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1648 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1649 u_int8_t command, u_int8_t features, u_int32_t lba,
1650 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1651 int timeout, int quiet)
1655 switch (ata_try_pass_16(device)) {
1659 /* Try using SCSI Passthrough */
1660 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1661 0, tag_action, command, features, lba,
1662 sector_count, data_ptr, dxfer_len,
1666 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1667 sizeof(struct ccb_hdr));
1668 cam_fill_ataio(&ccb->ataio,
1677 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1678 return ata_cam_send(device, ccb, quiet);
1682 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1683 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1684 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1685 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1686 u_int16_t dxfer_len, int timeout, int force48bit)
1690 retval = ata_try_pass_16(device);
1697 /* Try using SCSI Passthrough */
1698 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1699 ata_flags, tag_action, command, features,
1700 lba, sector_count, data_ptr, dxfer_len,
1703 if (ata_flags & AP_FLAG_CHK_COND) {
1704 /* Decode ata_res from sense data */
1705 struct ata_res_pass16 *res_pass16;
1706 struct ata_res *res;
1710 /* sense_data is 4 byte aligned */
1711 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1712 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1713 ptr[i] = le16toh(ptr[i]);
1715 /* sense_data is 4 byte aligned */
1716 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1717 &ccb->csio.sense_data;
1718 res = &ccb->ataio.res;
1719 res->flags = res_pass16->flags;
1720 res->status = res_pass16->status;
1721 res->error = res_pass16->error;
1722 res->lba_low = res_pass16->lba_low;
1723 res->lba_mid = res_pass16->lba_mid;
1724 res->lba_high = res_pass16->lba_high;
1725 res->device = res_pass16->device;
1726 res->lba_low_exp = res_pass16->lba_low_exp;
1727 res->lba_mid_exp = res_pass16->lba_mid_exp;
1728 res->lba_high_exp = res_pass16->lba_high_exp;
1729 res->sector_count = res_pass16->sector_count;
1730 res->sector_count_exp = res_pass16->sector_count_exp;
1736 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1737 sizeof(struct ccb_hdr));
1738 cam_fill_ataio(&ccb->ataio,
1747 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1748 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1750 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1752 if (ata_flags & AP_FLAG_CHK_COND)
1753 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1755 return ata_cam_send(device, ccb, 0);
1759 dump_data(uint16_t *ptr, uint32_t len)
1763 for (i = 0; i < len / 2; i++) {
1765 printf(" %3d: ", i);
1766 printf("%04hx ", ptr[i]);
1775 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1776 int is48bit, u_int64_t *hpasize)
1778 struct ata_res *res;
1780 res = &ccb->ataio.res;
1781 if (res->status & ATA_STATUS_ERROR) {
1782 if (arglist & CAM_ARG_VERBOSE) {
1783 cam_error_print(device, ccb, CAM_ESF_ALL,
1784 CAM_EPF_ALL, stderr);
1785 printf("error = 0x%02x, sector_count = 0x%04x, "
1786 "device = 0x%02x, status = 0x%02x\n",
1787 res->error, res->sector_count,
1788 res->device, res->status);
1791 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1792 warnx("Max address has already been set since "
1793 "last power-on or hardware reset");
1799 if (arglist & CAM_ARG_VERBOSE) {
1800 fprintf(stdout, "%s%d: Raw native max data:\n",
1801 device->device_name, device->dev_unit_num);
1802 /* res is 4 byte aligned */
1803 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1805 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1806 "status = 0x%02x\n", res->error, res->sector_count,
1807 res->device, res->status);
1810 if (hpasize != NULL) {
1812 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1813 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1814 ((res->lba_high << 16) | (res->lba_mid << 8) |
1817 *hpasize = (((res->device & 0x0f) << 24) |
1818 (res->lba_high << 16) | (res->lba_mid << 8) |
1827 ata_read_native_max(struct cam_device *device, int retry_count,
1828 u_int32_t timeout, union ccb *ccb,
1829 struct ata_params *parm, u_int64_t *hpasize)
1835 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1836 protocol = AP_PROTO_NON_DATA;
1839 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1840 protocol |= AP_EXTEND;
1842 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1845 error = ata_do_cmd(device,
1848 /*flags*/CAM_DIR_NONE,
1849 /*protocol*/protocol,
1850 /*ata_flags*/AP_FLAG_CHK_COND,
1851 /*tag_action*/MSG_SIMPLE_Q_TAG,
1858 timeout ? timeout : 1000,
1864 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1868 atahpa_set_max(struct cam_device *device, int retry_count,
1869 u_int32_t timeout, union ccb *ccb,
1870 int is48bit, u_int64_t maxsize, int persist)
1876 protocol = AP_PROTO_NON_DATA;
1879 cmd = ATA_SET_MAX_ADDRESS48;
1880 protocol |= AP_EXTEND;
1882 cmd = ATA_SET_MAX_ADDRESS;
1885 /* lba's are zero indexed so the max lba is requested max - 1 */
1889 error = ata_do_cmd(device,
1892 /*flags*/CAM_DIR_NONE,
1893 /*protocol*/protocol,
1894 /*ata_flags*/AP_FLAG_CHK_COND,
1895 /*tag_action*/MSG_SIMPLE_Q_TAG,
1897 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1899 /*sector_count*/persist,
1902 timeout ? timeout : 1000,
1908 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1912 atahpa_password(struct cam_device *device, int retry_count,
1913 u_int32_t timeout, union ccb *ccb,
1914 int is48bit, struct ata_set_max_pwd *pwd)
1920 protocol = AP_PROTO_PIO_OUT;
1921 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1923 error = ata_do_cmd(device,
1926 /*flags*/CAM_DIR_OUT,
1927 /*protocol*/protocol,
1928 /*ata_flags*/AP_FLAG_CHK_COND,
1929 /*tag_action*/MSG_SIMPLE_Q_TAG,
1931 /*features*/ATA_HPA_FEAT_SET_PWD,
1934 /*data_ptr*/(u_int8_t*)pwd,
1935 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1936 timeout ? timeout : 1000,
1942 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1946 atahpa_lock(struct cam_device *device, int retry_count,
1947 u_int32_t timeout, union ccb *ccb, int is48bit)
1953 protocol = AP_PROTO_NON_DATA;
1954 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1956 error = ata_do_cmd(device,
1959 /*flags*/CAM_DIR_NONE,
1960 /*protocol*/protocol,
1961 /*ata_flags*/AP_FLAG_CHK_COND,
1962 /*tag_action*/MSG_SIMPLE_Q_TAG,
1964 /*features*/ATA_HPA_FEAT_LOCK,
1969 timeout ? timeout : 1000,
1975 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1979 atahpa_unlock(struct cam_device *device, int retry_count,
1980 u_int32_t timeout, union ccb *ccb,
1981 int is48bit, struct ata_set_max_pwd *pwd)
1987 protocol = AP_PROTO_PIO_OUT;
1988 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1990 error = ata_do_cmd(device,
1993 /*flags*/CAM_DIR_OUT,
1994 /*protocol*/protocol,
1995 /*ata_flags*/AP_FLAG_CHK_COND,
1996 /*tag_action*/MSG_SIMPLE_Q_TAG,
1998 /*features*/ATA_HPA_FEAT_UNLOCK,
2001 /*data_ptr*/(u_int8_t*)pwd,
2002 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2003 timeout ? timeout : 1000,
2009 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2013 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2014 u_int32_t timeout, union ccb *ccb, int is48bit)
2020 protocol = AP_PROTO_NON_DATA;
2021 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2023 error = ata_do_cmd(device,
2026 /*flags*/CAM_DIR_NONE,
2027 /*protocol*/protocol,
2028 /*ata_flags*/AP_FLAG_CHK_COND,
2029 /*tag_action*/MSG_SIMPLE_Q_TAG,
2031 /*features*/ATA_HPA_FEAT_FREEZE,
2036 timeout ? timeout : 1000,
2042 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2047 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2048 union ccb *ccb, struct ata_params** ident_bufp)
2050 struct ata_params *ident_buf;
2051 struct ccb_pathinq cpi;
2052 struct ccb_getdev cgd;
2055 u_int8_t command, retry_command;
2057 if (get_cpi(device, &cpi) != 0) {
2058 warnx("couldn't get CPI");
2062 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2063 if (cpi.protocol == PROTO_ATA) {
2064 if (get_cgd(device, &cgd) != 0) {
2065 warnx("couldn't get CGD");
2069 command = (cgd.protocol == PROTO_ATA) ?
2070 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2073 /* We don't know which for sure so try both */
2074 command = ATA_ATA_IDENTIFY;
2075 retry_command = ATA_ATAPI_IDENTIFY;
2078 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2080 warnx("can't calloc memory for identify\n");
2084 error = ata_do_28bit_cmd(device,
2086 /*retries*/retry_count,
2087 /*flags*/CAM_DIR_IN,
2088 /*protocol*/AP_PROTO_PIO_IN,
2089 /*tag_action*/MSG_SIMPLE_Q_TAG,
2093 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2094 /*data_ptr*/(u_int8_t *)ptr,
2095 /*dxfer_len*/sizeof(struct ata_params),
2096 /*timeout*/timeout ? timeout : 30 * 1000,
2100 if (retry_command == 0) {
2104 error = ata_do_28bit_cmd(device,
2106 /*retries*/retry_count,
2107 /*flags*/CAM_DIR_IN,
2108 /*protocol*/AP_PROTO_PIO_IN,
2109 /*tag_action*/MSG_SIMPLE_Q_TAG,
2110 /*command*/retry_command,
2113 /*sector_count*/(u_int8_t)
2114 sizeof(struct ata_params),
2115 /*data_ptr*/(u_int8_t *)ptr,
2116 /*dxfer_len*/sizeof(struct ata_params),
2117 /*timeout*/timeout ? timeout : 30 * 1000,
2127 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2128 ptr[i] = le16toh(ptr[i]);
2133 if (arglist & CAM_ARG_VERBOSE) {
2134 fprintf(stdout, "%s%d: Raw identify data:\n",
2135 device->device_name, device->dev_unit_num);
2136 dump_data(ptr, sizeof(struct ata_params));
2139 /* check for invalid (all zero) response */
2141 warnx("Invalid identify response detected");
2146 ident_buf = (struct ata_params *)ptr;
2147 if (strncmp(ident_buf->model, "FX", 2) &&
2148 strncmp(ident_buf->model, "NEC", 3) &&
2149 strncmp(ident_buf->model, "Pioneer", 7) &&
2150 strncmp(ident_buf->model, "SHARP", 5)) {
2151 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2152 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2153 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2154 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2156 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2157 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2158 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2159 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2160 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2161 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2162 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2163 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2164 sizeof(ident_buf->media_serial));
2166 *ident_bufp = ident_buf;
2173 ataidentify(struct cam_device *device, int retry_count, int timeout)
2176 struct ata_params *ident_buf;
2179 if ((ccb = cam_getccb(device)) == NULL) {
2180 warnx("couldn't allocate CCB");
2184 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2189 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2190 if (ata_read_native_max(device, retry_count, timeout, ccb,
2191 ident_buf, &hpasize) != 0) {
2199 printf("%s%d: ", device->device_name, device->dev_unit_num);
2200 ata_print_ident(ident_buf);
2201 camxferrate(device);
2202 atacapprint(ident_buf);
2203 atahpa_print(ident_buf, hpasize, 0);
2210 #endif /* MINIMALISTIC */
2213 #ifndef MINIMALISTIC
2215 ATA_SECURITY_ACTION_PRINT,
2216 ATA_SECURITY_ACTION_FREEZE,
2217 ATA_SECURITY_ACTION_UNLOCK,
2218 ATA_SECURITY_ACTION_DISABLE,
2219 ATA_SECURITY_ACTION_ERASE,
2220 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2221 ATA_SECURITY_ACTION_SET_PASSWORD
2225 atasecurity_print_time(u_int16_t tw)
2229 printf("unspecified");
2231 printf("> 508 min");
2233 printf("%i min", 2 * tw);
2237 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2241 return 2 * 3600 * 1000; /* default: two hours */
2242 else if (timeout > 255)
2243 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2245 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2250 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2254 bzero(&cmd, sizeof(cmd));
2255 cmd.command = command;
2256 printf("Issuing %s", ata_op_string(&cmd));
2259 char pass[sizeof(pwd->password)+1];
2261 /* pwd->password may not be null terminated */
2262 pass[sizeof(pwd->password)] = '\0';
2263 strncpy(pass, pwd->password, sizeof(pwd->password));
2264 printf(" password='%s', user='%s'",
2266 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2269 if (command == ATA_SECURITY_SET_PASSWORD) {
2270 printf(", mode='%s'",
2271 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2272 "maximum" : "high");
2280 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2281 int retry_count, u_int32_t timeout, int quiet)
2285 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2287 return ata_do_28bit_cmd(device,
2290 /*flags*/CAM_DIR_NONE,
2291 /*protocol*/AP_PROTO_NON_DATA,
2292 /*tag_action*/MSG_SIMPLE_Q_TAG,
2293 /*command*/ATA_SECURITY_FREEZE_LOCK,
2304 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2305 int retry_count, u_int32_t timeout,
2306 struct ata_security_password *pwd, int quiet)
2310 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2312 return ata_do_28bit_cmd(device,
2315 /*flags*/CAM_DIR_OUT,
2316 /*protocol*/AP_PROTO_PIO_OUT,
2317 /*tag_action*/MSG_SIMPLE_Q_TAG,
2318 /*command*/ATA_SECURITY_UNLOCK,
2322 /*data_ptr*/(u_int8_t *)pwd,
2323 /*dxfer_len*/sizeof(*pwd),
2329 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2330 int retry_count, u_int32_t timeout,
2331 struct ata_security_password *pwd, int quiet)
2335 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2336 return ata_do_28bit_cmd(device,
2339 /*flags*/CAM_DIR_OUT,
2340 /*protocol*/AP_PROTO_PIO_OUT,
2341 /*tag_action*/MSG_SIMPLE_Q_TAG,
2342 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2346 /*data_ptr*/(u_int8_t *)pwd,
2347 /*dxfer_len*/sizeof(*pwd),
2354 atasecurity_erase_confirm(struct cam_device *device,
2355 struct ata_params* ident_buf)
2358 printf("\nYou are about to ERASE ALL DATA from the following"
2359 " device:\n%s%d,%s%d: ", device->device_name,
2360 device->dev_unit_num, device->given_dev_name,
2361 device->given_unit_number);
2362 ata_print_ident(ident_buf);
2366 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2368 if (fgets(str, sizeof(str), stdin) != NULL) {
2369 if (strncasecmp(str, "yes", 3) == 0) {
2371 } else if (strncasecmp(str, "no", 2) == 0) {
2374 printf("Please answer \"yes\" or "
2385 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2386 int retry_count, u_int32_t timeout,
2387 u_int32_t erase_timeout,
2388 struct ata_security_password *pwd, int quiet)
2393 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2395 error = ata_do_28bit_cmd(device,
2398 /*flags*/CAM_DIR_NONE,
2399 /*protocol*/AP_PROTO_NON_DATA,
2400 /*tag_action*/MSG_SIMPLE_Q_TAG,
2401 /*command*/ATA_SECURITY_ERASE_PREPARE,
2414 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2416 error = ata_do_28bit_cmd(device,
2419 /*flags*/CAM_DIR_OUT,
2420 /*protocol*/AP_PROTO_PIO_OUT,
2421 /*tag_action*/MSG_SIMPLE_Q_TAG,
2422 /*command*/ATA_SECURITY_ERASE_UNIT,
2426 /*data_ptr*/(u_int8_t *)pwd,
2427 /*dxfer_len*/sizeof(*pwd),
2428 /*timeout*/erase_timeout,
2431 if (error == 0 && quiet == 0)
2432 printf("\nErase Complete\n");
2438 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2439 int retry_count, u_int32_t timeout,
2440 struct ata_security_password *pwd, int quiet)
2444 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2446 return ata_do_28bit_cmd(device,
2449 /*flags*/CAM_DIR_OUT,
2450 /*protocol*/AP_PROTO_PIO_OUT,
2451 /*tag_action*/MSG_SIMPLE_Q_TAG,
2452 /*command*/ATA_SECURITY_SET_PASSWORD,
2456 /*data_ptr*/(u_int8_t *)pwd,
2457 /*dxfer_len*/sizeof(*pwd),
2463 atasecurity_print(struct ata_params *parm)
2466 printf("\nSecurity Option Value\n");
2467 if (arglist & CAM_ARG_VERBOSE) {
2468 printf("status %04x\n",
2469 parm->security_status);
2471 printf("supported %s\n",
2472 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2473 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2475 printf("enabled %s\n",
2476 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2477 printf("drive locked %s\n",
2478 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2479 printf("security config frozen %s\n",
2480 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2481 printf("count expired %s\n",
2482 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2483 printf("security level %s\n",
2484 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2485 printf("enhanced erase supported %s\n",
2486 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2487 printf("erase time ");
2488 atasecurity_print_time(parm->erase_time);
2490 printf("enhanced erase time ");
2491 atasecurity_print_time(parm->enhanced_erase_time);
2493 printf("master password rev %04x%s\n",
2494 parm->master_passwd_revision,
2495 parm->master_passwd_revision == 0x0000 ||
2496 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2500 * Validates and copies the password in optarg to the passed buffer.
2501 * If the password in optarg is the same length as the buffer then
2502 * the data will still be copied but no null termination will occur.
2505 ata_getpwd(u_int8_t *passwd, int max, char opt)
2509 len = strlen(optarg);
2511 warnx("-%c password is too long", opt);
2513 } else if (len == 0) {
2514 warnx("-%c password is missing", opt);
2516 } else if (optarg[0] == '-'){
2517 warnx("-%c password starts with '-' (generic arg?)", opt);
2519 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2520 warnx("-%c password conflicts with existing password from -%c",
2525 /* Callers pass in a buffer which does NOT need to be terminated */
2526 strncpy(passwd, optarg, max);
2533 ATA_HPA_ACTION_PRINT,
2534 ATA_HPA_ACTION_SET_MAX,
2535 ATA_HPA_ACTION_SET_PWD,
2536 ATA_HPA_ACTION_LOCK,
2537 ATA_HPA_ACTION_UNLOCK,
2538 ATA_HPA_ACTION_FREEZE_LOCK
2542 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2543 u_int64_t maxsize, int persist)
2545 printf("\nYou are about to configure HPA to limit the user accessible\n"
2546 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2547 persist ? "persistently" : "temporarily",
2548 device->device_name, device->dev_unit_num,
2549 device->given_dev_name, device->given_unit_number);
2550 ata_print_ident(ident_buf);
2554 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2556 if (NULL != fgets(str, sizeof(str), stdin)) {
2557 if (0 == strncasecmp(str, "yes", 3)) {
2559 } else if (0 == strncasecmp(str, "no", 2)) {
2562 printf("Please answer \"yes\" or "
2573 atahpa(struct cam_device *device, int retry_count, int timeout,
2574 int argc, char **argv, char *combinedopt)
2577 struct ata_params *ident_buf;
2578 struct ccb_getdev cgd;
2579 struct ata_set_max_pwd pwd;
2580 int error, confirm, quiet, c, action, actions, setpwd, persist;
2581 int security, is48bit, pwdsize;
2582 u_int64_t hpasize, maxsize;
2592 memset(&pwd, 0, sizeof(pwd));
2594 /* default action is to print hpa information */
2595 action = ATA_HPA_ACTION_PRINT;
2596 pwdsize = sizeof(pwd.password);
2598 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2601 action = ATA_HPA_ACTION_SET_MAX;
2602 maxsize = strtoumax(optarg, NULL, 0);
2607 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2609 action = ATA_HPA_ACTION_SET_PWD;
2615 action = ATA_HPA_ACTION_LOCK;
2621 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2623 action = ATA_HPA_ACTION_UNLOCK;
2629 action = ATA_HPA_ACTION_FREEZE_LOCK;
2649 warnx("too many hpa actions specified");
2653 if (get_cgd(device, &cgd) != 0) {
2654 warnx("couldn't get CGD");
2658 ccb = cam_getccb(device);
2660 warnx("couldn't allocate CCB");
2664 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2671 printf("%s%d: ", device->device_name, device->dev_unit_num);
2672 ata_print_ident(ident_buf);
2673 camxferrate(device);
2676 if (action == ATA_HPA_ACTION_PRINT) {
2677 error = ata_read_native_max(device, retry_count, timeout, ccb,
2678 ident_buf, &hpasize);
2680 atahpa_print(ident_buf, hpasize, 1);
2687 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2688 warnx("HPA is not supported by this device");
2694 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2695 warnx("HPA Security is not supported by this device");
2701 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2704 * The ATA spec requires:
2705 * 1. Read native max addr is called directly before set max addr
2706 * 2. Read native max addr is NOT called before any other set max call
2709 case ATA_HPA_ACTION_SET_MAX:
2711 atahpa_set_confirm(device, ident_buf, maxsize,
2718 error = ata_read_native_max(device, retry_count, timeout,
2719 ccb, ident_buf, &hpasize);
2721 error = atahpa_set_max(device, retry_count, timeout,
2722 ccb, is48bit, maxsize, persist);
2724 /* redo identify to get new lba values */
2725 error = ata_do_identify(device, retry_count,
2728 atahpa_print(ident_buf, hpasize, 1);
2733 case ATA_HPA_ACTION_SET_PWD:
2734 error = atahpa_password(device, retry_count, timeout,
2735 ccb, is48bit, &pwd);
2737 printf("HPA password has been set\n");
2740 case ATA_HPA_ACTION_LOCK:
2741 error = atahpa_lock(device, retry_count, timeout,
2744 printf("HPA has been locked\n");
2747 case ATA_HPA_ACTION_UNLOCK:
2748 error = atahpa_unlock(device, retry_count, timeout,
2749 ccb, is48bit, &pwd);
2751 printf("HPA has been unlocked\n");
2754 case ATA_HPA_ACTION_FREEZE_LOCK:
2755 error = atahpa_freeze_lock(device, retry_count, timeout,
2758 printf("HPA has been frozen\n");
2762 errx(1, "Option currently not supported");
2772 atasecurity(struct cam_device *device, int retry_count, int timeout,
2773 int argc, char **argv, char *combinedopt)
2776 struct ata_params *ident_buf;
2777 int error, confirm, quiet, c, action, actions, setpwd;
2778 int security_enabled, erase_timeout, pwdsize;
2779 struct ata_security_password pwd;
2787 memset(&pwd, 0, sizeof(pwd));
2789 /* default action is to print security information */
2790 action = ATA_SECURITY_ACTION_PRINT;
2792 /* user is master by default as its safer that way */
2793 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2794 pwdsize = sizeof(pwd.password);
2796 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2799 action = ATA_SECURITY_ACTION_FREEZE;
2804 if (strcasecmp(optarg, "user") == 0) {
2805 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2806 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2807 } else if (strcasecmp(optarg, "master") == 0) {
2808 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2809 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2811 warnx("-U argument '%s' is invalid (must be "
2812 "'user' or 'master')", optarg);
2818 if (strcasecmp(optarg, "high") == 0) {
2819 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2820 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2821 } else if (strcasecmp(optarg, "maximum") == 0) {
2822 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2823 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2825 warnx("-l argument '%s' is unknown (must be "
2826 "'high' or 'maximum')", optarg);
2832 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2834 action = ATA_SECURITY_ACTION_UNLOCK;
2839 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2841 action = ATA_SECURITY_ACTION_DISABLE;
2846 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2848 action = ATA_SECURITY_ACTION_ERASE;
2853 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2855 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2856 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2861 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2864 if (action == ATA_SECURITY_ACTION_PRINT)
2865 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2867 * Don't increment action as this can be combined
2868 * with other actions.
2881 erase_timeout = atoi(optarg) * 1000;
2887 warnx("too many security actions specified");
2891 if ((ccb = cam_getccb(device)) == NULL) {
2892 warnx("couldn't allocate CCB");
2896 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2903 printf("%s%d: ", device->device_name, device->dev_unit_num);
2904 ata_print_ident(ident_buf);
2905 camxferrate(device);
2908 if (action == ATA_SECURITY_ACTION_PRINT) {
2909 atasecurity_print(ident_buf);
2915 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2916 warnx("Security not supported");
2922 /* default timeout 15 seconds the same as linux hdparm */
2923 timeout = timeout ? timeout : 15 * 1000;
2925 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2927 /* first set the password if requested */
2929 /* confirm we can erase before setting the password if erasing */
2931 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2932 action == ATA_SECURITY_ACTION_ERASE) &&
2933 atasecurity_erase_confirm(device, ident_buf) == 0) {
2939 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2940 pwd.revision = ident_buf->master_passwd_revision;
2941 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2942 --pwd.revision == 0) {
2943 pwd.revision = 0xfffe;
2946 error = atasecurity_set_password(device, ccb, retry_count,
2947 timeout, &pwd, quiet);
2953 security_enabled = 1;
2957 case ATA_SECURITY_ACTION_FREEZE:
2958 error = atasecurity_freeze(device, ccb, retry_count,
2962 case ATA_SECURITY_ACTION_UNLOCK:
2963 if (security_enabled) {
2964 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2965 error = atasecurity_unlock(device, ccb,
2966 retry_count, timeout, &pwd, quiet);
2968 warnx("Can't unlock, drive is not locked");
2972 warnx("Can't unlock, security is disabled");
2977 case ATA_SECURITY_ACTION_DISABLE:
2978 if (security_enabled) {
2979 /* First unlock the drive if its locked */
2980 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2981 error = atasecurity_unlock(device, ccb,
2989 error = atasecurity_disable(device,
2997 warnx("Can't disable security (already disabled)");
3002 case ATA_SECURITY_ACTION_ERASE:
3003 if (security_enabled) {
3004 if (erase_timeout == 0) {
3005 erase_timeout = atasecurity_erase_timeout_msecs(
3006 ident_buf->erase_time);
3009 error = atasecurity_erase(device, ccb, retry_count,
3010 timeout, erase_timeout, &pwd,
3013 warnx("Can't secure erase (security is disabled)");
3018 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3019 if (security_enabled) {
3020 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3021 if (erase_timeout == 0) {
3023 atasecurity_erase_timeout_msecs(
3024 ident_buf->enhanced_erase_time);
3027 error = atasecurity_erase(device, ccb,
3028 retry_count, timeout,
3029 erase_timeout, &pwd,
3032 warnx("Enhanced erase is not supported");
3036 warnx("Can't secure erase (enhanced), "
3037 "(security is disabled)");
3048 #endif /* MINIMALISTIC */
3051 * Parse out a bus, or a bus, target and lun in the following
3057 * Returns the number of parsed components, or 0.
3060 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3061 cam_argmask *arglst)
3066 while (isspace(*tstr) && (*tstr != '\0'))
3069 tmpstr = (char *)strtok(tstr, ":");
3070 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3071 *bus = strtol(tmpstr, NULL, 0);
3072 *arglst |= CAM_ARG_BUS;
3074 tmpstr = (char *)strtok(NULL, ":");
3075 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3076 *target = strtol(tmpstr, NULL, 0);
3077 *arglst |= CAM_ARG_TARGET;
3079 tmpstr = (char *)strtok(NULL, ":");
3080 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3081 *lun = strtol(tmpstr, NULL, 0);
3082 *arglst |= CAM_ARG_LUN;
3092 dorescan_or_reset(int argc, char **argv, int rescan)
3094 static const char must[] =
3095 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3097 path_id_t bus = CAM_BUS_WILDCARD;
3098 target_id_t target = CAM_TARGET_WILDCARD;
3099 lun_id_t lun = CAM_LUN_WILDCARD;
3103 warnx(must, rescan? "rescan" : "reset");
3107 tstr = argv[optind];
3108 while (isspace(*tstr) && (*tstr != '\0'))
3110 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3111 arglist |= CAM_ARG_BUS;
3113 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3114 if (rv != 1 && rv != 3) {
3115 warnx(must, rescan? "rescan" : "reset");
3120 if ((arglist & CAM_ARG_BUS)
3121 && (arglist & CAM_ARG_TARGET)
3122 && (arglist & CAM_ARG_LUN))
3123 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3125 error = rescan_or_reset_bus(bus, rescan);
3131 rescan_or_reset_bus(path_id_t bus, int rescan)
3133 union ccb ccb, matchccb;
3139 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3140 warnx("error opening transport layer device %s", XPT_DEVICE);
3141 warn("%s", XPT_DEVICE);
3145 if (bus != CAM_BUS_WILDCARD) {
3146 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3147 ccb.ccb_h.path_id = bus;
3148 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3149 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3150 ccb.crcn.flags = CAM_FLAG_NONE;
3152 /* run this at a low priority */
3153 ccb.ccb_h.pinfo.priority = 5;
3155 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3156 warn("CAMIOCOMMAND ioctl failed");
3161 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3162 fprintf(stdout, "%s of bus %d was successful\n",
3163 rescan ? "Re-scan" : "Reset", bus);
3165 fprintf(stdout, "%s of bus %d returned error %#x\n",
3166 rescan ? "Re-scan" : "Reset", bus,
3167 ccb.ccb_h.status & CAM_STATUS_MASK);
3178 * The right way to handle this is to modify the xpt so that it can
3179 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3180 * that isn't implemented, so instead we enumerate the busses and
3181 * send the rescan or reset to those busses in the case where the
3182 * given bus is -1 (wildcard). We don't send a rescan or reset
3183 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3184 * no-op, sending a rescan to the xpt bus would result in a status of
3187 bzero(&(&matchccb.ccb_h)[1],
3188 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3189 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3190 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3191 bufsize = sizeof(struct dev_match_result) * 20;
3192 matchccb.cdm.match_buf_len = bufsize;
3193 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3194 if (matchccb.cdm.matches == NULL) {
3195 warnx("can't malloc memory for matches");
3199 matchccb.cdm.num_matches = 0;
3201 matchccb.cdm.num_patterns = 1;
3202 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3204 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3205 matchccb.cdm.pattern_buf_len);
3206 if (matchccb.cdm.patterns == NULL) {
3207 warnx("can't malloc memory for patterns");
3211 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3212 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3217 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3218 warn("CAMIOCOMMAND ioctl failed");
3223 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3224 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3225 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3226 warnx("got CAM error %#x, CDM error %d\n",
3227 matchccb.ccb_h.status, matchccb.cdm.status);
3232 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3233 struct bus_match_result *bus_result;
3235 /* This shouldn't happen. */
3236 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3239 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3242 * We don't want to rescan or reset the xpt bus.
3245 if (bus_result->path_id == CAM_XPT_PATH_ID)
3248 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3250 ccb.ccb_h.path_id = bus_result->path_id;
3251 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3252 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3253 ccb.crcn.flags = CAM_FLAG_NONE;
3255 /* run this at a low priority */
3256 ccb.ccb_h.pinfo.priority = 5;
3258 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3259 warn("CAMIOCOMMAND ioctl failed");
3264 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3265 fprintf(stdout, "%s of bus %d was successful\n",
3266 rescan? "Re-scan" : "Reset",
3267 bus_result->path_id);
3270 * Don't bail out just yet, maybe the other
3271 * rescan or reset commands will complete
3274 fprintf(stderr, "%s of bus %d returned error "
3275 "%#x\n", rescan? "Re-scan" : "Reset",
3276 bus_result->path_id,
3277 ccb.ccb_h.status & CAM_STATUS_MASK);
3281 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3282 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3289 if (matchccb.cdm.patterns != NULL)
3290 free(matchccb.cdm.patterns);
3291 if (matchccb.cdm.matches != NULL)
3292 free(matchccb.cdm.matches);
3298 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3301 struct cam_device *device;
3306 if (bus == CAM_BUS_WILDCARD) {
3307 warnx("invalid bus number %d", bus);
3311 if (target == CAM_TARGET_WILDCARD) {
3312 warnx("invalid target number %d", target);
3316 if (lun == CAM_LUN_WILDCARD) {
3317 warnx("invalid lun number %jx", (uintmax_t)lun);
3323 bzero(&ccb, sizeof(union ccb));
3326 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3327 warnx("error opening transport layer device %s\n",
3329 warn("%s", XPT_DEVICE);
3333 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3334 if (device == NULL) {
3335 warnx("%s", cam_errbuf);
3340 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3341 ccb.ccb_h.path_id = bus;
3342 ccb.ccb_h.target_id = target;
3343 ccb.ccb_h.target_lun = lun;
3344 ccb.ccb_h.timeout = 5000;
3345 ccb.crcn.flags = CAM_FLAG_NONE;
3347 /* run this at a low priority */
3348 ccb.ccb_h.pinfo.priority = 5;
3351 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3352 warn("CAMIOCOMMAND ioctl failed");
3357 if (cam_send_ccb(device, &ccb) < 0) {
3358 warn("error sending XPT_RESET_DEV CCB");
3359 cam_close_device(device);
3367 cam_close_device(device);
3370 * An error code of CAM_BDR_SENT is normal for a BDR request.
3372 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3374 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3375 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3376 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3379 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3380 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3381 ccb.ccb_h.status & CAM_STATUS_MASK);
3386 #ifndef MINIMALISTIC
3388 static struct scsi_nv defect_list_type_map[] = {
3389 { "block", SRDD10_BLOCK_FORMAT },
3390 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3391 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3392 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3393 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3394 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3398 readdefects(struct cam_device *device, int argc, char **argv,
3399 char *combinedopt, int retry_count, int timeout)
3401 union ccb *ccb = NULL;
3402 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3403 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3404 size_t hdr_size = 0, entry_size = 0;
3407 u_int8_t *defect_list = NULL;
3408 u_int8_t list_format = 0;
3409 int list_type_set = 0;
3410 u_int32_t dlist_length = 0;
3411 u_int32_t returned_length = 0, valid_len = 0;
3412 u_int32_t num_returned = 0, num_valid = 0;
3413 u_int32_t max_possible_size = 0, hdr_max = 0;
3414 u_int32_t starting_offset = 0;
3415 u_int8_t returned_format, returned_type;
3417 int summary = 0, quiet = 0;
3419 int lists_specified = 0;
3420 int get_length = 1, first_pass = 1;
3423 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3427 scsi_nv_status status;
3430 status = scsi_get_nv(defect_list_type_map,
3431 sizeof(defect_list_type_map) /
3432 sizeof(defect_list_type_map[0]), optarg,
3433 &entry_num, SCSI_NV_FLAG_IG_CASE);
3435 if (status == SCSI_NV_FOUND) {
3436 list_format = defect_list_type_map[
3440 warnx("%s: %s %s option %s", __func__,
3441 (status == SCSI_NV_AMBIGUOUS) ?
3442 "ambiguous" : "invalid", "defect list type",
3445 goto defect_bailout;
3450 arglist |= CAM_ARG_GLIST;
3453 arglist |= CAM_ARG_PLIST;
3464 starting_offset = strtoul(optarg, &endptr, 0);
3465 if (*endptr != '\0') {
3467 warnx("invalid starting offset %s", optarg);
3468 goto defect_bailout;
3480 if (list_type_set == 0) {
3482 warnx("no defect list format specified");
3483 goto defect_bailout;
3486 if (arglist & CAM_ARG_PLIST) {
3487 list_format |= SRDD10_PLIST;
3491 if (arglist & CAM_ARG_GLIST) {
3492 list_format |= SRDD10_GLIST;
3497 * This implies a summary, and was the previous behavior.
3499 if (lists_specified == 0)
3502 ccb = cam_getccb(device);
3507 * We start off asking for just the header to determine how much
3508 * defect data is available. Some Hitachi drives return an error
3509 * if you ask for more data than the drive has. Once we know the
3510 * length, we retry the command with the returned length.
3512 if (use_12byte == 0)
3513 dlist_length = sizeof(*hdr10);
3515 dlist_length = sizeof(*hdr12);
3518 if (defect_list != NULL) {
3522 defect_list = malloc(dlist_length);
3523 if (defect_list == NULL) {
3524 warnx("can't malloc memory for defect list");
3526 goto defect_bailout;
3530 bzero(defect_list, dlist_length);
3533 * cam_getccb() zeros the CCB header only. So we need to zero the
3534 * payload portion of the ccb.
3536 bzero(&(&ccb->ccb_h)[1],
3537 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3539 scsi_read_defects(&ccb->csio,
3540 /*retries*/ retry_count,
3542 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3543 /*list_format*/ list_format,
3544 /*addr_desc_index*/ starting_offset,
3545 /*data_ptr*/ defect_list,
3546 /*dxfer_len*/ dlist_length,
3547 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3548 /*sense_len*/ SSD_FULL_SIZE,
3549 /*timeout*/ timeout ? timeout : 5000);
3551 /* Disable freezing the device queue */
3552 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3554 if (cam_send_ccb(device, ccb) < 0) {
3555 perror("error reading defect list");
3557 if (arglist & CAM_ARG_VERBOSE) {
3558 cam_error_print(device, ccb, CAM_ESF_ALL,
3559 CAM_EPF_ALL, stderr);
3563 goto defect_bailout;
3566 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3568 if (use_12byte == 0) {
3569 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3570 hdr_size = sizeof(*hdr10);
3571 hdr_max = SRDDH10_MAX_LENGTH;
3573 if (valid_len >= hdr_size) {
3574 returned_length = scsi_2btoul(hdr10->length);
3575 returned_format = hdr10->format;
3577 returned_length = 0;
3578 returned_format = 0;
3581 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3582 hdr_size = sizeof(*hdr12);
3583 hdr_max = SRDDH12_MAX_LENGTH;
3585 if (valid_len >= hdr_size) {
3586 returned_length = scsi_4btoul(hdr12->length);
3587 returned_format = hdr12->format;
3589 returned_length = 0;
3590 returned_format = 0;
3594 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3595 switch (returned_type) {
3596 case SRDD10_BLOCK_FORMAT:
3597 entry_size = sizeof(struct scsi_defect_desc_block);
3599 case SRDD10_LONG_BLOCK_FORMAT:
3600 entry_size = sizeof(struct scsi_defect_desc_long_block);
3602 case SRDD10_EXT_PHYS_FORMAT:
3603 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3604 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3606 case SRDD10_EXT_BFI_FORMAT:
3607 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3608 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3611 warnx("Unknown defect format 0x%x\n", returned_type);
3613 goto defect_bailout;
3617 max_possible_size = (hdr_max / entry_size) * entry_size;
3618 num_returned = returned_length / entry_size;
3619 num_valid = min(returned_length, valid_len - hdr_size);
3620 num_valid /= entry_size;
3622 if (get_length != 0) {
3625 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3626 CAM_SCSI_STATUS_ERROR) {
3627 struct scsi_sense_data *sense;
3628 int error_code, sense_key, asc, ascq;
3630 sense = &ccb->csio.sense_data;
3631 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3632 ccb->csio.sense_resid, &error_code, &sense_key,
3633 &asc, &ascq, /*show_errors*/ 1);
3636 * If the drive is reporting that it just doesn't
3637 * support the defect list format, go ahead and use
3638 * the length it reported. Otherwise, the length
3639 * may not be valid, so use the maximum.
3641 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3642 && (asc == 0x1c) && (ascq == 0x00)
3643 && (returned_length > 0)) {
3644 if ((use_12byte == 0)
3645 && (returned_length >= max_possible_size)) {
3650 dlist_length = returned_length + hdr_size;
3651 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3652 && (asc == 0x1f) && (ascq == 0x00)
3653 && (returned_length > 0)) {
3654 /* Partial defect list transfer */
3656 * Hitachi drives return this error
3657 * along with a partial defect list if they
3658 * have more defects than the 10 byte
3659 * command can support. Retry with the 12
3662 if (use_12byte == 0) {
3667 dlist_length = returned_length + hdr_size;
3668 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3669 && (asc == 0x24) && (ascq == 0x00)) {
3670 /* Invalid field in CDB */
3672 * SBC-3 says that if the drive has more
3673 * defects than can be reported with the
3674 * 10 byte command, it should return this
3675 * error and no data. Retry with the 12
3678 if (use_12byte == 0) {
3683 dlist_length = returned_length + hdr_size;
3686 * If we got a SCSI error and no valid length,
3687 * just use the 10 byte maximum. The 12
3688 * byte maximum is too large.
3690 if (returned_length == 0)
3691 dlist_length = SRDD10_MAX_LENGTH;
3693 if ((use_12byte == 0)
3694 && (returned_length >=
3695 max_possible_size)) {
3700 dlist_length = returned_length +
3704 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3707 warnx("Error reading defect header");
3708 if (arglist & CAM_ARG_VERBOSE)
3709 cam_error_print(device, ccb, CAM_ESF_ALL,
3710 CAM_EPF_ALL, stderr);
3711 goto defect_bailout;
3713 if ((use_12byte == 0)
3714 && (returned_length >= max_possible_size)) {
3719 dlist_length = returned_length + hdr_size;
3722 fprintf(stdout, "%u", num_returned);
3724 fprintf(stdout, " defect%s",
3725 (num_returned != 1) ? "s" : "");
3727 fprintf(stdout, "\n");
3729 goto defect_bailout;
3733 * We always limit the list length to the 10-byte maximum
3734 * length (0xffff). The reason is that some controllers
3735 * can't handle larger I/Os, and we can transfer the entire
3736 * 10 byte list in one shot. For drives that support the 12
3737 * byte read defects command, we'll step through the list
3738 * by specifying a starting offset. For drives that don't
3739 * support the 12 byte command's starting offset, we'll
3740 * just display the first 64K.
3742 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3748 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3749 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3750 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3751 struct scsi_sense_data *sense;
3752 int error_code, sense_key, asc, ascq;
3754 sense = &ccb->csio.sense_data;
3755 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3756 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3757 &ascq, /*show_errors*/ 1);
3760 * According to the SCSI spec, if the disk doesn't support
3761 * the requested format, it will generally return a sense
3762 * key of RECOVERED ERROR, and an additional sense code
3763 * of "DEFECT LIST NOT FOUND". HGST drives also return
3764 * Primary/Grown defect list not found errors. So just
3765 * check for an ASC of 0x1c.
3767 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3769 const char *format_str;
3771 format_str = scsi_nv_to_str(defect_list_type_map,
3772 sizeof(defect_list_type_map) /
3773 sizeof(defect_list_type_map[0]),
3774 list_format & SRDD10_DLIST_FORMAT_MASK);
3775 warnx("requested defect format %s not available",
3776 format_str ? format_str : "unknown");
3778 format_str = scsi_nv_to_str(defect_list_type_map,
3779 sizeof(defect_list_type_map) /
3780 sizeof(defect_list_type_map[0]), returned_type);
3781 if (format_str != NULL) {
3782 warnx("Device returned %s format",
3786 warnx("Device returned unknown defect"
3787 " data format %#x", returned_type);
3788 goto defect_bailout;
3792 warnx("Error returned from read defect data command");
3793 if (arglist & CAM_ARG_VERBOSE)
3794 cam_error_print(device, ccb, CAM_ESF_ALL,
3795 CAM_EPF_ALL, stderr);
3796 goto defect_bailout;
3798 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3800 warnx("Error returned from read defect data command");
3801 if (arglist & CAM_ARG_VERBOSE)
3802 cam_error_print(device, ccb, CAM_ESF_ALL,
3803 CAM_EPF_ALL, stderr);
3804 goto defect_bailout;
3807 if (first_pass != 0) {
3808 fprintf(stderr, "Got %d defect", num_returned);
3810 if ((lists_specified == 0) || (num_returned == 0)) {
3811 fprintf(stderr, "s.\n");
3812 goto defect_bailout;
3813 } else if (num_returned == 1)
3814 fprintf(stderr, ":\n");
3816 fprintf(stderr, "s:\n");
3822 * XXX KDM I should probably clean up the printout format for the
3825 switch (returned_type) {
3826 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3827 case SRDD10_EXT_PHYS_FORMAT:
3829 struct scsi_defect_desc_phys_sector *dlist;
3831 dlist = (struct scsi_defect_desc_phys_sector *)
3832 (defect_list + hdr_size);
3834 for (i = 0; i < num_valid; i++) {
3837 sector = scsi_4btoul(dlist[i].sector);
3838 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3839 mads = (sector & SDD_EXT_PHYS_MADS) ?
3841 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3843 if (hex_format == 0)
3844 fprintf(stdout, "%d:%d:%d%s",
3845 scsi_3btoul(dlist[i].cylinder),
3847 scsi_4btoul(dlist[i].sector),
3848 mads ? " - " : "\n");
3850 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3851 scsi_3btoul(dlist[i].cylinder),
3853 scsi_4btoul(dlist[i].sector),
3854 mads ? " - " : "\n");
3857 if (num_valid < num_returned) {
3858 starting_offset += num_valid;
3863 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3864 case SRDD10_EXT_BFI_FORMAT:
3866 struct scsi_defect_desc_bytes_from_index *dlist;
3868 dlist = (struct scsi_defect_desc_bytes_from_index *)
3869 (defect_list + hdr_size);
3871 for (i = 0; i < num_valid; i++) {
3874 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3875 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3876 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3877 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3879 if (hex_format == 0)
3880 fprintf(stdout, "%d:%d:%d%s",
3881 scsi_3btoul(dlist[i].cylinder),
3883 scsi_4btoul(dlist[i].bytes_from_index),
3884 mads ? " - " : "\n");
3886 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3887 scsi_3btoul(dlist[i].cylinder),
3889 scsi_4btoul(dlist[i].bytes_from_index),
3890 mads ? " - " : "\n");
3894 if (num_valid < num_returned) {
3895 starting_offset += num_valid;
3900 case SRDDH10_BLOCK_FORMAT:
3902 struct scsi_defect_desc_block *dlist;
3904 dlist = (struct scsi_defect_desc_block *)
3905 (defect_list + hdr_size);
3907 for (i = 0; i < num_valid; i++) {
3908 if (hex_format == 0)
3909 fprintf(stdout, "%u\n",
3910 scsi_4btoul(dlist[i].address));
3912 fprintf(stdout, "0x%x\n",
3913 scsi_4btoul(dlist[i].address));
3916 if (num_valid < num_returned) {
3917 starting_offset += num_valid;
3923 case SRDD10_LONG_BLOCK_FORMAT:
3925 struct scsi_defect_desc_long_block *dlist;
3927 dlist = (struct scsi_defect_desc_long_block *)
3928 (defect_list + hdr_size);
3930 for (i = 0; i < num_valid; i++) {
3931 if (hex_format == 0)
3932 fprintf(stdout, "%ju\n",
3933 (uintmax_t)scsi_8btou64(
3936 fprintf(stdout, "0x%jx\n",
3937 (uintmax_t)scsi_8btou64(
3941 if (num_valid < num_returned) {
3942 starting_offset += num_valid;
3948 fprintf(stderr, "Unknown defect format 0x%x\n",
3955 if (defect_list != NULL)
3963 #endif /* MINIMALISTIC */
3967 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3971 ccb = cam_getccb(device);
3977 #ifndef MINIMALISTIC
3979 mode_sense(struct cam_device *device, int mode_page, int page_control,
3980 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3985 ccb = cam_getccb(device);
3988 errx(1, "mode_sense: couldn't allocate CCB");
3990 bzero(&(&ccb->ccb_h)[1],
3991 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3993 scsi_mode_sense(&ccb->csio,
3994 /* retries */ retry_count,
3996 /* tag_action */ MSG_SIMPLE_Q_TAG,
3998 /* page_code */ page_control << 6,
3999 /* page */ mode_page,
4000 /* param_buf */ data,
4001 /* param_len */ datalen,
4002 /* sense_len */ SSD_FULL_SIZE,
4003 /* timeout */ timeout ? timeout : 5000);
4005 if (arglist & CAM_ARG_ERR_RECOVER)
4006 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4008 /* Disable freezing the device queue */
4009 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4011 if (((retval = cam_send_ccb(device, ccb)) < 0)
4012 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4013 if (arglist & CAM_ARG_VERBOSE) {
4014 cam_error_print(device, ccb, CAM_ESF_ALL,
4015 CAM_EPF_ALL, stderr);
4018 cam_close_device(device);
4020 err(1, "error sending mode sense command");
4022 errx(1, "error sending mode sense command");
4029 mode_select(struct cam_device *device, int save_pages, int retry_count,
4030 int timeout, u_int8_t *data, int datalen)
4035 ccb = cam_getccb(device);
4038 errx(1, "mode_select: couldn't allocate CCB");
4040 bzero(&(&ccb->ccb_h)[1],
4041 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4043 scsi_mode_select(&ccb->csio,
4044 /* retries */ retry_count,
4046 /* tag_action */ MSG_SIMPLE_Q_TAG,
4047 /* scsi_page_fmt */ 1,
4048 /* save_pages */ save_pages,
4049 /* param_buf */ data,
4050 /* param_len */ datalen,
4051 /* sense_len */ SSD_FULL_SIZE,
4052 /* timeout */ timeout ? timeout : 5000);
4054 if (arglist & CAM_ARG_ERR_RECOVER)
4055 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4057 /* Disable freezing the device queue */
4058 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4060 if (((retval = cam_send_ccb(device, ccb)) < 0)
4061 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4062 if (arglist & CAM_ARG_VERBOSE) {
4063 cam_error_print(device, ccb, CAM_ESF_ALL,
4064 CAM_EPF_ALL, stderr);
4067 cam_close_device(device);
4070 err(1, "error sending mode select command");
4072 errx(1, "error sending mode select command");
4080 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4081 int retry_count, int timeout)
4083 int c, mode_page = -1, page_control = 0;
4084 int binary = 0, list = 0;
4086 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4092 arglist |= CAM_ARG_DBD;
4095 arglist |= CAM_ARG_MODE_EDIT;
4101 mode_page = strtol(optarg, NULL, 0);
4103 errx(1, "invalid mode page %d", mode_page);
4106 page_control = strtol(optarg, NULL, 0);
4107 if ((page_control < 0) || (page_control > 3))
4108 errx(1, "invalid page control field %d",
4110 arglist |= CAM_ARG_PAGE_CNTL;
4117 if (mode_page == -1 && list == 0)
4118 errx(1, "you must specify a mode page!");
4121 mode_list(device, page_control, arglist & CAM_ARG_DBD,
4122 retry_count, timeout);
4124 mode_edit(device, mode_page, page_control,
4125 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
4126 retry_count, timeout);
4131 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4132 int retry_count, int timeout)
4135 u_int32_t flags = CAM_DIR_NONE;
4136 u_int8_t *data_ptr = NULL;
4138 u_int8_t atacmd[12];
4139 struct get_hook hook;
4140 int c, data_bytes = 0;
4146 char *datastr = NULL, *tstr, *resstr = NULL;
4148 int fd_data = 0, fd_res = 0;
4151 ccb = cam_getccb(device);
4154 warnx("scsicmd: error allocating ccb");
4158 bzero(&(&ccb->ccb_h)[1],
4159 sizeof(union ccb) - sizeof(struct ccb_hdr));
4161 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4165 while (isspace(*tstr) && (*tstr != '\0'))
4167 hook.argc = argc - optind;
4168 hook.argv = argv + optind;
4170 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4173 * Increment optind by the number of arguments the
4174 * encoding routine processed. After each call to
4175 * getopt(3), optind points to the argument that
4176 * getopt should process _next_. In this case,
4177 * that means it points to the first command string
4178 * argument, if there is one. Once we increment
4179 * this, it should point to either the next command
4180 * line argument, or it should be past the end of
4187 while (isspace(*tstr) && (*tstr != '\0'))
4189 hook.argc = argc - optind;
4190 hook.argv = argv + optind;
4192 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4195 * Increment optind by the number of arguments the
4196 * encoding routine processed. After each call to
4197 * getopt(3), optind points to the argument that
4198 * getopt should process _next_. In this case,
4199 * that means it points to the first command string
4200 * argument, if there is one. Once we increment
4201 * this, it should point to either the next command
4202 * line argument, or it should be past the end of
4214 if (arglist & CAM_ARG_CMD_OUT) {
4215 warnx("command must either be "
4216 "read or write, not both");
4218 goto scsicmd_bailout;
4220 arglist |= CAM_ARG_CMD_IN;
4222 data_bytes = strtol(optarg, NULL, 0);
4223 if (data_bytes <= 0) {
4224 warnx("invalid number of input bytes %d",
4227 goto scsicmd_bailout;
4229 hook.argc = argc - optind;
4230 hook.argv = argv + optind;
4233 datastr = cget(&hook, NULL);
4235 * If the user supplied "-" instead of a format, he
4236 * wants the data to be written to stdout.
4238 if ((datastr != NULL)
4239 && (datastr[0] == '-'))
4242 data_ptr = (u_int8_t *)malloc(data_bytes);
4243 if (data_ptr == NULL) {
4244 warnx("can't malloc memory for data_ptr");
4246 goto scsicmd_bailout;
4250 if (arglist & CAM_ARG_CMD_IN) {
4251 warnx("command must either be "
4252 "read or write, not both");
4254 goto scsicmd_bailout;
4256 arglist |= CAM_ARG_CMD_OUT;
4257 flags = CAM_DIR_OUT;
4258 data_bytes = strtol(optarg, NULL, 0);
4259 if (data_bytes <= 0) {
4260 warnx("invalid number of output bytes %d",
4263 goto scsicmd_bailout;
4265 hook.argc = argc - optind;
4266 hook.argv = argv + optind;
4268 datastr = cget(&hook, NULL);
4269 data_ptr = (u_int8_t *)malloc(data_bytes);
4270 if (data_ptr == NULL) {
4271 warnx("can't malloc memory for data_ptr");
4273 goto scsicmd_bailout;
4275 bzero(data_ptr, data_bytes);
4277 * If the user supplied "-" instead of a format, he
4278 * wants the data to be read from stdin.
4280 if ((datastr != NULL)
4281 && (datastr[0] == '-'))
4284 buff_encode_visit(data_ptr, data_bytes, datastr,
4290 hook.argc = argc - optind;
4291 hook.argv = argv + optind;
4293 resstr = cget(&hook, NULL);
4294 if ((resstr != NULL) && (resstr[0] == '-'))
4304 * If fd_data is set, and we're writing to the device, we need to
4305 * read the data the user wants written from stdin.
4307 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4309 int amt_to_read = data_bytes;
4310 u_int8_t *buf_ptr = data_ptr;
4312 for (amt_read = 0; amt_to_read > 0;
4313 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4314 if (amt_read == -1) {
4315 warn("error reading data from stdin");
4317 goto scsicmd_bailout;
4319 amt_to_read -= amt_read;
4320 buf_ptr += amt_read;
4324 if (arglist & CAM_ARG_ERR_RECOVER)
4325 flags |= CAM_PASS_ERR_RECOVER;
4327 /* Disable freezing the device queue */
4328 flags |= CAM_DEV_QFRZDIS;
4332 * This is taken from the SCSI-3 draft spec.
4333 * (T10/1157D revision 0.3)
4334 * The top 3 bits of an opcode are the group code.
4335 * The next 5 bits are the command code.
4336 * Group 0: six byte commands
4337 * Group 1: ten byte commands
4338 * Group 2: ten byte commands
4340 * Group 4: sixteen byte commands
4341 * Group 5: twelve byte commands
4342 * Group 6: vendor specific
4343 * Group 7: vendor specific
4345 switch((cdb[0] >> 5) & 0x7) {
4356 /* computed by buff_encode_visit */
4367 * We should probably use csio_build_visit or something like that
4368 * here, but it's easier to encode arguments as you go. The
4369 * alternative would be skipping the CDB argument and then encoding
4370 * it here, since we've got the data buffer argument by now.
4372 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4374 cam_fill_csio(&ccb->csio,
4375 /*retries*/ retry_count,
4378 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4379 /*data_ptr*/ data_ptr,
4380 /*dxfer_len*/ data_bytes,
4381 /*sense_len*/ SSD_FULL_SIZE,
4382 /*cdb_len*/ cdb_len,
4383 /*timeout*/ timeout ? timeout : 5000);
4386 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4388 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4390 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4392 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4394 cam_fill_ataio(&ccb->ataio,
4395 /*retries*/ retry_count,
4399 /*data_ptr*/ data_ptr,
4400 /*dxfer_len*/ data_bytes,
4401 /*timeout*/ timeout ? timeout : 5000);
4404 if (((retval = cam_send_ccb(device, ccb)) < 0)
4405 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4406 const char warnstr[] = "error sending command";
4413 if (arglist & CAM_ARG_VERBOSE) {
4414 cam_error_print(device, ccb, CAM_ESF_ALL,
4415 CAM_EPF_ALL, stderr);
4419 goto scsicmd_bailout;
4422 if (atacmd_len && need_res) {
4424 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4426 fprintf(stdout, "\n");
4429 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4430 ccb->ataio.res.status,
4431 ccb->ataio.res.error,
4432 ccb->ataio.res.lba_low,
4433 ccb->ataio.res.lba_mid,
4434 ccb->ataio.res.lba_high,
4435 ccb->ataio.res.device,
4436 ccb->ataio.res.lba_low_exp,
4437 ccb->ataio.res.lba_mid_exp,
4438 ccb->ataio.res.lba_high_exp,
4439 ccb->ataio.res.sector_count,
4440 ccb->ataio.res.sector_count_exp);
4445 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4446 && (arglist & CAM_ARG_CMD_IN)
4447 && (data_bytes > 0)) {
4449 buff_decode_visit(data_ptr, data_bytes, datastr,
4451 fprintf(stdout, "\n");
4453 ssize_t amt_written;
4454 int amt_to_write = data_bytes;
4455 u_int8_t *buf_ptr = data_ptr;
4457 for (amt_written = 0; (amt_to_write > 0) &&
4458 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4459 amt_to_write -= amt_written;
4460 buf_ptr += amt_written;
4462 if (amt_written == -1) {
4463 warn("error writing data to stdout");
4465 goto scsicmd_bailout;
4466 } else if ((amt_written == 0)
4467 && (amt_to_write > 0)) {
4468 warnx("only wrote %u bytes out of %u",
4469 data_bytes - amt_to_write, data_bytes);
4476 if ((data_bytes > 0) && (data_ptr != NULL))
4485 camdebug(int argc, char **argv, char *combinedopt)
4488 path_id_t bus = CAM_BUS_WILDCARD;
4489 target_id_t target = CAM_TARGET_WILDCARD;
4490 lun_id_t lun = CAM_LUN_WILDCARD;
4491 char *tstr, *tmpstr = NULL;
4495 bzero(&ccb, sizeof(union ccb));
4497 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4500 arglist |= CAM_ARG_DEBUG_INFO;
4501 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4504 arglist |= CAM_ARG_DEBUG_PERIPH;
4505 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4508 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4509 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4512 arglist |= CAM_ARG_DEBUG_TRACE;
4513 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4516 arglist |= CAM_ARG_DEBUG_XPT;
4517 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4520 arglist |= CAM_ARG_DEBUG_CDB;
4521 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4524 arglist |= CAM_ARG_DEBUG_PROBE;
4525 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4532 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4533 warnx("error opening transport layer device %s", XPT_DEVICE);
4534 warn("%s", XPT_DEVICE);
4541 warnx("you must specify \"off\", \"all\" or a bus,");
4542 warnx("bus:target, or bus:target:lun");
4549 while (isspace(*tstr) && (*tstr != '\0'))
4552 if (strncmp(tstr, "off", 3) == 0) {
4553 ccb.cdbg.flags = CAM_DEBUG_NONE;
4554 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4555 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4556 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4557 } else if (strncmp(tstr, "all", 3) != 0) {
4558 tmpstr = (char *)strtok(tstr, ":");
4559 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4560 bus = strtol(tmpstr, NULL, 0);
4561 arglist |= CAM_ARG_BUS;
4562 tmpstr = (char *)strtok(NULL, ":");
4563 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4564 target = strtol(tmpstr, NULL, 0);
4565 arglist |= CAM_ARG_TARGET;
4566 tmpstr = (char *)strtok(NULL, ":");
4567 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4568 lun = strtol(tmpstr, NULL, 0);
4569 arglist |= CAM_ARG_LUN;
4574 warnx("you must specify \"all\", \"off\", or a bus,");
4575 warnx("bus:target, or bus:target:lun to debug");
4581 ccb.ccb_h.func_code = XPT_DEBUG;
4582 ccb.ccb_h.path_id = bus;
4583 ccb.ccb_h.target_id = target;
4584 ccb.ccb_h.target_lun = lun;
4586 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4587 warn("CAMIOCOMMAND ioctl failed");
4592 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4593 CAM_FUNC_NOTAVAIL) {
4594 warnx("CAM debugging not available");
4595 warnx("you need to put options CAMDEBUG in"
4596 " your kernel config file!");
4598 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4600 warnx("XPT_DEBUG CCB failed with status %#x",
4604 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4606 "Debugging turned off\n");
4609 "Debugging enabled for "
4611 bus, target, (uintmax_t)lun);
4622 tagcontrol(struct cam_device *device, int argc, char **argv,
4632 ccb = cam_getccb(device);
4635 warnx("tagcontrol: error allocating ccb");
4639 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4642 numtags = strtol(optarg, NULL, 0);
4644 warnx("tag count %d is < 0", numtags);
4646 goto tagcontrol_bailout;
4657 cam_path_string(device, pathstr, sizeof(pathstr));
4660 bzero(&(&ccb->ccb_h)[1],
4661 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4662 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4663 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4664 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4665 ccb->crs.openings = numtags;
4668 if (cam_send_ccb(device, ccb) < 0) {
4669 perror("error sending XPT_REL_SIMQ CCB");
4671 goto tagcontrol_bailout;
4674 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4675 warnx("XPT_REL_SIMQ CCB failed");
4676 cam_error_print(device, ccb, CAM_ESF_ALL,
4677 CAM_EPF_ALL, stderr);
4679 goto tagcontrol_bailout;
4684 fprintf(stdout, "%stagged openings now %d\n",
4685 pathstr, ccb->crs.openings);
4688 bzero(&(&ccb->ccb_h)[1],
4689 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4691 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4693 if (cam_send_ccb(device, ccb) < 0) {
4694 perror("error sending XPT_GDEV_STATS CCB");
4696 goto tagcontrol_bailout;
4699 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4700 warnx("XPT_GDEV_STATS CCB failed");
4701 cam_error_print(device, ccb, CAM_ESF_ALL,
4702 CAM_EPF_ALL, stderr);
4704 goto tagcontrol_bailout;
4707 if (arglist & CAM_ARG_VERBOSE) {
4708 fprintf(stdout, "%s", pathstr);
4709 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4710 fprintf(stdout, "%s", pathstr);
4711 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4712 fprintf(stdout, "%s", pathstr);
4713 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4714 fprintf(stdout, "%s", pathstr);
4715 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4716 fprintf(stdout, "%s", pathstr);
4717 fprintf(stdout, "held %d\n", ccb->cgds.held);
4718 fprintf(stdout, "%s", pathstr);
4719 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4720 fprintf(stdout, "%s", pathstr);
4721 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4724 fprintf(stdout, "%s", pathstr);
4725 fprintf(stdout, "device openings: ");
4727 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4728 ccb->cgds.dev_active);
4738 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4742 cam_path_string(device, pathstr, sizeof(pathstr));
4744 if (cts->transport == XPORT_SPI) {
4745 struct ccb_trans_settings_spi *spi =
4746 &cts->xport_specific.spi;
4748 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4750 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4753 if (spi->sync_offset != 0) {
4756 freq = scsi_calc_syncsrate(spi->sync_period);
4757 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4758 pathstr, freq / 1000, freq % 1000);
4762 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4763 fprintf(stdout, "%soffset: %d\n", pathstr,
4767 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4768 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4769 (0x01 << spi->bus_width) * 8);
4772 if (spi->valid & CTS_SPI_VALID_DISC) {
4773 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4774 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4775 "enabled" : "disabled");
4778 if (cts->transport == XPORT_FC) {
4779 struct ccb_trans_settings_fc *fc =
4780 &cts->xport_specific.fc;
4782 if (fc->valid & CTS_FC_VALID_WWNN)
4783 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4784 (long long) fc->wwnn);
4785 if (fc->valid & CTS_FC_VALID_WWPN)
4786 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4787 (long long) fc->wwpn);
4788 if (fc->valid & CTS_FC_VALID_PORT)
4789 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4790 if (fc->valid & CTS_FC_VALID_SPEED)
4791 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4792 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4794 if (cts->transport == XPORT_SAS) {
4795 struct ccb_trans_settings_sas *sas =
4796 &cts->xport_specific.sas;
4798 if (sas->valid & CTS_SAS_VALID_SPEED)
4799 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4800 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4802 if (cts->transport == XPORT_ATA) {
4803 struct ccb_trans_settings_pata *pata =
4804 &cts->xport_specific.ata;
4806 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4807 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4808 ata_mode2string(pata->mode));
4810 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4811 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4814 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4815 fprintf(stdout, "%sPIO transaction length: %d\n",
4816 pathstr, pata->bytecount);
4819 if (cts->transport == XPORT_SATA) {
4820 struct ccb_trans_settings_sata *sata =
4821 &cts->xport_specific.sata;
4823 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4824 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4827 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4828 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4829 ata_mode2string(sata->mode));
4831 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4832 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4835 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4836 fprintf(stdout, "%sPIO transaction length: %d\n",
4837 pathstr, sata->bytecount);
4839 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4840 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4843 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4844 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4847 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4848 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4852 if (cts->protocol == PROTO_ATA) {
4853 struct ccb_trans_settings_ata *ata=
4854 &cts->proto_specific.ata;
4856 if (ata->valid & CTS_ATA_VALID_TQ) {
4857 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4858 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4859 "enabled" : "disabled");
4862 if (cts->protocol == PROTO_SCSI) {
4863 struct ccb_trans_settings_scsi *scsi=
4864 &cts->proto_specific.scsi;
4866 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4867 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4868 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4869 "enabled" : "disabled");
4876 * Get a path inquiry CCB for the specified device.
4879 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4884 ccb = cam_getccb(device);
4886 warnx("get_cpi: couldn't allocate CCB");
4889 bzero(&(&ccb->ccb_h)[1],
4890 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4891 ccb->ccb_h.func_code = XPT_PATH_INQ;
4892 if (cam_send_ccb(device, ccb) < 0) {
4893 warn("get_cpi: error sending Path Inquiry CCB");
4894 if (arglist & CAM_ARG_VERBOSE)
4895 cam_error_print(device, ccb, CAM_ESF_ALL,
4896 CAM_EPF_ALL, stderr);
4898 goto get_cpi_bailout;
4900 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4901 if (arglist & CAM_ARG_VERBOSE)
4902 cam_error_print(device, ccb, CAM_ESF_ALL,
4903 CAM_EPF_ALL, stderr);
4905 goto get_cpi_bailout;
4907 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4915 * Get a get device CCB for the specified device.
4918 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4923 ccb = cam_getccb(device);
4925 warnx("get_cgd: couldn't allocate CCB");
4928 bzero(&(&ccb->ccb_h)[1],
4929 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4930 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4931 if (cam_send_ccb(device, ccb) < 0) {
4932 warn("get_cgd: error sending Path Inquiry CCB");
4933 if (arglist & CAM_ARG_VERBOSE)
4934 cam_error_print(device, ccb, CAM_ESF_ALL,
4935 CAM_EPF_ALL, stderr);
4937 goto get_cgd_bailout;
4939 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
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 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4954 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4958 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4959 int timeout, int verbosemode)
4961 union ccb *ccb = NULL;
4962 struct scsi_vpd_supported_page_list sup_pages;
4966 ccb = cam_getccb(dev);
4968 warn("Unable to allocate CCB");
4973 /* cam_getccb cleans up the header, caller has to zero the payload */
4974 bzero(&(&ccb->ccb_h)[1],
4975 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4977 bzero(&sup_pages, sizeof(sup_pages));
4979 scsi_inquiry(&ccb->csio,
4980 /*retries*/ retry_count,
4982 /* tag_action */ MSG_SIMPLE_Q_TAG,
4983 /* inq_buf */ (u_int8_t *)&sup_pages,
4984 /* inq_len */ sizeof(sup_pages),
4986 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
4987 /* sense_len */ SSD_FULL_SIZE,
4988 /* timeout */ timeout ? timeout : 5000);
4990 /* Disable freezing the device queue */
4991 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4993 if (retry_count != 0)
4994 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4996 if (cam_send_ccb(dev, ccb) < 0) {
5002 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5003 if (verbosemode != 0)
5004 cam_error_print(dev, ccb, CAM_ESF_ALL,
5005 CAM_EPF_ALL, stderr);
5010 for (i = 0; i < sup_pages.length; i++) {
5011 if (sup_pages.list[i] == page_id) {
5024 * devtype is filled in with the type of device.
5025 * Returns 0 for success, non-zero for failure.
5028 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5029 int verbosemode, camcontrol_devtype *devtype)
5031 struct ccb_getdev cgd;
5034 retval = get_cgd(dev, &cgd);
5038 switch (cgd.protocol) {
5044 *devtype = CC_DT_ATA;
5046 break; /*NOTREACHED*/
5048 *devtype = CC_DT_UNKNOWN;
5050 break; /*NOTREACHED*/
5054 * Check for the ATA Information VPD page (0x89). If this is an
5055 * ATA device behind a SCSI to ATA translation layer, this VPD page
5056 * should be present.
5058 * If that VPD page isn't present, or we get an error back from the
5059 * INQUIRY command, we'll just treat it as a normal SCSI device.
5061 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5062 timeout, verbosemode);
5064 *devtype = CC_DT_ATA_BEHIND_SCSI;
5066 *devtype = CC_DT_SCSI;
5075 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5076 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5077 uint16_t sector_count, uint64_t lba, uint8_t command, uint8_t *data_ptr,
5078 uint16_t dxfer_len, uint8_t sense_len, uint32_t timeout,
5079 int is48bit, camcontrol_devtype devtype)
5081 if (devtype == CC_DT_ATA) {
5082 cam_fill_ataio(&ccb->ataio,
5083 /*retries*/ retry_count,
5086 /*tag_action*/ tag_action,
5087 /*data_ptr*/ data_ptr,
5088 /*dxfer_len*/ dxfer_len,
5089 /*timeout*/ timeout);
5090 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5091 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5094 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5097 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5098 protocol |= AP_EXTEND;
5100 scsi_ata_pass_16(&ccb->csio,
5101 /*retries*/ retry_count,
5104 /*tag_action*/ tag_action,
5105 /*protocol*/ protocol,
5106 /*ata_flags*/ ata_flags,
5107 /*features*/ features,
5108 /*sector_count*/ sector_count,
5110 /*command*/ command,
5112 /*data_ptr*/ data_ptr,
5113 /*dxfer_len*/ dxfer_len,
5114 /*sense_len*/ sense_len,
5115 /*timeout*/ timeout);
5121 cpi_print(struct ccb_pathinq *cpi)
5123 char adapter_str[1024];
5126 snprintf(adapter_str, sizeof(adapter_str),
5127 "%s%d:", cpi->dev_name, cpi->unit_number);
5129 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5132 for (i = 1; i < 0xff; i = i << 1) {
5135 if ((i & cpi->hba_inquiry) == 0)
5138 fprintf(stdout, "%s supports ", adapter_str);
5142 str = "MDP message";
5145 str = "32 bit wide SCSI";
5148 str = "16 bit wide SCSI";
5151 str = "SDTR message";
5154 str = "linked CDBs";
5157 str = "tag queue messages";
5160 str = "soft reset alternative";
5163 str = "SATA Port Multiplier";
5166 str = "unknown PI bit set";
5169 fprintf(stdout, "%s\n", str);
5172 for (i = 1; i < 0xff; i = i << 1) {
5175 if ((i & cpi->hba_misc) == 0)
5178 fprintf(stdout, "%s ", adapter_str);
5182 str = "bus scans from high ID to low ID";
5185 str = "removable devices not included in scan";
5187 case PIM_NOINITIATOR:
5188 str = "initiator role not supported";
5190 case PIM_NOBUSRESET:
5191 str = "user has disabled initial BUS RESET or"
5192 " controller is in target/mixed mode";
5195 str = "do not send 6-byte commands";
5198 str = "scan bus sequentially";
5201 str = "unknown PIM bit set";
5204 fprintf(stdout, "%s\n", str);
5207 for (i = 1; i < 0xff; i = i << 1) {
5210 if ((i & cpi->target_sprt) == 0)
5213 fprintf(stdout, "%s supports ", adapter_str);
5216 str = "target mode processor mode";
5219 str = "target mode phase cog. mode";
5221 case PIT_DISCONNECT:
5222 str = "disconnects in target mode";
5225 str = "terminate I/O message in target mode";
5228 str = "group 6 commands in target mode";
5231 str = "group 7 commands in target mode";
5234 str = "unknown PIT bit set";
5238 fprintf(stdout, "%s\n", str);
5240 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5242 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5244 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5246 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5247 adapter_str, cpi->hpath_id);
5248 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5250 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5251 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5252 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5253 adapter_str, cpi->hba_vendor);
5254 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5255 adapter_str, cpi->hba_device);
5256 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5257 adapter_str, cpi->hba_subvendor);
5258 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5259 adapter_str, cpi->hba_subdevice);
5260 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5261 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5262 if (cpi->base_transfer_speed > 1000)
5263 fprintf(stdout, "%d.%03dMB/sec\n",
5264 cpi->base_transfer_speed / 1000,
5265 cpi->base_transfer_speed % 1000);
5267 fprintf(stdout, "%dKB/sec\n",
5268 (cpi->base_transfer_speed % 1000) * 1000);
5269 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5270 adapter_str, cpi->maxio);
5274 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5275 struct ccb_trans_settings *cts)
5281 ccb = cam_getccb(device);
5284 warnx("get_print_cts: error allocating ccb");
5288 bzero(&(&ccb->ccb_h)[1],
5289 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5291 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5293 if (user_settings == 0)
5294 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5296 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5298 if (cam_send_ccb(device, ccb) < 0) {
5299 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5300 if (arglist & CAM_ARG_VERBOSE)
5301 cam_error_print(device, ccb, CAM_ESF_ALL,
5302 CAM_EPF_ALL, stderr);
5304 goto get_print_cts_bailout;
5307 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5308 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5309 if (arglist & CAM_ARG_VERBOSE)
5310 cam_error_print(device, ccb, CAM_ESF_ALL,
5311 CAM_EPF_ALL, stderr);
5313 goto get_print_cts_bailout;
5317 cts_print(device, &ccb->cts);
5320 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5322 get_print_cts_bailout:
5330 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5331 int argc, char **argv, char *combinedopt)
5335 int user_settings = 0;
5337 int disc_enable = -1, tag_enable = -1;
5340 double syncrate = -1;
5343 int change_settings = 0, send_tur = 0;
5344 struct ccb_pathinq cpi;
5346 ccb = cam_getccb(device);
5348 warnx("ratecontrol: error allocating ccb");
5351 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5360 if (strncasecmp(optarg, "enable", 6) == 0)
5362 else if (strncasecmp(optarg, "disable", 7) == 0)
5365 warnx("-D argument \"%s\" is unknown", optarg);
5367 goto ratecontrol_bailout;
5369 change_settings = 1;
5372 mode = ata_string2mode(optarg);
5374 warnx("unknown mode '%s'", optarg);
5376 goto ratecontrol_bailout;
5378 change_settings = 1;
5381 offset = strtol(optarg, NULL, 0);
5383 warnx("offset value %d is < 0", offset);
5385 goto ratecontrol_bailout;
5387 change_settings = 1;
5393 syncrate = atof(optarg);
5395 warnx("sync rate %f is < 0", syncrate);
5397 goto ratecontrol_bailout;
5399 change_settings = 1;
5402 if (strncasecmp(optarg, "enable", 6) == 0)
5404 else if (strncasecmp(optarg, "disable", 7) == 0)
5407 warnx("-T argument \"%s\" is unknown", optarg);
5409 goto ratecontrol_bailout;
5411 change_settings = 1;
5417 bus_width = strtol(optarg, NULL, 0);
5418 if (bus_width < 0) {
5419 warnx("bus width %d is < 0", bus_width);
5421 goto ratecontrol_bailout;
5423 change_settings = 1;
5429 bzero(&(&ccb->ccb_h)[1],
5430 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
5432 * Grab path inquiry information, so we can determine whether
5433 * or not the initiator is capable of the things that the user
5436 ccb->ccb_h.func_code = XPT_PATH_INQ;
5437 if (cam_send_ccb(device, ccb) < 0) {
5438 perror("error sending XPT_PATH_INQ CCB");
5439 if (arglist & CAM_ARG_VERBOSE) {
5440 cam_error_print(device, ccb, CAM_ESF_ALL,
5441 CAM_EPF_ALL, stderr);
5444 goto ratecontrol_bailout;
5446 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5447 warnx("XPT_PATH_INQ CCB failed");
5448 if (arglist & CAM_ARG_VERBOSE) {
5449 cam_error_print(device, ccb, CAM_ESF_ALL,
5450 CAM_EPF_ALL, stderr);
5453 goto ratecontrol_bailout;
5455 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5456 bzero(&(&ccb->ccb_h)[1],
5457 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5459 fprintf(stdout, "%s parameters:\n",
5460 user_settings ? "User" : "Current");
5462 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5464 goto ratecontrol_bailout;
5466 if (arglist & CAM_ARG_VERBOSE)
5469 if (change_settings) {
5470 int didsettings = 0;
5471 struct ccb_trans_settings_spi *spi = NULL;
5472 struct ccb_trans_settings_pata *pata = NULL;
5473 struct ccb_trans_settings_sata *sata = NULL;
5474 struct ccb_trans_settings_ata *ata = NULL;
5475 struct ccb_trans_settings_scsi *scsi = NULL;
5477 if (ccb->cts.transport == XPORT_SPI)
5478 spi = &ccb->cts.xport_specific.spi;
5479 if (ccb->cts.transport == XPORT_ATA)
5480 pata = &ccb->cts.xport_specific.ata;
5481 if (ccb->cts.transport == XPORT_SATA)
5482 sata = &ccb->cts.xport_specific.sata;
5483 if (ccb->cts.protocol == PROTO_ATA)
5484 ata = &ccb->cts.proto_specific.ata;
5485 if (ccb->cts.protocol == PROTO_SCSI)
5486 scsi = &ccb->cts.proto_specific.scsi;
5487 ccb->cts.xport_specific.valid = 0;
5488 ccb->cts.proto_specific.valid = 0;
5489 if (spi && disc_enable != -1) {
5490 spi->valid |= CTS_SPI_VALID_DISC;
5491 if (disc_enable == 0)
5492 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5494 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5497 if (tag_enable != -1) {
5498 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5499 warnx("HBA does not support tagged queueing, "
5500 "so you cannot modify tag settings");
5502 goto ratecontrol_bailout;
5505 ata->valid |= CTS_SCSI_VALID_TQ;
5506 if (tag_enable == 0)
5507 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5509 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5512 scsi->valid |= CTS_SCSI_VALID_TQ;
5513 if (tag_enable == 0)
5514 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5516 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5520 if (spi && offset != -1) {
5521 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5522 warnx("HBA is not capable of changing offset");
5524 goto ratecontrol_bailout;
5526 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5527 spi->sync_offset = offset;
5530 if (spi && syncrate != -1) {
5531 int prelim_sync_period;
5533 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5534 warnx("HBA is not capable of changing "
5537 goto ratecontrol_bailout;
5539 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5541 * The sync rate the user gives us is in MHz.
5542 * We need to translate it into KHz for this
5547 * Next, we calculate a "preliminary" sync period
5548 * in tenths of a nanosecond.
5551 prelim_sync_period = 0;
5553 prelim_sync_period = 10000000 / syncrate;
5555 scsi_calc_syncparam(prelim_sync_period);
5558 if (sata && syncrate != -1) {
5559 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5560 warnx("HBA is not capable of changing "
5563 goto ratecontrol_bailout;
5565 if (!user_settings) {
5566 warnx("You can modify only user rate "
5567 "settings for SATA");
5569 goto ratecontrol_bailout;
5571 sata->revision = ata_speed2revision(syncrate * 100);
5572 if (sata->revision < 0) {
5573 warnx("Invalid rate %f", syncrate);
5575 goto ratecontrol_bailout;
5577 sata->valid |= CTS_SATA_VALID_REVISION;
5580 if ((pata || sata) && mode != -1) {
5581 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5582 warnx("HBA is not capable of changing "
5585 goto ratecontrol_bailout;
5587 if (!user_settings) {
5588 warnx("You can modify only user mode "
5589 "settings for ATA/SATA");
5591 goto ratecontrol_bailout;
5595 pata->valid |= CTS_ATA_VALID_MODE;
5598 sata->valid |= CTS_SATA_VALID_MODE;
5603 * The bus_width argument goes like this:
5607 * Therefore, if you shift the number of bits given on the
5608 * command line right by 4, you should get the correct
5611 if (spi && bus_width != -1) {
5613 * We might as well validate things here with a
5614 * decipherable error message, rather than what
5615 * will probably be an indecipherable error message
5616 * by the time it gets back to us.
5618 if ((bus_width == 16)
5619 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5620 warnx("HBA does not support 16 bit bus width");
5622 goto ratecontrol_bailout;
5623 } else if ((bus_width == 32)
5624 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5625 warnx("HBA does not support 32 bit bus width");
5627 goto ratecontrol_bailout;
5628 } else if ((bus_width != 8)
5629 && (bus_width != 16)
5630 && (bus_width != 32)) {
5631 warnx("Invalid bus width %d", bus_width);
5633 goto ratecontrol_bailout;
5635 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5636 spi->bus_width = bus_width >> 4;
5639 if (didsettings == 0) {
5640 goto ratecontrol_bailout;
5642 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5643 if (cam_send_ccb(device, ccb) < 0) {
5644 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5645 if (arglist & CAM_ARG_VERBOSE) {
5646 cam_error_print(device, ccb, CAM_ESF_ALL,
5647 CAM_EPF_ALL, stderr);
5650 goto ratecontrol_bailout;
5652 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5653 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5654 if (arglist & CAM_ARG_VERBOSE) {
5655 cam_error_print(device, ccb, CAM_ESF_ALL,
5656 CAM_EPF_ALL, stderr);
5659 goto ratecontrol_bailout;
5663 retval = testunitready(device, retry_count, timeout,
5664 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5666 * If the TUR didn't succeed, just bail.
5670 fprintf(stderr, "Test Unit Ready failed\n");
5671 goto ratecontrol_bailout;
5674 if ((change_settings || send_tur) && !quiet &&
5675 (ccb->cts.transport == XPORT_ATA ||
5676 ccb->cts.transport == XPORT_SATA || send_tur)) {
5677 fprintf(stdout, "New parameters:\n");
5678 retval = get_print_cts(device, user_settings, 0, NULL);
5681 ratecontrol_bailout:
5687 scsiformat(struct cam_device *device, int argc, char **argv,
5688 char *combinedopt, int retry_count, int timeout)
5692 int ycount = 0, quiet = 0;
5693 int error = 0, retval = 0;
5694 int use_timeout = 10800 * 1000;
5696 struct format_defect_list_header fh;
5697 u_int8_t *data_ptr = NULL;
5698 u_int32_t dxfer_len = 0;
5700 int num_warnings = 0;
5703 ccb = cam_getccb(device);
5706 warnx("scsiformat: error allocating ccb");
5710 bzero(&(&ccb->ccb_h)[1],
5711 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5713 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5734 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5735 "following device:\n");
5737 error = scsidoinquiry(device, argc, argv, combinedopt,
5738 retry_count, timeout);
5741 warnx("scsiformat: error sending inquiry");
5742 goto scsiformat_bailout;
5747 if (!get_confirmation()) {
5749 goto scsiformat_bailout;
5754 use_timeout = timeout;
5757 fprintf(stdout, "Current format timeout is %d seconds\n",
5758 use_timeout / 1000);
5762 * If the user hasn't disabled questions and didn't specify a
5763 * timeout on the command line, ask them if they want the current
5767 && (timeout == 0)) {
5769 int new_timeout = 0;
5771 fprintf(stdout, "Enter new timeout in seconds or press\n"
5772 "return to keep the current timeout [%d] ",
5773 use_timeout / 1000);
5775 if (fgets(str, sizeof(str), stdin) != NULL) {
5777 new_timeout = atoi(str);
5780 if (new_timeout != 0) {
5781 use_timeout = new_timeout * 1000;
5782 fprintf(stdout, "Using new timeout value %d\n",
5783 use_timeout / 1000);
5788 * Keep this outside the if block below to silence any unused
5789 * variable warnings.
5791 bzero(&fh, sizeof(fh));
5794 * If we're in immediate mode, we've got to include the format
5797 if (immediate != 0) {
5798 fh.byte2 = FU_DLH_IMMED;
5799 data_ptr = (u_int8_t *)&fh;
5800 dxfer_len = sizeof(fh);
5801 byte2 = FU_FMT_DATA;
5802 } else if (quiet == 0) {
5803 fprintf(stdout, "Formatting...");
5807 scsi_format_unit(&ccb->csio,
5808 /* retries */ retry_count,
5810 /* tag_action */ MSG_SIMPLE_Q_TAG,
5813 /* data_ptr */ data_ptr,
5814 /* dxfer_len */ dxfer_len,
5815 /* sense_len */ SSD_FULL_SIZE,
5816 /* timeout */ use_timeout);
5818 /* Disable freezing the device queue */
5819 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5821 if (arglist & CAM_ARG_ERR_RECOVER)
5822 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5824 if (((retval = cam_send_ccb(device, ccb)) < 0)
5825 || ((immediate == 0)
5826 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5827 const char errstr[] = "error sending format command";
5834 if (arglist & CAM_ARG_VERBOSE) {
5835 cam_error_print(device, ccb, CAM_ESF_ALL,
5836 CAM_EPF_ALL, stderr);
5839 goto scsiformat_bailout;
5843 * If we ran in non-immediate mode, we already checked for errors
5844 * above and printed out any necessary information. If we're in
5845 * immediate mode, we need to loop through and get status
5846 * information periodically.
5848 if (immediate == 0) {
5850 fprintf(stdout, "Format Complete\n");
5852 goto scsiformat_bailout;
5859 bzero(&(&ccb->ccb_h)[1],
5860 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5863 * There's really no need to do error recovery or
5864 * retries here, since we're just going to sit in a
5865 * loop and wait for the device to finish formatting.
5867 scsi_test_unit_ready(&ccb->csio,
5870 /* tag_action */ MSG_SIMPLE_Q_TAG,
5871 /* sense_len */ SSD_FULL_SIZE,
5872 /* timeout */ 5000);
5874 /* Disable freezing the device queue */
5875 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5877 retval = cam_send_ccb(device, ccb);
5880 * If we get an error from the ioctl, bail out. SCSI
5881 * errors are expected.
5884 warn("error sending CAMIOCOMMAND ioctl");
5885 if (arglist & CAM_ARG_VERBOSE) {
5886 cam_error_print(device, ccb, CAM_ESF_ALL,
5887 CAM_EPF_ALL, stderr);
5890 goto scsiformat_bailout;
5893 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5895 if ((status != CAM_REQ_CMP)
5896 && (status == CAM_SCSI_STATUS_ERROR)
5897 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5898 struct scsi_sense_data *sense;
5899 int error_code, sense_key, asc, ascq;
5901 sense = &ccb->csio.sense_data;
5902 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5903 ccb->csio.sense_resid, &error_code, &sense_key,
5904 &asc, &ascq, /*show_errors*/ 1);
5907 * According to the SCSI-2 and SCSI-3 specs, a
5908 * drive that is in the middle of a format should
5909 * return NOT READY with an ASC of "logical unit
5910 * not ready, format in progress". The sense key
5911 * specific bytes will then be a progress indicator.
5913 if ((sense_key == SSD_KEY_NOT_READY)
5914 && (asc == 0x04) && (ascq == 0x04)) {
5917 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5918 ccb->csio.sense_resid, sks) == 0)
5921 u_int64_t percentage;
5923 val = scsi_2btoul(&sks[1]);
5924 percentage = 10000 * val;
5927 "\rFormatting: %ju.%02u %% "
5929 (uintmax_t)(percentage /
5931 (unsigned)((percentage /
5935 } else if ((quiet == 0)
5936 && (++num_warnings <= 1)) {
5937 warnx("Unexpected SCSI Sense Key "
5938 "Specific value returned "
5940 scsi_sense_print(device, &ccb->csio,
5942 warnx("Unable to print status "
5943 "information, but format will "
5945 warnx("will exit when format is "
5950 warnx("Unexpected SCSI error during format");
5951 cam_error_print(device, ccb, CAM_ESF_ALL,
5952 CAM_EPF_ALL, stderr);
5954 goto scsiformat_bailout;
5957 } else if (status != CAM_REQ_CMP) {
5958 warnx("Unexpected CAM status %#x", status);
5959 if (arglist & CAM_ARG_VERBOSE)
5960 cam_error_print(device, ccb, CAM_ESF_ALL,
5961 CAM_EPF_ALL, stderr);
5963 goto scsiformat_bailout;
5966 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5969 fprintf(stdout, "\nFormat Complete\n");
5979 scsisanitize(struct cam_device *device, int argc, char **argv,
5980 char *combinedopt, int retry_count, int timeout)
5983 u_int8_t action = 0;
5985 int ycount = 0, quiet = 0;
5986 int error = 0, retval = 0;
5987 int use_timeout = 10800 * 1000;
5993 const char *pattern = NULL;
5994 u_int8_t *data_ptr = NULL;
5995 u_int32_t dxfer_len = 0;
5997 int num_warnings = 0;
6000 ccb = cam_getccb(device);
6003 warnx("scsisanitize: error allocating ccb");
6007 bzero(&(&ccb->ccb_h)[1],
6008 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6010 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6013 if (strcasecmp(optarg, "overwrite") == 0)
6014 action = SSZ_SERVICE_ACTION_OVERWRITE;
6015 else if (strcasecmp(optarg, "block") == 0)
6016 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6017 else if (strcasecmp(optarg, "crypto") == 0)
6018 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6019 else if (strcasecmp(optarg, "exitfailure") == 0)
6020 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6022 warnx("invalid service operation \"%s\"",
6025 goto scsisanitize_bailout;
6029 passes = strtol(optarg, NULL, 0);
6030 if (passes < 1 || passes > 31) {
6031 warnx("invalid passes value %d", passes);
6033 goto scsisanitize_bailout;
6064 warnx("an action is required");
6066 goto scsisanitize_bailout;
6067 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6068 struct scsi_sanitize_parameter_list *pl;
6072 if (pattern == NULL) {
6073 warnx("overwrite action requires -P argument");
6075 goto scsisanitize_bailout;
6077 fd = open(pattern, O_RDONLY);
6079 warn("cannot open pattern file %s", pattern);
6081 goto scsisanitize_bailout;
6083 if (fstat(fd, &sb) < 0) {
6084 warn("cannot stat pattern file %s", pattern);
6086 goto scsisanitize_bailout;
6089 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6090 warnx("pattern file size exceeds maximum value %d",
6091 SSZPL_MAX_PATTERN_LENGTH);
6093 goto scsisanitize_bailout;
6095 dxfer_len = sizeof(*pl) + sz;
6096 data_ptr = calloc(1, dxfer_len);
6097 if (data_ptr == NULL) {
6098 warnx("cannot allocate parameter list buffer");
6100 goto scsisanitize_bailout;
6103 amt = read(fd, data_ptr + sizeof(*pl), sz);
6105 warn("cannot read pattern file");
6107 goto scsisanitize_bailout;
6108 } else if (amt != sz) {
6109 warnx("short pattern file read");
6111 goto scsisanitize_bailout;
6114 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6120 pl->byte1 |= SSZPL_INVERT;
6121 scsi_ulto2b(sz, pl->length);
6127 else if (invert != 0)
6129 else if (pattern != NULL)
6134 warnx("%s argument only valid with overwrite "
6137 goto scsisanitize_bailout;
6142 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6143 "following device:\n");
6145 error = scsidoinquiry(device, argc, argv, combinedopt,
6146 retry_count, timeout);
6149 warnx("scsisanitize: error sending inquiry");
6150 goto scsisanitize_bailout;
6155 if (!get_confirmation()) {
6157 goto scsisanitize_bailout;
6162 use_timeout = timeout;
6165 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6166 use_timeout / 1000);
6170 * If the user hasn't disabled questions and didn't specify a
6171 * timeout on the command line, ask them if they want the current
6175 && (timeout == 0)) {
6177 int new_timeout = 0;
6179 fprintf(stdout, "Enter new timeout in seconds or press\n"
6180 "return to keep the current timeout [%d] ",
6181 use_timeout / 1000);
6183 if (fgets(str, sizeof(str), stdin) != NULL) {
6185 new_timeout = atoi(str);
6188 if (new_timeout != 0) {
6189 use_timeout = new_timeout * 1000;
6190 fprintf(stdout, "Using new timeout value %d\n",
6191 use_timeout / 1000);
6197 byte2 |= SSZ_UNRESTRICTED_EXIT;
6201 scsi_sanitize(&ccb->csio,
6202 /* retries */ retry_count,
6204 /* tag_action */ MSG_SIMPLE_Q_TAG,
6207 /* data_ptr */ data_ptr,
6208 /* dxfer_len */ dxfer_len,
6209 /* sense_len */ SSD_FULL_SIZE,
6210 /* timeout */ use_timeout);
6212 /* Disable freezing the device queue */
6213 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6215 if (arglist & CAM_ARG_ERR_RECOVER)
6216 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6218 if (cam_send_ccb(device, ccb) < 0) {
6219 warn("error sending sanitize command");
6221 goto scsisanitize_bailout;
6224 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6225 struct scsi_sense_data *sense;
6226 int error_code, sense_key, asc, ascq;
6228 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6229 CAM_SCSI_STATUS_ERROR) {
6230 sense = &ccb->csio.sense_data;
6231 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6232 ccb->csio.sense_resid, &error_code, &sense_key,
6233 &asc, &ascq, /*show_errors*/ 1);
6235 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6236 asc == 0x20 && ascq == 0x00)
6237 warnx("sanitize is not supported by "
6240 warnx("error sanitizing this device");
6242 warnx("error sanitizing this device");
6244 if (arglist & CAM_ARG_VERBOSE) {
6245 cam_error_print(device, ccb, CAM_ESF_ALL,
6246 CAM_EPF_ALL, stderr);
6249 goto scsisanitize_bailout;
6253 * If we ran in non-immediate mode, we already checked for errors
6254 * above and printed out any necessary information. If we're in
6255 * immediate mode, we need to loop through and get status
6256 * information periodically.
6258 if (immediate == 0) {
6260 fprintf(stdout, "Sanitize Complete\n");
6262 goto scsisanitize_bailout;
6269 bzero(&(&ccb->ccb_h)[1],
6270 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6273 * There's really no need to do error recovery or
6274 * retries here, since we're just going to sit in a
6275 * loop and wait for the device to finish sanitizing.
6277 scsi_test_unit_ready(&ccb->csio,
6280 /* tag_action */ MSG_SIMPLE_Q_TAG,
6281 /* sense_len */ SSD_FULL_SIZE,
6282 /* timeout */ 5000);
6284 /* Disable freezing the device queue */
6285 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6287 retval = cam_send_ccb(device, ccb);
6290 * If we get an error from the ioctl, bail out. SCSI
6291 * errors are expected.
6294 warn("error sending CAMIOCOMMAND ioctl");
6295 if (arglist & CAM_ARG_VERBOSE) {
6296 cam_error_print(device, ccb, CAM_ESF_ALL,
6297 CAM_EPF_ALL, stderr);
6300 goto scsisanitize_bailout;
6303 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6305 if ((status != CAM_REQ_CMP)
6306 && (status == CAM_SCSI_STATUS_ERROR)
6307 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6308 struct scsi_sense_data *sense;
6309 int error_code, sense_key, asc, ascq;
6311 sense = &ccb->csio.sense_data;
6312 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6313 ccb->csio.sense_resid, &error_code, &sense_key,
6314 &asc, &ascq, /*show_errors*/ 1);
6317 * According to the SCSI-3 spec, a drive that is in the
6318 * middle of a sanitize should return NOT READY with an
6319 * ASC of "logical unit not ready, sanitize in
6320 * progress". The sense key specific bytes will then
6321 * be a progress indicator.
6323 if ((sense_key == SSD_KEY_NOT_READY)
6324 && (asc == 0x04) && (ascq == 0x1b)) {
6327 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6328 ccb->csio.sense_resid, sks) == 0)
6331 u_int64_t percentage;
6333 val = scsi_2btoul(&sks[1]);
6334 percentage = 10000 * val;
6337 "\rSanitizing: %ju.%02u %% "
6339 (uintmax_t)(percentage /
6341 (unsigned)((percentage /
6345 } else if ((quiet == 0)
6346 && (++num_warnings <= 1)) {
6347 warnx("Unexpected SCSI Sense Key "
6348 "Specific value returned "
6349 "during sanitize:");
6350 scsi_sense_print(device, &ccb->csio,
6352 warnx("Unable to print status "
6353 "information, but sanitze will "
6355 warnx("will exit when sanitize is "
6360 warnx("Unexpected SCSI error during sanitize");
6361 cam_error_print(device, ccb, CAM_ESF_ALL,
6362 CAM_EPF_ALL, stderr);
6364 goto scsisanitize_bailout;
6367 } else if (status != CAM_REQ_CMP) {
6368 warnx("Unexpected CAM status %#x", status);
6369 if (arglist & CAM_ARG_VERBOSE)
6370 cam_error_print(device, ccb, CAM_ESF_ALL,
6371 CAM_EPF_ALL, stderr);
6373 goto scsisanitize_bailout;
6375 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6378 fprintf(stdout, "\nSanitize Complete\n");
6380 scsisanitize_bailout:
6383 if (data_ptr != NULL)
6391 scsireportluns(struct cam_device *device, int argc, char **argv,
6392 char *combinedopt, int retry_count, int timeout)
6395 int c, countonly, lunsonly;
6396 struct scsi_report_luns_data *lundata;
6398 uint8_t report_type;
6399 uint32_t list_len, i, j;
6404 report_type = RPL_REPORT_DEFAULT;
6405 ccb = cam_getccb(device);
6408 warnx("%s: error allocating ccb", __func__);
6412 bzero(&(&ccb->ccb_h)[1],
6413 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6418 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6427 if (strcasecmp(optarg, "default") == 0)
6428 report_type = RPL_REPORT_DEFAULT;
6429 else if (strcasecmp(optarg, "wellknown") == 0)
6430 report_type = RPL_REPORT_WELLKNOWN;
6431 else if (strcasecmp(optarg, "all") == 0)
6432 report_type = RPL_REPORT_ALL;
6434 warnx("%s: invalid report type \"%s\"",
6445 if ((countonly != 0)
6446 && (lunsonly != 0)) {
6447 warnx("%s: you can only specify one of -c or -l", __func__);
6452 * According to SPC-4, the allocation length must be at least 16
6453 * bytes -- enough for the header and one LUN.
6455 alloc_len = sizeof(*lundata) + 8;
6459 lundata = malloc(alloc_len);
6461 if (lundata == NULL) {
6462 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6467 scsi_report_luns(&ccb->csio,
6468 /*retries*/ retry_count,
6470 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6471 /*select_report*/ report_type,
6472 /*rpl_buf*/ lundata,
6473 /*alloc_len*/ alloc_len,
6474 /*sense_len*/ SSD_FULL_SIZE,
6475 /*timeout*/ timeout ? timeout : 5000);
6477 /* Disable freezing the device queue */
6478 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6480 if (arglist & CAM_ARG_ERR_RECOVER)
6481 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6483 if (cam_send_ccb(device, ccb) < 0) {
6484 warn("error sending REPORT LUNS command");
6486 if (arglist & CAM_ARG_VERBOSE)
6487 cam_error_print(device, ccb, CAM_ESF_ALL,
6488 CAM_EPF_ALL, stderr);
6494 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6495 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6501 list_len = scsi_4btoul(lundata->length);
6504 * If we need to list the LUNs, and our allocation
6505 * length was too short, reallocate and retry.
6507 if ((countonly == 0)
6508 && (list_len > (alloc_len - sizeof(*lundata)))) {
6509 alloc_len = list_len + sizeof(*lundata);
6515 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6516 ((list_len / 8) > 1) ? "s" : "");
6521 for (i = 0; i < (list_len / 8); i++) {
6525 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6527 fprintf(stdout, ",");
6528 switch (lundata->luns[i].lundata[j] &
6529 RPL_LUNDATA_ATYP_MASK) {
6530 case RPL_LUNDATA_ATYP_PERIPH:
6531 if ((lundata->luns[i].lundata[j] &
6532 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6533 fprintf(stdout, "%d:",
6534 lundata->luns[i].lundata[j] &
6535 RPL_LUNDATA_PERIPH_BUS_MASK);
6537 && ((lundata->luns[i].lundata[j+2] &
6538 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6541 fprintf(stdout, "%d",
6542 lundata->luns[i].lundata[j+1]);
6544 case RPL_LUNDATA_ATYP_FLAT: {
6546 tmplun[0] = lundata->luns[i].lundata[j] &
6547 RPL_LUNDATA_FLAT_LUN_MASK;
6548 tmplun[1] = lundata->luns[i].lundata[j+1];
6550 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6554 case RPL_LUNDATA_ATYP_LUN:
6555 fprintf(stdout, "%d:%d:%d",
6556 (lundata->luns[i].lundata[j+1] &
6557 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6558 lundata->luns[i].lundata[j] &
6559 RPL_LUNDATA_LUN_TARG_MASK,
6560 lundata->luns[i].lundata[j+1] &
6561 RPL_LUNDATA_LUN_LUN_MASK);
6563 case RPL_LUNDATA_ATYP_EXTLUN: {
6564 int field_len_code, eam_code;
6566 eam_code = lundata->luns[i].lundata[j] &
6567 RPL_LUNDATA_EXT_EAM_MASK;
6568 field_len_code = (lundata->luns[i].lundata[j] &
6569 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6571 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6572 && (field_len_code == 0x00)) {
6573 fprintf(stdout, "%d",
6574 lundata->luns[i].lundata[j+1]);
6575 } else if ((eam_code ==
6576 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6577 && (field_len_code == 0x03)) {
6581 * This format takes up all 8 bytes.
6582 * If we aren't starting at offset 0,
6586 fprintf(stdout, "Invalid "
6589 "specified format", j);
6593 bzero(tmp_lun, sizeof(tmp_lun));
6594 bcopy(&lundata->luns[i].lundata[j+1],
6595 &tmp_lun[1], sizeof(tmp_lun) - 1);
6596 fprintf(stdout, "%#jx",
6597 (intmax_t)scsi_8btou64(tmp_lun));
6600 fprintf(stderr, "Unknown Extended LUN"
6601 "Address method %#x, length "
6602 "code %#x", eam_code,
6609 fprintf(stderr, "Unknown LUN address method "
6610 "%#x\n", lundata->luns[i].lundata[0] &
6611 RPL_LUNDATA_ATYP_MASK);
6615 * For the flat addressing method, there are no
6616 * other levels after it.
6621 fprintf(stdout, "\n");
6634 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6635 char *combinedopt, int retry_count, int timeout)
6638 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6639 struct scsi_read_capacity_data rcap;
6640 struct scsi_read_capacity_data_long rcaplong;
6654 ccb = cam_getccb(device);
6657 warnx("%s: error allocating ccb", __func__);
6661 bzero(&(&ccb->ccb_h)[1],
6662 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6664 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6691 if ((blocksizeonly != 0)
6692 && (numblocks != 0)) {
6693 warnx("%s: you can only specify one of -b or -N", __func__);
6698 if ((blocksizeonly != 0)
6699 && (sizeonly != 0)) {
6700 warnx("%s: you can only specify one of -b or -s", __func__);
6707 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6713 && (blocksizeonly != 0)) {
6714 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6719 scsi_read_capacity(&ccb->csio,
6720 /*retries*/ retry_count,
6722 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6725 /*timeout*/ timeout ? timeout : 5000);
6727 /* Disable freezing the device queue */
6728 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6730 if (arglist & CAM_ARG_ERR_RECOVER)
6731 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6733 if (cam_send_ccb(device, ccb) < 0) {
6734 warn("error sending READ CAPACITY command");
6736 if (arglist & CAM_ARG_VERBOSE)
6737 cam_error_print(device, ccb, CAM_ESF_ALL,
6738 CAM_EPF_ALL, stderr);
6744 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6745 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6750 maxsector = scsi_4btoul(rcap.addr);
6751 block_len = scsi_4btoul(rcap.length);
6754 * A last block of 2^32-1 means that the true capacity is over 2TB,
6755 * and we need to issue the long READ CAPACITY to get the real
6756 * capacity. Otherwise, we're all set.
6758 if (maxsector != 0xffffffff)
6761 scsi_read_capacity_16(&ccb->csio,
6762 /*retries*/ retry_count,
6764 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6768 /*rcap_buf*/ (uint8_t *)&rcaplong,
6769 /*rcap_buf_len*/ sizeof(rcaplong),
6770 /*sense_len*/ SSD_FULL_SIZE,
6771 /*timeout*/ timeout ? timeout : 5000);
6773 /* Disable freezing the device queue */
6774 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6776 if (arglist & CAM_ARG_ERR_RECOVER)
6777 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6779 if (cam_send_ccb(device, ccb) < 0) {
6780 warn("error sending READ CAPACITY (16) command");
6782 if (arglist & CAM_ARG_VERBOSE)
6783 cam_error_print(device, ccb, CAM_ESF_ALL,
6784 CAM_EPF_ALL, stderr);
6790 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6791 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6796 maxsector = scsi_8btou64(rcaplong.addr);
6797 block_len = scsi_4btoul(rcaplong.length);
6800 if (blocksizeonly == 0) {
6802 * Humanize implies !quiet, and also implies numblocks.
6804 if (humanize != 0) {
6809 tmpbytes = (maxsector + 1) * block_len;
6810 ret = humanize_number(tmpstr, sizeof(tmpstr),
6811 tmpbytes, "", HN_AUTOSCALE,
6814 HN_DIVISOR_1000 : 0));
6816 warnx("%s: humanize_number failed!", __func__);
6820 fprintf(stdout, "Device Size: %s%s", tmpstr,
6821 (sizeonly == 0) ? ", " : "\n");
6822 } else if (numblocks != 0) {
6823 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6824 "Blocks: " : "", (uintmax_t)maxsector + 1,
6825 (sizeonly == 0) ? ", " : "\n");
6827 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6828 "Last Block: " : "", (uintmax_t)maxsector,
6829 (sizeonly == 0) ? ", " : "\n");
6833 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6834 "Block Length: " : "", block_len, (quiet == 0) ?
6843 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6844 int retry_count, int timeout)
6848 uint8_t *smp_request = NULL, *smp_response = NULL;
6849 int request_size = 0, response_size = 0;
6850 int fd_request = 0, fd_response = 0;
6851 char *datastr = NULL;
6852 struct get_hook hook;
6857 * Note that at the moment we don't support sending SMP CCBs to
6858 * devices that aren't probed by CAM.
6860 ccb = cam_getccb(device);
6862 warnx("%s: error allocating CCB", __func__);
6866 bzero(&(&ccb->ccb_h)[1],
6867 sizeof(union ccb) - sizeof(struct ccb_hdr));
6869 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6872 arglist |= CAM_ARG_CMD_IN;
6873 response_size = strtol(optarg, NULL, 0);
6874 if (response_size <= 0) {
6875 warnx("invalid number of response bytes %d",
6878 goto smpcmd_bailout;
6880 hook.argc = argc - optind;
6881 hook.argv = argv + optind;
6884 datastr = cget(&hook, NULL);
6886 * If the user supplied "-" instead of a format, he
6887 * wants the data to be written to stdout.
6889 if ((datastr != NULL)
6890 && (datastr[0] == '-'))
6893 smp_response = (u_int8_t *)malloc(response_size);
6894 if (smp_response == NULL) {
6895 warn("can't malloc memory for SMP response");
6897 goto smpcmd_bailout;
6901 arglist |= CAM_ARG_CMD_OUT;
6902 request_size = strtol(optarg, NULL, 0);
6903 if (request_size <= 0) {
6904 warnx("invalid number of request bytes %d",
6907 goto smpcmd_bailout;
6909 hook.argc = argc - optind;
6910 hook.argv = argv + optind;
6912 datastr = cget(&hook, NULL);
6913 smp_request = (u_int8_t *)malloc(request_size);
6914 if (smp_request == NULL) {
6915 warn("can't malloc memory for SMP request");
6917 goto smpcmd_bailout;
6919 bzero(smp_request, request_size);
6921 * If the user supplied "-" instead of a format, he
6922 * wants the data to be read from stdin.
6924 if ((datastr != NULL)
6925 && (datastr[0] == '-'))
6928 buff_encode_visit(smp_request, request_size,
6939 * If fd_data is set, and we're writing to the device, we need to
6940 * read the data the user wants written from stdin.
6942 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6944 int amt_to_read = request_size;
6945 u_int8_t *buf_ptr = smp_request;
6947 for (amt_read = 0; amt_to_read > 0;
6948 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6949 if (amt_read == -1) {
6950 warn("error reading data from stdin");
6952 goto smpcmd_bailout;
6954 amt_to_read -= amt_read;
6955 buf_ptr += amt_read;
6959 if (((arglist & CAM_ARG_CMD_IN) == 0)
6960 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6961 warnx("%s: need both the request (-r) and response (-R) "
6962 "arguments", __func__);
6964 goto smpcmd_bailout;
6967 flags |= CAM_DEV_QFRZDIS;
6969 cam_fill_smpio(&ccb->smpio,
6970 /*retries*/ retry_count,
6973 /*smp_request*/ smp_request,
6974 /*smp_request_len*/ request_size,
6975 /*smp_response*/ smp_response,
6976 /*smp_response_len*/ response_size,
6977 /*timeout*/ timeout ? timeout : 5000);
6979 ccb->smpio.flags = SMP_FLAG_NONE;
6981 if (((retval = cam_send_ccb(device, ccb)) < 0)
6982 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6983 const char warnstr[] = "error sending command";
6990 if (arglist & CAM_ARG_VERBOSE) {
6991 cam_error_print(device, ccb, CAM_ESF_ALL,
6992 CAM_EPF_ALL, stderr);
6996 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6997 && (response_size > 0)) {
6998 if (fd_response == 0) {
6999 buff_decode_visit(smp_response, response_size,
7000 datastr, arg_put, NULL);
7001 fprintf(stdout, "\n");
7003 ssize_t amt_written;
7004 int amt_to_write = response_size;
7005 u_int8_t *buf_ptr = smp_response;
7007 for (amt_written = 0; (amt_to_write > 0) &&
7008 (amt_written = write(STDOUT_FILENO, buf_ptr,
7009 amt_to_write)) > 0;){
7010 amt_to_write -= amt_written;
7011 buf_ptr += amt_written;
7013 if (amt_written == -1) {
7014 warn("error writing data to stdout");
7016 goto smpcmd_bailout;
7017 } else if ((amt_written == 0)
7018 && (amt_to_write > 0)) {
7019 warnx("only wrote %u bytes out of %u",
7020 response_size - amt_to_write,
7029 if (smp_request != NULL)
7032 if (smp_response != NULL)
7039 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7040 char *combinedopt, int retry_count, int timeout)
7043 struct smp_report_general_request *request = NULL;
7044 struct smp_report_general_response *response = NULL;
7045 struct sbuf *sb = NULL;
7047 int c, long_response = 0;
7051 * Note that at the moment we don't support sending SMP CCBs to
7052 * devices that aren't probed by CAM.
7054 ccb = cam_getccb(device);
7056 warnx("%s: error allocating CCB", __func__);
7060 bzero(&(&ccb->ccb_h)[1],
7061 sizeof(union ccb) - sizeof(struct ccb_hdr));
7063 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7072 request = malloc(sizeof(*request));
7073 if (request == NULL) {
7074 warn("%s: unable to allocate %zd bytes", __func__,
7080 response = malloc(sizeof(*response));
7081 if (response == NULL) {
7082 warn("%s: unable to allocate %zd bytes", __func__,
7089 smp_report_general(&ccb->smpio,
7093 /*request_len*/ sizeof(*request),
7094 (uint8_t *)response,
7095 /*response_len*/ sizeof(*response),
7096 /*long_response*/ long_response,
7099 if (((retval = cam_send_ccb(device, ccb)) < 0)
7100 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7101 const char warnstr[] = "error sending command";
7108 if (arglist & CAM_ARG_VERBOSE) {
7109 cam_error_print(device, ccb, CAM_ESF_ALL,
7110 CAM_EPF_ALL, stderr);
7117 * If the device supports the long response bit, try again and see
7118 * if we can get all of the data.
7120 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7121 && (long_response == 0)) {
7122 ccb->ccb_h.status = CAM_REQ_INPROG;
7123 bzero(&(&ccb->ccb_h)[1],
7124 sizeof(union ccb) - sizeof(struct ccb_hdr));
7130 * XXX KDM detect and decode SMP errors here.
7132 sb = sbuf_new_auto();
7134 warnx("%s: error allocating sbuf", __func__);
7138 smp_report_general_sbuf(response, sizeof(*response), sb);
7140 if (sbuf_finish(sb) != 0) {
7141 warnx("%s: sbuf_finish", __func__);
7145 printf("%s", sbuf_data(sb));
7151 if (request != NULL)
7154 if (response != NULL)
7163 static struct camcontrol_opts phy_ops[] = {
7164 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7165 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7166 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7167 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7168 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7169 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7170 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7171 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7172 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7177 smpphycontrol(struct cam_device *device, int argc, char **argv,
7178 char *combinedopt, int retry_count, int timeout)
7181 struct smp_phy_control_request *request = NULL;
7182 struct smp_phy_control_response *response = NULL;
7183 int long_response = 0;
7186 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7188 uint64_t attached_dev_name = 0;
7189 int dev_name_set = 0;
7190 uint32_t min_plr = 0, max_plr = 0;
7191 uint32_t pp_timeout_val = 0;
7192 int slumber_partial = 0;
7193 int set_pp_timeout_val = 0;
7197 * Note that at the moment we don't support sending SMP CCBs to
7198 * devices that aren't probed by CAM.
7200 ccb = cam_getccb(device);
7202 warnx("%s: error allocating CCB", __func__);
7206 bzero(&(&ccb->ccb_h)[1],
7207 sizeof(union ccb) - sizeof(struct ccb_hdr));
7209 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7217 if (strcasecmp(optarg, "enable") == 0)
7219 else if (strcasecmp(optarg, "disable") == 0)
7222 warnx("%s: Invalid argument %s", __func__,
7229 slumber_partial |= enable <<
7230 SMP_PC_SAS_SLUMBER_SHIFT;
7233 slumber_partial |= enable <<
7234 SMP_PC_SAS_PARTIAL_SHIFT;
7237 slumber_partial |= enable <<
7238 SMP_PC_SATA_SLUMBER_SHIFT;
7241 slumber_partial |= enable <<
7242 SMP_PC_SATA_PARTIAL_SHIFT;
7245 warnx("%s: programmer error", __func__);
7248 break; /*NOTREACHED*/
7253 attached_dev_name = (uintmax_t)strtoumax(optarg,
7262 * We don't do extensive checking here, so this
7263 * will continue to work when new speeds come out.
7265 min_plr = strtoul(optarg, NULL, 0);
7267 || (min_plr > 0xf)) {
7268 warnx("%s: invalid link rate %x",
7276 * We don't do extensive checking here, so this
7277 * will continue to work when new speeds come out.
7279 max_plr = strtoul(optarg, NULL, 0);
7281 || (max_plr > 0xf)) {
7282 warnx("%s: invalid link rate %x",
7289 camcontrol_optret optreturn;
7290 cam_argmask argnums;
7293 if (phy_op_set != 0) {
7294 warnx("%s: only one phy operation argument "
7295 "(-o) allowed", __func__);
7303 * Allow the user to specify the phy operation
7304 * numerically, as well as with a name. This will
7305 * future-proof it a bit, so options that are added
7306 * in future specs can be used.
7308 if (isdigit(optarg[0])) {
7309 phy_operation = strtoul(optarg, NULL, 0);
7310 if ((phy_operation == 0)
7311 || (phy_operation > 0xff)) {
7312 warnx("%s: invalid phy operation %#x",
7313 __func__, phy_operation);
7319 optreturn = getoption(phy_ops, optarg, &phy_operation,
7322 if (optreturn == CC_OR_AMBIGUOUS) {
7323 warnx("%s: ambiguous option %s", __func__,
7328 } else if (optreturn == CC_OR_NOT_FOUND) {
7329 warnx("%s: option %s not found", __func__,
7341 pp_timeout_val = strtoul(optarg, NULL, 0);
7342 if (pp_timeout_val > 15) {
7343 warnx("%s: invalid partial pathway timeout "
7344 "value %u, need a value less than 16",
7345 __func__, pp_timeout_val);
7349 set_pp_timeout_val = 1;
7357 warnx("%s: a PHY (-p phy) argument is required",__func__);
7362 if (((dev_name_set != 0)
7363 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7364 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7365 && (dev_name_set == 0))) {
7366 warnx("%s: -d name and -o setdevname arguments both "
7367 "required to set device name", __func__);
7372 request = malloc(sizeof(*request));
7373 if (request == NULL) {
7374 warn("%s: unable to allocate %zd bytes", __func__,
7380 response = malloc(sizeof(*response));
7381 if (response == NULL) {
7382 warn("%s: unable to allocate %zd bytes", __func__,
7388 smp_phy_control(&ccb->smpio,
7393 (uint8_t *)response,
7396 /*expected_exp_change_count*/ 0,
7399 (set_pp_timeout_val != 0) ? 1 : 0,
7407 if (((retval = cam_send_ccb(device, ccb)) < 0)
7408 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7409 const char warnstr[] = "error sending command";
7416 if (arglist & CAM_ARG_VERBOSE) {
7418 * Use CAM_EPF_NORMAL so we only get one line of
7419 * SMP command decoding.
7421 cam_error_print(device, ccb, CAM_ESF_ALL,
7422 CAM_EPF_NORMAL, stderr);
7428 /* XXX KDM print out something here for success? */
7433 if (request != NULL)
7436 if (response != NULL)
7443 smpmaninfo(struct cam_device *device, int argc, char **argv,
7444 char *combinedopt, int retry_count, int timeout)
7447 struct smp_report_manuf_info_request request;
7448 struct smp_report_manuf_info_response response;
7449 struct sbuf *sb = NULL;
7450 int long_response = 0;
7455 * Note that at the moment we don't support sending SMP CCBs to
7456 * devices that aren't probed by CAM.
7458 ccb = cam_getccb(device);
7460 warnx("%s: error allocating CCB", __func__);
7464 bzero(&(&ccb->ccb_h)[1],
7465 sizeof(union ccb) - sizeof(struct ccb_hdr));
7467 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7476 bzero(&request, sizeof(request));
7477 bzero(&response, sizeof(response));
7479 smp_report_manuf_info(&ccb->smpio,
7484 (uint8_t *)&response,
7489 if (((retval = cam_send_ccb(device, ccb)) < 0)
7490 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7491 const char warnstr[] = "error sending command";
7498 if (arglist & CAM_ARG_VERBOSE) {
7499 cam_error_print(device, ccb, CAM_ESF_ALL,
7500 CAM_EPF_ALL, stderr);
7506 sb = sbuf_new_auto();
7508 warnx("%s: error allocating sbuf", __func__);
7512 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7514 if (sbuf_finish(sb) != 0) {
7515 warnx("%s: sbuf_finish", __func__);
7519 printf("%s", sbuf_data(sb));
7533 getdevid(struct cam_devitem *item)
7536 union ccb *ccb = NULL;
7538 struct cam_device *dev;
7540 dev = cam_open_btl(item->dev_match.path_id,
7541 item->dev_match.target_id,
7542 item->dev_match.target_lun, O_RDWR, NULL);
7545 warnx("%s", cam_errbuf);
7550 item->device_id_len = 0;
7552 ccb = cam_getccb(dev);
7554 warnx("%s: error allocating CCB", __func__);
7559 bzero(&(&ccb->ccb_h)[1],
7560 sizeof(union ccb) - sizeof(struct ccb_hdr));
7563 * On the first try, we just probe for the size of the data, and
7564 * then allocate that much memory and try again.
7567 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7568 ccb->ccb_h.flags = CAM_DIR_IN;
7569 ccb->cdai.flags = CDAI_FLAG_NONE;
7570 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7571 ccb->cdai.bufsiz = item->device_id_len;
7572 if (item->device_id_len != 0)
7573 ccb->cdai.buf = (uint8_t *)item->device_id;
7575 if (cam_send_ccb(dev, ccb) < 0) {
7576 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7581 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7582 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7587 if (item->device_id_len == 0) {
7589 * This is our first time through. Allocate the buffer,
7590 * and then go back to get the data.
7592 if (ccb->cdai.provsiz == 0) {
7593 warnx("%s: invalid .provsiz field returned with "
7594 "XPT_GDEV_ADVINFO CCB", __func__);
7598 item->device_id_len = ccb->cdai.provsiz;
7599 item->device_id = malloc(item->device_id_len);
7600 if (item->device_id == NULL) {
7601 warn("%s: unable to allocate %d bytes", __func__,
7602 item->device_id_len);
7606 ccb->ccb_h.status = CAM_REQ_INPROG;
7612 cam_close_device(dev);
7621 * XXX KDM merge this code with getdevtree()?
7624 buildbusdevlist(struct cam_devlist *devlist)
7627 int bufsize, fd = -1;
7628 struct dev_match_pattern *patterns;
7629 struct cam_devitem *item = NULL;
7630 int skip_device = 0;
7633 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7634 warn("couldn't open %s", XPT_DEVICE);
7638 bzero(&ccb, sizeof(union ccb));
7640 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7641 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7642 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7644 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7645 bufsize = sizeof(struct dev_match_result) * 100;
7646 ccb.cdm.match_buf_len = bufsize;
7647 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7648 if (ccb.cdm.matches == NULL) {
7649 warnx("can't malloc memory for matches");
7653 ccb.cdm.num_matches = 0;
7654 ccb.cdm.num_patterns = 2;
7655 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7656 ccb.cdm.num_patterns;
7658 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7659 if (patterns == NULL) {
7660 warnx("can't malloc memory for patterns");
7665 ccb.cdm.patterns = patterns;
7666 bzero(patterns, ccb.cdm.pattern_buf_len);
7668 patterns[0].type = DEV_MATCH_DEVICE;
7669 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7670 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7671 patterns[1].type = DEV_MATCH_PERIPH;
7672 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7673 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7676 * We do the ioctl multiple times if necessary, in case there are
7677 * more than 100 nodes in the EDT.
7682 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7683 warn("error sending CAMIOCOMMAND ioctl");
7688 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7689 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7690 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7691 warnx("got CAM error %#x, CDM error %d\n",
7692 ccb.ccb_h.status, ccb.cdm.status);
7697 for (i = 0; i < ccb.cdm.num_matches; i++) {
7698 switch (ccb.cdm.matches[i].type) {
7699 case DEV_MATCH_DEVICE: {
7700 struct device_match_result *dev_result;
7703 &ccb.cdm.matches[i].result.device_result;
7705 if (dev_result->flags &
7706 DEV_RESULT_UNCONFIGURED) {
7712 item = malloc(sizeof(*item));
7714 warn("%s: unable to allocate %zd bytes",
7715 __func__, sizeof(*item));
7719 bzero(item, sizeof(*item));
7720 bcopy(dev_result, &item->dev_match,
7721 sizeof(*dev_result));
7722 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7725 if (getdevid(item) != 0) {
7731 case DEV_MATCH_PERIPH: {
7732 struct periph_match_result *periph_result;
7735 &ccb.cdm.matches[i].result.periph_result;
7737 if (skip_device != 0)
7739 item->num_periphs++;
7740 item->periph_matches = realloc(
7741 item->periph_matches,
7743 sizeof(struct periph_match_result));
7744 if (item->periph_matches == NULL) {
7745 warn("%s: error allocating periph "
7750 bcopy(periph_result, &item->periph_matches[
7751 item->num_periphs - 1],
7752 sizeof(*periph_result));
7756 fprintf(stderr, "%s: unexpected match "
7757 "type %d\n", __func__,
7758 ccb.cdm.matches[i].type);
7761 break; /*NOTREACHED*/
7764 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7765 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7773 free(ccb.cdm.matches);
7776 freebusdevlist(devlist);
7782 freebusdevlist(struct cam_devlist *devlist)
7784 struct cam_devitem *item, *item2;
7786 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7787 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7789 free(item->device_id);
7790 free(item->periph_matches);
7795 static struct cam_devitem *
7796 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7798 struct cam_devitem *item;
7800 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7801 struct scsi_vpd_id_descriptor *idd;
7804 * XXX KDM look for LUN IDs as well?
7806 idd = scsi_get_devid(item->device_id,
7807 item->device_id_len,
7808 scsi_devid_is_sas_target);
7812 if (scsi_8btou64(idd->identifier) == sasaddr)
7820 smpphylist(struct cam_device *device, int argc, char **argv,
7821 char *combinedopt, int retry_count, int timeout)
7823 struct smp_report_general_request *rgrequest = NULL;
7824 struct smp_report_general_response *rgresponse = NULL;
7825 struct smp_discover_request *disrequest = NULL;
7826 struct smp_discover_response *disresponse = NULL;
7827 struct cam_devlist devlist;
7829 int long_response = 0;
7836 * Note that at the moment we don't support sending SMP CCBs to
7837 * devices that aren't probed by CAM.
7839 ccb = cam_getccb(device);
7841 warnx("%s: error allocating CCB", __func__);
7845 bzero(&(&ccb->ccb_h)[1],
7846 sizeof(union ccb) - sizeof(struct ccb_hdr));
7847 STAILQ_INIT(&devlist.dev_queue);
7849 rgrequest = malloc(sizeof(*rgrequest));
7850 if (rgrequest == NULL) {
7851 warn("%s: unable to allocate %zd bytes", __func__,
7852 sizeof(*rgrequest));
7857 rgresponse = malloc(sizeof(*rgresponse));
7858 if (rgresponse == NULL) {
7859 warn("%s: unable to allocate %zd bytes", __func__,
7860 sizeof(*rgresponse));
7865 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7878 smp_report_general(&ccb->smpio,
7882 /*request_len*/ sizeof(*rgrequest),
7883 (uint8_t *)rgresponse,
7884 /*response_len*/ sizeof(*rgresponse),
7885 /*long_response*/ long_response,
7888 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7890 if (((retval = cam_send_ccb(device, ccb)) < 0)
7891 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7892 const char warnstr[] = "error sending command";
7899 if (arglist & CAM_ARG_VERBOSE) {
7900 cam_error_print(device, ccb, CAM_ESF_ALL,
7901 CAM_EPF_ALL, stderr);
7907 num_phys = rgresponse->num_phys;
7909 if (num_phys == 0) {
7911 fprintf(stdout, "%s: No Phys reported\n", __func__);
7916 devlist.path_id = device->path_id;
7918 retval = buildbusdevlist(&devlist);
7923 fprintf(stdout, "%d PHYs:\n", num_phys);
7924 fprintf(stdout, "PHY Attached SAS Address\n");
7927 disrequest = malloc(sizeof(*disrequest));
7928 if (disrequest == NULL) {
7929 warn("%s: unable to allocate %zd bytes", __func__,
7930 sizeof(*disrequest));
7935 disresponse = malloc(sizeof(*disresponse));
7936 if (disresponse == NULL) {
7937 warn("%s: unable to allocate %zd bytes", __func__,
7938 sizeof(*disresponse));
7943 for (i = 0; i < num_phys; i++) {
7944 struct cam_devitem *item;
7945 struct device_match_result *dev_match;
7946 char vendor[16], product[48], revision[16];
7950 bzero(&(&ccb->ccb_h)[1],
7951 sizeof(union ccb) - sizeof(struct ccb_hdr));
7953 ccb->ccb_h.status = CAM_REQ_INPROG;
7954 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7956 smp_discover(&ccb->smpio,
7960 sizeof(*disrequest),
7961 (uint8_t *)disresponse,
7962 sizeof(*disresponse),
7964 /*ignore_zone_group*/ 0,
7968 if (((retval = cam_send_ccb(device, ccb)) < 0)
7969 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7970 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7971 const char warnstr[] = "error sending command";
7978 if (arglist & CAM_ARG_VERBOSE) {
7979 cam_error_print(device, ccb, CAM_ESF_ALL,
7980 CAM_EPF_ALL, stderr);
7986 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7988 fprintf(stdout, "%3d <vacant>\n", i);
7992 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7995 item = findsasdevice(&devlist,
7996 scsi_8btou64(disresponse->attached_sas_address));
8000 || (item != NULL)) {
8001 fprintf(stdout, "%3d 0x%016jx", i,
8002 (uintmax_t)scsi_8btou64(
8003 disresponse->attached_sas_address));
8005 fprintf(stdout, "\n");
8008 } else if (quiet != 0)
8011 dev_match = &item->dev_match;
8013 if (dev_match->protocol == PROTO_SCSI) {
8014 cam_strvis(vendor, dev_match->inq_data.vendor,
8015 sizeof(dev_match->inq_data.vendor),
8017 cam_strvis(product, dev_match->inq_data.product,
8018 sizeof(dev_match->inq_data.product),
8020 cam_strvis(revision, dev_match->inq_data.revision,
8021 sizeof(dev_match->inq_data.revision),
8023 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8025 } else if ((dev_match->protocol == PROTO_ATA)
8026 || (dev_match->protocol == PROTO_SATAPM)) {
8027 cam_strvis(product, dev_match->ident_data.model,
8028 sizeof(dev_match->ident_data.model),
8030 cam_strvis(revision, dev_match->ident_data.revision,
8031 sizeof(dev_match->ident_data.revision),
8033 sprintf(tmpstr, "<%s %s>", product, revision);
8035 sprintf(tmpstr, "<>");
8037 fprintf(stdout, " %-33s ", tmpstr);
8040 * If we have 0 periphs, that's a bug...
8042 if (item->num_periphs == 0) {
8043 fprintf(stdout, "\n");
8047 fprintf(stdout, "(");
8048 for (j = 0; j < item->num_periphs; j++) {
8050 fprintf(stdout, ",");
8052 fprintf(stdout, "%s%d",
8053 item->periph_matches[j].periph_name,
8054 item->periph_matches[j].unit_number);
8057 fprintf(stdout, ")\n");
8071 freebusdevlist(&devlist);
8077 atapm(struct cam_device *device, int argc, char **argv,
8078 char *combinedopt, int retry_count, int timeout)
8086 ccb = cam_getccb(device);
8089 warnx("%s: error allocating ccb", __func__);
8093 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8102 if (strcmp(argv[1], "idle") == 0) {
8104 cmd = ATA_IDLE_IMMEDIATE;
8107 } else if (strcmp(argv[1], "standby") == 0) {
8109 cmd = ATA_STANDBY_IMMEDIATE;
8111 cmd = ATA_STANDBY_CMD;
8119 else if (t <= (240 * 5))
8121 else if (t <= (252 * 5))
8122 /* special encoding for 21 minutes */
8124 else if (t <= (11 * 30 * 60))
8125 sc = (t - 1) / (30 * 60) + 241;
8129 retval = ata_do_28bit_cmd(device,
8131 /*retries*/retry_count,
8132 /*flags*/CAM_DIR_NONE,
8133 /*protocol*/AP_PROTO_NON_DATA,
8134 /*tag_action*/MSG_SIMPLE_Q_TAG,
8141 /*timeout*/timeout ? timeout : 30 * 1000,
8149 ataaxm(struct cam_device *device, int argc, char **argv,
8150 char *combinedopt, int retry_count, int timeout)
8158 ccb = cam_getccb(device);
8161 warnx("%s: error allocating ccb", __func__);
8165 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8175 if (strcmp(argv[1], "apm") == 0) {
8191 retval = ata_do_28bit_cmd(device,
8193 /*retries*/retry_count,
8194 /*flags*/CAM_DIR_NONE,
8195 /*protocol*/AP_PROTO_NON_DATA,
8196 /*tag_action*/MSG_SIMPLE_Q_TAG,
8197 /*command*/ATA_SETFEATURES,
8203 /*timeout*/timeout ? timeout : 30 * 1000,
8211 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8212 int show_sa_errors, int sa_set, int service_action,
8213 int timeout_desc, int retry_count, int timeout, int verbosemode,
8214 uint32_t *fill_len, uint8_t **data_ptr)
8216 union ccb *ccb = NULL;
8217 uint8_t *buf = NULL;
8218 uint32_t alloc_len = 0, num_opcodes;
8219 uint32_t valid_len = 0;
8220 uint32_t avail_len = 0;
8221 struct scsi_report_supported_opcodes_all *all_hdr;
8222 struct scsi_report_supported_opcodes_one *one;
8227 * Make it clear that we haven't yet allocated or filled anything.
8232 ccb = cam_getccb(device);
8234 warnx("couldn't allocate CCB");
8239 /* cam_getccb cleans up the header, caller has to zero the payload */
8240 bzero(&(&ccb->ccb_h)[1],
8241 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
8243 if (opcode_set != 0) {
8244 options |= RSO_OPTIONS_OC;
8246 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8249 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8250 sizeof(struct scsi_report_supported_opcodes_descr));
8253 if (timeout_desc != 0) {
8254 options |= RSO_RCTD;
8255 alloc_len += num_opcodes *
8256 sizeof(struct scsi_report_supported_opcodes_timeout);
8260 options |= RSO_OPTIONS_OC_SA;
8261 if (show_sa_errors != 0)
8262 options &= ~RSO_OPTIONS_OC;
8271 buf = malloc(alloc_len);
8273 warn("Unable to allocate %u bytes", alloc_len);
8277 bzero(buf, alloc_len);
8279 scsi_report_supported_opcodes(&ccb->csio,
8280 /*retries*/ retry_count,
8282 /*tag_action*/ MSG_SIMPLE_Q_TAG,
8283 /*options*/ options,
8284 /*req_opcode*/ opcode,
8285 /*req_service_action*/ service_action,
8287 /*dxfer_len*/ alloc_len,
8288 /*sense_len*/ SSD_FULL_SIZE,
8289 /*timeout*/ timeout ? timeout : 10000);
8291 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8293 if (retry_count != 0)
8294 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8296 if (cam_send_ccb(device, ccb) < 0) {
8297 perror("error sending REPORT SUPPORTED OPERATION CODES");
8302 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8303 if (verbosemode != 0)
8304 cam_error_print(device, ccb, CAM_ESF_ALL,
8305 CAM_EPF_ALL, stderr);
8311 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8313 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8314 && (valid_len >= sizeof(*all_hdr))) {
8315 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8316 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8317 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8318 && (valid_len >= sizeof(*one))) {
8319 uint32_t cdb_length;
8321 one = (struct scsi_report_supported_opcodes_one *)buf;
8322 cdb_length = scsi_2btoul(one->cdb_length);
8323 avail_len = sizeof(*one) + cdb_length;
8324 if (one->support & RSO_ONE_CTDP) {
8325 struct scsi_report_supported_opcodes_timeout *td;
8327 td = (struct scsi_report_supported_opcodes_timeout *)
8329 if (valid_len >= (avail_len + sizeof(td->length))) {
8330 avail_len += scsi_2btoul(td->length) +
8333 avail_len += sizeof(*td);
8339 * avail_len could be zero if we didn't get enough data back from
8340 * thet target to determine
8342 if ((avail_len != 0)
8343 && (avail_len > valid_len)) {
8344 alloc_len = avail_len;
8348 *fill_len = valid_len;
8360 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8361 int req_sa, uint8_t *buf, uint32_t valid_len)
8363 struct scsi_report_supported_opcodes_one *one;
8364 struct scsi_report_supported_opcodes_timeout *td;
8365 uint32_t cdb_len = 0, td_len = 0;
8366 const char *op_desc = NULL;
8370 one = (struct scsi_report_supported_opcodes_one *)buf;
8373 * If we don't have the full single opcode descriptor, no point in
8376 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8378 warnx("Only %u bytes returned, not enough to verify support",
8384 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8386 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8389 printf(", SA 0x%x", req_sa);
8392 switch (one->support & RSO_ONE_SUP_MASK) {
8393 case RSO_ONE_SUP_UNAVAIL:
8394 printf("No command support information currently available\n");
8396 case RSO_ONE_SUP_NOT_SUP:
8397 printf("Command not supported\n");
8400 break; /*NOTREACHED*/
8401 case RSO_ONE_SUP_AVAIL:
8402 printf("Command is supported, complies with a SCSI standard\n");
8404 case RSO_ONE_SUP_VENDOR:
8405 printf("Command is supported, vendor-specific "
8406 "implementation\n");
8409 printf("Unknown command support flags 0x%#x\n",
8410 one->support & RSO_ONE_SUP_MASK);
8415 * If we don't have the CDB length, it isn't exactly an error, the
8416 * command probably isn't supported.
8418 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8422 cdb_len = scsi_2btoul(one->cdb_length);
8425 * If our valid data doesn't include the full reported length,
8426 * return. The caller should have detected this and adjusted his
8427 * allocation length to get all of the available data.
8429 if (valid_len < sizeof(*one) + cdb_len) {
8435 * If all we have is the opcode, there is no point in printing out
8443 printf("CDB usage bitmap:");
8444 for (i = 0; i < cdb_len; i++) {
8445 printf(" %02x", one->cdb_usage[i]);
8450 * If we don't have a timeout descriptor, we're done.
8452 if ((one->support & RSO_ONE_CTDP) == 0)
8456 * If we don't have enough valid length to include the timeout
8457 * descriptor length, we're done.
8459 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8462 td = (struct scsi_report_supported_opcodes_timeout *)
8463 &buf[sizeof(*one) + cdb_len];
8464 td_len = scsi_2btoul(td->length);
8465 td_len += sizeof(td->length);
8468 * If we don't have the full timeout descriptor, we're done.
8470 if (td_len < sizeof(*td))
8474 * If we don't have enough valid length to contain the full timeout
8475 * descriptor, we're done.
8477 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8480 printf("Timeout information:\n");
8481 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8482 printf("Nominal timeout: %u seconds\n",
8483 scsi_4btoul(td->nominal_time));
8484 printf("Recommended timeout: %u seconds\n",
8485 scsi_4btoul(td->recommended_time));
8492 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8495 struct scsi_report_supported_opcodes_all *hdr;
8496 struct scsi_report_supported_opcodes_descr *desc;
8497 uint32_t avail_len = 0, used_len = 0;
8501 if (valid_len < sizeof(*hdr)) {
8502 warnx("%s: not enough returned data (%u bytes) opcode list",
8503 __func__, valid_len);
8507 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8508 avail_len = scsi_4btoul(hdr->length);
8509 avail_len += sizeof(hdr->length);
8511 * Take the lesser of the amount of data the drive claims is
8512 * available, and the amount of data the HBA says was returned.
8514 avail_len = MIN(avail_len, valid_len);
8516 used_len = sizeof(hdr->length);
8518 printf("%-6s %4s %8s ",
8519 "Opcode", "SA", "CDB len" );
8522 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8523 printf(" Description\n");
8525 while ((avail_len - used_len) > sizeof(*desc)) {
8526 struct scsi_report_supported_opcodes_timeout *td;
8528 const char *op_desc = NULL;
8530 cur_ptr = &buf[used_len];
8531 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8533 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8534 if (op_desc == NULL)
8535 op_desc = "UNKNOWN";
8537 printf("0x%02x %#4x %8u ", desc->opcode,
8538 scsi_2btoul(desc->service_action),
8539 scsi_2btoul(desc->cdb_length));
8541 used_len += sizeof(*desc);
8543 if ((desc->flags & RSO_CTDP) == 0) {
8544 printf(" %s\n", op_desc);
8549 * If we don't have enough space to fit a timeout
8550 * descriptor, then we're done.
8552 if (avail_len - used_len < sizeof(*td)) {
8553 used_len = avail_len;
8554 printf(" %s\n", op_desc);
8557 cur_ptr = &buf[used_len];
8558 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8559 td_len = scsi_2btoul(td->length);
8560 td_len += sizeof(td->length);
8564 * If the given timeout descriptor length is less than what
8565 * we understand, skip it.
8567 if (td_len < sizeof(*td)) {
8568 printf(" %s\n", op_desc);
8572 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8573 scsi_4btoul(td->nominal_time),
8574 scsi_4btoul(td->recommended_time), op_desc);
8581 scsiopcodes(struct cam_device *device, int argc, char **argv,
8582 char *combinedopt, int retry_count, int timeout, int verbosemode)
8585 uint32_t opcode = 0, service_action = 0;
8586 int td_set = 0, opcode_set = 0, sa_set = 0;
8587 int show_sa_errors = 1;
8588 uint32_t valid_len = 0;
8589 uint8_t *buf = NULL;
8593 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8599 opcode = strtoul(optarg, &endptr, 0);
8600 if (*endptr != '\0') {
8601 warnx("Invalid opcode \"%s\", must be a number",
8606 if (opcode > 0xff) {
8607 warnx("Invalid opcode 0x%#x, must be between"
8608 "0 and 0xff inclusive", opcode);
8615 service_action = strtoul(optarg, &endptr, 0);
8616 if (*endptr != '\0') {
8617 warnx("Invalid service action \"%s\", must "
8618 "be a number", optarg);
8622 if (service_action > 0xffff) {
8623 warnx("Invalid service action 0x%#x, must "
8624 "be between 0 and 0xffff inclusive",
8639 && (opcode_set == 0)) {
8640 warnx("You must specify an opcode with -o if a service "
8645 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8646 sa_set, service_action, td_set, retry_count,
8647 timeout, verbosemode, &valid_len, &buf);
8651 if ((opcode_set != 0)
8653 retval = scsiprintoneopcode(device, opcode, sa_set,
8654 service_action, buf, valid_len);
8656 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8665 #endif /* MINIMALISTIC */
8668 usage(int printlong)
8671 fprintf(printlong ? stdout : stderr,
8672 "usage: camcontrol <command> [device id][generic args][command args]\n"
8673 " camcontrol devlist [-b] [-v]\n"
8674 #ifndef MINIMALISTIC
8675 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8676 " camcontrol tur [dev_id][generic args]\n"
8677 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8678 " camcontrol identify [dev_id][generic args] [-v]\n"
8679 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8680 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8682 " camcontrol start [dev_id][generic args]\n"
8683 " camcontrol stop [dev_id][generic args]\n"
8684 " camcontrol load [dev_id][generic args]\n"
8685 " camcontrol eject [dev_id][generic args]\n"
8686 #endif /* MINIMALISTIC */
8687 " camcontrol rescan <all | bus[:target:lun]>\n"
8688 " camcontrol reset <all | bus[:target:lun]>\n"
8689 #ifndef MINIMALISTIC
8690 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8691 " [-q][-s][-S offset][-X]\n"
8692 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8693 " [-P pagectl][-e | -b][-d]\n"
8694 " camcontrol cmd [dev_id][generic args]\n"
8695 " <-a cmd [args] | -c cmd [args]>\n"
8696 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8697 " camcontrol smpcmd [dev_id][generic args]\n"
8698 " <-r len fmt [args]> <-R len fmt [args]>\n"
8699 " camcontrol smprg [dev_id][generic args][-l]\n"
8700 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8701 " [-o operation][-d name][-m rate][-M rate]\n"
8702 " [-T pp_timeout][-a enable|disable]\n"
8703 " [-A enable|disable][-s enable|disable]\n"
8704 " [-S enable|disable]\n"
8705 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8706 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8707 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8708 " <all|bus[:target[:lun]]|off>\n"
8709 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8710 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8711 " [-D <enable|disable>][-M mode][-O offset]\n"
8712 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8713 " [-U][-W bus_width]\n"
8714 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8715 " camcontrol sanitize [dev_id][generic args]\n"
8716 " [-a overwrite|block|crypto|exitfailure]\n"
8717 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8719 " camcontrol idle [dev_id][generic args][-t time]\n"
8720 " camcontrol standby [dev_id][generic args][-t time]\n"
8721 " camcontrol sleep [dev_id][generic args]\n"
8722 " camcontrol apm [dev_id][generic args][-l level]\n"
8723 " camcontrol aam [dev_id][generic args][-l level]\n"
8724 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8726 " camcontrol security [dev_id][generic args]\n"
8727 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8728 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8729 " [-U <user|master>] [-y]\n"
8730 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8731 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8732 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8733 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8734 " [-s scope][-S][-T type][-U]\n"
8735 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8736 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8737 " [-p part][-s start][-T type][-V vol]\n"
8738 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8740 #endif /* MINIMALISTIC */
8741 " camcontrol help\n");
8744 #ifndef MINIMALISTIC
8746 "Specify one of the following options:\n"
8747 "devlist list all CAM devices\n"
8748 "periphlist list all CAM peripheral drivers attached to a device\n"
8749 "tur send a test unit ready to the named device\n"
8750 "inquiry send a SCSI inquiry command to the named device\n"
8751 "identify send a ATA identify command to the named device\n"
8752 "reportluns send a SCSI report luns command to the device\n"
8753 "readcap send a SCSI read capacity command to the device\n"
8754 "start send a Start Unit command to the device\n"
8755 "stop send a Stop Unit command to the device\n"
8756 "load send a Start Unit command to the device with the load bit set\n"
8757 "eject send a Stop Unit command to the device with the eject bit set\n"
8758 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8759 "reset reset all busses, the given bus, or bus:target:lun\n"
8760 "defects read the defect list of the specified device\n"
8761 "modepage display or edit (-e) the given mode page\n"
8762 "cmd send the given SCSI command, may need -i or -o as well\n"
8763 "smpcmd send the given SMP command, requires -o and -i\n"
8764 "smprg send the SMP Report General command\n"
8765 "smppc send the SMP PHY Control command, requires -p\n"
8766 "smpphylist display phys attached to a SAS expander\n"
8767 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8768 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8769 "tags report or set the number of transaction slots for a device\n"
8770 "negotiate report or set device negotiation parameters\n"
8771 "format send the SCSI FORMAT UNIT command to the named device\n"
8772 "sanitize send the SCSI SANITIZE command to the named device\n"
8773 "idle send the ATA IDLE command to the named device\n"
8774 "standby send the ATA STANDBY command to the named device\n"
8775 "sleep send the ATA SLEEP command to the named device\n"
8776 "fwdownload program firmware of the named device with the given image\n"
8777 "security report or send ATA security commands to the named device\n"
8778 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8779 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8780 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8781 "help this message\n"
8782 "Device Identifiers:\n"
8783 "bus:target specify the bus and target, lun defaults to 0\n"
8784 "bus:target:lun specify the bus, target and lun\n"
8785 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8786 "Generic arguments:\n"
8787 "-v be verbose, print out sense information\n"
8788 "-t timeout command timeout in seconds, overrides default timeout\n"
8789 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8790 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8791 "-E have the kernel attempt to perform SCSI error recovery\n"
8792 "-C count specify the SCSI command retry count (needs -E to work)\n"
8793 "modepage arguments:\n"
8794 "-l list all available mode pages\n"
8795 "-m page specify the mode page to view or edit\n"
8796 "-e edit the specified mode page\n"
8797 "-b force view to binary mode\n"
8798 "-d disable block descriptors for mode sense\n"
8799 "-P pgctl page control field 0-3\n"
8800 "defects arguments:\n"
8801 "-f format specify defect list format (block, bfi or phys)\n"
8802 "-G get the grown defect list\n"
8803 "-P get the permanent defect list\n"
8804 "inquiry arguments:\n"
8805 "-D get the standard inquiry data\n"
8806 "-S get the serial number\n"
8807 "-R get the transfer rate, etc.\n"
8808 "reportluns arguments:\n"
8809 "-c only report a count of available LUNs\n"
8810 "-l only print out luns, and not a count\n"
8811 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
8812 "readcap arguments\n"
8813 "-b only report the blocksize\n"
8814 "-h human readable device size, base 2\n"
8815 "-H human readable device size, base 10\n"
8816 "-N print the number of blocks instead of last block\n"
8817 "-q quiet, print numbers only\n"
8818 "-s only report the last block/device size\n"
8820 "-c cdb [args] specify the SCSI CDB\n"
8821 "-i len fmt specify input data and input data format\n"
8822 "-o len fmt [args] specify output data and output data fmt\n"
8823 "smpcmd arguments:\n"
8824 "-r len fmt [args] specify the SMP command to be sent\n"
8825 "-R len fmt [args] specify SMP response format\n"
8826 "smprg arguments:\n"
8827 "-l specify the long response format\n"
8828 "smppc arguments:\n"
8829 "-p phy specify the PHY to operate on\n"
8830 "-l specify the long request/response format\n"
8831 "-o operation specify the phy control operation\n"
8832 "-d name set the attached device name\n"
8833 "-m rate set the minimum physical link rate\n"
8834 "-M rate set the maximum physical link rate\n"
8835 "-T pp_timeout set the partial pathway timeout value\n"
8836 "-a enable|disable enable or disable SATA slumber\n"
8837 "-A enable|disable enable or disable SATA partial phy power\n"
8838 "-s enable|disable enable or disable SAS slumber\n"
8839 "-S enable|disable enable or disable SAS partial phy power\n"
8840 "smpphylist arguments:\n"
8841 "-l specify the long response format\n"
8842 "-q only print phys with attached devices\n"
8843 "smpmaninfo arguments:\n"
8844 "-l specify the long response format\n"
8845 "debug arguments:\n"
8846 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
8847 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
8848 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
8849 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
8851 "-N tags specify the number of tags to use for this device\n"
8852 "-q be quiet, don't report the number of tags\n"
8853 "-v report a number of tag-related parameters\n"
8854 "negotiate arguments:\n"
8855 "-a send a test unit ready after negotiation\n"
8856 "-c report/set current negotiation settings\n"
8857 "-D <arg> \"enable\" or \"disable\" disconnection\n"
8858 "-M mode set ATA mode\n"
8859 "-O offset set command delay offset\n"
8860 "-q be quiet, don't report anything\n"
8861 "-R syncrate synchronization rate in MHz\n"
8862 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
8863 "-U report/set user negotiation settings\n"
8864 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
8865 "-v also print a Path Inquiry CCB for the controller\n"
8866 "format arguments:\n"
8867 "-q be quiet, don't print status messages\n"
8868 "-r run in report only mode\n"
8869 "-w don't send immediate format command\n"
8870 "-y don't ask any questions\n"
8871 "sanitize arguments:\n"
8872 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
8873 "-c passes overwrite passes to perform (1 to 31)\n"
8874 "-I invert overwrite pattern after each pass\n"
8875 "-P pattern path to overwrite pattern file\n"
8876 "-q be quiet, don't print status messages\n"
8877 "-r run in report only mode\n"
8878 "-U run operation in unrestricted completion exit mode\n"
8879 "-w don't send immediate sanitize command\n"
8880 "-y don't ask any questions\n"
8881 "idle/standby arguments:\n"
8882 "-t <arg> number of seconds before respective state.\n"
8883 "fwdownload arguments:\n"
8884 "-f fw_image path to firmware image file\n"
8885 "-q don't print informational messages, only errors\n"
8886 "-s run in simulation mode\n"
8887 "-v print info for every firmware segment sent to device\n"
8888 "-y don't ask any questions\n"
8889 "security arguments:\n"
8890 "-d pwd disable security using the given password for the selected\n"
8892 "-e pwd erase the device using the given pwd for the selected user\n"
8893 "-f freeze the security configuration of the specified device\n"
8894 "-h pwd enhanced erase the device using the given pwd for the\n"
8896 "-k pwd unlock the device using the given pwd for the selected\n"
8898 "-l <high|maximum> specifies which security level to set: high or maximum\n"
8899 "-q be quiet, do not print any status messages\n"
8900 "-s pwd password the device (enable security) using the given\n"
8901 " pwd for the selected user\n"
8902 "-T timeout overrides the timeout (seconds) used for erase operation\n"
8903 "-U <user|master> specifies which user to set: user or master\n"
8904 "-y don't ask any questions\n"
8906 "-f freeze the HPA configuration of the device\n"
8907 "-l lock the HPA configuration of the device\n"
8908 "-P make the HPA max sectors persist\n"
8909 "-p pwd Set the HPA configuration password required for unlock\n"
8911 "-q be quiet, do not print any status messages\n"
8912 "-s sectors configures the maximum user accessible sectors of the\n"
8914 "-U pwd unlock the HPA configuration of the device\n"
8915 "-y don't ask any questions\n"
8916 "persist arguments:\n"
8917 "-i action specify read_keys, read_reservation, report_cap, or\n"
8918 " read_full_status\n"
8919 "-o action specify register, register_ignore, reserve, release,\n"
8920 " clear, preempt, preempt_abort, register_move, replace_lost\n"
8921 "-a set the All Target Ports (ALL_TG_PT) bit\n"
8922 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
8923 "-k key specify the Reservation Key\n"
8924 "-K sa_key specify the Service Action Reservation Key\n"
8925 "-p set the Activate Persist Through Power Loss bit\n"
8926 "-R rtp specify the Relative Target Port\n"
8927 "-s scope specify the scope: lun, extent, element or a number\n"
8928 "-S specify Transport ID for register, requires -I\n"
8929 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
8930 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
8931 "-U unregister the current initiator for register_move\n"
8932 "attrib arguments:\n"
8933 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
8935 "-w attr specify an attribute to write, one -w argument per attr\n"
8936 "-a attr_num only display this attribute number\n"
8937 "-c get cached attributes\n"
8938 "-e elem_addr request attributes for the given element in a changer\n"
8939 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
8940 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
8941 " field_none, field_desc, field_num, field_size, field_rw\n"
8942 "-p partition request attributes for the given partition\n"
8943 "-s start_attr request attributes starting at the given number\n"
8944 "-T elem_type specify the element type (used with -e)\n"
8945 "-V logical_vol specify the logical volume ID\n"
8946 "opcodes arguments:\n"
8947 "-o opcode specify the individual opcode to list\n"
8948 "-s service_action specify the service action for the opcode\n"
8949 "-N do not return SCSI error for unsupported SA\n"
8950 "-T request nominal and recommended timeout values\n"
8952 #endif /* MINIMALISTIC */
8956 main(int argc, char **argv)
8959 char *device = NULL;
8961 struct cam_device *cam_dev = NULL;
8962 int timeout = 0, retry_count = 1;
8963 camcontrol_optret optreturn;
8965 const char *mainopt = "C:En:t:u:v";
8966 const char *subopt = NULL;
8967 char combinedopt[256];
8968 int error = 0, optstart = 2;
8970 #ifndef MINIMALISTIC
8974 #endif /* MINIMALISTIC */
8976 cmdlist = CAM_CMD_NONE;
8977 arglist = CAM_ARG_NONE;
8985 * Get the base option.
8987 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
8989 if (optreturn == CC_OR_AMBIGUOUS) {
8990 warnx("ambiguous option %s", argv[1]);
8993 } else if (optreturn == CC_OR_NOT_FOUND) {
8994 warnx("option %s not found", argv[1]);
9000 * Ahh, getopt(3) is a pain.
9002 * This is a gross hack. There really aren't many other good
9003 * options (excuse the pun) for parsing options in a situation like
9004 * this. getopt is kinda braindead, so you end up having to run
9005 * through the options twice, and give each invocation of getopt
9006 * the option string for the other invocation.
9008 * You would think that you could just have two groups of options.
9009 * The first group would get parsed by the first invocation of
9010 * getopt, and the second group would get parsed by the second
9011 * invocation of getopt. It doesn't quite work out that way. When
9012 * the first invocation of getopt finishes, it leaves optind pointing
9013 * to the argument _after_ the first argument in the second group.
9014 * So when the second invocation of getopt comes around, it doesn't
9015 * recognize the first argument it gets and then bails out.
9017 * A nice alternative would be to have a flag for getopt that says
9018 * "just keep parsing arguments even when you encounter an unknown
9019 * argument", but there isn't one. So there's no real clean way to
9020 * easily parse two sets of arguments without having one invocation
9021 * of getopt know about the other.
9023 * Without this hack, the first invocation of getopt would work as
9024 * long as the generic arguments are first, but the second invocation
9025 * (in the subfunction) would fail in one of two ways. In the case
9026 * where you don't set optreset, it would fail because optind may be
9027 * pointing to the argument after the one it should be pointing at.
9028 * In the case where you do set optreset, and reset optind, it would
9029 * fail because getopt would run into the first set of options, which
9030 * it doesn't understand.
9032 * All of this would "sort of" work if you could somehow figure out
9033 * whether optind had been incremented one option too far. The
9034 * mechanics of that, however, are more daunting than just giving
9035 * both invocations all of the expect options for either invocation.
9037 * Needless to say, I wouldn't mind if someone invented a better
9038 * (non-GPL!) command line parsing interface than getopt. I
9039 * wouldn't mind if someone added more knobs to getopt to make it
9040 * work better. Who knows, I may talk myself into doing it someday,
9041 * if the standards weenies let me. As it is, it just leads to
9042 * hackery like this and causes people to avoid it in some cases.
9044 * KDM, September 8th, 1998
9047 sprintf(combinedopt, "%s%s", mainopt, subopt);
9049 sprintf(combinedopt, "%s", mainopt);
9052 * For these options we do not parse optional device arguments and
9053 * we do not open a passthrough device.
9055 if ((cmdlist == CAM_CMD_RESCAN)
9056 || (cmdlist == CAM_CMD_RESET)
9057 || (cmdlist == CAM_CMD_DEVTREE)
9058 || (cmdlist == CAM_CMD_USAGE)
9059 || (cmdlist == CAM_CMD_DEBUG))
9062 #ifndef MINIMALISTIC
9064 && (argc > 2 && argv[2][0] != '-')) {
9068 if (isdigit(argv[2][0])) {
9069 /* device specified as bus:target[:lun] */
9070 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9072 errx(1, "numeric device specification must "
9073 "be either bus:target, or "
9075 /* default to 0 if lun was not specified */
9076 if ((arglist & CAM_ARG_LUN) == 0) {
9078 arglist |= CAM_ARG_LUN;
9082 if (cam_get_device(argv[2], name, sizeof name, &unit)
9084 errx(1, "%s", cam_errbuf);
9085 device = strdup(name);
9086 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9090 #endif /* MINIMALISTIC */
9092 * Start getopt processing at argv[2/3], since we've already
9093 * accepted argv[1..2] as the command name, and as a possible
9099 * Now we run through the argument list looking for generic
9100 * options, and ignoring options that possibly belong to
9103 while ((c = getopt(argc, argv, combinedopt))!= -1){
9106 retry_count = strtol(optarg, NULL, 0);
9107 if (retry_count < 0)
9108 errx(1, "retry count %d is < 0",
9110 arglist |= CAM_ARG_RETRIES;
9113 arglist |= CAM_ARG_ERR_RECOVER;
9116 arglist |= CAM_ARG_DEVICE;
9118 while (isspace(*tstr) && (*tstr != '\0'))
9120 device = (char *)strdup(tstr);
9123 timeout = strtol(optarg, NULL, 0);
9125 errx(1, "invalid timeout %d", timeout);
9126 /* Convert the timeout from seconds to ms */
9128 arglist |= CAM_ARG_TIMEOUT;
9131 arglist |= CAM_ARG_UNIT;
9132 unit = strtol(optarg, NULL, 0);
9135 arglist |= CAM_ARG_VERBOSE;
9142 #ifndef MINIMALISTIC
9144 * For most commands we'll want to open the passthrough device
9145 * associated with the specified device. In the case of the rescan
9146 * commands, we don't use a passthrough device at all, just the
9147 * transport layer device.
9150 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9151 && (((arglist & CAM_ARG_DEVICE) == 0)
9152 || ((arglist & CAM_ARG_UNIT) == 0))) {
9153 errx(1, "subcommand \"%s\" requires a valid device "
9154 "identifier", argv[1]);
9157 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9158 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9159 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9161 errx(1,"%s", cam_errbuf);
9163 #endif /* MINIMALISTIC */
9166 * Reset optind to 2, and reset getopt, so these routines can parse
9167 * the arguments again.
9173 #ifndef MINIMALISTIC
9174 case CAM_CMD_DEVLIST:
9175 error = getdevlist(cam_dev);
9178 error = atahpa(cam_dev, retry_count, timeout,
9179 argc, argv, combinedopt);
9181 #endif /* MINIMALISTIC */
9182 case CAM_CMD_DEVTREE:
9183 error = getdevtree(argc, argv, combinedopt);
9185 #ifndef MINIMALISTIC
9187 error = testunitready(cam_dev, retry_count, timeout, 0);
9189 case CAM_CMD_INQUIRY:
9190 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9191 retry_count, timeout);
9193 case CAM_CMD_IDENTIFY:
9194 error = ataidentify(cam_dev, retry_count, timeout);
9196 case CAM_CMD_STARTSTOP:
9197 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9198 arglist & CAM_ARG_EJECT, retry_count,
9201 #endif /* MINIMALISTIC */
9202 case CAM_CMD_RESCAN:
9203 error = dorescan_or_reset(argc, argv, 1);
9206 error = dorescan_or_reset(argc, argv, 0);
9208 #ifndef MINIMALISTIC
9209 case CAM_CMD_READ_DEFECTS:
9210 error = readdefects(cam_dev, argc, argv, combinedopt,
9211 retry_count, timeout);
9213 case CAM_CMD_MODE_PAGE:
9214 modepage(cam_dev, argc, argv, combinedopt,
9215 retry_count, timeout);
9217 case CAM_CMD_SCSI_CMD:
9218 error = scsicmd(cam_dev, argc, argv, combinedopt,
9219 retry_count, timeout);
9221 case CAM_CMD_SMP_CMD:
9222 error = smpcmd(cam_dev, argc, argv, combinedopt,
9223 retry_count, timeout);
9225 case CAM_CMD_SMP_RG:
9226 error = smpreportgeneral(cam_dev, argc, argv,
9227 combinedopt, retry_count,
9230 case CAM_CMD_SMP_PC:
9231 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9232 retry_count, timeout);
9234 case CAM_CMD_SMP_PHYLIST:
9235 error = smpphylist(cam_dev, argc, argv, combinedopt,
9236 retry_count, timeout);
9238 case CAM_CMD_SMP_MANINFO:
9239 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9240 retry_count, timeout);
9243 error = camdebug(argc, argv, combinedopt);
9246 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9249 error = ratecontrol(cam_dev, retry_count, timeout,
9250 argc, argv, combinedopt);
9252 case CAM_CMD_FORMAT:
9253 error = scsiformat(cam_dev, argc, argv,
9254 combinedopt, retry_count, timeout);
9256 case CAM_CMD_REPORTLUNS:
9257 error = scsireportluns(cam_dev, argc, argv,
9258 combinedopt, retry_count,
9261 case CAM_CMD_READCAP:
9262 error = scsireadcapacity(cam_dev, argc, argv,
9263 combinedopt, retry_count,
9267 case CAM_CMD_STANDBY:
9269 error = atapm(cam_dev, argc, argv,
9270 combinedopt, retry_count, timeout);
9274 error = ataaxm(cam_dev, argc, argv,
9275 combinedopt, retry_count, timeout);
9277 case CAM_CMD_SECURITY:
9278 error = atasecurity(cam_dev, retry_count, timeout,
9279 argc, argv, combinedopt);
9281 case CAM_CMD_DOWNLOAD_FW:
9282 error = fwdownload(cam_dev, argc, argv, combinedopt,
9283 arglist & CAM_ARG_VERBOSE, retry_count, timeout);
9285 case CAM_CMD_SANITIZE:
9286 error = scsisanitize(cam_dev, argc, argv,
9287 combinedopt, retry_count, timeout);
9289 case CAM_CMD_PERSIST:
9290 error = scsipersist(cam_dev, argc, argv, combinedopt,
9291 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9292 arglist & CAM_ARG_ERR_RECOVER);
9294 case CAM_CMD_ATTRIB:
9295 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9296 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9297 arglist & CAM_ARG_ERR_RECOVER);
9299 case CAM_CMD_OPCODES:
9300 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9301 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9303 #endif /* MINIMALISTIC */
9313 if (cam_dev != NULL)
9314 cam_close_device(cam_dev);