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);
817 if (arglist & CAM_ARG_GET_XFERRATE)
818 error = camxferrate(device);
824 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
827 struct scsi_inquiry_data *inq_buf;
830 ccb = cam_getccb(device);
833 warnx("couldn't allocate CCB");
837 /* cam_getccb cleans up the header, caller has to zero the payload */
838 bzero(&(&ccb->ccb_h)[1],
839 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
841 inq_buf = (struct scsi_inquiry_data *)malloc(
842 sizeof(struct scsi_inquiry_data));
844 if (inq_buf == NULL) {
846 warnx("can't malloc memory for inquiry\n");
849 bzero(inq_buf, sizeof(*inq_buf));
852 * Note that although the size of the inquiry buffer is the full
853 * 256 bytes specified in the SCSI spec, we only tell the device
854 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
855 * two reasons for this:
857 * - The SCSI spec says that when a length field is only 1 byte,
858 * a value of 0 will be interpreted as 256. Therefore
859 * scsi_inquiry() will convert an inq_len (which is passed in as
860 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
861 * to 0. Evidently, very few devices meet the spec in that
862 * regard. Some devices, like many Seagate disks, take the 0 as
863 * 0, and don't return any data. One Pioneer DVD-R drive
864 * returns more data than the command asked for.
866 * So, since there are numerous devices that just don't work
867 * right with the full inquiry size, we don't send the full size.
869 * - The second reason not to use the full inquiry data length is
870 * that we don't need it here. The only reason we issue a
871 * standard inquiry is to get the vendor name, device name,
872 * and revision so scsi_print_inquiry() can print them.
874 * If, at some point in the future, more inquiry data is needed for
875 * some reason, this code should use a procedure similar to the
876 * probe code. i.e., issue a short inquiry, and determine from
877 * the additional length passed back from the device how much
878 * inquiry data the device supports. Once the amount the device
879 * supports is determined, issue an inquiry for that amount and no
884 scsi_inquiry(&ccb->csio,
885 /* retries */ retry_count,
887 /* tag_action */ MSG_SIMPLE_Q_TAG,
888 /* inq_buf */ (u_int8_t *)inq_buf,
889 /* inq_len */ SHORT_INQUIRY_LENGTH,
892 /* sense_len */ SSD_FULL_SIZE,
893 /* timeout */ timeout ? timeout : 5000);
895 /* Disable freezing the device queue */
896 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
898 if (arglist & CAM_ARG_ERR_RECOVER)
899 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
901 if (cam_send_ccb(device, ccb) < 0) {
902 perror("error sending SCSI inquiry");
904 if (arglist & CAM_ARG_VERBOSE) {
905 cam_error_print(device, ccb, CAM_ESF_ALL,
906 CAM_EPF_ALL, stderr);
913 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
916 if (arglist & CAM_ARG_VERBOSE) {
917 cam_error_print(device, ccb, CAM_ESF_ALL,
918 CAM_EPF_ALL, stderr);
929 fprintf(stdout, "%s%d: ", device->device_name,
930 device->dev_unit_num);
931 scsi_print_inquiry(inq_buf);
939 scsiserial(struct cam_device *device, int retry_count, int timeout)
942 struct scsi_vpd_unit_serial_number *serial_buf;
943 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
946 ccb = cam_getccb(device);
949 warnx("couldn't allocate CCB");
953 /* cam_getccb cleans up the header, caller has to zero the payload */
954 bzero(&(&ccb->ccb_h)[1],
955 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
957 serial_buf = (struct scsi_vpd_unit_serial_number *)
958 malloc(sizeof(*serial_buf));
960 if (serial_buf == NULL) {
962 warnx("can't malloc memory for serial number");
966 scsi_inquiry(&ccb->csio,
967 /*retries*/ retry_count,
969 /* tag_action */ MSG_SIMPLE_Q_TAG,
970 /* inq_buf */ (u_int8_t *)serial_buf,
971 /* inq_len */ sizeof(*serial_buf),
973 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
974 /* sense_len */ SSD_FULL_SIZE,
975 /* timeout */ timeout ? timeout : 5000);
977 /* Disable freezing the device queue */
978 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
980 if (arglist & CAM_ARG_ERR_RECOVER)
981 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
983 if (cam_send_ccb(device, ccb) < 0) {
984 warn("error getting serial number");
986 if (arglist & CAM_ARG_VERBOSE) {
987 cam_error_print(device, ccb, CAM_ESF_ALL,
988 CAM_EPF_ALL, stderr);
996 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
999 if (arglist & CAM_ARG_VERBOSE) {
1000 cam_error_print(device, ccb, CAM_ESF_ALL,
1001 CAM_EPF_ALL, stderr);
1012 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1013 serial_num[serial_buf->length] = '\0';
1015 if ((arglist & CAM_ARG_GET_STDINQ)
1016 || (arglist & CAM_ARG_GET_XFERRATE))
1017 fprintf(stdout, "%s%d: Serial Number ",
1018 device->device_name, device->dev_unit_num);
1020 fprintf(stdout, "%.60s\n", serial_num);
1028 camxferrate(struct cam_device *device)
1030 struct ccb_pathinq cpi;
1032 u_int32_t speed = 0;
1037 if ((retval = get_cpi(device, &cpi)) != 0)
1040 ccb = cam_getccb(device);
1043 warnx("couldn't allocate CCB");
1047 bzero(&(&ccb->ccb_h)[1],
1048 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
1050 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1051 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1053 if (((retval = cam_send_ccb(device, ccb)) < 0)
1054 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1055 const char error_string[] = "error getting transfer settings";
1060 warnx(error_string);
1062 if (arglist & CAM_ARG_VERBOSE)
1063 cam_error_print(device, ccb, CAM_ESF_ALL,
1064 CAM_EPF_ALL, stderr);
1068 goto xferrate_bailout;
1072 speed = cpi.base_transfer_speed;
1074 if (ccb->cts.transport == XPORT_SPI) {
1075 struct ccb_trans_settings_spi *spi =
1076 &ccb->cts.xport_specific.spi;
1078 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1079 freq = scsi_calc_syncsrate(spi->sync_period);
1082 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1083 speed *= (0x01 << spi->bus_width);
1085 } else if (ccb->cts.transport == XPORT_FC) {
1086 struct ccb_trans_settings_fc *fc =
1087 &ccb->cts.xport_specific.fc;
1089 if (fc->valid & CTS_FC_VALID_SPEED)
1090 speed = fc->bitrate;
1091 } else if (ccb->cts.transport == XPORT_SAS) {
1092 struct ccb_trans_settings_sas *sas =
1093 &ccb->cts.xport_specific.sas;
1095 if (sas->valid & CTS_SAS_VALID_SPEED)
1096 speed = sas->bitrate;
1097 } else if (ccb->cts.transport == XPORT_ATA) {
1098 struct ccb_trans_settings_pata *pata =
1099 &ccb->cts.xport_specific.ata;
1101 if (pata->valid & CTS_ATA_VALID_MODE)
1102 speed = ata_mode2speed(pata->mode);
1103 } else if (ccb->cts.transport == XPORT_SATA) {
1104 struct ccb_trans_settings_sata *sata =
1105 &ccb->cts.xport_specific.sata;
1107 if (sata->valid & CTS_SATA_VALID_REVISION)
1108 speed = ata_revision2speed(sata->revision);
1113 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1114 device->device_name, device->dev_unit_num,
1117 fprintf(stdout, "%s%d: %dKB/s transfers",
1118 device->device_name, device->dev_unit_num,
1122 if (ccb->cts.transport == XPORT_SPI) {
1123 struct ccb_trans_settings_spi *spi =
1124 &ccb->cts.xport_specific.spi;
1126 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1127 && (spi->sync_offset != 0))
1128 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1129 freq % 1000, spi->sync_offset);
1131 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1132 && (spi->bus_width > 0)) {
1133 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1134 && (spi->sync_offset != 0)) {
1135 fprintf(stdout, ", ");
1137 fprintf(stdout, " (");
1139 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1140 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1141 && (spi->sync_offset != 0)) {
1142 fprintf(stdout, ")");
1144 } else if (ccb->cts.transport == XPORT_ATA) {
1145 struct ccb_trans_settings_pata *pata =
1146 &ccb->cts.xport_specific.ata;
1149 if (pata->valid & CTS_ATA_VALID_MODE)
1150 printf("%s, ", ata_mode2string(pata->mode));
1151 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1152 printf("ATAPI %dbytes, ", pata->atapi);
1153 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1154 printf("PIO %dbytes", pata->bytecount);
1156 } else if (ccb->cts.transport == XPORT_SATA) {
1157 struct ccb_trans_settings_sata *sata =
1158 &ccb->cts.xport_specific.sata;
1161 if (sata->valid & CTS_SATA_VALID_REVISION)
1162 printf("SATA %d.x, ", sata->revision);
1165 if (sata->valid & CTS_SATA_VALID_MODE)
1166 printf("%s, ", ata_mode2string(sata->mode));
1167 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1168 printf("ATAPI %dbytes, ", sata->atapi);
1169 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1170 printf("PIO %dbytes", sata->bytecount);
1174 if (ccb->cts.protocol == PROTO_SCSI) {
1175 struct ccb_trans_settings_scsi *scsi =
1176 &ccb->cts.proto_specific.scsi;
1177 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1178 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1179 fprintf(stdout, ", Command Queueing Enabled");
1184 fprintf(stdout, "\n");
1194 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1196 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1197 ((u_int32_t)parm->lba_size_2 << 16);
1199 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1200 ((u_int64_t)parm->lba_size48_2 << 16) |
1201 ((u_int64_t)parm->lba_size48_3 << 32) |
1202 ((u_int64_t)parm->lba_size48_4 << 48);
1206 "Support Enabled Value\n");
1209 printf("Host Protected Area (HPA) ");
1210 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1211 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1212 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1215 printf("HPA - Security ");
1216 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1226 atasata(struct ata_params *parm)
1230 if (parm->satacapabilities != 0xffff &&
1231 parm->satacapabilities != 0x0000)
1238 atacapprint(struct ata_params *parm)
1240 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1241 ((u_int32_t)parm->lba_size_2 << 16);
1243 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1244 ((u_int64_t)parm->lba_size48_2 << 16) |
1245 ((u_int64_t)parm->lba_size48_3 << 32) |
1246 ((u_int64_t)parm->lba_size48_4 << 48);
1249 printf("protocol ");
1250 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1251 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1252 if (parm->satacapabilities & ATA_SATA_GEN3)
1253 printf(" SATA 3.x\n");
1254 else if (parm->satacapabilities & ATA_SATA_GEN2)
1255 printf(" SATA 2.x\n");
1256 else if (parm->satacapabilities & ATA_SATA_GEN1)
1257 printf(" SATA 1.x\n");
1263 printf("device model %.40s\n", parm->model);
1264 printf("firmware revision %.8s\n", parm->revision);
1265 printf("serial number %.20s\n", parm->serial);
1266 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1267 printf("WWN %04x%04x%04x%04x\n",
1268 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1270 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1271 printf("media serial number %.30s\n",
1272 parm->media_serial);
1275 printf("cylinders %d\n", parm->cylinders);
1276 printf("heads %d\n", parm->heads);
1277 printf("sectors/track %d\n", parm->sectors);
1278 printf("sector size logical %u, physical %lu, offset %lu\n",
1279 ata_logical_sector_size(parm),
1280 (unsigned long)ata_physical_sector_size(parm),
1281 (unsigned long)ata_logical_sector_offset(parm));
1283 if (parm->config == ATA_PROTO_CFA ||
1284 (parm->support.command2 & ATA_SUPPORT_CFA))
1285 printf("CFA supported\n");
1287 printf("LBA%ssupported ",
1288 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1290 printf("%d sectors\n", lbasize);
1294 printf("LBA48%ssupported ",
1295 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1297 printf("%ju sectors\n", (uintmax_t)lbasize48);
1301 printf("PIO supported PIO");
1302 switch (ata_max_pmode(parm)) {
1318 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1319 printf(" w/o IORDY");
1322 printf("DMA%ssupported ",
1323 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1324 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1325 if (parm->mwdmamodes & 0xff) {
1327 if (parm->mwdmamodes & 0x04)
1329 else if (parm->mwdmamodes & 0x02)
1331 else if (parm->mwdmamodes & 0x01)
1335 if ((parm->atavalid & ATA_FLAG_88) &&
1336 (parm->udmamodes & 0xff)) {
1338 if (parm->udmamodes & 0x40)
1340 else if (parm->udmamodes & 0x20)
1342 else if (parm->udmamodes & 0x10)
1344 else if (parm->udmamodes & 0x08)
1346 else if (parm->udmamodes & 0x04)
1348 else if (parm->udmamodes & 0x02)
1350 else if (parm->udmamodes & 0x01)
1357 if (parm->media_rotation_rate == 1) {
1358 printf("media RPM non-rotating\n");
1359 } else if (parm->media_rotation_rate >= 0x0401 &&
1360 parm->media_rotation_rate <= 0xFFFE) {
1361 printf("media RPM %d\n",
1362 parm->media_rotation_rate);
1366 "Support Enabled Value Vendor\n");
1367 printf("read ahead %s %s\n",
1368 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1369 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1370 printf("write cache %s %s\n",
1371 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1372 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1373 printf("flush cache %s %s\n",
1374 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1375 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1376 printf("overlap %s\n",
1377 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1378 printf("Tagged Command Queuing (TCQ) %s %s",
1379 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1380 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1381 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1382 printf(" %d tags\n",
1383 ATA_QUEUE_LEN(parm->queue) + 1);
1386 printf("Native Command Queuing (NCQ) ");
1387 if (parm->satacapabilities != 0xffff &&
1388 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1389 printf("yes %d tags\n",
1390 ATA_QUEUE_LEN(parm->queue) + 1);
1394 printf("NCQ Queue Management %s\n", atasata(parm) &&
1395 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1397 printf("NCQ Streaming %s\n", atasata(parm) &&
1398 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1400 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1401 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1404 printf("SMART %s %s\n",
1405 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1406 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1407 printf("microcode download %s %s\n",
1408 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1409 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1410 printf("security %s %s\n",
1411 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1412 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1413 printf("power management %s %s\n",
1414 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1415 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1416 printf("advanced power management %s %s",
1417 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1418 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1419 if (parm->support.command2 & ATA_SUPPORT_APM) {
1420 printf(" %d/0x%02X\n",
1421 parm->apm_value & 0xff, parm->apm_value & 0xff);
1424 printf("automatic acoustic management %s %s",
1425 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1426 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1427 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1428 printf(" %d/0x%02X %d/0x%02X\n",
1429 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1430 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1431 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1432 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1435 printf("media status notification %s %s\n",
1436 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1437 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1438 printf("power-up in Standby %s %s\n",
1439 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1440 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1441 printf("write-read-verify %s %s",
1442 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1443 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1444 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1445 printf(" %d/0x%x\n",
1446 parm->wrv_mode, parm->wrv_mode);
1449 printf("unload %s %s\n",
1450 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1451 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1452 printf("general purpose logging %s %s\n",
1453 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1454 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1455 printf("free-fall %s %s\n",
1456 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1457 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1458 printf("Data Set Management (DSM/TRIM) ");
1459 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1461 printf("DSM - max 512byte blocks ");
1462 if (parm->max_dsm_blocks == 0x00)
1463 printf("yes not specified\n");
1466 parm->max_dsm_blocks);
1468 printf("DSM - deterministic read ");
1469 if (parm->support3 & ATA_SUPPORT_DRAT) {
1470 if (parm->support3 & ATA_SUPPORT_RZAT)
1471 printf("yes zeroed\n");
1473 printf("yes any value\n");
1483 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1485 struct ata_pass_16 *ata_pass_16;
1486 struct ata_cmd ata_cmd;
1488 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1489 ata_cmd.command = ata_pass_16->command;
1490 ata_cmd.control = ata_pass_16->control;
1491 ata_cmd.features = ata_pass_16->features;
1493 if (arglist & CAM_ARG_VERBOSE) {
1494 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1495 ata_op_string(&ata_cmd),
1496 ccb->csio.ccb_h.timeout);
1499 /* Disable freezing the device queue */
1500 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1502 if (arglist & CAM_ARG_ERR_RECOVER)
1503 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1505 if (cam_send_ccb(device, ccb) < 0) {
1506 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1507 warn("error sending ATA %s via pass_16",
1508 ata_op_string(&ata_cmd));
1511 if (arglist & CAM_ARG_VERBOSE) {
1512 cam_error_print(device, ccb, CAM_ESF_ALL,
1513 CAM_EPF_ALL, stderr);
1519 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1520 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1521 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1522 warnx("ATA %s via pass_16 failed",
1523 ata_op_string(&ata_cmd));
1525 if (arglist & CAM_ARG_VERBOSE) {
1526 cam_error_print(device, ccb, CAM_ESF_ALL,
1527 CAM_EPF_ALL, stderr);
1538 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1540 if (arglist & CAM_ARG_VERBOSE) {
1541 warnx("sending ATA %s with timeout of %u msecs",
1542 ata_op_string(&(ccb->ataio.cmd)),
1543 ccb->ataio.ccb_h.timeout);
1546 /* Disable freezing the device queue */
1547 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1549 if (arglist & CAM_ARG_ERR_RECOVER)
1550 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1552 if (cam_send_ccb(device, ccb) < 0) {
1553 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1554 warn("error sending ATA %s",
1555 ata_op_string(&(ccb->ataio.cmd)));
1558 if (arglist & CAM_ARG_VERBOSE) {
1559 cam_error_print(device, ccb, CAM_ESF_ALL,
1560 CAM_EPF_ALL, stderr);
1566 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1567 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1568 warnx("ATA %s failed: %d",
1569 ata_op_string(&(ccb->ataio.cmd)), quiet);
1572 if (arglist & CAM_ARG_VERBOSE) {
1573 cam_error_print(device, ccb, CAM_ESF_ALL,
1574 CAM_EPF_ALL, stderr);
1584 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1585 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1586 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1587 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1588 u_int16_t dxfer_len, int timeout, int quiet)
1590 if (data_ptr != NULL) {
1591 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1592 AP_FLAG_TLEN_SECT_CNT;
1593 if (flags & CAM_DIR_OUT)
1594 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1596 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1598 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1601 bzero(&(&ccb->ccb_h)[1],
1602 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1604 scsi_ata_pass_16(&ccb->csio,
1618 /*sense_len*/SSD_FULL_SIZE,
1621 return scsi_cam_pass_16_send(device, ccb, quiet);
1625 ata_try_pass_16(struct cam_device *device)
1627 struct ccb_pathinq cpi;
1629 if (get_cpi(device, &cpi) != 0) {
1630 warnx("couldn't get CPI");
1634 if (cpi.protocol == PROTO_SCSI) {
1635 /* possibly compatible with pass_16 */
1639 /* likely not compatible with pass_16 */
1644 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1645 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1646 u_int8_t command, u_int8_t features, u_int32_t lba,
1647 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1648 int timeout, int quiet)
1652 switch (ata_try_pass_16(device)) {
1656 /* Try using SCSI Passthrough */
1657 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1658 0, tag_action, command, features, lba,
1659 sector_count, data_ptr, dxfer_len,
1663 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1664 sizeof(struct ccb_hdr));
1665 cam_fill_ataio(&ccb->ataio,
1674 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1675 return ata_cam_send(device, ccb, quiet);
1679 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1680 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1681 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1682 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1683 u_int16_t dxfer_len, int timeout, int force48bit)
1687 retval = ata_try_pass_16(device);
1694 /* Try using SCSI Passthrough */
1695 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1696 ata_flags, tag_action, command, features,
1697 lba, sector_count, data_ptr, dxfer_len,
1700 if (ata_flags & AP_FLAG_CHK_COND) {
1701 /* Decode ata_res from sense data */
1702 struct ata_res_pass16 *res_pass16;
1703 struct ata_res *res;
1707 /* sense_data is 4 byte aligned */
1708 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1709 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1710 ptr[i] = le16toh(ptr[i]);
1712 /* sense_data is 4 byte aligned */
1713 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1714 &ccb->csio.sense_data;
1715 res = &ccb->ataio.res;
1716 res->flags = res_pass16->flags;
1717 res->status = res_pass16->status;
1718 res->error = res_pass16->error;
1719 res->lba_low = res_pass16->lba_low;
1720 res->lba_mid = res_pass16->lba_mid;
1721 res->lba_high = res_pass16->lba_high;
1722 res->device = res_pass16->device;
1723 res->lba_low_exp = res_pass16->lba_low_exp;
1724 res->lba_mid_exp = res_pass16->lba_mid_exp;
1725 res->lba_high_exp = res_pass16->lba_high_exp;
1726 res->sector_count = res_pass16->sector_count;
1727 res->sector_count_exp = res_pass16->sector_count_exp;
1733 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1734 sizeof(struct ccb_hdr));
1735 cam_fill_ataio(&ccb->ataio,
1744 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1745 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1747 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1749 if (ata_flags & AP_FLAG_CHK_COND)
1750 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1752 return ata_cam_send(device, ccb, 0);
1756 dump_data(uint16_t *ptr, uint32_t len)
1760 for (i = 0; i < len / 2; i++) {
1762 printf(" %3d: ", i);
1763 printf("%04hx ", ptr[i]);
1772 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1773 int is48bit, u_int64_t *hpasize)
1775 struct ata_res *res;
1777 res = &ccb->ataio.res;
1778 if (res->status & ATA_STATUS_ERROR) {
1779 if (arglist & CAM_ARG_VERBOSE) {
1780 cam_error_print(device, ccb, CAM_ESF_ALL,
1781 CAM_EPF_ALL, stderr);
1782 printf("error = 0x%02x, sector_count = 0x%04x, "
1783 "device = 0x%02x, status = 0x%02x\n",
1784 res->error, res->sector_count,
1785 res->device, res->status);
1788 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1789 warnx("Max address has already been set since "
1790 "last power-on or hardware reset");
1796 if (arglist & CAM_ARG_VERBOSE) {
1797 fprintf(stdout, "%s%d: Raw native max data:\n",
1798 device->device_name, device->dev_unit_num);
1799 /* res is 4 byte aligned */
1800 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1802 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1803 "status = 0x%02x\n", res->error, res->sector_count,
1804 res->device, res->status);
1807 if (hpasize != NULL) {
1809 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1810 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1811 ((res->lba_high << 16) | (res->lba_mid << 8) |
1814 *hpasize = (((res->device & 0x0f) << 24) |
1815 (res->lba_high << 16) | (res->lba_mid << 8) |
1824 ata_read_native_max(struct cam_device *device, int retry_count,
1825 u_int32_t timeout, union ccb *ccb,
1826 struct ata_params *parm, u_int64_t *hpasize)
1832 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1833 protocol = AP_PROTO_NON_DATA;
1836 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1837 protocol |= AP_EXTEND;
1839 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1842 error = ata_do_cmd(device,
1845 /*flags*/CAM_DIR_NONE,
1846 /*protocol*/protocol,
1847 /*ata_flags*/AP_FLAG_CHK_COND,
1848 /*tag_action*/MSG_SIMPLE_Q_TAG,
1855 timeout ? timeout : 1000,
1861 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1865 atahpa_set_max(struct cam_device *device, int retry_count,
1866 u_int32_t timeout, union ccb *ccb,
1867 int is48bit, u_int64_t maxsize, int persist)
1873 protocol = AP_PROTO_NON_DATA;
1876 cmd = ATA_SET_MAX_ADDRESS48;
1877 protocol |= AP_EXTEND;
1879 cmd = ATA_SET_MAX_ADDRESS;
1882 /* lba's are zero indexed so the max lba is requested max - 1 */
1886 error = ata_do_cmd(device,
1889 /*flags*/CAM_DIR_NONE,
1890 /*protocol*/protocol,
1891 /*ata_flags*/AP_FLAG_CHK_COND,
1892 /*tag_action*/MSG_SIMPLE_Q_TAG,
1894 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1896 /*sector_count*/persist,
1899 timeout ? timeout : 1000,
1905 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1909 atahpa_password(struct cam_device *device, int retry_count,
1910 u_int32_t timeout, union ccb *ccb,
1911 int is48bit, struct ata_set_max_pwd *pwd)
1917 protocol = AP_PROTO_PIO_OUT;
1918 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1920 error = ata_do_cmd(device,
1923 /*flags*/CAM_DIR_OUT,
1924 /*protocol*/protocol,
1925 /*ata_flags*/AP_FLAG_CHK_COND,
1926 /*tag_action*/MSG_SIMPLE_Q_TAG,
1928 /*features*/ATA_HPA_FEAT_SET_PWD,
1931 /*data_ptr*/(u_int8_t*)pwd,
1932 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1933 timeout ? timeout : 1000,
1939 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1943 atahpa_lock(struct cam_device *device, int retry_count,
1944 u_int32_t timeout, union ccb *ccb, int is48bit)
1950 protocol = AP_PROTO_NON_DATA;
1951 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1953 error = ata_do_cmd(device,
1956 /*flags*/CAM_DIR_NONE,
1957 /*protocol*/protocol,
1958 /*ata_flags*/AP_FLAG_CHK_COND,
1959 /*tag_action*/MSG_SIMPLE_Q_TAG,
1961 /*features*/ATA_HPA_FEAT_LOCK,
1966 timeout ? timeout : 1000,
1972 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1976 atahpa_unlock(struct cam_device *device, int retry_count,
1977 u_int32_t timeout, union ccb *ccb,
1978 int is48bit, struct ata_set_max_pwd *pwd)
1984 protocol = AP_PROTO_PIO_OUT;
1985 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1987 error = ata_do_cmd(device,
1990 /*flags*/CAM_DIR_OUT,
1991 /*protocol*/protocol,
1992 /*ata_flags*/AP_FLAG_CHK_COND,
1993 /*tag_action*/MSG_SIMPLE_Q_TAG,
1995 /*features*/ATA_HPA_FEAT_UNLOCK,
1998 /*data_ptr*/(u_int8_t*)pwd,
1999 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2000 timeout ? timeout : 1000,
2006 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2010 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2011 u_int32_t timeout, union ccb *ccb, int is48bit)
2017 protocol = AP_PROTO_NON_DATA;
2018 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2020 error = ata_do_cmd(device,
2023 /*flags*/CAM_DIR_NONE,
2024 /*protocol*/protocol,
2025 /*ata_flags*/AP_FLAG_CHK_COND,
2026 /*tag_action*/MSG_SIMPLE_Q_TAG,
2028 /*features*/ATA_HPA_FEAT_FREEZE,
2033 timeout ? timeout : 1000,
2039 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2044 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2045 union ccb *ccb, struct ata_params** ident_bufp)
2047 struct ata_params *ident_buf;
2048 struct ccb_pathinq cpi;
2049 struct ccb_getdev cgd;
2052 u_int8_t command, retry_command;
2054 if (get_cpi(device, &cpi) != 0) {
2055 warnx("couldn't get CPI");
2059 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2060 if (cpi.protocol == PROTO_ATA) {
2061 if (get_cgd(device, &cgd) != 0) {
2062 warnx("couldn't get CGD");
2066 command = (cgd.protocol == PROTO_ATA) ?
2067 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2070 /* We don't know which for sure so try both */
2071 command = ATA_ATA_IDENTIFY;
2072 retry_command = ATA_ATAPI_IDENTIFY;
2075 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2077 warnx("can't calloc memory for identify\n");
2081 error = ata_do_28bit_cmd(device,
2083 /*retries*/retry_count,
2084 /*flags*/CAM_DIR_IN,
2085 /*protocol*/AP_PROTO_PIO_IN,
2086 /*tag_action*/MSG_SIMPLE_Q_TAG,
2090 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2091 /*data_ptr*/(u_int8_t *)ptr,
2092 /*dxfer_len*/sizeof(struct ata_params),
2093 /*timeout*/timeout ? timeout : 30 * 1000,
2097 if (retry_command == 0) {
2101 error = ata_do_28bit_cmd(device,
2103 /*retries*/retry_count,
2104 /*flags*/CAM_DIR_IN,
2105 /*protocol*/AP_PROTO_PIO_IN,
2106 /*tag_action*/MSG_SIMPLE_Q_TAG,
2107 /*command*/retry_command,
2110 /*sector_count*/(u_int8_t)
2111 sizeof(struct ata_params),
2112 /*data_ptr*/(u_int8_t *)ptr,
2113 /*dxfer_len*/sizeof(struct ata_params),
2114 /*timeout*/timeout ? timeout : 30 * 1000,
2124 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2125 ptr[i] = le16toh(ptr[i]);
2130 if (arglist & CAM_ARG_VERBOSE) {
2131 fprintf(stdout, "%s%d: Raw identify data:\n",
2132 device->device_name, device->dev_unit_num);
2133 dump_data(ptr, sizeof(struct ata_params));
2136 /* check for invalid (all zero) response */
2138 warnx("Invalid identify response detected");
2143 ident_buf = (struct ata_params *)ptr;
2144 if (strncmp(ident_buf->model, "FX", 2) &&
2145 strncmp(ident_buf->model, "NEC", 3) &&
2146 strncmp(ident_buf->model, "Pioneer", 7) &&
2147 strncmp(ident_buf->model, "SHARP", 5)) {
2148 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2149 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2150 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2151 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2153 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2154 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2155 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2156 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2157 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2158 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2159 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2160 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2161 sizeof(ident_buf->media_serial));
2163 *ident_bufp = ident_buf;
2170 ataidentify(struct cam_device *device, int retry_count, int timeout)
2173 struct ata_params *ident_buf;
2176 if ((ccb = cam_getccb(device)) == NULL) {
2177 warnx("couldn't allocate CCB");
2181 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2186 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2187 if (ata_read_native_max(device, retry_count, timeout, ccb,
2188 ident_buf, &hpasize) != 0) {
2196 printf("%s%d: ", device->device_name, device->dev_unit_num);
2197 ata_print_ident(ident_buf);
2198 camxferrate(device);
2199 atacapprint(ident_buf);
2200 atahpa_print(ident_buf, hpasize, 0);
2207 #endif /* MINIMALISTIC */
2210 #ifndef MINIMALISTIC
2212 ATA_SECURITY_ACTION_PRINT,
2213 ATA_SECURITY_ACTION_FREEZE,
2214 ATA_SECURITY_ACTION_UNLOCK,
2215 ATA_SECURITY_ACTION_DISABLE,
2216 ATA_SECURITY_ACTION_ERASE,
2217 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2218 ATA_SECURITY_ACTION_SET_PASSWORD
2222 atasecurity_print_time(u_int16_t tw)
2226 printf("unspecified");
2228 printf("> 508 min");
2230 printf("%i min", 2 * tw);
2234 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2238 return 2 * 3600 * 1000; /* default: two hours */
2239 else if (timeout > 255)
2240 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2242 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2247 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2251 bzero(&cmd, sizeof(cmd));
2252 cmd.command = command;
2253 printf("Issuing %s", ata_op_string(&cmd));
2256 char pass[sizeof(pwd->password)+1];
2258 /* pwd->password may not be null terminated */
2259 pass[sizeof(pwd->password)] = '\0';
2260 strncpy(pass, pwd->password, sizeof(pwd->password));
2261 printf(" password='%s', user='%s'",
2263 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2266 if (command == ATA_SECURITY_SET_PASSWORD) {
2267 printf(", mode='%s'",
2268 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2269 "maximum" : "high");
2277 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2278 int retry_count, u_int32_t timeout, int quiet)
2282 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2284 return ata_do_28bit_cmd(device,
2287 /*flags*/CAM_DIR_NONE,
2288 /*protocol*/AP_PROTO_NON_DATA,
2289 /*tag_action*/MSG_SIMPLE_Q_TAG,
2290 /*command*/ATA_SECURITY_FREEZE_LOCK,
2301 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2302 int retry_count, u_int32_t timeout,
2303 struct ata_security_password *pwd, int quiet)
2307 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2309 return ata_do_28bit_cmd(device,
2312 /*flags*/CAM_DIR_OUT,
2313 /*protocol*/AP_PROTO_PIO_OUT,
2314 /*tag_action*/MSG_SIMPLE_Q_TAG,
2315 /*command*/ATA_SECURITY_UNLOCK,
2319 /*data_ptr*/(u_int8_t *)pwd,
2320 /*dxfer_len*/sizeof(*pwd),
2326 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2327 int retry_count, u_int32_t timeout,
2328 struct ata_security_password *pwd, int quiet)
2332 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2333 return ata_do_28bit_cmd(device,
2336 /*flags*/CAM_DIR_OUT,
2337 /*protocol*/AP_PROTO_PIO_OUT,
2338 /*tag_action*/MSG_SIMPLE_Q_TAG,
2339 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2343 /*data_ptr*/(u_int8_t *)pwd,
2344 /*dxfer_len*/sizeof(*pwd),
2351 atasecurity_erase_confirm(struct cam_device *device,
2352 struct ata_params* ident_buf)
2355 printf("\nYou are about to ERASE ALL DATA from the following"
2356 " device:\n%s%d,%s%d: ", device->device_name,
2357 device->dev_unit_num, device->given_dev_name,
2358 device->given_unit_number);
2359 ata_print_ident(ident_buf);
2363 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2365 if (fgets(str, sizeof(str), stdin) != NULL) {
2366 if (strncasecmp(str, "yes", 3) == 0) {
2368 } else if (strncasecmp(str, "no", 2) == 0) {
2371 printf("Please answer \"yes\" or "
2382 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2383 int retry_count, u_int32_t timeout,
2384 u_int32_t erase_timeout,
2385 struct ata_security_password *pwd, int quiet)
2390 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2392 error = ata_do_28bit_cmd(device,
2395 /*flags*/CAM_DIR_NONE,
2396 /*protocol*/AP_PROTO_NON_DATA,
2397 /*tag_action*/MSG_SIMPLE_Q_TAG,
2398 /*command*/ATA_SECURITY_ERASE_PREPARE,
2411 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2413 error = ata_do_28bit_cmd(device,
2416 /*flags*/CAM_DIR_OUT,
2417 /*protocol*/AP_PROTO_PIO_OUT,
2418 /*tag_action*/MSG_SIMPLE_Q_TAG,
2419 /*command*/ATA_SECURITY_ERASE_UNIT,
2423 /*data_ptr*/(u_int8_t *)pwd,
2424 /*dxfer_len*/sizeof(*pwd),
2425 /*timeout*/erase_timeout,
2428 if (error == 0 && quiet == 0)
2429 printf("\nErase Complete\n");
2435 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2436 int retry_count, u_int32_t timeout,
2437 struct ata_security_password *pwd, int quiet)
2441 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2443 return ata_do_28bit_cmd(device,
2446 /*flags*/CAM_DIR_OUT,
2447 /*protocol*/AP_PROTO_PIO_OUT,
2448 /*tag_action*/MSG_SIMPLE_Q_TAG,
2449 /*command*/ATA_SECURITY_SET_PASSWORD,
2453 /*data_ptr*/(u_int8_t *)pwd,
2454 /*dxfer_len*/sizeof(*pwd),
2460 atasecurity_print(struct ata_params *parm)
2463 printf("\nSecurity Option Value\n");
2464 if (arglist & CAM_ARG_VERBOSE) {
2465 printf("status %04x\n",
2466 parm->security_status);
2468 printf("supported %s\n",
2469 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2470 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2472 printf("enabled %s\n",
2473 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2474 printf("drive locked %s\n",
2475 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2476 printf("security config frozen %s\n",
2477 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2478 printf("count expired %s\n",
2479 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2480 printf("security level %s\n",
2481 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2482 printf("enhanced erase supported %s\n",
2483 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2484 printf("erase time ");
2485 atasecurity_print_time(parm->erase_time);
2487 printf("enhanced erase time ");
2488 atasecurity_print_time(parm->enhanced_erase_time);
2490 printf("master password rev %04x%s\n",
2491 parm->master_passwd_revision,
2492 parm->master_passwd_revision == 0x0000 ||
2493 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2497 * Validates and copies the password in optarg to the passed buffer.
2498 * If the password in optarg is the same length as the buffer then
2499 * the data will still be copied but no null termination will occur.
2502 ata_getpwd(u_int8_t *passwd, int max, char opt)
2506 len = strlen(optarg);
2508 warnx("-%c password is too long", opt);
2510 } else if (len == 0) {
2511 warnx("-%c password is missing", opt);
2513 } else if (optarg[0] == '-'){
2514 warnx("-%c password starts with '-' (generic arg?)", opt);
2516 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2517 warnx("-%c password conflicts with existing password from -%c",
2522 /* Callers pass in a buffer which does NOT need to be terminated */
2523 strncpy(passwd, optarg, max);
2530 ATA_HPA_ACTION_PRINT,
2531 ATA_HPA_ACTION_SET_MAX,
2532 ATA_HPA_ACTION_SET_PWD,
2533 ATA_HPA_ACTION_LOCK,
2534 ATA_HPA_ACTION_UNLOCK,
2535 ATA_HPA_ACTION_FREEZE_LOCK
2539 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2540 u_int64_t maxsize, int persist)
2542 printf("\nYou are about to configure HPA to limit the user accessible\n"
2543 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2544 persist ? "persistently" : "temporarily",
2545 device->device_name, device->dev_unit_num,
2546 device->given_dev_name, device->given_unit_number);
2547 ata_print_ident(ident_buf);
2551 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2553 if (NULL != fgets(str, sizeof(str), stdin)) {
2554 if (0 == strncasecmp(str, "yes", 3)) {
2556 } else if (0 == strncasecmp(str, "no", 2)) {
2559 printf("Please answer \"yes\" or "
2570 atahpa(struct cam_device *device, int retry_count, int timeout,
2571 int argc, char **argv, char *combinedopt)
2574 struct ata_params *ident_buf;
2575 struct ccb_getdev cgd;
2576 struct ata_set_max_pwd pwd;
2577 int error, confirm, quiet, c, action, actions, setpwd, persist;
2578 int security, is48bit, pwdsize;
2579 u_int64_t hpasize, maxsize;
2589 memset(&pwd, 0, sizeof(pwd));
2591 /* default action is to print hpa information */
2592 action = ATA_HPA_ACTION_PRINT;
2593 pwdsize = sizeof(pwd.password);
2595 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2598 action = ATA_HPA_ACTION_SET_MAX;
2599 maxsize = strtoumax(optarg, NULL, 0);
2604 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2606 action = ATA_HPA_ACTION_SET_PWD;
2612 action = ATA_HPA_ACTION_LOCK;
2618 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2620 action = ATA_HPA_ACTION_UNLOCK;
2626 action = ATA_HPA_ACTION_FREEZE_LOCK;
2646 warnx("too many hpa actions specified");
2650 if (get_cgd(device, &cgd) != 0) {
2651 warnx("couldn't get CGD");
2655 ccb = cam_getccb(device);
2657 warnx("couldn't allocate CCB");
2661 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2668 printf("%s%d: ", device->device_name, device->dev_unit_num);
2669 ata_print_ident(ident_buf);
2670 camxferrate(device);
2673 if (action == ATA_HPA_ACTION_PRINT) {
2674 error = ata_read_native_max(device, retry_count, timeout, ccb,
2675 ident_buf, &hpasize);
2677 atahpa_print(ident_buf, hpasize, 1);
2684 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2685 warnx("HPA is not supported by this device");
2691 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2692 warnx("HPA Security is not supported by this device");
2698 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2701 * The ATA spec requires:
2702 * 1. Read native max addr is called directly before set max addr
2703 * 2. Read native max addr is NOT called before any other set max call
2706 case ATA_HPA_ACTION_SET_MAX:
2708 atahpa_set_confirm(device, ident_buf, maxsize,
2715 error = ata_read_native_max(device, retry_count, timeout,
2716 ccb, ident_buf, &hpasize);
2718 error = atahpa_set_max(device, retry_count, timeout,
2719 ccb, is48bit, maxsize, persist);
2721 /* redo identify to get new lba values */
2722 error = ata_do_identify(device, retry_count,
2725 atahpa_print(ident_buf, hpasize, 1);
2730 case ATA_HPA_ACTION_SET_PWD:
2731 error = atahpa_password(device, retry_count, timeout,
2732 ccb, is48bit, &pwd);
2734 printf("HPA password has been set\n");
2737 case ATA_HPA_ACTION_LOCK:
2738 error = atahpa_lock(device, retry_count, timeout,
2741 printf("HPA has been locked\n");
2744 case ATA_HPA_ACTION_UNLOCK:
2745 error = atahpa_unlock(device, retry_count, timeout,
2746 ccb, is48bit, &pwd);
2748 printf("HPA has been unlocked\n");
2751 case ATA_HPA_ACTION_FREEZE_LOCK:
2752 error = atahpa_freeze_lock(device, retry_count, timeout,
2755 printf("HPA has been frozen\n");
2759 errx(1, "Option currently not supported");
2769 atasecurity(struct cam_device *device, int retry_count, int timeout,
2770 int argc, char **argv, char *combinedopt)
2773 struct ata_params *ident_buf;
2774 int error, confirm, quiet, c, action, actions, setpwd;
2775 int security_enabled, erase_timeout, pwdsize;
2776 struct ata_security_password pwd;
2784 memset(&pwd, 0, sizeof(pwd));
2786 /* default action is to print security information */
2787 action = ATA_SECURITY_ACTION_PRINT;
2789 /* user is master by default as its safer that way */
2790 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2791 pwdsize = sizeof(pwd.password);
2793 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2796 action = ATA_SECURITY_ACTION_FREEZE;
2801 if (strcasecmp(optarg, "user") == 0) {
2802 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2803 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2804 } else if (strcasecmp(optarg, "master") == 0) {
2805 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2806 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2808 warnx("-U argument '%s' is invalid (must be "
2809 "'user' or 'master')", optarg);
2815 if (strcasecmp(optarg, "high") == 0) {
2816 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2817 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2818 } else if (strcasecmp(optarg, "maximum") == 0) {
2819 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2820 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2822 warnx("-l argument '%s' is unknown (must be "
2823 "'high' or 'maximum')", optarg);
2829 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2831 action = ATA_SECURITY_ACTION_UNLOCK;
2836 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2838 action = ATA_SECURITY_ACTION_DISABLE;
2843 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2845 action = ATA_SECURITY_ACTION_ERASE;
2850 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2852 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2853 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2858 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2861 if (action == ATA_SECURITY_ACTION_PRINT)
2862 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2864 * Don't increment action as this can be combined
2865 * with other actions.
2878 erase_timeout = atoi(optarg) * 1000;
2884 warnx("too many security actions specified");
2888 if ((ccb = cam_getccb(device)) == NULL) {
2889 warnx("couldn't allocate CCB");
2893 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2900 printf("%s%d: ", device->device_name, device->dev_unit_num);
2901 ata_print_ident(ident_buf);
2902 camxferrate(device);
2905 if (action == ATA_SECURITY_ACTION_PRINT) {
2906 atasecurity_print(ident_buf);
2912 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2913 warnx("Security not supported");
2919 /* default timeout 15 seconds the same as linux hdparm */
2920 timeout = timeout ? timeout : 15 * 1000;
2922 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2924 /* first set the password if requested */
2926 /* confirm we can erase before setting the password if erasing */
2928 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2929 action == ATA_SECURITY_ACTION_ERASE) &&
2930 atasecurity_erase_confirm(device, ident_buf) == 0) {
2936 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2937 pwd.revision = ident_buf->master_passwd_revision;
2938 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2939 --pwd.revision == 0) {
2940 pwd.revision = 0xfffe;
2943 error = atasecurity_set_password(device, ccb, retry_count,
2944 timeout, &pwd, quiet);
2950 security_enabled = 1;
2954 case ATA_SECURITY_ACTION_FREEZE:
2955 error = atasecurity_freeze(device, ccb, retry_count,
2959 case ATA_SECURITY_ACTION_UNLOCK:
2960 if (security_enabled) {
2961 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2962 error = atasecurity_unlock(device, ccb,
2963 retry_count, timeout, &pwd, quiet);
2965 warnx("Can't unlock, drive is not locked");
2969 warnx("Can't unlock, security is disabled");
2974 case ATA_SECURITY_ACTION_DISABLE:
2975 if (security_enabled) {
2976 /* First unlock the drive if its locked */
2977 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2978 error = atasecurity_unlock(device, ccb,
2986 error = atasecurity_disable(device,
2994 warnx("Can't disable security (already disabled)");
2999 case ATA_SECURITY_ACTION_ERASE:
3000 if (security_enabled) {
3001 if (erase_timeout == 0) {
3002 erase_timeout = atasecurity_erase_timeout_msecs(
3003 ident_buf->erase_time);
3006 error = atasecurity_erase(device, ccb, retry_count,
3007 timeout, erase_timeout, &pwd,
3010 warnx("Can't secure erase (security is disabled)");
3015 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3016 if (security_enabled) {
3017 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3018 if (erase_timeout == 0) {
3020 atasecurity_erase_timeout_msecs(
3021 ident_buf->enhanced_erase_time);
3024 error = atasecurity_erase(device, ccb,
3025 retry_count, timeout,
3026 erase_timeout, &pwd,
3029 warnx("Enhanced erase is not supported");
3033 warnx("Can't secure erase (enhanced), "
3034 "(security is disabled)");
3045 #endif /* MINIMALISTIC */
3048 * Parse out a bus, or a bus, target and lun in the following
3054 * Returns the number of parsed components, or 0.
3057 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3058 cam_argmask *arglst)
3063 while (isspace(*tstr) && (*tstr != '\0'))
3066 tmpstr = (char *)strtok(tstr, ":");
3067 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3068 *bus = strtol(tmpstr, NULL, 0);
3069 *arglst |= CAM_ARG_BUS;
3071 tmpstr = (char *)strtok(NULL, ":");
3072 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3073 *target = strtol(tmpstr, NULL, 0);
3074 *arglst |= CAM_ARG_TARGET;
3076 tmpstr = (char *)strtok(NULL, ":");
3077 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3078 *lun = strtol(tmpstr, NULL, 0);
3079 *arglst |= CAM_ARG_LUN;
3089 dorescan_or_reset(int argc, char **argv, int rescan)
3091 static const char must[] =
3092 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3094 path_id_t bus = CAM_BUS_WILDCARD;
3095 target_id_t target = CAM_TARGET_WILDCARD;
3096 lun_id_t lun = CAM_LUN_WILDCARD;
3100 warnx(must, rescan? "rescan" : "reset");
3104 tstr = argv[optind];
3105 while (isspace(*tstr) && (*tstr != '\0'))
3107 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3108 arglist |= CAM_ARG_BUS;
3110 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3111 if (rv != 1 && rv != 3) {
3112 warnx(must, rescan? "rescan" : "reset");
3117 if ((arglist & CAM_ARG_BUS)
3118 && (arglist & CAM_ARG_TARGET)
3119 && (arglist & CAM_ARG_LUN))
3120 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3122 error = rescan_or_reset_bus(bus, rescan);
3128 rescan_or_reset_bus(path_id_t bus, int rescan)
3130 union ccb ccb, matchccb;
3136 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3137 warnx("error opening transport layer device %s", XPT_DEVICE);
3138 warn("%s", XPT_DEVICE);
3142 if (bus != CAM_BUS_WILDCARD) {
3143 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3144 ccb.ccb_h.path_id = bus;
3145 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3146 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3147 ccb.crcn.flags = CAM_FLAG_NONE;
3149 /* run this at a low priority */
3150 ccb.ccb_h.pinfo.priority = 5;
3152 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3153 warn("CAMIOCOMMAND ioctl failed");
3158 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3159 fprintf(stdout, "%s of bus %d was successful\n",
3160 rescan ? "Re-scan" : "Reset", bus);
3162 fprintf(stdout, "%s of bus %d returned error %#x\n",
3163 rescan ? "Re-scan" : "Reset", bus,
3164 ccb.ccb_h.status & CAM_STATUS_MASK);
3175 * The right way to handle this is to modify the xpt so that it can
3176 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3177 * that isn't implemented, so instead we enumerate the busses and
3178 * send the rescan or reset to those busses in the case where the
3179 * given bus is -1 (wildcard). We don't send a rescan or reset
3180 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3181 * no-op, sending a rescan to the xpt bus would result in a status of
3184 bzero(&(&matchccb.ccb_h)[1],
3185 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3186 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3187 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3188 bufsize = sizeof(struct dev_match_result) * 20;
3189 matchccb.cdm.match_buf_len = bufsize;
3190 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3191 if (matchccb.cdm.matches == NULL) {
3192 warnx("can't malloc memory for matches");
3196 matchccb.cdm.num_matches = 0;
3198 matchccb.cdm.num_patterns = 1;
3199 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3201 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3202 matchccb.cdm.pattern_buf_len);
3203 if (matchccb.cdm.patterns == NULL) {
3204 warnx("can't malloc memory for patterns");
3208 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3209 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3214 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3215 warn("CAMIOCOMMAND ioctl failed");
3220 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3221 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3222 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3223 warnx("got CAM error %#x, CDM error %d\n",
3224 matchccb.ccb_h.status, matchccb.cdm.status);
3229 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3230 struct bus_match_result *bus_result;
3232 /* This shouldn't happen. */
3233 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3236 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3239 * We don't want to rescan or reset the xpt bus.
3242 if (bus_result->path_id == CAM_XPT_PATH_ID)
3245 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3247 ccb.ccb_h.path_id = bus_result->path_id;
3248 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3249 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3250 ccb.crcn.flags = CAM_FLAG_NONE;
3252 /* run this at a low priority */
3253 ccb.ccb_h.pinfo.priority = 5;
3255 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3256 warn("CAMIOCOMMAND ioctl failed");
3261 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3262 fprintf(stdout, "%s of bus %d was successful\n",
3263 rescan? "Re-scan" : "Reset",
3264 bus_result->path_id);
3267 * Don't bail out just yet, maybe the other
3268 * rescan or reset commands will complete
3271 fprintf(stderr, "%s of bus %d returned error "
3272 "%#x\n", rescan? "Re-scan" : "Reset",
3273 bus_result->path_id,
3274 ccb.ccb_h.status & CAM_STATUS_MASK);
3278 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3279 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3286 if (matchccb.cdm.patterns != NULL)
3287 free(matchccb.cdm.patterns);
3288 if (matchccb.cdm.matches != NULL)
3289 free(matchccb.cdm.matches);
3295 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3298 struct cam_device *device;
3303 if (bus == CAM_BUS_WILDCARD) {
3304 warnx("invalid bus number %d", bus);
3308 if (target == CAM_TARGET_WILDCARD) {
3309 warnx("invalid target number %d", target);
3313 if (lun == CAM_LUN_WILDCARD) {
3314 warnx("invalid lun number %jx", (uintmax_t)lun);
3320 bzero(&ccb, sizeof(union ccb));
3323 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3324 warnx("error opening transport layer device %s\n",
3326 warn("%s", XPT_DEVICE);
3330 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3331 if (device == NULL) {
3332 warnx("%s", cam_errbuf);
3337 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3338 ccb.ccb_h.path_id = bus;
3339 ccb.ccb_h.target_id = target;
3340 ccb.ccb_h.target_lun = lun;
3341 ccb.ccb_h.timeout = 5000;
3342 ccb.crcn.flags = CAM_FLAG_NONE;
3344 /* run this at a low priority */
3345 ccb.ccb_h.pinfo.priority = 5;
3348 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3349 warn("CAMIOCOMMAND ioctl failed");
3354 if (cam_send_ccb(device, &ccb) < 0) {
3355 warn("error sending XPT_RESET_DEV CCB");
3356 cam_close_device(device);
3364 cam_close_device(device);
3367 * An error code of CAM_BDR_SENT is normal for a BDR request.
3369 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3371 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3372 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3373 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3376 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3377 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3378 ccb.ccb_h.status & CAM_STATUS_MASK);
3383 #ifndef MINIMALISTIC
3385 static struct scsi_nv defect_list_type_map[] = {
3386 { "block", SRDD10_BLOCK_FORMAT },
3387 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3388 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3389 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3390 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3391 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3395 readdefects(struct cam_device *device, int argc, char **argv,
3396 char *combinedopt, int retry_count, int timeout)
3398 union ccb *ccb = NULL;
3399 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3400 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3401 size_t hdr_size = 0, entry_size = 0;
3404 u_int8_t *defect_list = NULL;
3405 u_int8_t list_format = 0;
3406 int list_type_set = 0;
3407 u_int32_t dlist_length = 0;
3408 u_int32_t returned_length = 0, valid_len = 0;
3409 u_int32_t num_returned = 0, num_valid = 0;
3410 u_int32_t max_possible_size = 0, hdr_max = 0;
3411 u_int32_t starting_offset = 0;
3412 u_int8_t returned_format, returned_type;
3414 int summary = 0, quiet = 0;
3416 int lists_specified = 0;
3417 int get_length = 1, first_pass = 1;
3420 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3424 scsi_nv_status status;
3427 status = scsi_get_nv(defect_list_type_map,
3428 sizeof(defect_list_type_map) /
3429 sizeof(defect_list_type_map[0]), optarg,
3430 &entry_num, SCSI_NV_FLAG_IG_CASE);
3432 if (status == SCSI_NV_FOUND) {
3433 list_format = defect_list_type_map[
3437 warnx("%s: %s %s option %s", __func__,
3438 (status == SCSI_NV_AMBIGUOUS) ?
3439 "ambiguous" : "invalid", "defect list type",
3442 goto defect_bailout;
3447 arglist |= CAM_ARG_GLIST;
3450 arglist |= CAM_ARG_PLIST;
3461 starting_offset = strtoul(optarg, &endptr, 0);
3462 if (*endptr != '\0') {
3464 warnx("invalid starting offset %s", optarg);
3465 goto defect_bailout;
3477 if (list_type_set == 0) {
3479 warnx("no defect list format specified");
3480 goto defect_bailout;
3483 if (arglist & CAM_ARG_PLIST) {
3484 list_format |= SRDD10_PLIST;
3488 if (arglist & CAM_ARG_GLIST) {
3489 list_format |= SRDD10_GLIST;
3494 * This implies a summary, and was the previous behavior.
3496 if (lists_specified == 0)
3499 ccb = cam_getccb(device);
3504 * We start off asking for just the header to determine how much
3505 * defect data is available. Some Hitachi drives return an error
3506 * if you ask for more data than the drive has. Once we know the
3507 * length, we retry the command with the returned length.
3509 if (use_12byte == 0)
3510 dlist_length = sizeof(*hdr10);
3512 dlist_length = sizeof(*hdr12);
3515 if (defect_list != NULL) {
3519 defect_list = malloc(dlist_length);
3520 if (defect_list == NULL) {
3521 warnx("can't malloc memory for defect list");
3523 goto defect_bailout;
3527 bzero(defect_list, dlist_length);
3530 * cam_getccb() zeros the CCB header only. So we need to zero the
3531 * payload portion of the ccb.
3533 bzero(&(&ccb->ccb_h)[1],
3534 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3536 scsi_read_defects(&ccb->csio,
3537 /*retries*/ retry_count,
3539 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3540 /*list_format*/ list_format,
3541 /*addr_desc_index*/ starting_offset,
3542 /*data_ptr*/ defect_list,
3543 /*dxfer_len*/ dlist_length,
3544 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3545 /*sense_len*/ SSD_FULL_SIZE,
3546 /*timeout*/ timeout ? timeout : 5000);
3548 /* Disable freezing the device queue */
3549 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3551 if (cam_send_ccb(device, ccb) < 0) {
3552 perror("error reading defect list");
3554 if (arglist & CAM_ARG_VERBOSE) {
3555 cam_error_print(device, ccb, CAM_ESF_ALL,
3556 CAM_EPF_ALL, stderr);
3560 goto defect_bailout;
3563 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3565 if (use_12byte == 0) {
3566 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3567 hdr_size = sizeof(*hdr10);
3568 hdr_max = SRDDH10_MAX_LENGTH;
3570 if (valid_len >= hdr_size) {
3571 returned_length = scsi_2btoul(hdr10->length);
3572 returned_format = hdr10->format;
3574 returned_length = 0;
3575 returned_format = 0;
3578 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3579 hdr_size = sizeof(*hdr12);
3580 hdr_max = SRDDH12_MAX_LENGTH;
3582 if (valid_len >= hdr_size) {
3583 returned_length = scsi_4btoul(hdr12->length);
3584 returned_format = hdr12->format;
3586 returned_length = 0;
3587 returned_format = 0;
3591 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3592 switch (returned_type) {
3593 case SRDD10_BLOCK_FORMAT:
3594 entry_size = sizeof(struct scsi_defect_desc_block);
3596 case SRDD10_LONG_BLOCK_FORMAT:
3597 entry_size = sizeof(struct scsi_defect_desc_long_block);
3599 case SRDD10_EXT_PHYS_FORMAT:
3600 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3601 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3603 case SRDD10_EXT_BFI_FORMAT:
3604 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3605 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3608 warnx("Unknown defect format 0x%x\n", returned_type);
3610 goto defect_bailout;
3614 max_possible_size = (hdr_max / entry_size) * entry_size;
3615 num_returned = returned_length / entry_size;
3616 num_valid = min(returned_length, valid_len - hdr_size);
3617 num_valid /= entry_size;
3619 if (get_length != 0) {
3622 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3623 CAM_SCSI_STATUS_ERROR) {
3624 struct scsi_sense_data *sense;
3625 int error_code, sense_key, asc, ascq;
3627 sense = &ccb->csio.sense_data;
3628 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3629 ccb->csio.sense_resid, &error_code, &sense_key,
3630 &asc, &ascq, /*show_errors*/ 1);
3633 * If the drive is reporting that it just doesn't
3634 * support the defect list format, go ahead and use
3635 * the length it reported. Otherwise, the length
3636 * may not be valid, so use the maximum.
3638 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3639 && (asc == 0x1c) && (ascq == 0x00)
3640 && (returned_length > 0)) {
3641 if ((use_12byte == 0)
3642 && (returned_length >= max_possible_size)) {
3647 dlist_length = returned_length + hdr_size;
3648 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3649 && (asc == 0x1f) && (ascq == 0x00)
3650 && (returned_length > 0)) {
3651 /* Partial defect list transfer */
3653 * Hitachi drives return this error
3654 * along with a partial defect list if they
3655 * have more defects than the 10 byte
3656 * command can support. Retry with the 12
3659 if (use_12byte == 0) {
3664 dlist_length = returned_length + hdr_size;
3665 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3666 && (asc == 0x24) && (ascq == 0x00)) {
3667 /* Invalid field in CDB */
3669 * SBC-3 says that if the drive has more
3670 * defects than can be reported with the
3671 * 10 byte command, it should return this
3672 * error and no data. Retry with the 12
3675 if (use_12byte == 0) {
3680 dlist_length = returned_length + hdr_size;
3683 * If we got a SCSI error and no valid length,
3684 * just use the 10 byte maximum. The 12
3685 * byte maximum is too large.
3687 if (returned_length == 0)
3688 dlist_length = SRDD10_MAX_LENGTH;
3690 if ((use_12byte == 0)
3691 && (returned_length >=
3692 max_possible_size)) {
3697 dlist_length = returned_length +
3701 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3704 warnx("Error reading defect header");
3705 if (arglist & CAM_ARG_VERBOSE)
3706 cam_error_print(device, ccb, CAM_ESF_ALL,
3707 CAM_EPF_ALL, stderr);
3708 goto defect_bailout;
3710 if ((use_12byte == 0)
3711 && (returned_length >= max_possible_size)) {
3716 dlist_length = returned_length + hdr_size;
3719 fprintf(stdout, "%u", num_returned);
3721 fprintf(stdout, " defect%s",
3722 (num_returned != 1) ? "s" : "");
3724 fprintf(stdout, "\n");
3726 goto defect_bailout;
3730 * We always limit the list length to the 10-byte maximum
3731 * length (0xffff). The reason is that some controllers
3732 * can't handle larger I/Os, and we can transfer the entire
3733 * 10 byte list in one shot. For drives that support the 12
3734 * byte read defects command, we'll step through the list
3735 * by specifying a starting offset. For drives that don't
3736 * support the 12 byte command's starting offset, we'll
3737 * just display the first 64K.
3739 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3745 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3746 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3747 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3748 struct scsi_sense_data *sense;
3749 int error_code, sense_key, asc, ascq;
3751 sense = &ccb->csio.sense_data;
3752 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3753 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3754 &ascq, /*show_errors*/ 1);
3757 * According to the SCSI spec, if the disk doesn't support
3758 * the requested format, it will generally return a sense
3759 * key of RECOVERED ERROR, and an additional sense code
3760 * of "DEFECT LIST NOT FOUND". HGST drives also return
3761 * Primary/Grown defect list not found errors. So just
3762 * check for an ASC of 0x1c.
3764 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3766 const char *format_str;
3768 format_str = scsi_nv_to_str(defect_list_type_map,
3769 sizeof(defect_list_type_map) /
3770 sizeof(defect_list_type_map[0]),
3771 list_format & SRDD10_DLIST_FORMAT_MASK);
3772 warnx("requested defect format %s not available",
3773 format_str ? format_str : "unknown");
3775 format_str = scsi_nv_to_str(defect_list_type_map,
3776 sizeof(defect_list_type_map) /
3777 sizeof(defect_list_type_map[0]), returned_type);
3778 if (format_str != NULL) {
3779 warnx("Device returned %s format",
3783 warnx("Device returned unknown defect"
3784 " data format %#x", returned_type);
3785 goto defect_bailout;
3789 warnx("Error returned from read defect data command");
3790 if (arglist & CAM_ARG_VERBOSE)
3791 cam_error_print(device, ccb, CAM_ESF_ALL,
3792 CAM_EPF_ALL, stderr);
3793 goto defect_bailout;
3795 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3797 warnx("Error returned from read defect data command");
3798 if (arglist & CAM_ARG_VERBOSE)
3799 cam_error_print(device, ccb, CAM_ESF_ALL,
3800 CAM_EPF_ALL, stderr);
3801 goto defect_bailout;
3804 if (first_pass != 0) {
3805 fprintf(stderr, "Got %d defect", num_returned);
3807 if ((lists_specified == 0) || (num_returned == 0)) {
3808 fprintf(stderr, "s.\n");
3809 goto defect_bailout;
3810 } else if (num_returned == 1)
3811 fprintf(stderr, ":\n");
3813 fprintf(stderr, "s:\n");
3819 * XXX KDM I should probably clean up the printout format for the
3822 switch (returned_type) {
3823 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3824 case SRDD10_EXT_PHYS_FORMAT:
3826 struct scsi_defect_desc_phys_sector *dlist;
3828 dlist = (struct scsi_defect_desc_phys_sector *)
3829 (defect_list + hdr_size);
3831 for (i = 0; i < num_valid; i++) {
3834 sector = scsi_4btoul(dlist[i].sector);
3835 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3836 mads = (sector & SDD_EXT_PHYS_MADS) ?
3838 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3840 if (hex_format == 0)
3841 fprintf(stdout, "%d:%d:%d%s",
3842 scsi_3btoul(dlist[i].cylinder),
3844 scsi_4btoul(dlist[i].sector),
3845 mads ? " - " : "\n");
3847 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3848 scsi_3btoul(dlist[i].cylinder),
3850 scsi_4btoul(dlist[i].sector),
3851 mads ? " - " : "\n");
3854 if (num_valid < num_returned) {
3855 starting_offset += num_valid;
3860 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3861 case SRDD10_EXT_BFI_FORMAT:
3863 struct scsi_defect_desc_bytes_from_index *dlist;
3865 dlist = (struct scsi_defect_desc_bytes_from_index *)
3866 (defect_list + hdr_size);
3868 for (i = 0; i < num_valid; i++) {
3871 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3872 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3873 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3874 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3876 if (hex_format == 0)
3877 fprintf(stdout, "%d:%d:%d%s",
3878 scsi_3btoul(dlist[i].cylinder),
3880 scsi_4btoul(dlist[i].bytes_from_index),
3881 mads ? " - " : "\n");
3883 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3884 scsi_3btoul(dlist[i].cylinder),
3886 scsi_4btoul(dlist[i].bytes_from_index),
3887 mads ? " - " : "\n");
3891 if (num_valid < num_returned) {
3892 starting_offset += num_valid;
3897 case SRDDH10_BLOCK_FORMAT:
3899 struct scsi_defect_desc_block *dlist;
3901 dlist = (struct scsi_defect_desc_block *)
3902 (defect_list + hdr_size);
3904 for (i = 0; i < num_valid; i++) {
3905 if (hex_format == 0)
3906 fprintf(stdout, "%u\n",
3907 scsi_4btoul(dlist[i].address));
3909 fprintf(stdout, "0x%x\n",
3910 scsi_4btoul(dlist[i].address));
3913 if (num_valid < num_returned) {
3914 starting_offset += num_valid;
3920 case SRDD10_LONG_BLOCK_FORMAT:
3922 struct scsi_defect_desc_long_block *dlist;
3924 dlist = (struct scsi_defect_desc_long_block *)
3925 (defect_list + hdr_size);
3927 for (i = 0; i < num_valid; i++) {
3928 if (hex_format == 0)
3929 fprintf(stdout, "%ju\n",
3930 (uintmax_t)scsi_8btou64(
3933 fprintf(stdout, "0x%jx\n",
3934 (uintmax_t)scsi_8btou64(
3938 if (num_valid < num_returned) {
3939 starting_offset += num_valid;
3945 fprintf(stderr, "Unknown defect format 0x%x\n",
3952 if (defect_list != NULL)
3960 #endif /* MINIMALISTIC */
3964 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3968 ccb = cam_getccb(device);
3974 #ifndef MINIMALISTIC
3976 mode_sense(struct cam_device *device, int mode_page, int page_control,
3977 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3982 ccb = cam_getccb(device);
3985 errx(1, "mode_sense: couldn't allocate CCB");
3987 bzero(&(&ccb->ccb_h)[1],
3988 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3990 scsi_mode_sense(&ccb->csio,
3991 /* retries */ retry_count,
3993 /* tag_action */ MSG_SIMPLE_Q_TAG,
3995 /* page_code */ page_control << 6,
3996 /* page */ mode_page,
3997 /* param_buf */ data,
3998 /* param_len */ datalen,
3999 /* sense_len */ SSD_FULL_SIZE,
4000 /* timeout */ timeout ? timeout : 5000);
4002 if (arglist & CAM_ARG_ERR_RECOVER)
4003 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4005 /* Disable freezing the device queue */
4006 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4008 if (((retval = cam_send_ccb(device, ccb)) < 0)
4009 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4010 if (arglist & CAM_ARG_VERBOSE) {
4011 cam_error_print(device, ccb, CAM_ESF_ALL,
4012 CAM_EPF_ALL, stderr);
4015 cam_close_device(device);
4017 err(1, "error sending mode sense command");
4019 errx(1, "error sending mode sense command");
4026 mode_select(struct cam_device *device, int save_pages, int retry_count,
4027 int timeout, u_int8_t *data, int datalen)
4032 ccb = cam_getccb(device);
4035 errx(1, "mode_select: couldn't allocate CCB");
4037 bzero(&(&ccb->ccb_h)[1],
4038 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4040 scsi_mode_select(&ccb->csio,
4041 /* retries */ retry_count,
4043 /* tag_action */ MSG_SIMPLE_Q_TAG,
4044 /* scsi_page_fmt */ 1,
4045 /* save_pages */ save_pages,
4046 /* param_buf */ data,
4047 /* param_len */ datalen,
4048 /* sense_len */ SSD_FULL_SIZE,
4049 /* timeout */ timeout ? timeout : 5000);
4051 if (arglist & CAM_ARG_ERR_RECOVER)
4052 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4054 /* Disable freezing the device queue */
4055 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4057 if (((retval = cam_send_ccb(device, ccb)) < 0)
4058 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4059 if (arglist & CAM_ARG_VERBOSE) {
4060 cam_error_print(device, ccb, CAM_ESF_ALL,
4061 CAM_EPF_ALL, stderr);
4064 cam_close_device(device);
4067 err(1, "error sending mode select command");
4069 errx(1, "error sending mode select command");
4077 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4078 int retry_count, int timeout)
4080 int c, mode_page = -1, page_control = 0;
4081 int binary = 0, list = 0;
4083 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4089 arglist |= CAM_ARG_DBD;
4092 arglist |= CAM_ARG_MODE_EDIT;
4098 mode_page = strtol(optarg, NULL, 0);
4100 errx(1, "invalid mode page %d", mode_page);
4103 page_control = strtol(optarg, NULL, 0);
4104 if ((page_control < 0) || (page_control > 3))
4105 errx(1, "invalid page control field %d",
4107 arglist |= CAM_ARG_PAGE_CNTL;
4114 if (mode_page == -1 && list == 0)
4115 errx(1, "you must specify a mode page!");
4118 mode_list(device, page_control, arglist & CAM_ARG_DBD,
4119 retry_count, timeout);
4121 mode_edit(device, mode_page, page_control,
4122 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
4123 retry_count, timeout);
4128 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4129 int retry_count, int timeout)
4132 u_int32_t flags = CAM_DIR_NONE;
4133 u_int8_t *data_ptr = NULL;
4135 u_int8_t atacmd[12];
4136 struct get_hook hook;
4137 int c, data_bytes = 0;
4143 char *datastr = NULL, *tstr, *resstr = NULL;
4145 int fd_data = 0, fd_res = 0;
4148 ccb = cam_getccb(device);
4151 warnx("scsicmd: error allocating ccb");
4155 bzero(&(&ccb->ccb_h)[1],
4156 sizeof(union ccb) - sizeof(struct ccb_hdr));
4158 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4162 while (isspace(*tstr) && (*tstr != '\0'))
4164 hook.argc = argc - optind;
4165 hook.argv = argv + optind;
4167 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4170 * Increment optind by the number of arguments the
4171 * encoding routine processed. After each call to
4172 * getopt(3), optind points to the argument that
4173 * getopt should process _next_. In this case,
4174 * that means it points to the first command string
4175 * argument, if there is one. Once we increment
4176 * this, it should point to either the next command
4177 * line argument, or it should be past the end of
4184 while (isspace(*tstr) && (*tstr != '\0'))
4186 hook.argc = argc - optind;
4187 hook.argv = argv + optind;
4189 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4192 * Increment optind by the number of arguments the
4193 * encoding routine processed. After each call to
4194 * getopt(3), optind points to the argument that
4195 * getopt should process _next_. In this case,
4196 * that means it points to the first command string
4197 * argument, if there is one. Once we increment
4198 * this, it should point to either the next command
4199 * line argument, or it should be past the end of
4211 if (arglist & CAM_ARG_CMD_OUT) {
4212 warnx("command must either be "
4213 "read or write, not both");
4215 goto scsicmd_bailout;
4217 arglist |= CAM_ARG_CMD_IN;
4219 data_bytes = strtol(optarg, NULL, 0);
4220 if (data_bytes <= 0) {
4221 warnx("invalid number of input bytes %d",
4224 goto scsicmd_bailout;
4226 hook.argc = argc - optind;
4227 hook.argv = argv + optind;
4230 datastr = cget(&hook, NULL);
4232 * If the user supplied "-" instead of a format, he
4233 * wants the data to be written to stdout.
4235 if ((datastr != NULL)
4236 && (datastr[0] == '-'))
4239 data_ptr = (u_int8_t *)malloc(data_bytes);
4240 if (data_ptr == NULL) {
4241 warnx("can't malloc memory for data_ptr");
4243 goto scsicmd_bailout;
4247 if (arglist & CAM_ARG_CMD_IN) {
4248 warnx("command must either be "
4249 "read or write, not both");
4251 goto scsicmd_bailout;
4253 arglist |= CAM_ARG_CMD_OUT;
4254 flags = CAM_DIR_OUT;
4255 data_bytes = strtol(optarg, NULL, 0);
4256 if (data_bytes <= 0) {
4257 warnx("invalid number of output bytes %d",
4260 goto scsicmd_bailout;
4262 hook.argc = argc - optind;
4263 hook.argv = argv + optind;
4265 datastr = cget(&hook, NULL);
4266 data_ptr = (u_int8_t *)malloc(data_bytes);
4267 if (data_ptr == NULL) {
4268 warnx("can't malloc memory for data_ptr");
4270 goto scsicmd_bailout;
4272 bzero(data_ptr, data_bytes);
4274 * If the user supplied "-" instead of a format, he
4275 * wants the data to be read from stdin.
4277 if ((datastr != NULL)
4278 && (datastr[0] == '-'))
4281 buff_encode_visit(data_ptr, data_bytes, datastr,
4287 hook.argc = argc - optind;
4288 hook.argv = argv + optind;
4290 resstr = cget(&hook, NULL);
4291 if ((resstr != NULL) && (resstr[0] == '-'))
4301 * If fd_data is set, and we're writing to the device, we need to
4302 * read the data the user wants written from stdin.
4304 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4306 int amt_to_read = data_bytes;
4307 u_int8_t *buf_ptr = data_ptr;
4309 for (amt_read = 0; amt_to_read > 0;
4310 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4311 if (amt_read == -1) {
4312 warn("error reading data from stdin");
4314 goto scsicmd_bailout;
4316 amt_to_read -= amt_read;
4317 buf_ptr += amt_read;
4321 if (arglist & CAM_ARG_ERR_RECOVER)
4322 flags |= CAM_PASS_ERR_RECOVER;
4324 /* Disable freezing the device queue */
4325 flags |= CAM_DEV_QFRZDIS;
4329 * This is taken from the SCSI-3 draft spec.
4330 * (T10/1157D revision 0.3)
4331 * The top 3 bits of an opcode are the group code.
4332 * The next 5 bits are the command code.
4333 * Group 0: six byte commands
4334 * Group 1: ten byte commands
4335 * Group 2: ten byte commands
4337 * Group 4: sixteen byte commands
4338 * Group 5: twelve byte commands
4339 * Group 6: vendor specific
4340 * Group 7: vendor specific
4342 switch((cdb[0] >> 5) & 0x7) {
4353 /* computed by buff_encode_visit */
4364 * We should probably use csio_build_visit or something like that
4365 * here, but it's easier to encode arguments as you go. The
4366 * alternative would be skipping the CDB argument and then encoding
4367 * it here, since we've got the data buffer argument by now.
4369 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4371 cam_fill_csio(&ccb->csio,
4372 /*retries*/ retry_count,
4375 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4376 /*data_ptr*/ data_ptr,
4377 /*dxfer_len*/ data_bytes,
4378 /*sense_len*/ SSD_FULL_SIZE,
4379 /*cdb_len*/ cdb_len,
4380 /*timeout*/ timeout ? timeout : 5000);
4383 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4385 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4387 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4389 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4391 cam_fill_ataio(&ccb->ataio,
4392 /*retries*/ retry_count,
4396 /*data_ptr*/ data_ptr,
4397 /*dxfer_len*/ data_bytes,
4398 /*timeout*/ timeout ? timeout : 5000);
4401 if (((retval = cam_send_ccb(device, ccb)) < 0)
4402 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4403 const char warnstr[] = "error sending command";
4410 if (arglist & CAM_ARG_VERBOSE) {
4411 cam_error_print(device, ccb, CAM_ESF_ALL,
4412 CAM_EPF_ALL, stderr);
4416 goto scsicmd_bailout;
4419 if (atacmd_len && need_res) {
4421 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4423 fprintf(stdout, "\n");
4426 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4427 ccb->ataio.res.status,
4428 ccb->ataio.res.error,
4429 ccb->ataio.res.lba_low,
4430 ccb->ataio.res.lba_mid,
4431 ccb->ataio.res.lba_high,
4432 ccb->ataio.res.device,
4433 ccb->ataio.res.lba_low_exp,
4434 ccb->ataio.res.lba_mid_exp,
4435 ccb->ataio.res.lba_high_exp,
4436 ccb->ataio.res.sector_count,
4437 ccb->ataio.res.sector_count_exp);
4442 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4443 && (arglist & CAM_ARG_CMD_IN)
4444 && (data_bytes > 0)) {
4446 buff_decode_visit(data_ptr, data_bytes, datastr,
4448 fprintf(stdout, "\n");
4450 ssize_t amt_written;
4451 int amt_to_write = data_bytes;
4452 u_int8_t *buf_ptr = data_ptr;
4454 for (amt_written = 0; (amt_to_write > 0) &&
4455 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4456 amt_to_write -= amt_written;
4457 buf_ptr += amt_written;
4459 if (amt_written == -1) {
4460 warn("error writing data to stdout");
4462 goto scsicmd_bailout;
4463 } else if ((amt_written == 0)
4464 && (amt_to_write > 0)) {
4465 warnx("only wrote %u bytes out of %u",
4466 data_bytes - amt_to_write, data_bytes);
4473 if ((data_bytes > 0) && (data_ptr != NULL))
4482 camdebug(int argc, char **argv, char *combinedopt)
4485 path_id_t bus = CAM_BUS_WILDCARD;
4486 target_id_t target = CAM_TARGET_WILDCARD;
4487 lun_id_t lun = CAM_LUN_WILDCARD;
4488 char *tstr, *tmpstr = NULL;
4492 bzero(&ccb, sizeof(union ccb));
4494 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4497 arglist |= CAM_ARG_DEBUG_INFO;
4498 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4501 arglist |= CAM_ARG_DEBUG_PERIPH;
4502 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4505 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4506 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4509 arglist |= CAM_ARG_DEBUG_TRACE;
4510 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4513 arglist |= CAM_ARG_DEBUG_XPT;
4514 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4517 arglist |= CAM_ARG_DEBUG_CDB;
4518 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4521 arglist |= CAM_ARG_DEBUG_PROBE;
4522 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4529 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4530 warnx("error opening transport layer device %s", XPT_DEVICE);
4531 warn("%s", XPT_DEVICE);
4538 warnx("you must specify \"off\", \"all\" or a bus,");
4539 warnx("bus:target, or bus:target:lun");
4546 while (isspace(*tstr) && (*tstr != '\0'))
4549 if (strncmp(tstr, "off", 3) == 0) {
4550 ccb.cdbg.flags = CAM_DEBUG_NONE;
4551 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4552 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4553 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4554 } else if (strncmp(tstr, "all", 3) != 0) {
4555 tmpstr = (char *)strtok(tstr, ":");
4556 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4557 bus = strtol(tmpstr, NULL, 0);
4558 arglist |= CAM_ARG_BUS;
4559 tmpstr = (char *)strtok(NULL, ":");
4560 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4561 target = strtol(tmpstr, NULL, 0);
4562 arglist |= CAM_ARG_TARGET;
4563 tmpstr = (char *)strtok(NULL, ":");
4564 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4565 lun = strtol(tmpstr, NULL, 0);
4566 arglist |= CAM_ARG_LUN;
4571 warnx("you must specify \"all\", \"off\", or a bus,");
4572 warnx("bus:target, or bus:target:lun to debug");
4578 ccb.ccb_h.func_code = XPT_DEBUG;
4579 ccb.ccb_h.path_id = bus;
4580 ccb.ccb_h.target_id = target;
4581 ccb.ccb_h.target_lun = lun;
4583 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4584 warn("CAMIOCOMMAND ioctl failed");
4589 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4590 CAM_FUNC_NOTAVAIL) {
4591 warnx("CAM debugging not available");
4592 warnx("you need to put options CAMDEBUG in"
4593 " your kernel config file!");
4595 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4597 warnx("XPT_DEBUG CCB failed with status %#x",
4601 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4603 "Debugging turned off\n");
4606 "Debugging enabled for "
4608 bus, target, (uintmax_t)lun);
4619 tagcontrol(struct cam_device *device, int argc, char **argv,
4629 ccb = cam_getccb(device);
4632 warnx("tagcontrol: error allocating ccb");
4636 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4639 numtags = strtol(optarg, NULL, 0);
4641 warnx("tag count %d is < 0", numtags);
4643 goto tagcontrol_bailout;
4654 cam_path_string(device, pathstr, sizeof(pathstr));
4657 bzero(&(&ccb->ccb_h)[1],
4658 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4659 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4660 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4661 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4662 ccb->crs.openings = numtags;
4665 if (cam_send_ccb(device, ccb) < 0) {
4666 perror("error sending XPT_REL_SIMQ CCB");
4668 goto tagcontrol_bailout;
4671 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4672 warnx("XPT_REL_SIMQ CCB failed");
4673 cam_error_print(device, ccb, CAM_ESF_ALL,
4674 CAM_EPF_ALL, stderr);
4676 goto tagcontrol_bailout;
4681 fprintf(stdout, "%stagged openings now %d\n",
4682 pathstr, ccb->crs.openings);
4685 bzero(&(&ccb->ccb_h)[1],
4686 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4688 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4690 if (cam_send_ccb(device, ccb) < 0) {
4691 perror("error sending XPT_GDEV_STATS CCB");
4693 goto tagcontrol_bailout;
4696 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4697 warnx("XPT_GDEV_STATS CCB failed");
4698 cam_error_print(device, ccb, CAM_ESF_ALL,
4699 CAM_EPF_ALL, stderr);
4701 goto tagcontrol_bailout;
4704 if (arglist & CAM_ARG_VERBOSE) {
4705 fprintf(stdout, "%s", pathstr);
4706 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4707 fprintf(stdout, "%s", pathstr);
4708 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4709 fprintf(stdout, "%s", pathstr);
4710 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4711 fprintf(stdout, "%s", pathstr);
4712 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4713 fprintf(stdout, "%s", pathstr);
4714 fprintf(stdout, "held %d\n", ccb->cgds.held);
4715 fprintf(stdout, "%s", pathstr);
4716 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4717 fprintf(stdout, "%s", pathstr);
4718 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4721 fprintf(stdout, "%s", pathstr);
4722 fprintf(stdout, "device openings: ");
4724 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4725 ccb->cgds.dev_active);
4735 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4739 cam_path_string(device, pathstr, sizeof(pathstr));
4741 if (cts->transport == XPORT_SPI) {
4742 struct ccb_trans_settings_spi *spi =
4743 &cts->xport_specific.spi;
4745 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4747 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4750 if (spi->sync_offset != 0) {
4753 freq = scsi_calc_syncsrate(spi->sync_period);
4754 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4755 pathstr, freq / 1000, freq % 1000);
4759 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4760 fprintf(stdout, "%soffset: %d\n", pathstr,
4764 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4765 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4766 (0x01 << spi->bus_width) * 8);
4769 if (spi->valid & CTS_SPI_VALID_DISC) {
4770 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4771 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4772 "enabled" : "disabled");
4775 if (cts->transport == XPORT_FC) {
4776 struct ccb_trans_settings_fc *fc =
4777 &cts->xport_specific.fc;
4779 if (fc->valid & CTS_FC_VALID_WWNN)
4780 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4781 (long long) fc->wwnn);
4782 if (fc->valid & CTS_FC_VALID_WWPN)
4783 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4784 (long long) fc->wwpn);
4785 if (fc->valid & CTS_FC_VALID_PORT)
4786 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4787 if (fc->valid & CTS_FC_VALID_SPEED)
4788 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4789 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4791 if (cts->transport == XPORT_SAS) {
4792 struct ccb_trans_settings_sas *sas =
4793 &cts->xport_specific.sas;
4795 if (sas->valid & CTS_SAS_VALID_SPEED)
4796 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4797 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4799 if (cts->transport == XPORT_ATA) {
4800 struct ccb_trans_settings_pata *pata =
4801 &cts->xport_specific.ata;
4803 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4804 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4805 ata_mode2string(pata->mode));
4807 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4808 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4811 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4812 fprintf(stdout, "%sPIO transaction length: %d\n",
4813 pathstr, pata->bytecount);
4816 if (cts->transport == XPORT_SATA) {
4817 struct ccb_trans_settings_sata *sata =
4818 &cts->xport_specific.sata;
4820 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4821 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4824 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4825 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4826 ata_mode2string(sata->mode));
4828 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4829 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4832 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4833 fprintf(stdout, "%sPIO transaction length: %d\n",
4834 pathstr, sata->bytecount);
4836 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4837 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4840 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4841 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4844 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4845 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4849 if (cts->protocol == PROTO_ATA) {
4850 struct ccb_trans_settings_ata *ata=
4851 &cts->proto_specific.ata;
4853 if (ata->valid & CTS_ATA_VALID_TQ) {
4854 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4855 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4856 "enabled" : "disabled");
4859 if (cts->protocol == PROTO_SCSI) {
4860 struct ccb_trans_settings_scsi *scsi=
4861 &cts->proto_specific.scsi;
4863 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4864 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4865 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4866 "enabled" : "disabled");
4873 * Get a path inquiry CCB for the specified device.
4876 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4881 ccb = cam_getccb(device);
4883 warnx("get_cpi: couldn't allocate CCB");
4886 bzero(&(&ccb->ccb_h)[1],
4887 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4888 ccb->ccb_h.func_code = XPT_PATH_INQ;
4889 if (cam_send_ccb(device, ccb) < 0) {
4890 warn("get_cpi: error sending Path Inquiry CCB");
4891 if (arglist & CAM_ARG_VERBOSE)
4892 cam_error_print(device, ccb, CAM_ESF_ALL,
4893 CAM_EPF_ALL, stderr);
4895 goto get_cpi_bailout;
4897 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4898 if (arglist & CAM_ARG_VERBOSE)
4899 cam_error_print(device, ccb, CAM_ESF_ALL,
4900 CAM_EPF_ALL, stderr);
4902 goto get_cpi_bailout;
4904 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4912 * Get a get device CCB for the specified device.
4915 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4920 ccb = cam_getccb(device);
4922 warnx("get_cgd: couldn't allocate CCB");
4925 bzero(&(&ccb->ccb_h)[1],
4926 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4927 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4928 if (cam_send_ccb(device, ccb) < 0) {
4929 warn("get_cgd: error sending Path Inquiry CCB");
4930 if (arglist & CAM_ARG_VERBOSE)
4931 cam_error_print(device, ccb, CAM_ESF_ALL,
4932 CAM_EPF_ALL, stderr);
4934 goto get_cgd_bailout;
4936 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4937 if (arglist & CAM_ARG_VERBOSE)
4938 cam_error_print(device, ccb, CAM_ESF_ALL,
4939 CAM_EPF_ALL, stderr);
4941 goto get_cgd_bailout;
4943 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4951 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4955 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4956 int timeout, int verbosemode)
4958 union ccb *ccb = NULL;
4959 struct scsi_vpd_supported_page_list sup_pages;
4963 ccb = cam_getccb(dev);
4965 warn("Unable to allocate CCB");
4970 /* cam_getccb cleans up the header, caller has to zero the payload */
4971 bzero(&(&ccb->ccb_h)[1],
4972 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4974 bzero(&sup_pages, sizeof(sup_pages));
4976 scsi_inquiry(&ccb->csio,
4977 /*retries*/ retry_count,
4979 /* tag_action */ MSG_SIMPLE_Q_TAG,
4980 /* inq_buf */ (u_int8_t *)&sup_pages,
4981 /* inq_len */ sizeof(sup_pages),
4983 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
4984 /* sense_len */ SSD_FULL_SIZE,
4985 /* timeout */ timeout ? timeout : 5000);
4987 /* Disable freezing the device queue */
4988 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4990 if (retry_count != 0)
4991 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4993 if (cam_send_ccb(dev, ccb) < 0) {
4999 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5000 if (verbosemode != 0)
5001 cam_error_print(dev, ccb, CAM_ESF_ALL,
5002 CAM_EPF_ALL, stderr);
5007 for (i = 0; i < sup_pages.length; i++) {
5008 if (sup_pages.list[i] == page_id) {
5021 * devtype is filled in with the type of device.
5022 * Returns 0 for success, non-zero for failure.
5025 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5026 int verbosemode, camcontrol_devtype *devtype)
5028 struct ccb_getdev cgd;
5031 retval = get_cgd(dev, &cgd);
5035 switch (cgd.protocol) {
5041 *devtype = CC_DT_ATA;
5043 break; /*NOTREACHED*/
5045 *devtype = CC_DT_UNKNOWN;
5047 break; /*NOTREACHED*/
5051 * Check for the ATA Information VPD page (0x89). If this is an
5052 * ATA device behind a SCSI to ATA translation layer, this VPD page
5053 * should be present.
5055 * If that VPD page isn't present, or we get an error back from the
5056 * INQUIRY command, we'll just treat it as a normal SCSI device.
5058 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5059 timeout, verbosemode);
5061 *devtype = CC_DT_ATA_BEHIND_SCSI;
5063 *devtype = CC_DT_SCSI;
5072 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5073 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5074 uint16_t sector_count, uint64_t lba, uint8_t command, uint8_t *data_ptr,
5075 uint16_t dxfer_len, uint8_t sense_len, uint32_t timeout,
5076 int is48bit, camcontrol_devtype devtype)
5078 if (devtype == CC_DT_ATA) {
5079 cam_fill_ataio(&ccb->ataio,
5080 /*retries*/ retry_count,
5083 /*tag_action*/ tag_action,
5084 /*data_ptr*/ data_ptr,
5085 /*dxfer_len*/ dxfer_len,
5086 /*timeout*/ timeout);
5087 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5088 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5091 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5094 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5095 protocol |= AP_EXTEND;
5097 scsi_ata_pass_16(&ccb->csio,
5098 /*retries*/ retry_count,
5101 /*tag_action*/ tag_action,
5102 /*protocol*/ protocol,
5103 /*ata_flags*/ ata_flags,
5104 /*features*/ features,
5105 /*sector_count*/ sector_count,
5107 /*command*/ command,
5109 /*data_ptr*/ data_ptr,
5110 /*dxfer_len*/ dxfer_len,
5111 /*sense_len*/ sense_len,
5112 /*timeout*/ timeout);
5118 cpi_print(struct ccb_pathinq *cpi)
5120 char adapter_str[1024];
5123 snprintf(adapter_str, sizeof(adapter_str),
5124 "%s%d:", cpi->dev_name, cpi->unit_number);
5126 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5129 for (i = 1; i < 0xff; i = i << 1) {
5132 if ((i & cpi->hba_inquiry) == 0)
5135 fprintf(stdout, "%s supports ", adapter_str);
5139 str = "MDP message";
5142 str = "32 bit wide SCSI";
5145 str = "16 bit wide SCSI";
5148 str = "SDTR message";
5151 str = "linked CDBs";
5154 str = "tag queue messages";
5157 str = "soft reset alternative";
5160 str = "SATA Port Multiplier";
5163 str = "unknown PI bit set";
5166 fprintf(stdout, "%s\n", str);
5169 for (i = 1; i < 0xff; i = i << 1) {
5172 if ((i & cpi->hba_misc) == 0)
5175 fprintf(stdout, "%s ", adapter_str);
5179 str = "bus scans from high ID to low ID";
5182 str = "removable devices not included in scan";
5184 case PIM_NOINITIATOR:
5185 str = "initiator role not supported";
5187 case PIM_NOBUSRESET:
5188 str = "user has disabled initial BUS RESET or"
5189 " controller is in target/mixed mode";
5192 str = "do not send 6-byte commands";
5195 str = "scan bus sequentially";
5198 str = "unknown PIM bit set";
5201 fprintf(stdout, "%s\n", str);
5204 for (i = 1; i < 0xff; i = i << 1) {
5207 if ((i & cpi->target_sprt) == 0)
5210 fprintf(stdout, "%s supports ", adapter_str);
5213 str = "target mode processor mode";
5216 str = "target mode phase cog. mode";
5218 case PIT_DISCONNECT:
5219 str = "disconnects in target mode";
5222 str = "terminate I/O message in target mode";
5225 str = "group 6 commands in target mode";
5228 str = "group 7 commands in target mode";
5231 str = "unknown PIT bit set";
5235 fprintf(stdout, "%s\n", str);
5237 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5239 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5241 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5243 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5244 adapter_str, cpi->hpath_id);
5245 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5247 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5248 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5249 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5250 adapter_str, cpi->hba_vendor);
5251 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5252 adapter_str, cpi->hba_device);
5253 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5254 adapter_str, cpi->hba_subvendor);
5255 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5256 adapter_str, cpi->hba_subdevice);
5257 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5258 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5259 if (cpi->base_transfer_speed > 1000)
5260 fprintf(stdout, "%d.%03dMB/sec\n",
5261 cpi->base_transfer_speed / 1000,
5262 cpi->base_transfer_speed % 1000);
5264 fprintf(stdout, "%dKB/sec\n",
5265 (cpi->base_transfer_speed % 1000) * 1000);
5266 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5267 adapter_str, cpi->maxio);
5271 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5272 struct ccb_trans_settings *cts)
5278 ccb = cam_getccb(device);
5281 warnx("get_print_cts: error allocating ccb");
5285 bzero(&(&ccb->ccb_h)[1],
5286 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5288 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5290 if (user_settings == 0)
5291 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5293 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5295 if (cam_send_ccb(device, ccb) < 0) {
5296 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5297 if (arglist & CAM_ARG_VERBOSE)
5298 cam_error_print(device, ccb, CAM_ESF_ALL,
5299 CAM_EPF_ALL, stderr);
5301 goto get_print_cts_bailout;
5304 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5305 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5306 if (arglist & CAM_ARG_VERBOSE)
5307 cam_error_print(device, ccb, CAM_ESF_ALL,
5308 CAM_EPF_ALL, stderr);
5310 goto get_print_cts_bailout;
5314 cts_print(device, &ccb->cts);
5317 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5319 get_print_cts_bailout:
5327 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5328 int argc, char **argv, char *combinedopt)
5332 int user_settings = 0;
5334 int disc_enable = -1, tag_enable = -1;
5337 double syncrate = -1;
5340 int change_settings = 0, send_tur = 0;
5341 struct ccb_pathinq cpi;
5343 ccb = cam_getccb(device);
5345 warnx("ratecontrol: error allocating ccb");
5348 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5357 if (strncasecmp(optarg, "enable", 6) == 0)
5359 else if (strncasecmp(optarg, "disable", 7) == 0)
5362 warnx("-D argument \"%s\" is unknown", optarg);
5364 goto ratecontrol_bailout;
5366 change_settings = 1;
5369 mode = ata_string2mode(optarg);
5371 warnx("unknown mode '%s'", optarg);
5373 goto ratecontrol_bailout;
5375 change_settings = 1;
5378 offset = strtol(optarg, NULL, 0);
5380 warnx("offset value %d is < 0", offset);
5382 goto ratecontrol_bailout;
5384 change_settings = 1;
5390 syncrate = atof(optarg);
5392 warnx("sync rate %f is < 0", syncrate);
5394 goto ratecontrol_bailout;
5396 change_settings = 1;
5399 if (strncasecmp(optarg, "enable", 6) == 0)
5401 else if (strncasecmp(optarg, "disable", 7) == 0)
5404 warnx("-T argument \"%s\" is unknown", optarg);
5406 goto ratecontrol_bailout;
5408 change_settings = 1;
5414 bus_width = strtol(optarg, NULL, 0);
5415 if (bus_width < 0) {
5416 warnx("bus width %d is < 0", bus_width);
5418 goto ratecontrol_bailout;
5420 change_settings = 1;
5426 bzero(&(&ccb->ccb_h)[1],
5427 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
5429 * Grab path inquiry information, so we can determine whether
5430 * or not the initiator is capable of the things that the user
5433 ccb->ccb_h.func_code = XPT_PATH_INQ;
5434 if (cam_send_ccb(device, ccb) < 0) {
5435 perror("error sending XPT_PATH_INQ CCB");
5436 if (arglist & CAM_ARG_VERBOSE) {
5437 cam_error_print(device, ccb, CAM_ESF_ALL,
5438 CAM_EPF_ALL, stderr);
5441 goto ratecontrol_bailout;
5443 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5444 warnx("XPT_PATH_INQ CCB failed");
5445 if (arglist & CAM_ARG_VERBOSE) {
5446 cam_error_print(device, ccb, CAM_ESF_ALL,
5447 CAM_EPF_ALL, stderr);
5450 goto ratecontrol_bailout;
5452 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5453 bzero(&(&ccb->ccb_h)[1],
5454 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5456 fprintf(stdout, "%s parameters:\n",
5457 user_settings ? "User" : "Current");
5459 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5461 goto ratecontrol_bailout;
5463 if (arglist & CAM_ARG_VERBOSE)
5466 if (change_settings) {
5467 int didsettings = 0;
5468 struct ccb_trans_settings_spi *spi = NULL;
5469 struct ccb_trans_settings_pata *pata = NULL;
5470 struct ccb_trans_settings_sata *sata = NULL;
5471 struct ccb_trans_settings_ata *ata = NULL;
5472 struct ccb_trans_settings_scsi *scsi = NULL;
5474 if (ccb->cts.transport == XPORT_SPI)
5475 spi = &ccb->cts.xport_specific.spi;
5476 if (ccb->cts.transport == XPORT_ATA)
5477 pata = &ccb->cts.xport_specific.ata;
5478 if (ccb->cts.transport == XPORT_SATA)
5479 sata = &ccb->cts.xport_specific.sata;
5480 if (ccb->cts.protocol == PROTO_ATA)
5481 ata = &ccb->cts.proto_specific.ata;
5482 if (ccb->cts.protocol == PROTO_SCSI)
5483 scsi = &ccb->cts.proto_specific.scsi;
5484 ccb->cts.xport_specific.valid = 0;
5485 ccb->cts.proto_specific.valid = 0;
5486 if (spi && disc_enable != -1) {
5487 spi->valid |= CTS_SPI_VALID_DISC;
5488 if (disc_enable == 0)
5489 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5491 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5494 if (tag_enable != -1) {
5495 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5496 warnx("HBA does not support tagged queueing, "
5497 "so you cannot modify tag settings");
5499 goto ratecontrol_bailout;
5502 ata->valid |= CTS_SCSI_VALID_TQ;
5503 if (tag_enable == 0)
5504 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5506 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5509 scsi->valid |= CTS_SCSI_VALID_TQ;
5510 if (tag_enable == 0)
5511 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5513 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5517 if (spi && offset != -1) {
5518 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5519 warnx("HBA is not capable of changing offset");
5521 goto ratecontrol_bailout;
5523 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5524 spi->sync_offset = offset;
5527 if (spi && syncrate != -1) {
5528 int prelim_sync_period;
5530 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5531 warnx("HBA is not capable of changing "
5534 goto ratecontrol_bailout;
5536 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5538 * The sync rate the user gives us is in MHz.
5539 * We need to translate it into KHz for this
5544 * Next, we calculate a "preliminary" sync period
5545 * in tenths of a nanosecond.
5548 prelim_sync_period = 0;
5550 prelim_sync_period = 10000000 / syncrate;
5552 scsi_calc_syncparam(prelim_sync_period);
5555 if (sata && syncrate != -1) {
5556 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5557 warnx("HBA is not capable of changing "
5560 goto ratecontrol_bailout;
5562 if (!user_settings) {
5563 warnx("You can modify only user rate "
5564 "settings for SATA");
5566 goto ratecontrol_bailout;
5568 sata->revision = ata_speed2revision(syncrate * 100);
5569 if (sata->revision < 0) {
5570 warnx("Invalid rate %f", syncrate);
5572 goto ratecontrol_bailout;
5574 sata->valid |= CTS_SATA_VALID_REVISION;
5577 if ((pata || sata) && mode != -1) {
5578 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5579 warnx("HBA is not capable of changing "
5582 goto ratecontrol_bailout;
5584 if (!user_settings) {
5585 warnx("You can modify only user mode "
5586 "settings for ATA/SATA");
5588 goto ratecontrol_bailout;
5592 pata->valid |= CTS_ATA_VALID_MODE;
5595 sata->valid |= CTS_SATA_VALID_MODE;
5600 * The bus_width argument goes like this:
5604 * Therefore, if you shift the number of bits given on the
5605 * command line right by 4, you should get the correct
5608 if (spi && bus_width != -1) {
5610 * We might as well validate things here with a
5611 * decipherable error message, rather than what
5612 * will probably be an indecipherable error message
5613 * by the time it gets back to us.
5615 if ((bus_width == 16)
5616 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5617 warnx("HBA does not support 16 bit bus width");
5619 goto ratecontrol_bailout;
5620 } else if ((bus_width == 32)
5621 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5622 warnx("HBA does not support 32 bit bus width");
5624 goto ratecontrol_bailout;
5625 } else if ((bus_width != 8)
5626 && (bus_width != 16)
5627 && (bus_width != 32)) {
5628 warnx("Invalid bus width %d", bus_width);
5630 goto ratecontrol_bailout;
5632 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5633 spi->bus_width = bus_width >> 4;
5636 if (didsettings == 0) {
5637 goto ratecontrol_bailout;
5639 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5640 if (cam_send_ccb(device, ccb) < 0) {
5641 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5642 if (arglist & CAM_ARG_VERBOSE) {
5643 cam_error_print(device, ccb, CAM_ESF_ALL,
5644 CAM_EPF_ALL, stderr);
5647 goto ratecontrol_bailout;
5649 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5650 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5651 if (arglist & CAM_ARG_VERBOSE) {
5652 cam_error_print(device, ccb, CAM_ESF_ALL,
5653 CAM_EPF_ALL, stderr);
5656 goto ratecontrol_bailout;
5660 retval = testunitready(device, retry_count, timeout,
5661 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5663 * If the TUR didn't succeed, just bail.
5667 fprintf(stderr, "Test Unit Ready failed\n");
5668 goto ratecontrol_bailout;
5671 if ((change_settings || send_tur) && !quiet &&
5672 (ccb->cts.transport == XPORT_ATA ||
5673 ccb->cts.transport == XPORT_SATA || send_tur)) {
5674 fprintf(stdout, "New parameters:\n");
5675 retval = get_print_cts(device, user_settings, 0, NULL);
5678 ratecontrol_bailout:
5684 scsiformat(struct cam_device *device, int argc, char **argv,
5685 char *combinedopt, int retry_count, int timeout)
5689 int ycount = 0, quiet = 0;
5690 int error = 0, retval = 0;
5691 int use_timeout = 10800 * 1000;
5693 struct format_defect_list_header fh;
5694 u_int8_t *data_ptr = NULL;
5695 u_int32_t dxfer_len = 0;
5697 int num_warnings = 0;
5700 ccb = cam_getccb(device);
5703 warnx("scsiformat: error allocating ccb");
5707 bzero(&(&ccb->ccb_h)[1],
5708 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5710 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5731 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5732 "following device:\n");
5734 error = scsidoinquiry(device, argc, argv, combinedopt,
5735 retry_count, timeout);
5738 warnx("scsiformat: error sending inquiry");
5739 goto scsiformat_bailout;
5744 if (!get_confirmation()) {
5746 goto scsiformat_bailout;
5751 use_timeout = timeout;
5754 fprintf(stdout, "Current format timeout is %d seconds\n",
5755 use_timeout / 1000);
5759 * If the user hasn't disabled questions and didn't specify a
5760 * timeout on the command line, ask them if they want the current
5764 && (timeout == 0)) {
5766 int new_timeout = 0;
5768 fprintf(stdout, "Enter new timeout in seconds or press\n"
5769 "return to keep the current timeout [%d] ",
5770 use_timeout / 1000);
5772 if (fgets(str, sizeof(str), stdin) != NULL) {
5774 new_timeout = atoi(str);
5777 if (new_timeout != 0) {
5778 use_timeout = new_timeout * 1000;
5779 fprintf(stdout, "Using new timeout value %d\n",
5780 use_timeout / 1000);
5785 * Keep this outside the if block below to silence any unused
5786 * variable warnings.
5788 bzero(&fh, sizeof(fh));
5791 * If we're in immediate mode, we've got to include the format
5794 if (immediate != 0) {
5795 fh.byte2 = FU_DLH_IMMED;
5796 data_ptr = (u_int8_t *)&fh;
5797 dxfer_len = sizeof(fh);
5798 byte2 = FU_FMT_DATA;
5799 } else if (quiet == 0) {
5800 fprintf(stdout, "Formatting...");
5804 scsi_format_unit(&ccb->csio,
5805 /* retries */ retry_count,
5807 /* tag_action */ MSG_SIMPLE_Q_TAG,
5810 /* data_ptr */ data_ptr,
5811 /* dxfer_len */ dxfer_len,
5812 /* sense_len */ SSD_FULL_SIZE,
5813 /* timeout */ use_timeout);
5815 /* Disable freezing the device queue */
5816 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5818 if (arglist & CAM_ARG_ERR_RECOVER)
5819 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5821 if (((retval = cam_send_ccb(device, ccb)) < 0)
5822 || ((immediate == 0)
5823 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5824 const char errstr[] = "error sending format command";
5831 if (arglist & CAM_ARG_VERBOSE) {
5832 cam_error_print(device, ccb, CAM_ESF_ALL,
5833 CAM_EPF_ALL, stderr);
5836 goto scsiformat_bailout;
5840 * If we ran in non-immediate mode, we already checked for errors
5841 * above and printed out any necessary information. If we're in
5842 * immediate mode, we need to loop through and get status
5843 * information periodically.
5845 if (immediate == 0) {
5847 fprintf(stdout, "Format Complete\n");
5849 goto scsiformat_bailout;
5856 bzero(&(&ccb->ccb_h)[1],
5857 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5860 * There's really no need to do error recovery or
5861 * retries here, since we're just going to sit in a
5862 * loop and wait for the device to finish formatting.
5864 scsi_test_unit_ready(&ccb->csio,
5867 /* tag_action */ MSG_SIMPLE_Q_TAG,
5868 /* sense_len */ SSD_FULL_SIZE,
5869 /* timeout */ 5000);
5871 /* Disable freezing the device queue */
5872 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5874 retval = cam_send_ccb(device, ccb);
5877 * If we get an error from the ioctl, bail out. SCSI
5878 * errors are expected.
5881 warn("error sending CAMIOCOMMAND ioctl");
5882 if (arglist & CAM_ARG_VERBOSE) {
5883 cam_error_print(device, ccb, CAM_ESF_ALL,
5884 CAM_EPF_ALL, stderr);
5887 goto scsiformat_bailout;
5890 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5892 if ((status != CAM_REQ_CMP)
5893 && (status == CAM_SCSI_STATUS_ERROR)
5894 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5895 struct scsi_sense_data *sense;
5896 int error_code, sense_key, asc, ascq;
5898 sense = &ccb->csio.sense_data;
5899 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5900 ccb->csio.sense_resid, &error_code, &sense_key,
5901 &asc, &ascq, /*show_errors*/ 1);
5904 * According to the SCSI-2 and SCSI-3 specs, a
5905 * drive that is in the middle of a format should
5906 * return NOT READY with an ASC of "logical unit
5907 * not ready, format in progress". The sense key
5908 * specific bytes will then be a progress indicator.
5910 if ((sense_key == SSD_KEY_NOT_READY)
5911 && (asc == 0x04) && (ascq == 0x04)) {
5914 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5915 ccb->csio.sense_resid, sks) == 0)
5918 u_int64_t percentage;
5920 val = scsi_2btoul(&sks[1]);
5921 percentage = 10000 * val;
5924 "\rFormatting: %ju.%02u %% "
5926 (uintmax_t)(percentage /
5928 (unsigned)((percentage /
5932 } else if ((quiet == 0)
5933 && (++num_warnings <= 1)) {
5934 warnx("Unexpected SCSI Sense Key "
5935 "Specific value returned "
5937 scsi_sense_print(device, &ccb->csio,
5939 warnx("Unable to print status "
5940 "information, but format will "
5942 warnx("will exit when format is "
5947 warnx("Unexpected SCSI error during format");
5948 cam_error_print(device, ccb, CAM_ESF_ALL,
5949 CAM_EPF_ALL, stderr);
5951 goto scsiformat_bailout;
5954 } else if (status != CAM_REQ_CMP) {
5955 warnx("Unexpected CAM status %#x", status);
5956 if (arglist & CAM_ARG_VERBOSE)
5957 cam_error_print(device, ccb, CAM_ESF_ALL,
5958 CAM_EPF_ALL, stderr);
5960 goto scsiformat_bailout;
5963 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5966 fprintf(stdout, "\nFormat Complete\n");
5976 scsisanitize(struct cam_device *device, int argc, char **argv,
5977 char *combinedopt, int retry_count, int timeout)
5980 u_int8_t action = 0;
5982 int ycount = 0, quiet = 0;
5983 int error = 0, retval = 0;
5984 int use_timeout = 10800 * 1000;
5990 const char *pattern = NULL;
5991 u_int8_t *data_ptr = NULL;
5992 u_int32_t dxfer_len = 0;
5994 int num_warnings = 0;
5997 ccb = cam_getccb(device);
6000 warnx("scsisanitize: error allocating ccb");
6004 bzero(&(&ccb->ccb_h)[1],
6005 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6007 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6010 if (strcasecmp(optarg, "overwrite") == 0)
6011 action = SSZ_SERVICE_ACTION_OVERWRITE;
6012 else if (strcasecmp(optarg, "block") == 0)
6013 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6014 else if (strcasecmp(optarg, "crypto") == 0)
6015 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6016 else if (strcasecmp(optarg, "exitfailure") == 0)
6017 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6019 warnx("invalid service operation \"%s\"",
6022 goto scsisanitize_bailout;
6026 passes = strtol(optarg, NULL, 0);
6027 if (passes < 1 || passes > 31) {
6028 warnx("invalid passes value %d", passes);
6030 goto scsisanitize_bailout;
6061 warnx("an action is required");
6063 goto scsisanitize_bailout;
6064 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6065 struct scsi_sanitize_parameter_list *pl;
6069 if (pattern == NULL) {
6070 warnx("overwrite action requires -P argument");
6072 goto scsisanitize_bailout;
6074 fd = open(pattern, O_RDONLY);
6076 warn("cannot open pattern file %s", pattern);
6078 goto scsisanitize_bailout;
6080 if (fstat(fd, &sb) < 0) {
6081 warn("cannot stat pattern file %s", pattern);
6083 goto scsisanitize_bailout;
6086 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6087 warnx("pattern file size exceeds maximum value %d",
6088 SSZPL_MAX_PATTERN_LENGTH);
6090 goto scsisanitize_bailout;
6092 dxfer_len = sizeof(*pl) + sz;
6093 data_ptr = calloc(1, dxfer_len);
6094 if (data_ptr == NULL) {
6095 warnx("cannot allocate parameter list buffer");
6097 goto scsisanitize_bailout;
6100 amt = read(fd, data_ptr + sizeof(*pl), sz);
6102 warn("cannot read pattern file");
6104 goto scsisanitize_bailout;
6105 } else if (amt != sz) {
6106 warnx("short pattern file read");
6108 goto scsisanitize_bailout;
6111 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6117 pl->byte1 |= SSZPL_INVERT;
6118 scsi_ulto2b(sz, pl->length);
6124 else if (invert != 0)
6126 else if (pattern != NULL)
6131 warnx("%s argument only valid with overwrite "
6134 goto scsisanitize_bailout;
6139 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6140 "following device:\n");
6142 error = scsidoinquiry(device, argc, argv, combinedopt,
6143 retry_count, timeout);
6146 warnx("scsisanitize: error sending inquiry");
6147 goto scsisanitize_bailout;
6152 if (!get_confirmation()) {
6154 goto scsisanitize_bailout;
6159 use_timeout = timeout;
6162 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6163 use_timeout / 1000);
6167 * If the user hasn't disabled questions and didn't specify a
6168 * timeout on the command line, ask them if they want the current
6172 && (timeout == 0)) {
6174 int new_timeout = 0;
6176 fprintf(stdout, "Enter new timeout in seconds or press\n"
6177 "return to keep the current timeout [%d] ",
6178 use_timeout / 1000);
6180 if (fgets(str, sizeof(str), stdin) != NULL) {
6182 new_timeout = atoi(str);
6185 if (new_timeout != 0) {
6186 use_timeout = new_timeout * 1000;
6187 fprintf(stdout, "Using new timeout value %d\n",
6188 use_timeout / 1000);
6194 byte2 |= SSZ_UNRESTRICTED_EXIT;
6198 scsi_sanitize(&ccb->csio,
6199 /* retries */ retry_count,
6201 /* tag_action */ MSG_SIMPLE_Q_TAG,
6204 /* data_ptr */ data_ptr,
6205 /* dxfer_len */ dxfer_len,
6206 /* sense_len */ SSD_FULL_SIZE,
6207 /* timeout */ use_timeout);
6209 /* Disable freezing the device queue */
6210 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6212 if (arglist & CAM_ARG_ERR_RECOVER)
6213 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6215 if (cam_send_ccb(device, ccb) < 0) {
6216 warn("error sending sanitize command");
6218 goto scsisanitize_bailout;
6221 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6222 struct scsi_sense_data *sense;
6223 int error_code, sense_key, asc, ascq;
6225 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6226 CAM_SCSI_STATUS_ERROR) {
6227 sense = &ccb->csio.sense_data;
6228 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6229 ccb->csio.sense_resid, &error_code, &sense_key,
6230 &asc, &ascq, /*show_errors*/ 1);
6232 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6233 asc == 0x20 && ascq == 0x00)
6234 warnx("sanitize is not supported by "
6237 warnx("error sanitizing this device");
6239 warnx("error sanitizing this device");
6241 if (arglist & CAM_ARG_VERBOSE) {
6242 cam_error_print(device, ccb, CAM_ESF_ALL,
6243 CAM_EPF_ALL, stderr);
6246 goto scsisanitize_bailout;
6250 * If we ran in non-immediate mode, we already checked for errors
6251 * above and printed out any necessary information. If we're in
6252 * immediate mode, we need to loop through and get status
6253 * information periodically.
6255 if (immediate == 0) {
6257 fprintf(stdout, "Sanitize Complete\n");
6259 goto scsisanitize_bailout;
6266 bzero(&(&ccb->ccb_h)[1],
6267 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6270 * There's really no need to do error recovery or
6271 * retries here, since we're just going to sit in a
6272 * loop and wait for the device to finish sanitizing.
6274 scsi_test_unit_ready(&ccb->csio,
6277 /* tag_action */ MSG_SIMPLE_Q_TAG,
6278 /* sense_len */ SSD_FULL_SIZE,
6279 /* timeout */ 5000);
6281 /* Disable freezing the device queue */
6282 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6284 retval = cam_send_ccb(device, ccb);
6287 * If we get an error from the ioctl, bail out. SCSI
6288 * errors are expected.
6291 warn("error sending CAMIOCOMMAND ioctl");
6292 if (arglist & CAM_ARG_VERBOSE) {
6293 cam_error_print(device, ccb, CAM_ESF_ALL,
6294 CAM_EPF_ALL, stderr);
6297 goto scsisanitize_bailout;
6300 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6302 if ((status != CAM_REQ_CMP)
6303 && (status == CAM_SCSI_STATUS_ERROR)
6304 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6305 struct scsi_sense_data *sense;
6306 int error_code, sense_key, asc, ascq;
6308 sense = &ccb->csio.sense_data;
6309 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6310 ccb->csio.sense_resid, &error_code, &sense_key,
6311 &asc, &ascq, /*show_errors*/ 1);
6314 * According to the SCSI-3 spec, a drive that is in the
6315 * middle of a sanitize should return NOT READY with an
6316 * ASC of "logical unit not ready, sanitize in
6317 * progress". The sense key specific bytes will then
6318 * be a progress indicator.
6320 if ((sense_key == SSD_KEY_NOT_READY)
6321 && (asc == 0x04) && (ascq == 0x1b)) {
6324 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6325 ccb->csio.sense_resid, sks) == 0)
6328 u_int64_t percentage;
6330 val = scsi_2btoul(&sks[1]);
6331 percentage = 10000 * val;
6334 "\rSanitizing: %ju.%02u %% "
6336 (uintmax_t)(percentage /
6338 (unsigned)((percentage /
6342 } else if ((quiet == 0)
6343 && (++num_warnings <= 1)) {
6344 warnx("Unexpected SCSI Sense Key "
6345 "Specific value returned "
6346 "during sanitize:");
6347 scsi_sense_print(device, &ccb->csio,
6349 warnx("Unable to print status "
6350 "information, but sanitze will "
6352 warnx("will exit when sanitize is "
6357 warnx("Unexpected SCSI error during sanitize");
6358 cam_error_print(device, ccb, CAM_ESF_ALL,
6359 CAM_EPF_ALL, stderr);
6361 goto scsisanitize_bailout;
6364 } else if (status != CAM_REQ_CMP) {
6365 warnx("Unexpected CAM status %#x", status);
6366 if (arglist & CAM_ARG_VERBOSE)
6367 cam_error_print(device, ccb, CAM_ESF_ALL,
6368 CAM_EPF_ALL, stderr);
6370 goto scsisanitize_bailout;
6372 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6375 fprintf(stdout, "\nSanitize Complete\n");
6377 scsisanitize_bailout:
6380 if (data_ptr != NULL)
6388 scsireportluns(struct cam_device *device, int argc, char **argv,
6389 char *combinedopt, int retry_count, int timeout)
6392 int c, countonly, lunsonly;
6393 struct scsi_report_luns_data *lundata;
6395 uint8_t report_type;
6396 uint32_t list_len, i, j;
6401 report_type = RPL_REPORT_DEFAULT;
6402 ccb = cam_getccb(device);
6405 warnx("%s: error allocating ccb", __func__);
6409 bzero(&(&ccb->ccb_h)[1],
6410 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6415 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6424 if (strcasecmp(optarg, "default") == 0)
6425 report_type = RPL_REPORT_DEFAULT;
6426 else if (strcasecmp(optarg, "wellknown") == 0)
6427 report_type = RPL_REPORT_WELLKNOWN;
6428 else if (strcasecmp(optarg, "all") == 0)
6429 report_type = RPL_REPORT_ALL;
6431 warnx("%s: invalid report type \"%s\"",
6442 if ((countonly != 0)
6443 && (lunsonly != 0)) {
6444 warnx("%s: you can only specify one of -c or -l", __func__);
6449 * According to SPC-4, the allocation length must be at least 16
6450 * bytes -- enough for the header and one LUN.
6452 alloc_len = sizeof(*lundata) + 8;
6456 lundata = malloc(alloc_len);
6458 if (lundata == NULL) {
6459 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6464 scsi_report_luns(&ccb->csio,
6465 /*retries*/ retry_count,
6467 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6468 /*select_report*/ report_type,
6469 /*rpl_buf*/ lundata,
6470 /*alloc_len*/ alloc_len,
6471 /*sense_len*/ SSD_FULL_SIZE,
6472 /*timeout*/ timeout ? timeout : 5000);
6474 /* Disable freezing the device queue */
6475 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6477 if (arglist & CAM_ARG_ERR_RECOVER)
6478 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6480 if (cam_send_ccb(device, ccb) < 0) {
6481 warn("error sending REPORT LUNS command");
6483 if (arglist & CAM_ARG_VERBOSE)
6484 cam_error_print(device, ccb, CAM_ESF_ALL,
6485 CAM_EPF_ALL, stderr);
6491 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6492 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6498 list_len = scsi_4btoul(lundata->length);
6501 * If we need to list the LUNs, and our allocation
6502 * length was too short, reallocate and retry.
6504 if ((countonly == 0)
6505 && (list_len > (alloc_len - sizeof(*lundata)))) {
6506 alloc_len = list_len + sizeof(*lundata);
6512 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6513 ((list_len / 8) > 1) ? "s" : "");
6518 for (i = 0; i < (list_len / 8); i++) {
6522 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6524 fprintf(stdout, ",");
6525 switch (lundata->luns[i].lundata[j] &
6526 RPL_LUNDATA_ATYP_MASK) {
6527 case RPL_LUNDATA_ATYP_PERIPH:
6528 if ((lundata->luns[i].lundata[j] &
6529 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6530 fprintf(stdout, "%d:",
6531 lundata->luns[i].lundata[j] &
6532 RPL_LUNDATA_PERIPH_BUS_MASK);
6534 && ((lundata->luns[i].lundata[j+2] &
6535 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6538 fprintf(stdout, "%d",
6539 lundata->luns[i].lundata[j+1]);
6541 case RPL_LUNDATA_ATYP_FLAT: {
6543 tmplun[0] = lundata->luns[i].lundata[j] &
6544 RPL_LUNDATA_FLAT_LUN_MASK;
6545 tmplun[1] = lundata->luns[i].lundata[j+1];
6547 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6551 case RPL_LUNDATA_ATYP_LUN:
6552 fprintf(stdout, "%d:%d:%d",
6553 (lundata->luns[i].lundata[j+1] &
6554 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6555 lundata->luns[i].lundata[j] &
6556 RPL_LUNDATA_LUN_TARG_MASK,
6557 lundata->luns[i].lundata[j+1] &
6558 RPL_LUNDATA_LUN_LUN_MASK);
6560 case RPL_LUNDATA_ATYP_EXTLUN: {
6561 int field_len_code, eam_code;
6563 eam_code = lundata->luns[i].lundata[j] &
6564 RPL_LUNDATA_EXT_EAM_MASK;
6565 field_len_code = (lundata->luns[i].lundata[j] &
6566 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6568 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6569 && (field_len_code == 0x00)) {
6570 fprintf(stdout, "%d",
6571 lundata->luns[i].lundata[j+1]);
6572 } else if ((eam_code ==
6573 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6574 && (field_len_code == 0x03)) {
6578 * This format takes up all 8 bytes.
6579 * If we aren't starting at offset 0,
6583 fprintf(stdout, "Invalid "
6586 "specified format", j);
6590 bzero(tmp_lun, sizeof(tmp_lun));
6591 bcopy(&lundata->luns[i].lundata[j+1],
6592 &tmp_lun[1], sizeof(tmp_lun) - 1);
6593 fprintf(stdout, "%#jx",
6594 (intmax_t)scsi_8btou64(tmp_lun));
6597 fprintf(stderr, "Unknown Extended LUN"
6598 "Address method %#x, length "
6599 "code %#x", eam_code,
6606 fprintf(stderr, "Unknown LUN address method "
6607 "%#x\n", lundata->luns[i].lundata[0] &
6608 RPL_LUNDATA_ATYP_MASK);
6612 * For the flat addressing method, there are no
6613 * other levels after it.
6618 fprintf(stdout, "\n");
6631 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6632 char *combinedopt, int retry_count, int timeout)
6635 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6636 struct scsi_read_capacity_data rcap;
6637 struct scsi_read_capacity_data_long rcaplong;
6651 ccb = cam_getccb(device);
6654 warnx("%s: error allocating ccb", __func__);
6658 bzero(&(&ccb->ccb_h)[1],
6659 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6661 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6688 if ((blocksizeonly != 0)
6689 && (numblocks != 0)) {
6690 warnx("%s: you can only specify one of -b or -N", __func__);
6695 if ((blocksizeonly != 0)
6696 && (sizeonly != 0)) {
6697 warnx("%s: you can only specify one of -b or -s", __func__);
6704 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6710 && (blocksizeonly != 0)) {
6711 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6716 scsi_read_capacity(&ccb->csio,
6717 /*retries*/ retry_count,
6719 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6722 /*timeout*/ timeout ? timeout : 5000);
6724 /* Disable freezing the device queue */
6725 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6727 if (arglist & CAM_ARG_ERR_RECOVER)
6728 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6730 if (cam_send_ccb(device, ccb) < 0) {
6731 warn("error sending READ CAPACITY command");
6733 if (arglist & CAM_ARG_VERBOSE)
6734 cam_error_print(device, ccb, CAM_ESF_ALL,
6735 CAM_EPF_ALL, stderr);
6741 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6742 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6747 maxsector = scsi_4btoul(rcap.addr);
6748 block_len = scsi_4btoul(rcap.length);
6751 * A last block of 2^32-1 means that the true capacity is over 2TB,
6752 * and we need to issue the long READ CAPACITY to get the real
6753 * capacity. Otherwise, we're all set.
6755 if (maxsector != 0xffffffff)
6758 scsi_read_capacity_16(&ccb->csio,
6759 /*retries*/ retry_count,
6761 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6765 /*rcap_buf*/ (uint8_t *)&rcaplong,
6766 /*rcap_buf_len*/ sizeof(rcaplong),
6767 /*sense_len*/ SSD_FULL_SIZE,
6768 /*timeout*/ timeout ? timeout : 5000);
6770 /* Disable freezing the device queue */
6771 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6773 if (arglist & CAM_ARG_ERR_RECOVER)
6774 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6776 if (cam_send_ccb(device, ccb) < 0) {
6777 warn("error sending READ CAPACITY (16) command");
6779 if (arglist & CAM_ARG_VERBOSE)
6780 cam_error_print(device, ccb, CAM_ESF_ALL,
6781 CAM_EPF_ALL, stderr);
6787 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6788 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6793 maxsector = scsi_8btou64(rcaplong.addr);
6794 block_len = scsi_4btoul(rcaplong.length);
6797 if (blocksizeonly == 0) {
6799 * Humanize implies !quiet, and also implies numblocks.
6801 if (humanize != 0) {
6806 tmpbytes = (maxsector + 1) * block_len;
6807 ret = humanize_number(tmpstr, sizeof(tmpstr),
6808 tmpbytes, "", HN_AUTOSCALE,
6811 HN_DIVISOR_1000 : 0));
6813 warnx("%s: humanize_number failed!", __func__);
6817 fprintf(stdout, "Device Size: %s%s", tmpstr,
6818 (sizeonly == 0) ? ", " : "\n");
6819 } else if (numblocks != 0) {
6820 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6821 "Blocks: " : "", (uintmax_t)maxsector + 1,
6822 (sizeonly == 0) ? ", " : "\n");
6824 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6825 "Last Block: " : "", (uintmax_t)maxsector,
6826 (sizeonly == 0) ? ", " : "\n");
6830 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6831 "Block Length: " : "", block_len, (quiet == 0) ?
6840 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6841 int retry_count, int timeout)
6845 uint8_t *smp_request = NULL, *smp_response = NULL;
6846 int request_size = 0, response_size = 0;
6847 int fd_request = 0, fd_response = 0;
6848 char *datastr = NULL;
6849 struct get_hook hook;
6854 * Note that at the moment we don't support sending SMP CCBs to
6855 * devices that aren't probed by CAM.
6857 ccb = cam_getccb(device);
6859 warnx("%s: error allocating CCB", __func__);
6863 bzero(&(&ccb->ccb_h)[1],
6864 sizeof(union ccb) - sizeof(struct ccb_hdr));
6866 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6869 arglist |= CAM_ARG_CMD_IN;
6870 response_size = strtol(optarg, NULL, 0);
6871 if (response_size <= 0) {
6872 warnx("invalid number of response bytes %d",
6875 goto smpcmd_bailout;
6877 hook.argc = argc - optind;
6878 hook.argv = argv + optind;
6881 datastr = cget(&hook, NULL);
6883 * If the user supplied "-" instead of a format, he
6884 * wants the data to be written to stdout.
6886 if ((datastr != NULL)
6887 && (datastr[0] == '-'))
6890 smp_response = (u_int8_t *)malloc(response_size);
6891 if (smp_response == NULL) {
6892 warn("can't malloc memory for SMP response");
6894 goto smpcmd_bailout;
6898 arglist |= CAM_ARG_CMD_OUT;
6899 request_size = strtol(optarg, NULL, 0);
6900 if (request_size <= 0) {
6901 warnx("invalid number of request bytes %d",
6904 goto smpcmd_bailout;
6906 hook.argc = argc - optind;
6907 hook.argv = argv + optind;
6909 datastr = cget(&hook, NULL);
6910 smp_request = (u_int8_t *)malloc(request_size);
6911 if (smp_request == NULL) {
6912 warn("can't malloc memory for SMP request");
6914 goto smpcmd_bailout;
6916 bzero(smp_request, request_size);
6918 * If the user supplied "-" instead of a format, he
6919 * wants the data to be read from stdin.
6921 if ((datastr != NULL)
6922 && (datastr[0] == '-'))
6925 buff_encode_visit(smp_request, request_size,
6936 * If fd_data is set, and we're writing to the device, we need to
6937 * read the data the user wants written from stdin.
6939 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6941 int amt_to_read = request_size;
6942 u_int8_t *buf_ptr = smp_request;
6944 for (amt_read = 0; amt_to_read > 0;
6945 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6946 if (amt_read == -1) {
6947 warn("error reading data from stdin");
6949 goto smpcmd_bailout;
6951 amt_to_read -= amt_read;
6952 buf_ptr += amt_read;
6956 if (((arglist & CAM_ARG_CMD_IN) == 0)
6957 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6958 warnx("%s: need both the request (-r) and response (-R) "
6959 "arguments", __func__);
6961 goto smpcmd_bailout;
6964 flags |= CAM_DEV_QFRZDIS;
6966 cam_fill_smpio(&ccb->smpio,
6967 /*retries*/ retry_count,
6970 /*smp_request*/ smp_request,
6971 /*smp_request_len*/ request_size,
6972 /*smp_response*/ smp_response,
6973 /*smp_response_len*/ response_size,
6974 /*timeout*/ timeout ? timeout : 5000);
6976 ccb->smpio.flags = SMP_FLAG_NONE;
6978 if (((retval = cam_send_ccb(device, ccb)) < 0)
6979 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6980 const char warnstr[] = "error sending command";
6987 if (arglist & CAM_ARG_VERBOSE) {
6988 cam_error_print(device, ccb, CAM_ESF_ALL,
6989 CAM_EPF_ALL, stderr);
6993 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6994 && (response_size > 0)) {
6995 if (fd_response == 0) {
6996 buff_decode_visit(smp_response, response_size,
6997 datastr, arg_put, NULL);
6998 fprintf(stdout, "\n");
7000 ssize_t amt_written;
7001 int amt_to_write = response_size;
7002 u_int8_t *buf_ptr = smp_response;
7004 for (amt_written = 0; (amt_to_write > 0) &&
7005 (amt_written = write(STDOUT_FILENO, buf_ptr,
7006 amt_to_write)) > 0;){
7007 amt_to_write -= amt_written;
7008 buf_ptr += amt_written;
7010 if (amt_written == -1) {
7011 warn("error writing data to stdout");
7013 goto smpcmd_bailout;
7014 } else if ((amt_written == 0)
7015 && (amt_to_write > 0)) {
7016 warnx("only wrote %u bytes out of %u",
7017 response_size - amt_to_write,
7026 if (smp_request != NULL)
7029 if (smp_response != NULL)
7036 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7037 char *combinedopt, int retry_count, int timeout)
7040 struct smp_report_general_request *request = NULL;
7041 struct smp_report_general_response *response = NULL;
7042 struct sbuf *sb = NULL;
7044 int c, long_response = 0;
7048 * Note that at the moment we don't support sending SMP CCBs to
7049 * devices that aren't probed by CAM.
7051 ccb = cam_getccb(device);
7053 warnx("%s: error allocating CCB", __func__);
7057 bzero(&(&ccb->ccb_h)[1],
7058 sizeof(union ccb) - sizeof(struct ccb_hdr));
7060 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7069 request = malloc(sizeof(*request));
7070 if (request == NULL) {
7071 warn("%s: unable to allocate %zd bytes", __func__,
7077 response = malloc(sizeof(*response));
7078 if (response == NULL) {
7079 warn("%s: unable to allocate %zd bytes", __func__,
7086 smp_report_general(&ccb->smpio,
7090 /*request_len*/ sizeof(*request),
7091 (uint8_t *)response,
7092 /*response_len*/ sizeof(*response),
7093 /*long_response*/ long_response,
7096 if (((retval = cam_send_ccb(device, ccb)) < 0)
7097 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7098 const char warnstr[] = "error sending command";
7105 if (arglist & CAM_ARG_VERBOSE) {
7106 cam_error_print(device, ccb, CAM_ESF_ALL,
7107 CAM_EPF_ALL, stderr);
7114 * If the device supports the long response bit, try again and see
7115 * if we can get all of the data.
7117 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7118 && (long_response == 0)) {
7119 ccb->ccb_h.status = CAM_REQ_INPROG;
7120 bzero(&(&ccb->ccb_h)[1],
7121 sizeof(union ccb) - sizeof(struct ccb_hdr));
7127 * XXX KDM detect and decode SMP errors here.
7129 sb = sbuf_new_auto();
7131 warnx("%s: error allocating sbuf", __func__);
7135 smp_report_general_sbuf(response, sizeof(*response), sb);
7137 if (sbuf_finish(sb) != 0) {
7138 warnx("%s: sbuf_finish", __func__);
7142 printf("%s", sbuf_data(sb));
7148 if (request != NULL)
7151 if (response != NULL)
7160 static struct camcontrol_opts phy_ops[] = {
7161 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7162 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7163 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7164 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7165 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7166 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7167 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7168 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7169 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7174 smpphycontrol(struct cam_device *device, int argc, char **argv,
7175 char *combinedopt, int retry_count, int timeout)
7178 struct smp_phy_control_request *request = NULL;
7179 struct smp_phy_control_response *response = NULL;
7180 int long_response = 0;
7183 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7185 uint64_t attached_dev_name = 0;
7186 int dev_name_set = 0;
7187 uint32_t min_plr = 0, max_plr = 0;
7188 uint32_t pp_timeout_val = 0;
7189 int slumber_partial = 0;
7190 int set_pp_timeout_val = 0;
7194 * Note that at the moment we don't support sending SMP CCBs to
7195 * devices that aren't probed by CAM.
7197 ccb = cam_getccb(device);
7199 warnx("%s: error allocating CCB", __func__);
7203 bzero(&(&ccb->ccb_h)[1],
7204 sizeof(union ccb) - sizeof(struct ccb_hdr));
7206 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7214 if (strcasecmp(optarg, "enable") == 0)
7216 else if (strcasecmp(optarg, "disable") == 0)
7219 warnx("%s: Invalid argument %s", __func__,
7226 slumber_partial |= enable <<
7227 SMP_PC_SAS_SLUMBER_SHIFT;
7230 slumber_partial |= enable <<
7231 SMP_PC_SAS_PARTIAL_SHIFT;
7234 slumber_partial |= enable <<
7235 SMP_PC_SATA_SLUMBER_SHIFT;
7238 slumber_partial |= enable <<
7239 SMP_PC_SATA_PARTIAL_SHIFT;
7242 warnx("%s: programmer error", __func__);
7245 break; /*NOTREACHED*/
7250 attached_dev_name = (uintmax_t)strtoumax(optarg,
7259 * We don't do extensive checking here, so this
7260 * will continue to work when new speeds come out.
7262 min_plr = strtoul(optarg, NULL, 0);
7264 || (min_plr > 0xf)) {
7265 warnx("%s: invalid link rate %x",
7273 * We don't do extensive checking here, so this
7274 * will continue to work when new speeds come out.
7276 max_plr = strtoul(optarg, NULL, 0);
7278 || (max_plr > 0xf)) {
7279 warnx("%s: invalid link rate %x",
7286 camcontrol_optret optreturn;
7287 cam_argmask argnums;
7290 if (phy_op_set != 0) {
7291 warnx("%s: only one phy operation argument "
7292 "(-o) allowed", __func__);
7300 * Allow the user to specify the phy operation
7301 * numerically, as well as with a name. This will
7302 * future-proof it a bit, so options that are added
7303 * in future specs can be used.
7305 if (isdigit(optarg[0])) {
7306 phy_operation = strtoul(optarg, NULL, 0);
7307 if ((phy_operation == 0)
7308 || (phy_operation > 0xff)) {
7309 warnx("%s: invalid phy operation %#x",
7310 __func__, phy_operation);
7316 optreturn = getoption(phy_ops, optarg, &phy_operation,
7319 if (optreturn == CC_OR_AMBIGUOUS) {
7320 warnx("%s: ambiguous option %s", __func__,
7325 } else if (optreturn == CC_OR_NOT_FOUND) {
7326 warnx("%s: option %s not found", __func__,
7338 pp_timeout_val = strtoul(optarg, NULL, 0);
7339 if (pp_timeout_val > 15) {
7340 warnx("%s: invalid partial pathway timeout "
7341 "value %u, need a value less than 16",
7342 __func__, pp_timeout_val);
7346 set_pp_timeout_val = 1;
7354 warnx("%s: a PHY (-p phy) argument is required",__func__);
7359 if (((dev_name_set != 0)
7360 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7361 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7362 && (dev_name_set == 0))) {
7363 warnx("%s: -d name and -o setdevname arguments both "
7364 "required to set device name", __func__);
7369 request = malloc(sizeof(*request));
7370 if (request == NULL) {
7371 warn("%s: unable to allocate %zd bytes", __func__,
7377 response = malloc(sizeof(*response));
7378 if (response == NULL) {
7379 warn("%s: unable to allocate %zd bytes", __func__,
7385 smp_phy_control(&ccb->smpio,
7390 (uint8_t *)response,
7393 /*expected_exp_change_count*/ 0,
7396 (set_pp_timeout_val != 0) ? 1 : 0,
7404 if (((retval = cam_send_ccb(device, ccb)) < 0)
7405 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7406 const char warnstr[] = "error sending command";
7413 if (arglist & CAM_ARG_VERBOSE) {
7415 * Use CAM_EPF_NORMAL so we only get one line of
7416 * SMP command decoding.
7418 cam_error_print(device, ccb, CAM_ESF_ALL,
7419 CAM_EPF_NORMAL, stderr);
7425 /* XXX KDM print out something here for success? */
7430 if (request != NULL)
7433 if (response != NULL)
7440 smpmaninfo(struct cam_device *device, int argc, char **argv,
7441 char *combinedopt, int retry_count, int timeout)
7444 struct smp_report_manuf_info_request request;
7445 struct smp_report_manuf_info_response response;
7446 struct sbuf *sb = NULL;
7447 int long_response = 0;
7452 * Note that at the moment we don't support sending SMP CCBs to
7453 * devices that aren't probed by CAM.
7455 ccb = cam_getccb(device);
7457 warnx("%s: error allocating CCB", __func__);
7461 bzero(&(&ccb->ccb_h)[1],
7462 sizeof(union ccb) - sizeof(struct ccb_hdr));
7464 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7473 bzero(&request, sizeof(request));
7474 bzero(&response, sizeof(response));
7476 smp_report_manuf_info(&ccb->smpio,
7481 (uint8_t *)&response,
7486 if (((retval = cam_send_ccb(device, ccb)) < 0)
7487 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7488 const char warnstr[] = "error sending command";
7495 if (arglist & CAM_ARG_VERBOSE) {
7496 cam_error_print(device, ccb, CAM_ESF_ALL,
7497 CAM_EPF_ALL, stderr);
7503 sb = sbuf_new_auto();
7505 warnx("%s: error allocating sbuf", __func__);
7509 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7511 if (sbuf_finish(sb) != 0) {
7512 warnx("%s: sbuf_finish", __func__);
7516 printf("%s", sbuf_data(sb));
7530 getdevid(struct cam_devitem *item)
7533 union ccb *ccb = NULL;
7535 struct cam_device *dev;
7537 dev = cam_open_btl(item->dev_match.path_id,
7538 item->dev_match.target_id,
7539 item->dev_match.target_lun, O_RDWR, NULL);
7542 warnx("%s", cam_errbuf);
7547 item->device_id_len = 0;
7549 ccb = cam_getccb(dev);
7551 warnx("%s: error allocating CCB", __func__);
7556 bzero(&(&ccb->ccb_h)[1],
7557 sizeof(union ccb) - sizeof(struct ccb_hdr));
7560 * On the first try, we just probe for the size of the data, and
7561 * then allocate that much memory and try again.
7564 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7565 ccb->ccb_h.flags = CAM_DIR_IN;
7566 ccb->cdai.flags = CDAI_FLAG_NONE;
7567 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7568 ccb->cdai.bufsiz = item->device_id_len;
7569 if (item->device_id_len != 0)
7570 ccb->cdai.buf = (uint8_t *)item->device_id;
7572 if (cam_send_ccb(dev, ccb) < 0) {
7573 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7578 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7579 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7584 if (item->device_id_len == 0) {
7586 * This is our first time through. Allocate the buffer,
7587 * and then go back to get the data.
7589 if (ccb->cdai.provsiz == 0) {
7590 warnx("%s: invalid .provsiz field returned with "
7591 "XPT_GDEV_ADVINFO CCB", __func__);
7595 item->device_id_len = ccb->cdai.provsiz;
7596 item->device_id = malloc(item->device_id_len);
7597 if (item->device_id == NULL) {
7598 warn("%s: unable to allocate %d bytes", __func__,
7599 item->device_id_len);
7603 ccb->ccb_h.status = CAM_REQ_INPROG;
7609 cam_close_device(dev);
7618 * XXX KDM merge this code with getdevtree()?
7621 buildbusdevlist(struct cam_devlist *devlist)
7624 int bufsize, fd = -1;
7625 struct dev_match_pattern *patterns;
7626 struct cam_devitem *item = NULL;
7627 int skip_device = 0;
7630 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7631 warn("couldn't open %s", XPT_DEVICE);
7635 bzero(&ccb, sizeof(union ccb));
7637 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7638 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7639 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7641 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7642 bufsize = sizeof(struct dev_match_result) * 100;
7643 ccb.cdm.match_buf_len = bufsize;
7644 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7645 if (ccb.cdm.matches == NULL) {
7646 warnx("can't malloc memory for matches");
7650 ccb.cdm.num_matches = 0;
7651 ccb.cdm.num_patterns = 2;
7652 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7653 ccb.cdm.num_patterns;
7655 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7656 if (patterns == NULL) {
7657 warnx("can't malloc memory for patterns");
7662 ccb.cdm.patterns = patterns;
7663 bzero(patterns, ccb.cdm.pattern_buf_len);
7665 patterns[0].type = DEV_MATCH_DEVICE;
7666 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7667 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7668 patterns[1].type = DEV_MATCH_PERIPH;
7669 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7670 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7673 * We do the ioctl multiple times if necessary, in case there are
7674 * more than 100 nodes in the EDT.
7679 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7680 warn("error sending CAMIOCOMMAND ioctl");
7685 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7686 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7687 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7688 warnx("got CAM error %#x, CDM error %d\n",
7689 ccb.ccb_h.status, ccb.cdm.status);
7694 for (i = 0; i < ccb.cdm.num_matches; i++) {
7695 switch (ccb.cdm.matches[i].type) {
7696 case DEV_MATCH_DEVICE: {
7697 struct device_match_result *dev_result;
7700 &ccb.cdm.matches[i].result.device_result;
7702 if (dev_result->flags &
7703 DEV_RESULT_UNCONFIGURED) {
7709 item = malloc(sizeof(*item));
7711 warn("%s: unable to allocate %zd bytes",
7712 __func__, sizeof(*item));
7716 bzero(item, sizeof(*item));
7717 bcopy(dev_result, &item->dev_match,
7718 sizeof(*dev_result));
7719 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7722 if (getdevid(item) != 0) {
7728 case DEV_MATCH_PERIPH: {
7729 struct periph_match_result *periph_result;
7732 &ccb.cdm.matches[i].result.periph_result;
7734 if (skip_device != 0)
7736 item->num_periphs++;
7737 item->periph_matches = realloc(
7738 item->periph_matches,
7740 sizeof(struct periph_match_result));
7741 if (item->periph_matches == NULL) {
7742 warn("%s: error allocating periph "
7747 bcopy(periph_result, &item->periph_matches[
7748 item->num_periphs - 1],
7749 sizeof(*periph_result));
7753 fprintf(stderr, "%s: unexpected match "
7754 "type %d\n", __func__,
7755 ccb.cdm.matches[i].type);
7758 break; /*NOTREACHED*/
7761 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7762 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7770 free(ccb.cdm.matches);
7773 freebusdevlist(devlist);
7779 freebusdevlist(struct cam_devlist *devlist)
7781 struct cam_devitem *item, *item2;
7783 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7784 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7786 free(item->device_id);
7787 free(item->periph_matches);
7792 static struct cam_devitem *
7793 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7795 struct cam_devitem *item;
7797 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7798 struct scsi_vpd_id_descriptor *idd;
7801 * XXX KDM look for LUN IDs as well?
7803 idd = scsi_get_devid(item->device_id,
7804 item->device_id_len,
7805 scsi_devid_is_sas_target);
7809 if (scsi_8btou64(idd->identifier) == sasaddr)
7817 smpphylist(struct cam_device *device, int argc, char **argv,
7818 char *combinedopt, int retry_count, int timeout)
7820 struct smp_report_general_request *rgrequest = NULL;
7821 struct smp_report_general_response *rgresponse = NULL;
7822 struct smp_discover_request *disrequest = NULL;
7823 struct smp_discover_response *disresponse = NULL;
7824 struct cam_devlist devlist;
7826 int long_response = 0;
7833 * Note that at the moment we don't support sending SMP CCBs to
7834 * devices that aren't probed by CAM.
7836 ccb = cam_getccb(device);
7838 warnx("%s: error allocating CCB", __func__);
7842 bzero(&(&ccb->ccb_h)[1],
7843 sizeof(union ccb) - sizeof(struct ccb_hdr));
7844 STAILQ_INIT(&devlist.dev_queue);
7846 rgrequest = malloc(sizeof(*rgrequest));
7847 if (rgrequest == NULL) {
7848 warn("%s: unable to allocate %zd bytes", __func__,
7849 sizeof(*rgrequest));
7854 rgresponse = malloc(sizeof(*rgresponse));
7855 if (rgresponse == NULL) {
7856 warn("%s: unable to allocate %zd bytes", __func__,
7857 sizeof(*rgresponse));
7862 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7875 smp_report_general(&ccb->smpio,
7879 /*request_len*/ sizeof(*rgrequest),
7880 (uint8_t *)rgresponse,
7881 /*response_len*/ sizeof(*rgresponse),
7882 /*long_response*/ long_response,
7885 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7887 if (((retval = cam_send_ccb(device, ccb)) < 0)
7888 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7889 const char warnstr[] = "error sending command";
7896 if (arglist & CAM_ARG_VERBOSE) {
7897 cam_error_print(device, ccb, CAM_ESF_ALL,
7898 CAM_EPF_ALL, stderr);
7904 num_phys = rgresponse->num_phys;
7906 if (num_phys == 0) {
7908 fprintf(stdout, "%s: No Phys reported\n", __func__);
7913 devlist.path_id = device->path_id;
7915 retval = buildbusdevlist(&devlist);
7920 fprintf(stdout, "%d PHYs:\n", num_phys);
7921 fprintf(stdout, "PHY Attached SAS Address\n");
7924 disrequest = malloc(sizeof(*disrequest));
7925 if (disrequest == NULL) {
7926 warn("%s: unable to allocate %zd bytes", __func__,
7927 sizeof(*disrequest));
7932 disresponse = malloc(sizeof(*disresponse));
7933 if (disresponse == NULL) {
7934 warn("%s: unable to allocate %zd bytes", __func__,
7935 sizeof(*disresponse));
7940 for (i = 0; i < num_phys; i++) {
7941 struct cam_devitem *item;
7942 struct device_match_result *dev_match;
7943 char vendor[16], product[48], revision[16];
7947 bzero(&(&ccb->ccb_h)[1],
7948 sizeof(union ccb) - sizeof(struct ccb_hdr));
7950 ccb->ccb_h.status = CAM_REQ_INPROG;
7951 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7953 smp_discover(&ccb->smpio,
7957 sizeof(*disrequest),
7958 (uint8_t *)disresponse,
7959 sizeof(*disresponse),
7961 /*ignore_zone_group*/ 0,
7965 if (((retval = cam_send_ccb(device, ccb)) < 0)
7966 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7967 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7968 const char warnstr[] = "error sending command";
7975 if (arglist & CAM_ARG_VERBOSE) {
7976 cam_error_print(device, ccb, CAM_ESF_ALL,
7977 CAM_EPF_ALL, stderr);
7983 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7985 fprintf(stdout, "%3d <vacant>\n", i);
7989 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7992 item = findsasdevice(&devlist,
7993 scsi_8btou64(disresponse->attached_sas_address));
7997 || (item != NULL)) {
7998 fprintf(stdout, "%3d 0x%016jx", i,
7999 (uintmax_t)scsi_8btou64(
8000 disresponse->attached_sas_address));
8002 fprintf(stdout, "\n");
8005 } else if (quiet != 0)
8008 dev_match = &item->dev_match;
8010 if (dev_match->protocol == PROTO_SCSI) {
8011 cam_strvis(vendor, dev_match->inq_data.vendor,
8012 sizeof(dev_match->inq_data.vendor),
8014 cam_strvis(product, dev_match->inq_data.product,
8015 sizeof(dev_match->inq_data.product),
8017 cam_strvis(revision, dev_match->inq_data.revision,
8018 sizeof(dev_match->inq_data.revision),
8020 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8022 } else if ((dev_match->protocol == PROTO_ATA)
8023 || (dev_match->protocol == PROTO_SATAPM)) {
8024 cam_strvis(product, dev_match->ident_data.model,
8025 sizeof(dev_match->ident_data.model),
8027 cam_strvis(revision, dev_match->ident_data.revision,
8028 sizeof(dev_match->ident_data.revision),
8030 sprintf(tmpstr, "<%s %s>", product, revision);
8032 sprintf(tmpstr, "<>");
8034 fprintf(stdout, " %-33s ", tmpstr);
8037 * If we have 0 periphs, that's a bug...
8039 if (item->num_periphs == 0) {
8040 fprintf(stdout, "\n");
8044 fprintf(stdout, "(");
8045 for (j = 0; j < item->num_periphs; j++) {
8047 fprintf(stdout, ",");
8049 fprintf(stdout, "%s%d",
8050 item->periph_matches[j].periph_name,
8051 item->periph_matches[j].unit_number);
8054 fprintf(stdout, ")\n");
8068 freebusdevlist(&devlist);
8074 atapm(struct cam_device *device, int argc, char **argv,
8075 char *combinedopt, int retry_count, int timeout)
8083 ccb = cam_getccb(device);
8086 warnx("%s: error allocating ccb", __func__);
8090 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8099 if (strcmp(argv[1], "idle") == 0) {
8101 cmd = ATA_IDLE_IMMEDIATE;
8104 } else if (strcmp(argv[1], "standby") == 0) {
8106 cmd = ATA_STANDBY_IMMEDIATE;
8108 cmd = ATA_STANDBY_CMD;
8116 else if (t <= (240 * 5))
8118 else if (t <= (252 * 5))
8119 /* special encoding for 21 minutes */
8121 else if (t <= (11 * 30 * 60))
8122 sc = (t - 1) / (30 * 60) + 241;
8126 retval = ata_do_28bit_cmd(device,
8128 /*retries*/retry_count,
8129 /*flags*/CAM_DIR_NONE,
8130 /*protocol*/AP_PROTO_NON_DATA,
8131 /*tag_action*/MSG_SIMPLE_Q_TAG,
8138 /*timeout*/timeout ? timeout : 30 * 1000,
8146 ataaxm(struct cam_device *device, int argc, char **argv,
8147 char *combinedopt, int retry_count, int timeout)
8155 ccb = cam_getccb(device);
8158 warnx("%s: error allocating ccb", __func__);
8162 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8172 if (strcmp(argv[1], "apm") == 0) {
8188 retval = ata_do_28bit_cmd(device,
8190 /*retries*/retry_count,
8191 /*flags*/CAM_DIR_NONE,
8192 /*protocol*/AP_PROTO_NON_DATA,
8193 /*tag_action*/MSG_SIMPLE_Q_TAG,
8194 /*command*/ATA_SETFEATURES,
8200 /*timeout*/timeout ? timeout : 30 * 1000,
8208 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8209 int show_sa_errors, int sa_set, int service_action,
8210 int timeout_desc, int retry_count, int timeout, int verbosemode,
8211 uint32_t *fill_len, uint8_t **data_ptr)
8213 union ccb *ccb = NULL;
8214 uint8_t *buf = NULL;
8215 uint32_t alloc_len = 0, num_opcodes;
8216 uint32_t valid_len = 0;
8217 uint32_t avail_len = 0;
8218 struct scsi_report_supported_opcodes_all *all_hdr;
8219 struct scsi_report_supported_opcodes_one *one;
8224 * Make it clear that we haven't yet allocated or filled anything.
8229 ccb = cam_getccb(device);
8231 warnx("couldn't allocate CCB");
8236 /* cam_getccb cleans up the header, caller has to zero the payload */
8237 bzero(&(&ccb->ccb_h)[1],
8238 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
8240 if (opcode_set != 0) {
8241 options |= RSO_OPTIONS_OC;
8243 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8246 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8247 sizeof(struct scsi_report_supported_opcodes_descr));
8250 if (timeout_desc != 0) {
8251 options |= RSO_RCTD;
8252 alloc_len += num_opcodes *
8253 sizeof(struct scsi_report_supported_opcodes_timeout);
8257 options |= RSO_OPTIONS_OC_SA;
8258 if (show_sa_errors != 0)
8259 options &= ~RSO_OPTIONS_OC;
8268 buf = malloc(alloc_len);
8270 warn("Unable to allocate %u bytes", alloc_len);
8274 bzero(buf, alloc_len);
8276 scsi_report_supported_opcodes(&ccb->csio,
8277 /*retries*/ retry_count,
8279 /*tag_action*/ MSG_SIMPLE_Q_TAG,
8280 /*options*/ options,
8281 /*req_opcode*/ opcode,
8282 /*req_service_action*/ service_action,
8284 /*dxfer_len*/ alloc_len,
8285 /*sense_len*/ SSD_FULL_SIZE,
8286 /*timeout*/ timeout ? timeout : 10000);
8288 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8290 if (retry_count != 0)
8291 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8293 if (cam_send_ccb(device, ccb) < 0) {
8294 perror("error sending REPORT SUPPORTED OPERATION CODES");
8299 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8300 if (verbosemode != 0)
8301 cam_error_print(device, ccb, CAM_ESF_ALL,
8302 CAM_EPF_ALL, stderr);
8308 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8310 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8311 && (valid_len >= sizeof(*all_hdr))) {
8312 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8313 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8314 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8315 && (valid_len >= sizeof(*one))) {
8316 uint32_t cdb_length;
8318 one = (struct scsi_report_supported_opcodes_one *)buf;
8319 cdb_length = scsi_2btoul(one->cdb_length);
8320 avail_len = sizeof(*one) + cdb_length;
8321 if (one->support & RSO_ONE_CTDP) {
8322 struct scsi_report_supported_opcodes_timeout *td;
8324 td = (struct scsi_report_supported_opcodes_timeout *)
8326 if (valid_len >= (avail_len + sizeof(td->length))) {
8327 avail_len += scsi_2btoul(td->length) +
8330 avail_len += sizeof(*td);
8336 * avail_len could be zero if we didn't get enough data back from
8337 * thet target to determine
8339 if ((avail_len != 0)
8340 && (avail_len > valid_len)) {
8341 alloc_len = avail_len;
8345 *fill_len = valid_len;
8357 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8358 int req_sa, uint8_t *buf, uint32_t valid_len)
8360 struct scsi_report_supported_opcodes_one *one;
8361 struct scsi_report_supported_opcodes_timeout *td;
8362 uint32_t cdb_len = 0, td_len = 0;
8363 const char *op_desc = NULL;
8367 one = (struct scsi_report_supported_opcodes_one *)buf;
8370 * If we don't have the full single opcode descriptor, no point in
8373 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8375 warnx("Only %u bytes returned, not enough to verify support",
8381 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8383 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8386 printf(", SA 0x%x", req_sa);
8389 switch (one->support & RSO_ONE_SUP_MASK) {
8390 case RSO_ONE_SUP_UNAVAIL:
8391 printf("No command support information currently available\n");
8393 case RSO_ONE_SUP_NOT_SUP:
8394 printf("Command not supported\n");
8397 break; /*NOTREACHED*/
8398 case RSO_ONE_SUP_AVAIL:
8399 printf("Command is supported, complies with a SCSI standard\n");
8401 case RSO_ONE_SUP_VENDOR:
8402 printf("Command is supported, vendor-specific "
8403 "implementation\n");
8406 printf("Unknown command support flags 0x%#x\n",
8407 one->support & RSO_ONE_SUP_MASK);
8412 * If we don't have the CDB length, it isn't exactly an error, the
8413 * command probably isn't supported.
8415 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8419 cdb_len = scsi_2btoul(one->cdb_length);
8422 * If our valid data doesn't include the full reported length,
8423 * return. The caller should have detected this and adjusted his
8424 * allocation length to get all of the available data.
8426 if (valid_len < sizeof(*one) + cdb_len) {
8432 * If all we have is the opcode, there is no point in printing out
8440 printf("CDB usage bitmap:");
8441 for (i = 0; i < cdb_len; i++) {
8442 printf(" %02x", one->cdb_usage[i]);
8447 * If we don't have a timeout descriptor, we're done.
8449 if ((one->support & RSO_ONE_CTDP) == 0)
8453 * If we don't have enough valid length to include the timeout
8454 * descriptor length, we're done.
8456 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8459 td = (struct scsi_report_supported_opcodes_timeout *)
8460 &buf[sizeof(*one) + cdb_len];
8461 td_len = scsi_2btoul(td->length);
8462 td_len += sizeof(td->length);
8465 * If we don't have the full timeout descriptor, we're done.
8467 if (td_len < sizeof(*td))
8471 * If we don't have enough valid length to contain the full timeout
8472 * descriptor, we're done.
8474 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8477 printf("Timeout information:\n");
8478 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8479 printf("Nominal timeout: %u seconds\n",
8480 scsi_4btoul(td->nominal_time));
8481 printf("Recommended timeout: %u seconds\n",
8482 scsi_4btoul(td->recommended_time));
8489 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8492 struct scsi_report_supported_opcodes_all *hdr;
8493 struct scsi_report_supported_opcodes_descr *desc;
8494 uint32_t avail_len = 0, used_len = 0;
8498 if (valid_len < sizeof(*hdr)) {
8499 warnx("%s: not enough returned data (%u bytes) opcode list",
8500 __func__, valid_len);
8504 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8505 avail_len = scsi_4btoul(hdr->length);
8506 avail_len += sizeof(hdr->length);
8508 * Take the lesser of the amount of data the drive claims is
8509 * available, and the amount of data the HBA says was returned.
8511 avail_len = MIN(avail_len, valid_len);
8513 used_len = sizeof(hdr->length);
8515 printf("%-6s %4s %8s ",
8516 "Opcode", "SA", "CDB len" );
8519 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8520 printf(" Description\n");
8522 while ((avail_len - used_len) > sizeof(*desc)) {
8523 struct scsi_report_supported_opcodes_timeout *td;
8525 const char *op_desc = NULL;
8527 cur_ptr = &buf[used_len];
8528 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8530 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8531 if (op_desc == NULL)
8532 op_desc = "UNKNOWN";
8534 printf("0x%02x %#4x %8u ", desc->opcode,
8535 scsi_2btoul(desc->service_action),
8536 scsi_2btoul(desc->cdb_length));
8538 used_len += sizeof(*desc);
8540 if ((desc->flags & RSO_CTDP) == 0) {
8541 printf(" %s\n", op_desc);
8546 * If we don't have enough space to fit a timeout
8547 * descriptor, then we're done.
8549 if (avail_len - used_len < sizeof(*td)) {
8550 used_len = avail_len;
8551 printf(" %s\n", op_desc);
8554 cur_ptr = &buf[used_len];
8555 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8556 td_len = scsi_2btoul(td->length);
8557 td_len += sizeof(td->length);
8561 * If the given timeout descriptor length is less than what
8562 * we understand, skip it.
8564 if (td_len < sizeof(*td)) {
8565 printf(" %s\n", op_desc);
8569 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8570 scsi_4btoul(td->nominal_time),
8571 scsi_4btoul(td->recommended_time), op_desc);
8578 scsiopcodes(struct cam_device *device, int argc, char **argv,
8579 char *combinedopt, int retry_count, int timeout, int verbosemode)
8582 uint32_t opcode = 0, service_action = 0;
8583 int td_set = 0, opcode_set = 0, sa_set = 0;
8584 int show_sa_errors = 1;
8585 uint32_t valid_len = 0;
8586 uint8_t *buf = NULL;
8590 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8596 opcode = strtoul(optarg, &endptr, 0);
8597 if (*endptr != '\0') {
8598 warnx("Invalid opcode \"%s\", must be a number",
8603 if (opcode > 0xff) {
8604 warnx("Invalid opcode 0x%#x, must be between"
8605 "0 and 0xff inclusive", opcode);
8612 service_action = strtoul(optarg, &endptr, 0);
8613 if (*endptr != '\0') {
8614 warnx("Invalid service action \"%s\", must "
8615 "be a number", optarg);
8619 if (service_action > 0xffff) {
8620 warnx("Invalid service action 0x%#x, must "
8621 "be between 0 and 0xffff inclusive",
8636 && (opcode_set == 0)) {
8637 warnx("You must specify an opcode with -o if a service "
8642 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8643 sa_set, service_action, td_set, retry_count,
8644 timeout, verbosemode, &valid_len, &buf);
8648 if ((opcode_set != 0)
8650 retval = scsiprintoneopcode(device, opcode, sa_set,
8651 service_action, buf, valid_len);
8653 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8662 #endif /* MINIMALISTIC */
8665 usage(int printlong)
8668 fprintf(printlong ? stdout : stderr,
8669 "usage: camcontrol <command> [device id][generic args][command args]\n"
8670 " camcontrol devlist [-b] [-v]\n"
8671 #ifndef MINIMALISTIC
8672 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8673 " camcontrol tur [dev_id][generic args]\n"
8674 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8675 " camcontrol identify [dev_id][generic args] [-v]\n"
8676 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8677 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8679 " camcontrol start [dev_id][generic args]\n"
8680 " camcontrol stop [dev_id][generic args]\n"
8681 " camcontrol load [dev_id][generic args]\n"
8682 " camcontrol eject [dev_id][generic args]\n"
8683 #endif /* MINIMALISTIC */
8684 " camcontrol rescan <all | bus[:target:lun]>\n"
8685 " camcontrol reset <all | bus[:target:lun]>\n"
8686 #ifndef MINIMALISTIC
8687 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8688 " [-q][-s][-S offset][-X]\n"
8689 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8690 " [-P pagectl][-e | -b][-d]\n"
8691 " camcontrol cmd [dev_id][generic args]\n"
8692 " <-a cmd [args] | -c cmd [args]>\n"
8693 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8694 " camcontrol smpcmd [dev_id][generic args]\n"
8695 " <-r len fmt [args]> <-R len fmt [args]>\n"
8696 " camcontrol smprg [dev_id][generic args][-l]\n"
8697 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8698 " [-o operation][-d name][-m rate][-M rate]\n"
8699 " [-T pp_timeout][-a enable|disable]\n"
8700 " [-A enable|disable][-s enable|disable]\n"
8701 " [-S enable|disable]\n"
8702 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8703 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8704 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8705 " <all|bus[:target[:lun]]|off>\n"
8706 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8707 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8708 " [-D <enable|disable>][-M mode][-O offset]\n"
8709 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8710 " [-U][-W bus_width]\n"
8711 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8712 " camcontrol sanitize [dev_id][generic args]\n"
8713 " [-a overwrite|block|crypto|exitfailure]\n"
8714 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8716 " camcontrol idle [dev_id][generic args][-t time]\n"
8717 " camcontrol standby [dev_id][generic args][-t time]\n"
8718 " camcontrol sleep [dev_id][generic args]\n"
8719 " camcontrol apm [dev_id][generic args][-l level]\n"
8720 " camcontrol aam [dev_id][generic args][-l level]\n"
8721 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8723 " camcontrol security [dev_id][generic args]\n"
8724 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8725 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8726 " [-U <user|master>] [-y]\n"
8727 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8728 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8729 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8730 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8731 " [-s scope][-S][-T type][-U]\n"
8732 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8733 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8734 " [-p part][-s start][-T type][-V vol]\n"
8735 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8737 #endif /* MINIMALISTIC */
8738 " camcontrol help\n");
8741 #ifndef MINIMALISTIC
8743 "Specify one of the following options:\n"
8744 "devlist list all CAM devices\n"
8745 "periphlist list all CAM peripheral drivers attached to a device\n"
8746 "tur send a test unit ready to the named device\n"
8747 "inquiry send a SCSI inquiry command to the named device\n"
8748 "identify send a ATA identify command to the named device\n"
8749 "reportluns send a SCSI report luns command to the device\n"
8750 "readcap send a SCSI read capacity command to the device\n"
8751 "start send a Start Unit command to the device\n"
8752 "stop send a Stop Unit command to the device\n"
8753 "load send a Start Unit command to the device with the load bit set\n"
8754 "eject send a Stop Unit command to the device with the eject bit set\n"
8755 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8756 "reset reset all busses, the given bus, or bus:target:lun\n"
8757 "defects read the defect list of the specified device\n"
8758 "modepage display or edit (-e) the given mode page\n"
8759 "cmd send the given SCSI command, may need -i or -o as well\n"
8760 "smpcmd send the given SMP command, requires -o and -i\n"
8761 "smprg send the SMP Report General command\n"
8762 "smppc send the SMP PHY Control command, requires -p\n"
8763 "smpphylist display phys attached to a SAS expander\n"
8764 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8765 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8766 "tags report or set the number of transaction slots for a device\n"
8767 "negotiate report or set device negotiation parameters\n"
8768 "format send the SCSI FORMAT UNIT command to the named device\n"
8769 "sanitize send the SCSI SANITIZE command to the named device\n"
8770 "idle send the ATA IDLE command to the named device\n"
8771 "standby send the ATA STANDBY command to the named device\n"
8772 "sleep send the ATA SLEEP command to the named device\n"
8773 "fwdownload program firmware of the named device with the given image\n"
8774 "security report or send ATA security commands to the named device\n"
8775 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8776 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8777 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8778 "help this message\n"
8779 "Device Identifiers:\n"
8780 "bus:target specify the bus and target, lun defaults to 0\n"
8781 "bus:target:lun specify the bus, target and lun\n"
8782 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8783 "Generic arguments:\n"
8784 "-v be verbose, print out sense information\n"
8785 "-t timeout command timeout in seconds, overrides default timeout\n"
8786 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8787 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8788 "-E have the kernel attempt to perform SCSI error recovery\n"
8789 "-C count specify the SCSI command retry count (needs -E to work)\n"
8790 "modepage arguments:\n"
8791 "-l list all available mode pages\n"
8792 "-m page specify the mode page to view or edit\n"
8793 "-e edit the specified mode page\n"
8794 "-b force view to binary mode\n"
8795 "-d disable block descriptors for mode sense\n"
8796 "-P pgctl page control field 0-3\n"
8797 "defects arguments:\n"
8798 "-f format specify defect list format (block, bfi or phys)\n"
8799 "-G get the grown defect list\n"
8800 "-P get the permanent defect list\n"
8801 "inquiry arguments:\n"
8802 "-D get the standard inquiry data\n"
8803 "-S get the serial number\n"
8804 "-R get the transfer rate, etc.\n"
8805 "reportluns arguments:\n"
8806 "-c only report a count of available LUNs\n"
8807 "-l only print out luns, and not a count\n"
8808 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
8809 "readcap arguments\n"
8810 "-b only report the blocksize\n"
8811 "-h human readable device size, base 2\n"
8812 "-H human readable device size, base 10\n"
8813 "-N print the number of blocks instead of last block\n"
8814 "-q quiet, print numbers only\n"
8815 "-s only report the last block/device size\n"
8817 "-c cdb [args] specify the SCSI CDB\n"
8818 "-i len fmt specify input data and input data format\n"
8819 "-o len fmt [args] specify output data and output data fmt\n"
8820 "smpcmd arguments:\n"
8821 "-r len fmt [args] specify the SMP command to be sent\n"
8822 "-R len fmt [args] specify SMP response format\n"
8823 "smprg arguments:\n"
8824 "-l specify the long response format\n"
8825 "smppc arguments:\n"
8826 "-p phy specify the PHY to operate on\n"
8827 "-l specify the long request/response format\n"
8828 "-o operation specify the phy control operation\n"
8829 "-d name set the attached device name\n"
8830 "-m rate set the minimum physical link rate\n"
8831 "-M rate set the maximum physical link rate\n"
8832 "-T pp_timeout set the partial pathway timeout value\n"
8833 "-a enable|disable enable or disable SATA slumber\n"
8834 "-A enable|disable enable or disable SATA partial phy power\n"
8835 "-s enable|disable enable or disable SAS slumber\n"
8836 "-S enable|disable enable or disable SAS partial phy power\n"
8837 "smpphylist arguments:\n"
8838 "-l specify the long response format\n"
8839 "-q only print phys with attached devices\n"
8840 "smpmaninfo arguments:\n"
8841 "-l specify the long response format\n"
8842 "debug arguments:\n"
8843 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
8844 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
8845 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
8846 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
8848 "-N tags specify the number of tags to use for this device\n"
8849 "-q be quiet, don't report the number of tags\n"
8850 "-v report a number of tag-related parameters\n"
8851 "negotiate arguments:\n"
8852 "-a send a test unit ready after negotiation\n"
8853 "-c report/set current negotiation settings\n"
8854 "-D <arg> \"enable\" or \"disable\" disconnection\n"
8855 "-M mode set ATA mode\n"
8856 "-O offset set command delay offset\n"
8857 "-q be quiet, don't report anything\n"
8858 "-R syncrate synchronization rate in MHz\n"
8859 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
8860 "-U report/set user negotiation settings\n"
8861 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
8862 "-v also print a Path Inquiry CCB for the controller\n"
8863 "format arguments:\n"
8864 "-q be quiet, don't print status messages\n"
8865 "-r run in report only mode\n"
8866 "-w don't send immediate format command\n"
8867 "-y don't ask any questions\n"
8868 "sanitize arguments:\n"
8869 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
8870 "-c passes overwrite passes to perform (1 to 31)\n"
8871 "-I invert overwrite pattern after each pass\n"
8872 "-P pattern path to overwrite pattern file\n"
8873 "-q be quiet, don't print status messages\n"
8874 "-r run in report only mode\n"
8875 "-U run operation in unrestricted completion exit mode\n"
8876 "-w don't send immediate sanitize command\n"
8877 "-y don't ask any questions\n"
8878 "idle/standby arguments:\n"
8879 "-t <arg> number of seconds before respective state.\n"
8880 "fwdownload arguments:\n"
8881 "-f fw_image path to firmware image file\n"
8882 "-q don't print informational messages, only errors\n"
8883 "-s run in simulation mode\n"
8884 "-v print info for every firmware segment sent to device\n"
8885 "-y don't ask any questions\n"
8886 "security arguments:\n"
8887 "-d pwd disable security using the given password for the selected\n"
8889 "-e pwd erase the device using the given pwd for the selected user\n"
8890 "-f freeze the security configuration of the specified device\n"
8891 "-h pwd enhanced erase the device using the given pwd for the\n"
8893 "-k pwd unlock the device using the given pwd for the selected\n"
8895 "-l <high|maximum> specifies which security level to set: high or maximum\n"
8896 "-q be quiet, do not print any status messages\n"
8897 "-s pwd password the device (enable security) using the given\n"
8898 " pwd for the selected user\n"
8899 "-T timeout overrides the timeout (seconds) used for erase operation\n"
8900 "-U <user|master> specifies which user to set: user or master\n"
8901 "-y don't ask any questions\n"
8903 "-f freeze the HPA configuration of the device\n"
8904 "-l lock the HPA configuration of the device\n"
8905 "-P make the HPA max sectors persist\n"
8906 "-p pwd Set the HPA configuration password required for unlock\n"
8908 "-q be quiet, do not print any status messages\n"
8909 "-s sectors configures the maximum user accessible sectors of the\n"
8911 "-U pwd unlock the HPA configuration of the device\n"
8912 "-y don't ask any questions\n"
8913 "persist arguments:\n"
8914 "-i action specify read_keys, read_reservation, report_cap, or\n"
8915 " read_full_status\n"
8916 "-o action specify register, register_ignore, reserve, release,\n"
8917 " clear, preempt, preempt_abort, register_move, replace_lost\n"
8918 "-a set the All Target Ports (ALL_TG_PT) bit\n"
8919 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
8920 "-k key specify the Reservation Key\n"
8921 "-K sa_key specify the Service Action Reservation Key\n"
8922 "-p set the Activate Persist Through Power Loss bit\n"
8923 "-R rtp specify the Relative Target Port\n"
8924 "-s scope specify the scope: lun, extent, element or a number\n"
8925 "-S specify Transport ID for register, requires -I\n"
8926 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
8927 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
8928 "-U unregister the current initiator for register_move\n"
8929 "attrib arguments:\n"
8930 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
8932 "-w attr specify an attribute to write, one -w argument per attr\n"
8933 "-a attr_num only display this attribute number\n"
8934 "-c get cached attributes\n"
8935 "-e elem_addr request attributes for the given element in a changer\n"
8936 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
8937 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
8938 " field_none, field_desc, field_num, field_size, field_rw\n"
8939 "-p partition request attributes for the given partition\n"
8940 "-s start_attr request attributes starting at the given number\n"
8941 "-T elem_type specify the element type (used with -e)\n"
8942 "-V logical_vol specify the logical volume ID\n"
8943 "opcodes arguments:\n"
8944 "-o opcode specify the individual opcode to list\n"
8945 "-s service_action specify the service action for the opcode\n"
8946 "-N do not return SCSI error for unsupported SA\n"
8947 "-T request nominal and recommended timeout values\n"
8949 #endif /* MINIMALISTIC */
8953 main(int argc, char **argv)
8956 char *device = NULL;
8958 struct cam_device *cam_dev = NULL;
8959 int timeout = 0, retry_count = 1;
8960 camcontrol_optret optreturn;
8962 const char *mainopt = "C:En:t:u:v";
8963 const char *subopt = NULL;
8964 char combinedopt[256];
8965 int error = 0, optstart = 2;
8967 #ifndef MINIMALISTIC
8971 #endif /* MINIMALISTIC */
8973 cmdlist = CAM_CMD_NONE;
8974 arglist = CAM_ARG_NONE;
8982 * Get the base option.
8984 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
8986 if (optreturn == CC_OR_AMBIGUOUS) {
8987 warnx("ambiguous option %s", argv[1]);
8990 } else if (optreturn == CC_OR_NOT_FOUND) {
8991 warnx("option %s not found", argv[1]);
8997 * Ahh, getopt(3) is a pain.
8999 * This is a gross hack. There really aren't many other good
9000 * options (excuse the pun) for parsing options in a situation like
9001 * this. getopt is kinda braindead, so you end up having to run
9002 * through the options twice, and give each invocation of getopt
9003 * the option string for the other invocation.
9005 * You would think that you could just have two groups of options.
9006 * The first group would get parsed by the first invocation of
9007 * getopt, and the second group would get parsed by the second
9008 * invocation of getopt. It doesn't quite work out that way. When
9009 * the first invocation of getopt finishes, it leaves optind pointing
9010 * to the argument _after_ the first argument in the second group.
9011 * So when the second invocation of getopt comes around, it doesn't
9012 * recognize the first argument it gets and then bails out.
9014 * A nice alternative would be to have a flag for getopt that says
9015 * "just keep parsing arguments even when you encounter an unknown
9016 * argument", but there isn't one. So there's no real clean way to
9017 * easily parse two sets of arguments without having one invocation
9018 * of getopt know about the other.
9020 * Without this hack, the first invocation of getopt would work as
9021 * long as the generic arguments are first, but the second invocation
9022 * (in the subfunction) would fail in one of two ways. In the case
9023 * where you don't set optreset, it would fail because optind may be
9024 * pointing to the argument after the one it should be pointing at.
9025 * In the case where you do set optreset, and reset optind, it would
9026 * fail because getopt would run into the first set of options, which
9027 * it doesn't understand.
9029 * All of this would "sort of" work if you could somehow figure out
9030 * whether optind had been incremented one option too far. The
9031 * mechanics of that, however, are more daunting than just giving
9032 * both invocations all of the expect options for either invocation.
9034 * Needless to say, I wouldn't mind if someone invented a better
9035 * (non-GPL!) command line parsing interface than getopt. I
9036 * wouldn't mind if someone added more knobs to getopt to make it
9037 * work better. Who knows, I may talk myself into doing it someday,
9038 * if the standards weenies let me. As it is, it just leads to
9039 * hackery like this and causes people to avoid it in some cases.
9041 * KDM, September 8th, 1998
9044 sprintf(combinedopt, "%s%s", mainopt, subopt);
9046 sprintf(combinedopt, "%s", mainopt);
9049 * For these options we do not parse optional device arguments and
9050 * we do not open a passthrough device.
9052 if ((cmdlist == CAM_CMD_RESCAN)
9053 || (cmdlist == CAM_CMD_RESET)
9054 || (cmdlist == CAM_CMD_DEVTREE)
9055 || (cmdlist == CAM_CMD_USAGE)
9056 || (cmdlist == CAM_CMD_DEBUG))
9059 #ifndef MINIMALISTIC
9061 && (argc > 2 && argv[2][0] != '-')) {
9065 if (isdigit(argv[2][0])) {
9066 /* device specified as bus:target[:lun] */
9067 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9069 errx(1, "numeric device specification must "
9070 "be either bus:target, or "
9072 /* default to 0 if lun was not specified */
9073 if ((arglist & CAM_ARG_LUN) == 0) {
9075 arglist |= CAM_ARG_LUN;
9079 if (cam_get_device(argv[2], name, sizeof name, &unit)
9081 errx(1, "%s", cam_errbuf);
9082 device = strdup(name);
9083 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9087 #endif /* MINIMALISTIC */
9089 * Start getopt processing at argv[2/3], since we've already
9090 * accepted argv[1..2] as the command name, and as a possible
9096 * Now we run through the argument list looking for generic
9097 * options, and ignoring options that possibly belong to
9100 while ((c = getopt(argc, argv, combinedopt))!= -1){
9103 retry_count = strtol(optarg, NULL, 0);
9104 if (retry_count < 0)
9105 errx(1, "retry count %d is < 0",
9107 arglist |= CAM_ARG_RETRIES;
9110 arglist |= CAM_ARG_ERR_RECOVER;
9113 arglist |= CAM_ARG_DEVICE;
9115 while (isspace(*tstr) && (*tstr != '\0'))
9117 device = (char *)strdup(tstr);
9120 timeout = strtol(optarg, NULL, 0);
9122 errx(1, "invalid timeout %d", timeout);
9123 /* Convert the timeout from seconds to ms */
9125 arglist |= CAM_ARG_TIMEOUT;
9128 arglist |= CAM_ARG_UNIT;
9129 unit = strtol(optarg, NULL, 0);
9132 arglist |= CAM_ARG_VERBOSE;
9139 #ifndef MINIMALISTIC
9141 * For most commands we'll want to open the passthrough device
9142 * associated with the specified device. In the case of the rescan
9143 * commands, we don't use a passthrough device at all, just the
9144 * transport layer device.
9147 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9148 && (((arglist & CAM_ARG_DEVICE) == 0)
9149 || ((arglist & CAM_ARG_UNIT) == 0))) {
9150 errx(1, "subcommand \"%s\" requires a valid device "
9151 "identifier", argv[1]);
9154 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9155 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9156 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9158 errx(1,"%s", cam_errbuf);
9160 #endif /* MINIMALISTIC */
9163 * Reset optind to 2, and reset getopt, so these routines can parse
9164 * the arguments again.
9170 #ifndef MINIMALISTIC
9171 case CAM_CMD_DEVLIST:
9172 error = getdevlist(cam_dev);
9175 error = atahpa(cam_dev, retry_count, timeout,
9176 argc, argv, combinedopt);
9178 #endif /* MINIMALISTIC */
9179 case CAM_CMD_DEVTREE:
9180 error = getdevtree(argc, argv, combinedopt);
9182 #ifndef MINIMALISTIC
9184 error = testunitready(cam_dev, retry_count, timeout, 0);
9186 case CAM_CMD_INQUIRY:
9187 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9188 retry_count, timeout);
9190 case CAM_CMD_IDENTIFY:
9191 error = ataidentify(cam_dev, retry_count, timeout);
9193 case CAM_CMD_STARTSTOP:
9194 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9195 arglist & CAM_ARG_EJECT, retry_count,
9198 #endif /* MINIMALISTIC */
9199 case CAM_CMD_RESCAN:
9200 error = dorescan_or_reset(argc, argv, 1);
9203 error = dorescan_or_reset(argc, argv, 0);
9205 #ifndef MINIMALISTIC
9206 case CAM_CMD_READ_DEFECTS:
9207 error = readdefects(cam_dev, argc, argv, combinedopt,
9208 retry_count, timeout);
9210 case CAM_CMD_MODE_PAGE:
9211 modepage(cam_dev, argc, argv, combinedopt,
9212 retry_count, timeout);
9214 case CAM_CMD_SCSI_CMD:
9215 error = scsicmd(cam_dev, argc, argv, combinedopt,
9216 retry_count, timeout);
9218 case CAM_CMD_SMP_CMD:
9219 error = smpcmd(cam_dev, argc, argv, combinedopt,
9220 retry_count, timeout);
9222 case CAM_CMD_SMP_RG:
9223 error = smpreportgeneral(cam_dev, argc, argv,
9224 combinedopt, retry_count,
9227 case CAM_CMD_SMP_PC:
9228 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9229 retry_count, timeout);
9231 case CAM_CMD_SMP_PHYLIST:
9232 error = smpphylist(cam_dev, argc, argv, combinedopt,
9233 retry_count, timeout);
9235 case CAM_CMD_SMP_MANINFO:
9236 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9237 retry_count, timeout);
9240 error = camdebug(argc, argv, combinedopt);
9243 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9246 error = ratecontrol(cam_dev, retry_count, timeout,
9247 argc, argv, combinedopt);
9249 case CAM_CMD_FORMAT:
9250 error = scsiformat(cam_dev, argc, argv,
9251 combinedopt, retry_count, timeout);
9253 case CAM_CMD_REPORTLUNS:
9254 error = scsireportluns(cam_dev, argc, argv,
9255 combinedopt, retry_count,
9258 case CAM_CMD_READCAP:
9259 error = scsireadcapacity(cam_dev, argc, argv,
9260 combinedopt, retry_count,
9264 case CAM_CMD_STANDBY:
9266 error = atapm(cam_dev, argc, argv,
9267 combinedopt, retry_count, timeout);
9271 error = ataaxm(cam_dev, argc, argv,
9272 combinedopt, retry_count, timeout);
9274 case CAM_CMD_SECURITY:
9275 error = atasecurity(cam_dev, retry_count, timeout,
9276 argc, argv, combinedopt);
9278 case CAM_CMD_DOWNLOAD_FW:
9279 error = fwdownload(cam_dev, argc, argv, combinedopt,
9280 arglist & CAM_ARG_VERBOSE, retry_count, timeout);
9282 case CAM_CMD_SANITIZE:
9283 error = scsisanitize(cam_dev, argc, argv,
9284 combinedopt, retry_count, timeout);
9286 case CAM_CMD_PERSIST:
9287 error = scsipersist(cam_dev, argc, argv, combinedopt,
9288 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9289 arglist & CAM_ARG_ERR_RECOVER);
9291 case CAM_CMD_ATTRIB:
9292 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9293 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9294 arglist & CAM_ARG_ERR_RECOVER);
9296 case CAM_CMD_OPCODES:
9297 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9298 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9300 #endif /* MINIMALISTIC */
9310 if (cam_dev != NULL)
9311 cam_close_device(cam_dev);