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) {
5000 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5001 if (verbosemode != 0)
5002 cam_error_print(dev, ccb, CAM_ESF_ALL,
5003 CAM_EPF_ALL, stderr);
5008 for (i = 0; i < sup_pages.length; i++) {
5009 if (sup_pages.list[i] == page_id) {
5022 * devtype is filled in with the type of device.
5023 * Returns 0 for success, non-zero for failure.
5026 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5027 int verbosemode, camcontrol_devtype *devtype)
5029 struct ccb_getdev cgd;
5032 retval = get_cgd(dev, &cgd);
5036 switch (cgd.protocol) {
5042 *devtype = CC_DT_ATA;
5044 break; /*NOTREACHED*/
5046 *devtype = CC_DT_UNKNOWN;
5048 break; /*NOTREACHED*/
5052 * Check for the ATA Information VPD page (0x89). If this is an
5053 * ATA device behind a SCSI to ATA translation layer, this VPD page
5054 * should be present.
5056 * If that VPD page isn't present, or we get an error back from the
5057 * INQUIRY command, we'll just treat it as a normal SCSI device.
5059 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5060 timeout, verbosemode);
5062 *devtype = CC_DT_ATA_BEHIND_SCSI;
5064 *devtype = CC_DT_SCSI;
5073 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5074 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5075 uint16_t sector_count, uint64_t lba, uint8_t command, uint8_t *data_ptr,
5076 uint16_t dxfer_len, uint8_t sense_len, uint32_t timeout,
5077 int is48bit, camcontrol_devtype devtype)
5079 if (devtype == CC_DT_ATA) {
5080 cam_fill_ataio(&ccb->ataio,
5081 /*retries*/ retry_count,
5084 /*tag_action*/ tag_action,
5085 /*data_ptr*/ data_ptr,
5086 /*dxfer_len*/ dxfer_len,
5087 /*timeout*/ timeout);
5088 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5089 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5092 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5095 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5096 protocol |= AP_EXTEND;
5098 scsi_ata_pass_16(&ccb->csio,
5099 /*retries*/ retry_count,
5102 /*tag_action*/ tag_action,
5103 /*protocol*/ protocol,
5104 /*ata_flags*/ ata_flags,
5105 /*features*/ features,
5106 /*sector_count*/ sector_count,
5108 /*command*/ command,
5110 /*data_ptr*/ data_ptr,
5111 /*dxfer_len*/ dxfer_len,
5112 /*sense_len*/ sense_len,
5113 /*timeout*/ timeout);
5119 cpi_print(struct ccb_pathinq *cpi)
5121 char adapter_str[1024];
5124 snprintf(adapter_str, sizeof(adapter_str),
5125 "%s%d:", cpi->dev_name, cpi->unit_number);
5127 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5130 for (i = 1; i < 0xff; i = i << 1) {
5133 if ((i & cpi->hba_inquiry) == 0)
5136 fprintf(stdout, "%s supports ", adapter_str);
5140 str = "MDP message";
5143 str = "32 bit wide SCSI";
5146 str = "16 bit wide SCSI";
5149 str = "SDTR message";
5152 str = "linked CDBs";
5155 str = "tag queue messages";
5158 str = "soft reset alternative";
5161 str = "SATA Port Multiplier";
5164 str = "unknown PI bit set";
5167 fprintf(stdout, "%s\n", str);
5170 for (i = 1; i < 0xff; i = i << 1) {
5173 if ((i & cpi->hba_misc) == 0)
5176 fprintf(stdout, "%s ", adapter_str);
5180 str = "bus scans from high ID to low ID";
5183 str = "removable devices not included in scan";
5185 case PIM_NOINITIATOR:
5186 str = "initiator role not supported";
5188 case PIM_NOBUSRESET:
5189 str = "user has disabled initial BUS RESET or"
5190 " controller is in target/mixed mode";
5193 str = "do not send 6-byte commands";
5196 str = "scan bus sequentially";
5199 str = "unknown PIM bit set";
5202 fprintf(stdout, "%s\n", str);
5205 for (i = 1; i < 0xff; i = i << 1) {
5208 if ((i & cpi->target_sprt) == 0)
5211 fprintf(stdout, "%s supports ", adapter_str);
5214 str = "target mode processor mode";
5217 str = "target mode phase cog. mode";
5219 case PIT_DISCONNECT:
5220 str = "disconnects in target mode";
5223 str = "terminate I/O message in target mode";
5226 str = "group 6 commands in target mode";
5229 str = "group 7 commands in target mode";
5232 str = "unknown PIT bit set";
5236 fprintf(stdout, "%s\n", str);
5238 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5240 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5242 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5244 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5245 adapter_str, cpi->hpath_id);
5246 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5248 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5249 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5250 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5251 adapter_str, cpi->hba_vendor);
5252 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5253 adapter_str, cpi->hba_device);
5254 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5255 adapter_str, cpi->hba_subvendor);
5256 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5257 adapter_str, cpi->hba_subdevice);
5258 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5259 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5260 if (cpi->base_transfer_speed > 1000)
5261 fprintf(stdout, "%d.%03dMB/sec\n",
5262 cpi->base_transfer_speed / 1000,
5263 cpi->base_transfer_speed % 1000);
5265 fprintf(stdout, "%dKB/sec\n",
5266 (cpi->base_transfer_speed % 1000) * 1000);
5267 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5268 adapter_str, cpi->maxio);
5272 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5273 struct ccb_trans_settings *cts)
5279 ccb = cam_getccb(device);
5282 warnx("get_print_cts: error allocating ccb");
5286 bzero(&(&ccb->ccb_h)[1],
5287 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5289 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5291 if (user_settings == 0)
5292 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5294 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5296 if (cam_send_ccb(device, ccb) < 0) {
5297 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5298 if (arglist & CAM_ARG_VERBOSE)
5299 cam_error_print(device, ccb, CAM_ESF_ALL,
5300 CAM_EPF_ALL, stderr);
5302 goto get_print_cts_bailout;
5305 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5306 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5307 if (arglist & CAM_ARG_VERBOSE)
5308 cam_error_print(device, ccb, CAM_ESF_ALL,
5309 CAM_EPF_ALL, stderr);
5311 goto get_print_cts_bailout;
5315 cts_print(device, &ccb->cts);
5318 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5320 get_print_cts_bailout:
5328 ratecontrol(struct cam_device *device, int retry_count, int timeout,
5329 int argc, char **argv, char *combinedopt)
5333 int user_settings = 0;
5335 int disc_enable = -1, tag_enable = -1;
5338 double syncrate = -1;
5341 int change_settings = 0, send_tur = 0;
5342 struct ccb_pathinq cpi;
5344 ccb = cam_getccb(device);
5346 warnx("ratecontrol: error allocating ccb");
5349 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5358 if (strncasecmp(optarg, "enable", 6) == 0)
5360 else if (strncasecmp(optarg, "disable", 7) == 0)
5363 warnx("-D argument \"%s\" is unknown", optarg);
5365 goto ratecontrol_bailout;
5367 change_settings = 1;
5370 mode = ata_string2mode(optarg);
5372 warnx("unknown mode '%s'", optarg);
5374 goto ratecontrol_bailout;
5376 change_settings = 1;
5379 offset = strtol(optarg, NULL, 0);
5381 warnx("offset value %d is < 0", offset);
5383 goto ratecontrol_bailout;
5385 change_settings = 1;
5391 syncrate = atof(optarg);
5393 warnx("sync rate %f is < 0", syncrate);
5395 goto ratecontrol_bailout;
5397 change_settings = 1;
5400 if (strncasecmp(optarg, "enable", 6) == 0)
5402 else if (strncasecmp(optarg, "disable", 7) == 0)
5405 warnx("-T argument \"%s\" is unknown", optarg);
5407 goto ratecontrol_bailout;
5409 change_settings = 1;
5415 bus_width = strtol(optarg, NULL, 0);
5416 if (bus_width < 0) {
5417 warnx("bus width %d is < 0", bus_width);
5419 goto ratecontrol_bailout;
5421 change_settings = 1;
5427 bzero(&(&ccb->ccb_h)[1],
5428 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
5430 * Grab path inquiry information, so we can determine whether
5431 * or not the initiator is capable of the things that the user
5434 ccb->ccb_h.func_code = XPT_PATH_INQ;
5435 if (cam_send_ccb(device, ccb) < 0) {
5436 perror("error sending XPT_PATH_INQ CCB");
5437 if (arglist & CAM_ARG_VERBOSE) {
5438 cam_error_print(device, ccb, CAM_ESF_ALL,
5439 CAM_EPF_ALL, stderr);
5442 goto ratecontrol_bailout;
5444 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5445 warnx("XPT_PATH_INQ CCB failed");
5446 if (arglist & CAM_ARG_VERBOSE) {
5447 cam_error_print(device, ccb, CAM_ESF_ALL,
5448 CAM_EPF_ALL, stderr);
5451 goto ratecontrol_bailout;
5453 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5454 bzero(&(&ccb->ccb_h)[1],
5455 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5457 fprintf(stdout, "%s parameters:\n",
5458 user_settings ? "User" : "Current");
5460 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5462 goto ratecontrol_bailout;
5464 if (arglist & CAM_ARG_VERBOSE)
5467 if (change_settings) {
5468 int didsettings = 0;
5469 struct ccb_trans_settings_spi *spi = NULL;
5470 struct ccb_trans_settings_pata *pata = NULL;
5471 struct ccb_trans_settings_sata *sata = NULL;
5472 struct ccb_trans_settings_ata *ata = NULL;
5473 struct ccb_trans_settings_scsi *scsi = NULL;
5475 if (ccb->cts.transport == XPORT_SPI)
5476 spi = &ccb->cts.xport_specific.spi;
5477 if (ccb->cts.transport == XPORT_ATA)
5478 pata = &ccb->cts.xport_specific.ata;
5479 if (ccb->cts.transport == XPORT_SATA)
5480 sata = &ccb->cts.xport_specific.sata;
5481 if (ccb->cts.protocol == PROTO_ATA)
5482 ata = &ccb->cts.proto_specific.ata;
5483 if (ccb->cts.protocol == PROTO_SCSI)
5484 scsi = &ccb->cts.proto_specific.scsi;
5485 ccb->cts.xport_specific.valid = 0;
5486 ccb->cts.proto_specific.valid = 0;
5487 if (spi && disc_enable != -1) {
5488 spi->valid |= CTS_SPI_VALID_DISC;
5489 if (disc_enable == 0)
5490 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5492 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5495 if (tag_enable != -1) {
5496 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5497 warnx("HBA does not support tagged queueing, "
5498 "so you cannot modify tag settings");
5500 goto ratecontrol_bailout;
5503 ata->valid |= CTS_SCSI_VALID_TQ;
5504 if (tag_enable == 0)
5505 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5507 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5510 scsi->valid |= CTS_SCSI_VALID_TQ;
5511 if (tag_enable == 0)
5512 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5514 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5518 if (spi && offset != -1) {
5519 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5520 warnx("HBA is not capable of changing offset");
5522 goto ratecontrol_bailout;
5524 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5525 spi->sync_offset = offset;
5528 if (spi && syncrate != -1) {
5529 int prelim_sync_period;
5531 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5532 warnx("HBA is not capable of changing "
5535 goto ratecontrol_bailout;
5537 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5539 * The sync rate the user gives us is in MHz.
5540 * We need to translate it into KHz for this
5545 * Next, we calculate a "preliminary" sync period
5546 * in tenths of a nanosecond.
5549 prelim_sync_period = 0;
5551 prelim_sync_period = 10000000 / syncrate;
5553 scsi_calc_syncparam(prelim_sync_period);
5556 if (sata && syncrate != -1) {
5557 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5558 warnx("HBA is not capable of changing "
5561 goto ratecontrol_bailout;
5563 if (!user_settings) {
5564 warnx("You can modify only user rate "
5565 "settings for SATA");
5567 goto ratecontrol_bailout;
5569 sata->revision = ata_speed2revision(syncrate * 100);
5570 if (sata->revision < 0) {
5571 warnx("Invalid rate %f", syncrate);
5573 goto ratecontrol_bailout;
5575 sata->valid |= CTS_SATA_VALID_REVISION;
5578 if ((pata || sata) && mode != -1) {
5579 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5580 warnx("HBA is not capable of changing "
5583 goto ratecontrol_bailout;
5585 if (!user_settings) {
5586 warnx("You can modify only user mode "
5587 "settings for ATA/SATA");
5589 goto ratecontrol_bailout;
5593 pata->valid |= CTS_ATA_VALID_MODE;
5596 sata->valid |= CTS_SATA_VALID_MODE;
5601 * The bus_width argument goes like this:
5605 * Therefore, if you shift the number of bits given on the
5606 * command line right by 4, you should get the correct
5609 if (spi && bus_width != -1) {
5611 * We might as well validate things here with a
5612 * decipherable error message, rather than what
5613 * will probably be an indecipherable error message
5614 * by the time it gets back to us.
5616 if ((bus_width == 16)
5617 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5618 warnx("HBA does not support 16 bit bus width");
5620 goto ratecontrol_bailout;
5621 } else if ((bus_width == 32)
5622 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5623 warnx("HBA does not support 32 bit bus width");
5625 goto ratecontrol_bailout;
5626 } else if ((bus_width != 8)
5627 && (bus_width != 16)
5628 && (bus_width != 32)) {
5629 warnx("Invalid bus width %d", bus_width);
5631 goto ratecontrol_bailout;
5633 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5634 spi->bus_width = bus_width >> 4;
5637 if (didsettings == 0) {
5638 goto ratecontrol_bailout;
5640 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5641 if (cam_send_ccb(device, ccb) < 0) {
5642 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5643 if (arglist & CAM_ARG_VERBOSE) {
5644 cam_error_print(device, ccb, CAM_ESF_ALL,
5645 CAM_EPF_ALL, stderr);
5648 goto ratecontrol_bailout;
5650 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5651 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5652 if (arglist & CAM_ARG_VERBOSE) {
5653 cam_error_print(device, ccb, CAM_ESF_ALL,
5654 CAM_EPF_ALL, stderr);
5657 goto ratecontrol_bailout;
5661 retval = testunitready(device, retry_count, timeout,
5662 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5664 * If the TUR didn't succeed, just bail.
5668 fprintf(stderr, "Test Unit Ready failed\n");
5669 goto ratecontrol_bailout;
5672 if ((change_settings || send_tur) && !quiet &&
5673 (ccb->cts.transport == XPORT_ATA ||
5674 ccb->cts.transport == XPORT_SATA || send_tur)) {
5675 fprintf(stdout, "New parameters:\n");
5676 retval = get_print_cts(device, user_settings, 0, NULL);
5679 ratecontrol_bailout:
5685 scsiformat(struct cam_device *device, int argc, char **argv,
5686 char *combinedopt, int retry_count, int timeout)
5690 int ycount = 0, quiet = 0;
5691 int error = 0, retval = 0;
5692 int use_timeout = 10800 * 1000;
5694 struct format_defect_list_header fh;
5695 u_int8_t *data_ptr = NULL;
5696 u_int32_t dxfer_len = 0;
5698 int num_warnings = 0;
5701 ccb = cam_getccb(device);
5704 warnx("scsiformat: error allocating ccb");
5708 bzero(&(&ccb->ccb_h)[1],
5709 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5711 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5732 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5733 "following device:\n");
5735 error = scsidoinquiry(device, argc, argv, combinedopt,
5736 retry_count, timeout);
5739 warnx("scsiformat: error sending inquiry");
5740 goto scsiformat_bailout;
5745 if (!get_confirmation()) {
5747 goto scsiformat_bailout;
5752 use_timeout = timeout;
5755 fprintf(stdout, "Current format timeout is %d seconds\n",
5756 use_timeout / 1000);
5760 * If the user hasn't disabled questions and didn't specify a
5761 * timeout on the command line, ask them if they want the current
5765 && (timeout == 0)) {
5767 int new_timeout = 0;
5769 fprintf(stdout, "Enter new timeout in seconds or press\n"
5770 "return to keep the current timeout [%d] ",
5771 use_timeout / 1000);
5773 if (fgets(str, sizeof(str), stdin) != NULL) {
5775 new_timeout = atoi(str);
5778 if (new_timeout != 0) {
5779 use_timeout = new_timeout * 1000;
5780 fprintf(stdout, "Using new timeout value %d\n",
5781 use_timeout / 1000);
5786 * Keep this outside the if block below to silence any unused
5787 * variable warnings.
5789 bzero(&fh, sizeof(fh));
5792 * If we're in immediate mode, we've got to include the format
5795 if (immediate != 0) {
5796 fh.byte2 = FU_DLH_IMMED;
5797 data_ptr = (u_int8_t *)&fh;
5798 dxfer_len = sizeof(fh);
5799 byte2 = FU_FMT_DATA;
5800 } else if (quiet == 0) {
5801 fprintf(stdout, "Formatting...");
5805 scsi_format_unit(&ccb->csio,
5806 /* retries */ retry_count,
5808 /* tag_action */ MSG_SIMPLE_Q_TAG,
5811 /* data_ptr */ data_ptr,
5812 /* dxfer_len */ dxfer_len,
5813 /* sense_len */ SSD_FULL_SIZE,
5814 /* timeout */ use_timeout);
5816 /* Disable freezing the device queue */
5817 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5819 if (arglist & CAM_ARG_ERR_RECOVER)
5820 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5822 if (((retval = cam_send_ccb(device, ccb)) < 0)
5823 || ((immediate == 0)
5824 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5825 const char errstr[] = "error sending format command";
5832 if (arglist & CAM_ARG_VERBOSE) {
5833 cam_error_print(device, ccb, CAM_ESF_ALL,
5834 CAM_EPF_ALL, stderr);
5837 goto scsiformat_bailout;
5841 * If we ran in non-immediate mode, we already checked for errors
5842 * above and printed out any necessary information. If we're in
5843 * immediate mode, we need to loop through and get status
5844 * information periodically.
5846 if (immediate == 0) {
5848 fprintf(stdout, "Format Complete\n");
5850 goto scsiformat_bailout;
5857 bzero(&(&ccb->ccb_h)[1],
5858 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5861 * There's really no need to do error recovery or
5862 * retries here, since we're just going to sit in a
5863 * loop and wait for the device to finish formatting.
5865 scsi_test_unit_ready(&ccb->csio,
5868 /* tag_action */ MSG_SIMPLE_Q_TAG,
5869 /* sense_len */ SSD_FULL_SIZE,
5870 /* timeout */ 5000);
5872 /* Disable freezing the device queue */
5873 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5875 retval = cam_send_ccb(device, ccb);
5878 * If we get an error from the ioctl, bail out. SCSI
5879 * errors are expected.
5882 warn("error sending CAMIOCOMMAND ioctl");
5883 if (arglist & CAM_ARG_VERBOSE) {
5884 cam_error_print(device, ccb, CAM_ESF_ALL,
5885 CAM_EPF_ALL, stderr);
5888 goto scsiformat_bailout;
5891 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5893 if ((status != CAM_REQ_CMP)
5894 && (status == CAM_SCSI_STATUS_ERROR)
5895 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5896 struct scsi_sense_data *sense;
5897 int error_code, sense_key, asc, ascq;
5899 sense = &ccb->csio.sense_data;
5900 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5901 ccb->csio.sense_resid, &error_code, &sense_key,
5902 &asc, &ascq, /*show_errors*/ 1);
5905 * According to the SCSI-2 and SCSI-3 specs, a
5906 * drive that is in the middle of a format should
5907 * return NOT READY with an ASC of "logical unit
5908 * not ready, format in progress". The sense key
5909 * specific bytes will then be a progress indicator.
5911 if ((sense_key == SSD_KEY_NOT_READY)
5912 && (asc == 0x04) && (ascq == 0x04)) {
5915 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5916 ccb->csio.sense_resid, sks) == 0)
5919 u_int64_t percentage;
5921 val = scsi_2btoul(&sks[1]);
5922 percentage = 10000 * val;
5925 "\rFormatting: %ju.%02u %% "
5927 (uintmax_t)(percentage /
5929 (unsigned)((percentage /
5933 } else if ((quiet == 0)
5934 && (++num_warnings <= 1)) {
5935 warnx("Unexpected SCSI Sense Key "
5936 "Specific value returned "
5938 scsi_sense_print(device, &ccb->csio,
5940 warnx("Unable to print status "
5941 "information, but format will "
5943 warnx("will exit when format is "
5948 warnx("Unexpected SCSI error during format");
5949 cam_error_print(device, ccb, CAM_ESF_ALL,
5950 CAM_EPF_ALL, stderr);
5952 goto scsiformat_bailout;
5955 } else if (status != CAM_REQ_CMP) {
5956 warnx("Unexpected CAM status %#x", status);
5957 if (arglist & CAM_ARG_VERBOSE)
5958 cam_error_print(device, ccb, CAM_ESF_ALL,
5959 CAM_EPF_ALL, stderr);
5961 goto scsiformat_bailout;
5964 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5967 fprintf(stdout, "\nFormat Complete\n");
5977 scsisanitize(struct cam_device *device, int argc, char **argv,
5978 char *combinedopt, int retry_count, int timeout)
5981 u_int8_t action = 0;
5983 int ycount = 0, quiet = 0;
5984 int error = 0, retval = 0;
5985 int use_timeout = 10800 * 1000;
5991 const char *pattern = NULL;
5992 u_int8_t *data_ptr = NULL;
5993 u_int32_t dxfer_len = 0;
5995 int num_warnings = 0;
5998 ccb = cam_getccb(device);
6001 warnx("scsisanitize: error allocating ccb");
6005 bzero(&(&ccb->ccb_h)[1],
6006 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6008 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6011 if (strcasecmp(optarg, "overwrite") == 0)
6012 action = SSZ_SERVICE_ACTION_OVERWRITE;
6013 else if (strcasecmp(optarg, "block") == 0)
6014 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6015 else if (strcasecmp(optarg, "crypto") == 0)
6016 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6017 else if (strcasecmp(optarg, "exitfailure") == 0)
6018 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6020 warnx("invalid service operation \"%s\"",
6023 goto scsisanitize_bailout;
6027 passes = strtol(optarg, NULL, 0);
6028 if (passes < 1 || passes > 31) {
6029 warnx("invalid passes value %d", passes);
6031 goto scsisanitize_bailout;
6062 warnx("an action is required");
6064 goto scsisanitize_bailout;
6065 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6066 struct scsi_sanitize_parameter_list *pl;
6070 if (pattern == NULL) {
6071 warnx("overwrite action requires -P argument");
6073 goto scsisanitize_bailout;
6075 fd = open(pattern, O_RDONLY);
6077 warn("cannot open pattern file %s", pattern);
6079 goto scsisanitize_bailout;
6081 if (fstat(fd, &sb) < 0) {
6082 warn("cannot stat pattern file %s", pattern);
6084 goto scsisanitize_bailout;
6087 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6088 warnx("pattern file size exceeds maximum value %d",
6089 SSZPL_MAX_PATTERN_LENGTH);
6091 goto scsisanitize_bailout;
6093 dxfer_len = sizeof(*pl) + sz;
6094 data_ptr = calloc(1, dxfer_len);
6095 if (data_ptr == NULL) {
6096 warnx("cannot allocate parameter list buffer");
6098 goto scsisanitize_bailout;
6101 amt = read(fd, data_ptr + sizeof(*pl), sz);
6103 warn("cannot read pattern file");
6105 goto scsisanitize_bailout;
6106 } else if (amt != sz) {
6107 warnx("short pattern file read");
6109 goto scsisanitize_bailout;
6112 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6118 pl->byte1 |= SSZPL_INVERT;
6119 scsi_ulto2b(sz, pl->length);
6125 else if (invert != 0)
6127 else if (pattern != NULL)
6132 warnx("%s argument only valid with overwrite "
6135 goto scsisanitize_bailout;
6140 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6141 "following device:\n");
6143 error = scsidoinquiry(device, argc, argv, combinedopt,
6144 retry_count, timeout);
6147 warnx("scsisanitize: error sending inquiry");
6148 goto scsisanitize_bailout;
6153 if (!get_confirmation()) {
6155 goto scsisanitize_bailout;
6160 use_timeout = timeout;
6163 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6164 use_timeout / 1000);
6168 * If the user hasn't disabled questions and didn't specify a
6169 * timeout on the command line, ask them if they want the current
6173 && (timeout == 0)) {
6175 int new_timeout = 0;
6177 fprintf(stdout, "Enter new timeout in seconds or press\n"
6178 "return to keep the current timeout [%d] ",
6179 use_timeout / 1000);
6181 if (fgets(str, sizeof(str), stdin) != NULL) {
6183 new_timeout = atoi(str);
6186 if (new_timeout != 0) {
6187 use_timeout = new_timeout * 1000;
6188 fprintf(stdout, "Using new timeout value %d\n",
6189 use_timeout / 1000);
6195 byte2 |= SSZ_UNRESTRICTED_EXIT;
6199 scsi_sanitize(&ccb->csio,
6200 /* retries */ retry_count,
6202 /* tag_action */ MSG_SIMPLE_Q_TAG,
6205 /* data_ptr */ data_ptr,
6206 /* dxfer_len */ dxfer_len,
6207 /* sense_len */ SSD_FULL_SIZE,
6208 /* timeout */ use_timeout);
6210 /* Disable freezing the device queue */
6211 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6213 if (arglist & CAM_ARG_ERR_RECOVER)
6214 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6216 if (cam_send_ccb(device, ccb) < 0) {
6217 warn("error sending sanitize command");
6219 goto scsisanitize_bailout;
6222 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6223 struct scsi_sense_data *sense;
6224 int error_code, sense_key, asc, ascq;
6226 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6227 CAM_SCSI_STATUS_ERROR) {
6228 sense = &ccb->csio.sense_data;
6229 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6230 ccb->csio.sense_resid, &error_code, &sense_key,
6231 &asc, &ascq, /*show_errors*/ 1);
6233 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6234 asc == 0x20 && ascq == 0x00)
6235 warnx("sanitize is not supported by "
6238 warnx("error sanitizing this device");
6240 warnx("error sanitizing this device");
6242 if (arglist & CAM_ARG_VERBOSE) {
6243 cam_error_print(device, ccb, CAM_ESF_ALL,
6244 CAM_EPF_ALL, stderr);
6247 goto scsisanitize_bailout;
6251 * If we ran in non-immediate mode, we already checked for errors
6252 * above and printed out any necessary information. If we're in
6253 * immediate mode, we need to loop through and get status
6254 * information periodically.
6256 if (immediate == 0) {
6258 fprintf(stdout, "Sanitize Complete\n");
6260 goto scsisanitize_bailout;
6267 bzero(&(&ccb->ccb_h)[1],
6268 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6271 * There's really no need to do error recovery or
6272 * retries here, since we're just going to sit in a
6273 * loop and wait for the device to finish sanitizing.
6275 scsi_test_unit_ready(&ccb->csio,
6278 /* tag_action */ MSG_SIMPLE_Q_TAG,
6279 /* sense_len */ SSD_FULL_SIZE,
6280 /* timeout */ 5000);
6282 /* Disable freezing the device queue */
6283 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6285 retval = cam_send_ccb(device, ccb);
6288 * If we get an error from the ioctl, bail out. SCSI
6289 * errors are expected.
6292 warn("error sending CAMIOCOMMAND ioctl");
6293 if (arglist & CAM_ARG_VERBOSE) {
6294 cam_error_print(device, ccb, CAM_ESF_ALL,
6295 CAM_EPF_ALL, stderr);
6298 goto scsisanitize_bailout;
6301 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6303 if ((status != CAM_REQ_CMP)
6304 && (status == CAM_SCSI_STATUS_ERROR)
6305 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6306 struct scsi_sense_data *sense;
6307 int error_code, sense_key, asc, ascq;
6309 sense = &ccb->csio.sense_data;
6310 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6311 ccb->csio.sense_resid, &error_code, &sense_key,
6312 &asc, &ascq, /*show_errors*/ 1);
6315 * According to the SCSI-3 spec, a drive that is in the
6316 * middle of a sanitize should return NOT READY with an
6317 * ASC of "logical unit not ready, sanitize in
6318 * progress". The sense key specific bytes will then
6319 * be a progress indicator.
6321 if ((sense_key == SSD_KEY_NOT_READY)
6322 && (asc == 0x04) && (ascq == 0x1b)) {
6325 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6326 ccb->csio.sense_resid, sks) == 0)
6329 u_int64_t percentage;
6331 val = scsi_2btoul(&sks[1]);
6332 percentage = 10000 * val;
6335 "\rSanitizing: %ju.%02u %% "
6337 (uintmax_t)(percentage /
6339 (unsigned)((percentage /
6343 } else if ((quiet == 0)
6344 && (++num_warnings <= 1)) {
6345 warnx("Unexpected SCSI Sense Key "
6346 "Specific value returned "
6347 "during sanitize:");
6348 scsi_sense_print(device, &ccb->csio,
6350 warnx("Unable to print status "
6351 "information, but sanitze will "
6353 warnx("will exit when sanitize is "
6358 warnx("Unexpected SCSI error during sanitize");
6359 cam_error_print(device, ccb, CAM_ESF_ALL,
6360 CAM_EPF_ALL, stderr);
6362 goto scsisanitize_bailout;
6365 } else if (status != CAM_REQ_CMP) {
6366 warnx("Unexpected CAM status %#x", status);
6367 if (arglist & CAM_ARG_VERBOSE)
6368 cam_error_print(device, ccb, CAM_ESF_ALL,
6369 CAM_EPF_ALL, stderr);
6371 goto scsisanitize_bailout;
6373 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6376 fprintf(stdout, "\nSanitize Complete\n");
6378 scsisanitize_bailout:
6381 if (data_ptr != NULL)
6389 scsireportluns(struct cam_device *device, int argc, char **argv,
6390 char *combinedopt, int retry_count, int timeout)
6393 int c, countonly, lunsonly;
6394 struct scsi_report_luns_data *lundata;
6396 uint8_t report_type;
6397 uint32_t list_len, i, j;
6402 report_type = RPL_REPORT_DEFAULT;
6403 ccb = cam_getccb(device);
6406 warnx("%s: error allocating ccb", __func__);
6410 bzero(&(&ccb->ccb_h)[1],
6411 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6416 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6425 if (strcasecmp(optarg, "default") == 0)
6426 report_type = RPL_REPORT_DEFAULT;
6427 else if (strcasecmp(optarg, "wellknown") == 0)
6428 report_type = RPL_REPORT_WELLKNOWN;
6429 else if (strcasecmp(optarg, "all") == 0)
6430 report_type = RPL_REPORT_ALL;
6432 warnx("%s: invalid report type \"%s\"",
6443 if ((countonly != 0)
6444 && (lunsonly != 0)) {
6445 warnx("%s: you can only specify one of -c or -l", __func__);
6450 * According to SPC-4, the allocation length must be at least 16
6451 * bytes -- enough for the header and one LUN.
6453 alloc_len = sizeof(*lundata) + 8;
6457 lundata = malloc(alloc_len);
6459 if (lundata == NULL) {
6460 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6465 scsi_report_luns(&ccb->csio,
6466 /*retries*/ retry_count,
6468 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6469 /*select_report*/ report_type,
6470 /*rpl_buf*/ lundata,
6471 /*alloc_len*/ alloc_len,
6472 /*sense_len*/ SSD_FULL_SIZE,
6473 /*timeout*/ timeout ? timeout : 5000);
6475 /* Disable freezing the device queue */
6476 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6478 if (arglist & CAM_ARG_ERR_RECOVER)
6479 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6481 if (cam_send_ccb(device, ccb) < 0) {
6482 warn("error sending REPORT LUNS command");
6484 if (arglist & CAM_ARG_VERBOSE)
6485 cam_error_print(device, ccb, CAM_ESF_ALL,
6486 CAM_EPF_ALL, stderr);
6492 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6493 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6499 list_len = scsi_4btoul(lundata->length);
6502 * If we need to list the LUNs, and our allocation
6503 * length was too short, reallocate and retry.
6505 if ((countonly == 0)
6506 && (list_len > (alloc_len - sizeof(*lundata)))) {
6507 alloc_len = list_len + sizeof(*lundata);
6513 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6514 ((list_len / 8) > 1) ? "s" : "");
6519 for (i = 0; i < (list_len / 8); i++) {
6523 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6525 fprintf(stdout, ",");
6526 switch (lundata->luns[i].lundata[j] &
6527 RPL_LUNDATA_ATYP_MASK) {
6528 case RPL_LUNDATA_ATYP_PERIPH:
6529 if ((lundata->luns[i].lundata[j] &
6530 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6531 fprintf(stdout, "%d:",
6532 lundata->luns[i].lundata[j] &
6533 RPL_LUNDATA_PERIPH_BUS_MASK);
6535 && ((lundata->luns[i].lundata[j+2] &
6536 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6539 fprintf(stdout, "%d",
6540 lundata->luns[i].lundata[j+1]);
6542 case RPL_LUNDATA_ATYP_FLAT: {
6544 tmplun[0] = lundata->luns[i].lundata[j] &
6545 RPL_LUNDATA_FLAT_LUN_MASK;
6546 tmplun[1] = lundata->luns[i].lundata[j+1];
6548 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6552 case RPL_LUNDATA_ATYP_LUN:
6553 fprintf(stdout, "%d:%d:%d",
6554 (lundata->luns[i].lundata[j+1] &
6555 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6556 lundata->luns[i].lundata[j] &
6557 RPL_LUNDATA_LUN_TARG_MASK,
6558 lundata->luns[i].lundata[j+1] &
6559 RPL_LUNDATA_LUN_LUN_MASK);
6561 case RPL_LUNDATA_ATYP_EXTLUN: {
6562 int field_len_code, eam_code;
6564 eam_code = lundata->luns[i].lundata[j] &
6565 RPL_LUNDATA_EXT_EAM_MASK;
6566 field_len_code = (lundata->luns[i].lundata[j] &
6567 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6569 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6570 && (field_len_code == 0x00)) {
6571 fprintf(stdout, "%d",
6572 lundata->luns[i].lundata[j+1]);
6573 } else if ((eam_code ==
6574 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6575 && (field_len_code == 0x03)) {
6579 * This format takes up all 8 bytes.
6580 * If we aren't starting at offset 0,
6584 fprintf(stdout, "Invalid "
6587 "specified format", j);
6591 bzero(tmp_lun, sizeof(tmp_lun));
6592 bcopy(&lundata->luns[i].lundata[j+1],
6593 &tmp_lun[1], sizeof(tmp_lun) - 1);
6594 fprintf(stdout, "%#jx",
6595 (intmax_t)scsi_8btou64(tmp_lun));
6598 fprintf(stderr, "Unknown Extended LUN"
6599 "Address method %#x, length "
6600 "code %#x", eam_code,
6607 fprintf(stderr, "Unknown LUN address method "
6608 "%#x\n", lundata->luns[i].lundata[0] &
6609 RPL_LUNDATA_ATYP_MASK);
6613 * For the flat addressing method, there are no
6614 * other levels after it.
6619 fprintf(stdout, "\n");
6632 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6633 char *combinedopt, int retry_count, int timeout)
6636 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6637 struct scsi_read_capacity_data rcap;
6638 struct scsi_read_capacity_data_long rcaplong;
6652 ccb = cam_getccb(device);
6655 warnx("%s: error allocating ccb", __func__);
6659 bzero(&(&ccb->ccb_h)[1],
6660 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6662 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6689 if ((blocksizeonly != 0)
6690 && (numblocks != 0)) {
6691 warnx("%s: you can only specify one of -b or -N", __func__);
6696 if ((blocksizeonly != 0)
6697 && (sizeonly != 0)) {
6698 warnx("%s: you can only specify one of -b or -s", __func__);
6705 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6711 && (blocksizeonly != 0)) {
6712 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6717 scsi_read_capacity(&ccb->csio,
6718 /*retries*/ retry_count,
6720 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6723 /*timeout*/ timeout ? timeout : 5000);
6725 /* Disable freezing the device queue */
6726 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6728 if (arglist & CAM_ARG_ERR_RECOVER)
6729 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6731 if (cam_send_ccb(device, ccb) < 0) {
6732 warn("error sending READ CAPACITY command");
6734 if (arglist & CAM_ARG_VERBOSE)
6735 cam_error_print(device, ccb, CAM_ESF_ALL,
6736 CAM_EPF_ALL, stderr);
6742 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6743 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6748 maxsector = scsi_4btoul(rcap.addr);
6749 block_len = scsi_4btoul(rcap.length);
6752 * A last block of 2^32-1 means that the true capacity is over 2TB,
6753 * and we need to issue the long READ CAPACITY to get the real
6754 * capacity. Otherwise, we're all set.
6756 if (maxsector != 0xffffffff)
6759 scsi_read_capacity_16(&ccb->csio,
6760 /*retries*/ retry_count,
6762 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6766 /*rcap_buf*/ (uint8_t *)&rcaplong,
6767 /*rcap_buf_len*/ sizeof(rcaplong),
6768 /*sense_len*/ SSD_FULL_SIZE,
6769 /*timeout*/ timeout ? timeout : 5000);
6771 /* Disable freezing the device queue */
6772 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6774 if (arglist & CAM_ARG_ERR_RECOVER)
6775 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6777 if (cam_send_ccb(device, ccb) < 0) {
6778 warn("error sending READ CAPACITY (16) command");
6780 if (arglist & CAM_ARG_VERBOSE)
6781 cam_error_print(device, ccb, CAM_ESF_ALL,
6782 CAM_EPF_ALL, stderr);
6788 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6789 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6794 maxsector = scsi_8btou64(rcaplong.addr);
6795 block_len = scsi_4btoul(rcaplong.length);
6798 if (blocksizeonly == 0) {
6800 * Humanize implies !quiet, and also implies numblocks.
6802 if (humanize != 0) {
6807 tmpbytes = (maxsector + 1) * block_len;
6808 ret = humanize_number(tmpstr, sizeof(tmpstr),
6809 tmpbytes, "", HN_AUTOSCALE,
6812 HN_DIVISOR_1000 : 0));
6814 warnx("%s: humanize_number failed!", __func__);
6818 fprintf(stdout, "Device Size: %s%s", tmpstr,
6819 (sizeonly == 0) ? ", " : "\n");
6820 } else if (numblocks != 0) {
6821 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6822 "Blocks: " : "", (uintmax_t)maxsector + 1,
6823 (sizeonly == 0) ? ", " : "\n");
6825 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6826 "Last Block: " : "", (uintmax_t)maxsector,
6827 (sizeonly == 0) ? ", " : "\n");
6831 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6832 "Block Length: " : "", block_len, (quiet == 0) ?
6841 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6842 int retry_count, int timeout)
6846 uint8_t *smp_request = NULL, *smp_response = NULL;
6847 int request_size = 0, response_size = 0;
6848 int fd_request = 0, fd_response = 0;
6849 char *datastr = NULL;
6850 struct get_hook hook;
6855 * Note that at the moment we don't support sending SMP CCBs to
6856 * devices that aren't probed by CAM.
6858 ccb = cam_getccb(device);
6860 warnx("%s: error allocating CCB", __func__);
6864 bzero(&(&ccb->ccb_h)[1],
6865 sizeof(union ccb) - sizeof(struct ccb_hdr));
6867 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6870 arglist |= CAM_ARG_CMD_IN;
6871 response_size = strtol(optarg, NULL, 0);
6872 if (response_size <= 0) {
6873 warnx("invalid number of response bytes %d",
6876 goto smpcmd_bailout;
6878 hook.argc = argc - optind;
6879 hook.argv = argv + optind;
6882 datastr = cget(&hook, NULL);
6884 * If the user supplied "-" instead of a format, he
6885 * wants the data to be written to stdout.
6887 if ((datastr != NULL)
6888 && (datastr[0] == '-'))
6891 smp_response = (u_int8_t *)malloc(response_size);
6892 if (smp_response == NULL) {
6893 warn("can't malloc memory for SMP response");
6895 goto smpcmd_bailout;
6899 arglist |= CAM_ARG_CMD_OUT;
6900 request_size = strtol(optarg, NULL, 0);
6901 if (request_size <= 0) {
6902 warnx("invalid number of request bytes %d",
6905 goto smpcmd_bailout;
6907 hook.argc = argc - optind;
6908 hook.argv = argv + optind;
6910 datastr = cget(&hook, NULL);
6911 smp_request = (u_int8_t *)malloc(request_size);
6912 if (smp_request == NULL) {
6913 warn("can't malloc memory for SMP request");
6915 goto smpcmd_bailout;
6917 bzero(smp_request, request_size);
6919 * If the user supplied "-" instead of a format, he
6920 * wants the data to be read from stdin.
6922 if ((datastr != NULL)
6923 && (datastr[0] == '-'))
6926 buff_encode_visit(smp_request, request_size,
6937 * If fd_data is set, and we're writing to the device, we need to
6938 * read the data the user wants written from stdin.
6940 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6942 int amt_to_read = request_size;
6943 u_int8_t *buf_ptr = smp_request;
6945 for (amt_read = 0; amt_to_read > 0;
6946 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6947 if (amt_read == -1) {
6948 warn("error reading data from stdin");
6950 goto smpcmd_bailout;
6952 amt_to_read -= amt_read;
6953 buf_ptr += amt_read;
6957 if (((arglist & CAM_ARG_CMD_IN) == 0)
6958 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6959 warnx("%s: need both the request (-r) and response (-R) "
6960 "arguments", __func__);
6962 goto smpcmd_bailout;
6965 flags |= CAM_DEV_QFRZDIS;
6967 cam_fill_smpio(&ccb->smpio,
6968 /*retries*/ retry_count,
6971 /*smp_request*/ smp_request,
6972 /*smp_request_len*/ request_size,
6973 /*smp_response*/ smp_response,
6974 /*smp_response_len*/ response_size,
6975 /*timeout*/ timeout ? timeout : 5000);
6977 ccb->smpio.flags = SMP_FLAG_NONE;
6979 if (((retval = cam_send_ccb(device, ccb)) < 0)
6980 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6981 const char warnstr[] = "error sending command";
6988 if (arglist & CAM_ARG_VERBOSE) {
6989 cam_error_print(device, ccb, CAM_ESF_ALL,
6990 CAM_EPF_ALL, stderr);
6994 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6995 && (response_size > 0)) {
6996 if (fd_response == 0) {
6997 buff_decode_visit(smp_response, response_size,
6998 datastr, arg_put, NULL);
6999 fprintf(stdout, "\n");
7001 ssize_t amt_written;
7002 int amt_to_write = response_size;
7003 u_int8_t *buf_ptr = smp_response;
7005 for (amt_written = 0; (amt_to_write > 0) &&
7006 (amt_written = write(STDOUT_FILENO, buf_ptr,
7007 amt_to_write)) > 0;){
7008 amt_to_write -= amt_written;
7009 buf_ptr += amt_written;
7011 if (amt_written == -1) {
7012 warn("error writing data to stdout");
7014 goto smpcmd_bailout;
7015 } else if ((amt_written == 0)
7016 && (amt_to_write > 0)) {
7017 warnx("only wrote %u bytes out of %u",
7018 response_size - amt_to_write,
7027 if (smp_request != NULL)
7030 if (smp_response != NULL)
7037 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7038 char *combinedopt, int retry_count, int timeout)
7041 struct smp_report_general_request *request = NULL;
7042 struct smp_report_general_response *response = NULL;
7043 struct sbuf *sb = NULL;
7045 int c, long_response = 0;
7049 * Note that at the moment we don't support sending SMP CCBs to
7050 * devices that aren't probed by CAM.
7052 ccb = cam_getccb(device);
7054 warnx("%s: error allocating CCB", __func__);
7058 bzero(&(&ccb->ccb_h)[1],
7059 sizeof(union ccb) - sizeof(struct ccb_hdr));
7061 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7070 request = malloc(sizeof(*request));
7071 if (request == NULL) {
7072 warn("%s: unable to allocate %zd bytes", __func__,
7078 response = malloc(sizeof(*response));
7079 if (response == NULL) {
7080 warn("%s: unable to allocate %zd bytes", __func__,
7087 smp_report_general(&ccb->smpio,
7091 /*request_len*/ sizeof(*request),
7092 (uint8_t *)response,
7093 /*response_len*/ sizeof(*response),
7094 /*long_response*/ long_response,
7097 if (((retval = cam_send_ccb(device, ccb)) < 0)
7098 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7099 const char warnstr[] = "error sending command";
7106 if (arglist & CAM_ARG_VERBOSE) {
7107 cam_error_print(device, ccb, CAM_ESF_ALL,
7108 CAM_EPF_ALL, stderr);
7115 * If the device supports the long response bit, try again and see
7116 * if we can get all of the data.
7118 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7119 && (long_response == 0)) {
7120 ccb->ccb_h.status = CAM_REQ_INPROG;
7121 bzero(&(&ccb->ccb_h)[1],
7122 sizeof(union ccb) - sizeof(struct ccb_hdr));
7128 * XXX KDM detect and decode SMP errors here.
7130 sb = sbuf_new_auto();
7132 warnx("%s: error allocating sbuf", __func__);
7136 smp_report_general_sbuf(response, sizeof(*response), sb);
7138 if (sbuf_finish(sb) != 0) {
7139 warnx("%s: sbuf_finish", __func__);
7143 printf("%s", sbuf_data(sb));
7149 if (request != NULL)
7152 if (response != NULL)
7161 static struct camcontrol_opts phy_ops[] = {
7162 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7163 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7164 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7165 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7166 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7167 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7168 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7169 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7170 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7175 smpphycontrol(struct cam_device *device, int argc, char **argv,
7176 char *combinedopt, int retry_count, int timeout)
7179 struct smp_phy_control_request *request = NULL;
7180 struct smp_phy_control_response *response = NULL;
7181 int long_response = 0;
7184 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7186 uint64_t attached_dev_name = 0;
7187 int dev_name_set = 0;
7188 uint32_t min_plr = 0, max_plr = 0;
7189 uint32_t pp_timeout_val = 0;
7190 int slumber_partial = 0;
7191 int set_pp_timeout_val = 0;
7195 * Note that at the moment we don't support sending SMP CCBs to
7196 * devices that aren't probed by CAM.
7198 ccb = cam_getccb(device);
7200 warnx("%s: error allocating CCB", __func__);
7204 bzero(&(&ccb->ccb_h)[1],
7205 sizeof(union ccb) - sizeof(struct ccb_hdr));
7207 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7215 if (strcasecmp(optarg, "enable") == 0)
7217 else if (strcasecmp(optarg, "disable") == 0)
7220 warnx("%s: Invalid argument %s", __func__,
7227 slumber_partial |= enable <<
7228 SMP_PC_SAS_SLUMBER_SHIFT;
7231 slumber_partial |= enable <<
7232 SMP_PC_SAS_PARTIAL_SHIFT;
7235 slumber_partial |= enable <<
7236 SMP_PC_SATA_SLUMBER_SHIFT;
7239 slumber_partial |= enable <<
7240 SMP_PC_SATA_PARTIAL_SHIFT;
7243 warnx("%s: programmer error", __func__);
7246 break; /*NOTREACHED*/
7251 attached_dev_name = (uintmax_t)strtoumax(optarg,
7260 * We don't do extensive checking here, so this
7261 * will continue to work when new speeds come out.
7263 min_plr = strtoul(optarg, NULL, 0);
7265 || (min_plr > 0xf)) {
7266 warnx("%s: invalid link rate %x",
7274 * We don't do extensive checking here, so this
7275 * will continue to work when new speeds come out.
7277 max_plr = strtoul(optarg, NULL, 0);
7279 || (max_plr > 0xf)) {
7280 warnx("%s: invalid link rate %x",
7287 camcontrol_optret optreturn;
7288 cam_argmask argnums;
7291 if (phy_op_set != 0) {
7292 warnx("%s: only one phy operation argument "
7293 "(-o) allowed", __func__);
7301 * Allow the user to specify the phy operation
7302 * numerically, as well as with a name. This will
7303 * future-proof it a bit, so options that are added
7304 * in future specs can be used.
7306 if (isdigit(optarg[0])) {
7307 phy_operation = strtoul(optarg, NULL, 0);
7308 if ((phy_operation == 0)
7309 || (phy_operation > 0xff)) {
7310 warnx("%s: invalid phy operation %#x",
7311 __func__, phy_operation);
7317 optreturn = getoption(phy_ops, optarg, &phy_operation,
7320 if (optreturn == CC_OR_AMBIGUOUS) {
7321 warnx("%s: ambiguous option %s", __func__,
7326 } else if (optreturn == CC_OR_NOT_FOUND) {
7327 warnx("%s: option %s not found", __func__,
7339 pp_timeout_val = strtoul(optarg, NULL, 0);
7340 if (pp_timeout_val > 15) {
7341 warnx("%s: invalid partial pathway timeout "
7342 "value %u, need a value less than 16",
7343 __func__, pp_timeout_val);
7347 set_pp_timeout_val = 1;
7355 warnx("%s: a PHY (-p phy) argument is required",__func__);
7360 if (((dev_name_set != 0)
7361 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7362 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7363 && (dev_name_set == 0))) {
7364 warnx("%s: -d name and -o setdevname arguments both "
7365 "required to set device name", __func__);
7370 request = malloc(sizeof(*request));
7371 if (request == NULL) {
7372 warn("%s: unable to allocate %zd bytes", __func__,
7378 response = malloc(sizeof(*response));
7379 if (response == NULL) {
7380 warn("%s: unable to allocate %zd bytes", __func__,
7386 smp_phy_control(&ccb->smpio,
7391 (uint8_t *)response,
7394 /*expected_exp_change_count*/ 0,
7397 (set_pp_timeout_val != 0) ? 1 : 0,
7405 if (((retval = cam_send_ccb(device, ccb)) < 0)
7406 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7407 const char warnstr[] = "error sending command";
7414 if (arglist & CAM_ARG_VERBOSE) {
7416 * Use CAM_EPF_NORMAL so we only get one line of
7417 * SMP command decoding.
7419 cam_error_print(device, ccb, CAM_ESF_ALL,
7420 CAM_EPF_NORMAL, stderr);
7426 /* XXX KDM print out something here for success? */
7431 if (request != NULL)
7434 if (response != NULL)
7441 smpmaninfo(struct cam_device *device, int argc, char **argv,
7442 char *combinedopt, int retry_count, int timeout)
7445 struct smp_report_manuf_info_request request;
7446 struct smp_report_manuf_info_response response;
7447 struct sbuf *sb = NULL;
7448 int long_response = 0;
7453 * Note that at the moment we don't support sending SMP CCBs to
7454 * devices that aren't probed by CAM.
7456 ccb = cam_getccb(device);
7458 warnx("%s: error allocating CCB", __func__);
7462 bzero(&(&ccb->ccb_h)[1],
7463 sizeof(union ccb) - sizeof(struct ccb_hdr));
7465 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7474 bzero(&request, sizeof(request));
7475 bzero(&response, sizeof(response));
7477 smp_report_manuf_info(&ccb->smpio,
7482 (uint8_t *)&response,
7487 if (((retval = cam_send_ccb(device, ccb)) < 0)
7488 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7489 const char warnstr[] = "error sending command";
7496 if (arglist & CAM_ARG_VERBOSE) {
7497 cam_error_print(device, ccb, CAM_ESF_ALL,
7498 CAM_EPF_ALL, stderr);
7504 sb = sbuf_new_auto();
7506 warnx("%s: error allocating sbuf", __func__);
7510 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7512 if (sbuf_finish(sb) != 0) {
7513 warnx("%s: sbuf_finish", __func__);
7517 printf("%s", sbuf_data(sb));
7531 getdevid(struct cam_devitem *item)
7534 union ccb *ccb = NULL;
7536 struct cam_device *dev;
7538 dev = cam_open_btl(item->dev_match.path_id,
7539 item->dev_match.target_id,
7540 item->dev_match.target_lun, O_RDWR, NULL);
7543 warnx("%s", cam_errbuf);
7548 item->device_id_len = 0;
7550 ccb = cam_getccb(dev);
7552 warnx("%s: error allocating CCB", __func__);
7557 bzero(&(&ccb->ccb_h)[1],
7558 sizeof(union ccb) - sizeof(struct ccb_hdr));
7561 * On the first try, we just probe for the size of the data, and
7562 * then allocate that much memory and try again.
7565 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7566 ccb->ccb_h.flags = CAM_DIR_IN;
7567 ccb->cdai.flags = CDAI_FLAG_NONE;
7568 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7569 ccb->cdai.bufsiz = item->device_id_len;
7570 if (item->device_id_len != 0)
7571 ccb->cdai.buf = (uint8_t *)item->device_id;
7573 if (cam_send_ccb(dev, ccb) < 0) {
7574 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7579 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7580 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7585 if (item->device_id_len == 0) {
7587 * This is our first time through. Allocate the buffer,
7588 * and then go back to get the data.
7590 if (ccb->cdai.provsiz == 0) {
7591 warnx("%s: invalid .provsiz field returned with "
7592 "XPT_GDEV_ADVINFO CCB", __func__);
7596 item->device_id_len = ccb->cdai.provsiz;
7597 item->device_id = malloc(item->device_id_len);
7598 if (item->device_id == NULL) {
7599 warn("%s: unable to allocate %d bytes", __func__,
7600 item->device_id_len);
7604 ccb->ccb_h.status = CAM_REQ_INPROG;
7610 cam_close_device(dev);
7619 * XXX KDM merge this code with getdevtree()?
7622 buildbusdevlist(struct cam_devlist *devlist)
7625 int bufsize, fd = -1;
7626 struct dev_match_pattern *patterns;
7627 struct cam_devitem *item = NULL;
7628 int skip_device = 0;
7631 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7632 warn("couldn't open %s", XPT_DEVICE);
7636 bzero(&ccb, sizeof(union ccb));
7638 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7639 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7640 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7642 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7643 bufsize = sizeof(struct dev_match_result) * 100;
7644 ccb.cdm.match_buf_len = bufsize;
7645 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7646 if (ccb.cdm.matches == NULL) {
7647 warnx("can't malloc memory for matches");
7651 ccb.cdm.num_matches = 0;
7652 ccb.cdm.num_patterns = 2;
7653 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7654 ccb.cdm.num_patterns;
7656 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7657 if (patterns == NULL) {
7658 warnx("can't malloc memory for patterns");
7663 ccb.cdm.patterns = patterns;
7664 bzero(patterns, ccb.cdm.pattern_buf_len);
7666 patterns[0].type = DEV_MATCH_DEVICE;
7667 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7668 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7669 patterns[1].type = DEV_MATCH_PERIPH;
7670 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7671 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7674 * We do the ioctl multiple times if necessary, in case there are
7675 * more than 100 nodes in the EDT.
7680 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7681 warn("error sending CAMIOCOMMAND ioctl");
7686 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7687 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7688 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7689 warnx("got CAM error %#x, CDM error %d\n",
7690 ccb.ccb_h.status, ccb.cdm.status);
7695 for (i = 0; i < ccb.cdm.num_matches; i++) {
7696 switch (ccb.cdm.matches[i].type) {
7697 case DEV_MATCH_DEVICE: {
7698 struct device_match_result *dev_result;
7701 &ccb.cdm.matches[i].result.device_result;
7703 if (dev_result->flags &
7704 DEV_RESULT_UNCONFIGURED) {
7710 item = malloc(sizeof(*item));
7712 warn("%s: unable to allocate %zd bytes",
7713 __func__, sizeof(*item));
7717 bzero(item, sizeof(*item));
7718 bcopy(dev_result, &item->dev_match,
7719 sizeof(*dev_result));
7720 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7723 if (getdevid(item) != 0) {
7729 case DEV_MATCH_PERIPH: {
7730 struct periph_match_result *periph_result;
7733 &ccb.cdm.matches[i].result.periph_result;
7735 if (skip_device != 0)
7737 item->num_periphs++;
7738 item->periph_matches = realloc(
7739 item->periph_matches,
7741 sizeof(struct periph_match_result));
7742 if (item->periph_matches == NULL) {
7743 warn("%s: error allocating periph "
7748 bcopy(periph_result, &item->periph_matches[
7749 item->num_periphs - 1],
7750 sizeof(*periph_result));
7754 fprintf(stderr, "%s: unexpected match "
7755 "type %d\n", __func__,
7756 ccb.cdm.matches[i].type);
7759 break; /*NOTREACHED*/
7762 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7763 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7771 free(ccb.cdm.matches);
7774 freebusdevlist(devlist);
7780 freebusdevlist(struct cam_devlist *devlist)
7782 struct cam_devitem *item, *item2;
7784 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7785 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7787 free(item->device_id);
7788 free(item->periph_matches);
7793 static struct cam_devitem *
7794 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7796 struct cam_devitem *item;
7798 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7799 struct scsi_vpd_id_descriptor *idd;
7802 * XXX KDM look for LUN IDs as well?
7804 idd = scsi_get_devid(item->device_id,
7805 item->device_id_len,
7806 scsi_devid_is_sas_target);
7810 if (scsi_8btou64(idd->identifier) == sasaddr)
7818 smpphylist(struct cam_device *device, int argc, char **argv,
7819 char *combinedopt, int retry_count, int timeout)
7821 struct smp_report_general_request *rgrequest = NULL;
7822 struct smp_report_general_response *rgresponse = NULL;
7823 struct smp_discover_request *disrequest = NULL;
7824 struct smp_discover_response *disresponse = NULL;
7825 struct cam_devlist devlist;
7827 int long_response = 0;
7834 * Note that at the moment we don't support sending SMP CCBs to
7835 * devices that aren't probed by CAM.
7837 ccb = cam_getccb(device);
7839 warnx("%s: error allocating CCB", __func__);
7843 bzero(&(&ccb->ccb_h)[1],
7844 sizeof(union ccb) - sizeof(struct ccb_hdr));
7845 STAILQ_INIT(&devlist.dev_queue);
7847 rgrequest = malloc(sizeof(*rgrequest));
7848 if (rgrequest == NULL) {
7849 warn("%s: unable to allocate %zd bytes", __func__,
7850 sizeof(*rgrequest));
7855 rgresponse = malloc(sizeof(*rgresponse));
7856 if (rgresponse == NULL) {
7857 warn("%s: unable to allocate %zd bytes", __func__,
7858 sizeof(*rgresponse));
7863 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7876 smp_report_general(&ccb->smpio,
7880 /*request_len*/ sizeof(*rgrequest),
7881 (uint8_t *)rgresponse,
7882 /*response_len*/ sizeof(*rgresponse),
7883 /*long_response*/ long_response,
7886 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7888 if (((retval = cam_send_ccb(device, ccb)) < 0)
7889 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7890 const char warnstr[] = "error sending command";
7897 if (arglist & CAM_ARG_VERBOSE) {
7898 cam_error_print(device, ccb, CAM_ESF_ALL,
7899 CAM_EPF_ALL, stderr);
7905 num_phys = rgresponse->num_phys;
7907 if (num_phys == 0) {
7909 fprintf(stdout, "%s: No Phys reported\n", __func__);
7914 devlist.path_id = device->path_id;
7916 retval = buildbusdevlist(&devlist);
7921 fprintf(stdout, "%d PHYs:\n", num_phys);
7922 fprintf(stdout, "PHY Attached SAS Address\n");
7925 disrequest = malloc(sizeof(*disrequest));
7926 if (disrequest == NULL) {
7927 warn("%s: unable to allocate %zd bytes", __func__,
7928 sizeof(*disrequest));
7933 disresponse = malloc(sizeof(*disresponse));
7934 if (disresponse == NULL) {
7935 warn("%s: unable to allocate %zd bytes", __func__,
7936 sizeof(*disresponse));
7941 for (i = 0; i < num_phys; i++) {
7942 struct cam_devitem *item;
7943 struct device_match_result *dev_match;
7944 char vendor[16], product[48], revision[16];
7948 bzero(&(&ccb->ccb_h)[1],
7949 sizeof(union ccb) - sizeof(struct ccb_hdr));
7951 ccb->ccb_h.status = CAM_REQ_INPROG;
7952 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7954 smp_discover(&ccb->smpio,
7958 sizeof(*disrequest),
7959 (uint8_t *)disresponse,
7960 sizeof(*disresponse),
7962 /*ignore_zone_group*/ 0,
7966 if (((retval = cam_send_ccb(device, ccb)) < 0)
7967 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7968 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7969 const char warnstr[] = "error sending command";
7976 if (arglist & CAM_ARG_VERBOSE) {
7977 cam_error_print(device, ccb, CAM_ESF_ALL,
7978 CAM_EPF_ALL, stderr);
7984 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7986 fprintf(stdout, "%3d <vacant>\n", i);
7990 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7993 item = findsasdevice(&devlist,
7994 scsi_8btou64(disresponse->attached_sas_address));
7998 || (item != NULL)) {
7999 fprintf(stdout, "%3d 0x%016jx", i,
8000 (uintmax_t)scsi_8btou64(
8001 disresponse->attached_sas_address));
8003 fprintf(stdout, "\n");
8006 } else if (quiet != 0)
8009 dev_match = &item->dev_match;
8011 if (dev_match->protocol == PROTO_SCSI) {
8012 cam_strvis(vendor, dev_match->inq_data.vendor,
8013 sizeof(dev_match->inq_data.vendor),
8015 cam_strvis(product, dev_match->inq_data.product,
8016 sizeof(dev_match->inq_data.product),
8018 cam_strvis(revision, dev_match->inq_data.revision,
8019 sizeof(dev_match->inq_data.revision),
8021 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8023 } else if ((dev_match->protocol == PROTO_ATA)
8024 || (dev_match->protocol == PROTO_SATAPM)) {
8025 cam_strvis(product, dev_match->ident_data.model,
8026 sizeof(dev_match->ident_data.model),
8028 cam_strvis(revision, dev_match->ident_data.revision,
8029 sizeof(dev_match->ident_data.revision),
8031 sprintf(tmpstr, "<%s %s>", product, revision);
8033 sprintf(tmpstr, "<>");
8035 fprintf(stdout, " %-33s ", tmpstr);
8038 * If we have 0 periphs, that's a bug...
8040 if (item->num_periphs == 0) {
8041 fprintf(stdout, "\n");
8045 fprintf(stdout, "(");
8046 for (j = 0; j < item->num_periphs; j++) {
8048 fprintf(stdout, ",");
8050 fprintf(stdout, "%s%d",
8051 item->periph_matches[j].periph_name,
8052 item->periph_matches[j].unit_number);
8055 fprintf(stdout, ")\n");
8069 freebusdevlist(&devlist);
8075 atapm(struct cam_device *device, int argc, char **argv,
8076 char *combinedopt, int retry_count, int timeout)
8084 ccb = cam_getccb(device);
8087 warnx("%s: error allocating ccb", __func__);
8091 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8100 if (strcmp(argv[1], "idle") == 0) {
8102 cmd = ATA_IDLE_IMMEDIATE;
8105 } else if (strcmp(argv[1], "standby") == 0) {
8107 cmd = ATA_STANDBY_IMMEDIATE;
8109 cmd = ATA_STANDBY_CMD;
8117 else if (t <= (240 * 5))
8119 else if (t <= (252 * 5))
8120 /* special encoding for 21 minutes */
8122 else if (t <= (11 * 30 * 60))
8123 sc = (t - 1) / (30 * 60) + 241;
8127 retval = ata_do_28bit_cmd(device,
8129 /*retries*/retry_count,
8130 /*flags*/CAM_DIR_NONE,
8131 /*protocol*/AP_PROTO_NON_DATA,
8132 /*tag_action*/MSG_SIMPLE_Q_TAG,
8139 /*timeout*/timeout ? timeout : 30 * 1000,
8147 ataaxm(struct cam_device *device, int argc, char **argv,
8148 char *combinedopt, int retry_count, int timeout)
8156 ccb = cam_getccb(device);
8159 warnx("%s: error allocating ccb", __func__);
8163 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8173 if (strcmp(argv[1], "apm") == 0) {
8189 retval = ata_do_28bit_cmd(device,
8191 /*retries*/retry_count,
8192 /*flags*/CAM_DIR_NONE,
8193 /*protocol*/AP_PROTO_NON_DATA,
8194 /*tag_action*/MSG_SIMPLE_Q_TAG,
8195 /*command*/ATA_SETFEATURES,
8201 /*timeout*/timeout ? timeout : 30 * 1000,
8209 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8210 int show_sa_errors, int sa_set, int service_action,
8211 int timeout_desc, int retry_count, int timeout, int verbosemode,
8212 uint32_t *fill_len, uint8_t **data_ptr)
8214 union ccb *ccb = NULL;
8215 uint8_t *buf = NULL;
8216 uint32_t alloc_len = 0, num_opcodes;
8217 uint32_t valid_len = 0;
8218 uint32_t avail_len = 0;
8219 struct scsi_report_supported_opcodes_all *all_hdr;
8220 struct scsi_report_supported_opcodes_one *one;
8225 * Make it clear that we haven't yet allocated or filled anything.
8230 ccb = cam_getccb(device);
8232 warnx("couldn't allocate CCB");
8237 /* cam_getccb cleans up the header, caller has to zero the payload */
8238 bzero(&(&ccb->ccb_h)[1],
8239 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
8241 if (opcode_set != 0) {
8242 options |= RSO_OPTIONS_OC;
8244 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8247 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8248 sizeof(struct scsi_report_supported_opcodes_descr));
8251 if (timeout_desc != 0) {
8252 options |= RSO_RCTD;
8253 alloc_len += num_opcodes *
8254 sizeof(struct scsi_report_supported_opcodes_timeout);
8258 options |= RSO_OPTIONS_OC_SA;
8259 if (show_sa_errors != 0)
8260 options &= ~RSO_OPTIONS_OC;
8269 buf = malloc(alloc_len);
8271 warn("Unable to allocate %u bytes", alloc_len);
8275 bzero(buf, alloc_len);
8277 scsi_report_supported_opcodes(&ccb->csio,
8278 /*retries*/ retry_count,
8280 /*tag_action*/ MSG_SIMPLE_Q_TAG,
8281 /*options*/ options,
8282 /*req_opcode*/ opcode,
8283 /*req_service_action*/ service_action,
8285 /*dxfer_len*/ alloc_len,
8286 /*sense_len*/ SSD_FULL_SIZE,
8287 /*timeout*/ timeout ? timeout : 10000);
8289 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8291 if (retry_count != 0)
8292 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8294 if (cam_send_ccb(device, ccb) < 0) {
8295 perror("error sending REPORT SUPPORTED OPERATION CODES");
8300 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8301 if (verbosemode != 0)
8302 cam_error_print(device, ccb, CAM_ESF_ALL,
8303 CAM_EPF_ALL, stderr);
8309 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8311 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8312 && (valid_len >= sizeof(*all_hdr))) {
8313 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8314 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8315 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8316 && (valid_len >= sizeof(*one))) {
8317 uint32_t cdb_length;
8319 one = (struct scsi_report_supported_opcodes_one *)buf;
8320 cdb_length = scsi_2btoul(one->cdb_length);
8321 avail_len = sizeof(*one) + cdb_length;
8322 if (one->support & RSO_ONE_CTDP) {
8323 struct scsi_report_supported_opcodes_timeout *td;
8325 td = (struct scsi_report_supported_opcodes_timeout *)
8327 if (valid_len >= (avail_len + sizeof(td->length))) {
8328 avail_len += scsi_2btoul(td->length) +
8331 avail_len += sizeof(*td);
8337 * avail_len could be zero if we didn't get enough data back from
8338 * thet target to determine
8340 if ((avail_len != 0)
8341 && (avail_len > valid_len)) {
8342 alloc_len = avail_len;
8346 *fill_len = valid_len;
8358 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8359 int req_sa, uint8_t *buf, uint32_t valid_len)
8361 struct scsi_report_supported_opcodes_one *one;
8362 struct scsi_report_supported_opcodes_timeout *td;
8363 uint32_t cdb_len = 0, td_len = 0;
8364 const char *op_desc = NULL;
8368 one = (struct scsi_report_supported_opcodes_one *)buf;
8371 * If we don't have the full single opcode descriptor, no point in
8374 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8376 warnx("Only %u bytes returned, not enough to verify support",
8382 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8384 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8387 printf(", SA 0x%x", req_sa);
8390 switch (one->support & RSO_ONE_SUP_MASK) {
8391 case RSO_ONE_SUP_UNAVAIL:
8392 printf("No command support information currently available\n");
8394 case RSO_ONE_SUP_NOT_SUP:
8395 printf("Command not supported\n");
8398 break; /*NOTREACHED*/
8399 case RSO_ONE_SUP_AVAIL:
8400 printf("Command is supported, complies with a SCSI standard\n");
8402 case RSO_ONE_SUP_VENDOR:
8403 printf("Command is supported, vendor-specific "
8404 "implementation\n");
8407 printf("Unknown command support flags 0x%#x\n",
8408 one->support & RSO_ONE_SUP_MASK);
8413 * If we don't have the CDB length, it isn't exactly an error, the
8414 * command probably isn't supported.
8416 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8420 cdb_len = scsi_2btoul(one->cdb_length);
8423 * If our valid data doesn't include the full reported length,
8424 * return. The caller should have detected this and adjusted his
8425 * allocation length to get all of the available data.
8427 if (valid_len < sizeof(*one) + cdb_len) {
8433 * If all we have is the opcode, there is no point in printing out
8441 printf("CDB usage bitmap:");
8442 for (i = 0; i < cdb_len; i++) {
8443 printf(" %02x", one->cdb_usage[i]);
8448 * If we don't have a timeout descriptor, we're done.
8450 if ((one->support & RSO_ONE_CTDP) == 0)
8454 * If we don't have enough valid length to include the timeout
8455 * descriptor length, we're done.
8457 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8460 td = (struct scsi_report_supported_opcodes_timeout *)
8461 &buf[sizeof(*one) + cdb_len];
8462 td_len = scsi_2btoul(td->length);
8463 td_len += sizeof(td->length);
8466 * If we don't have the full timeout descriptor, we're done.
8468 if (td_len < sizeof(*td))
8472 * If we don't have enough valid length to contain the full timeout
8473 * descriptor, we're done.
8475 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8478 printf("Timeout information:\n");
8479 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8480 printf("Nominal timeout: %u seconds\n",
8481 scsi_4btoul(td->nominal_time));
8482 printf("Recommended timeout: %u seconds\n",
8483 scsi_4btoul(td->recommended_time));
8490 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8493 struct scsi_report_supported_opcodes_all *hdr;
8494 struct scsi_report_supported_opcodes_descr *desc;
8495 uint32_t avail_len = 0, used_len = 0;
8499 if (valid_len < sizeof(*hdr)) {
8500 warnx("%s: not enough returned data (%u bytes) opcode list",
8501 __func__, valid_len);
8505 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8506 avail_len = scsi_4btoul(hdr->length);
8507 avail_len += sizeof(hdr->length);
8509 * Take the lesser of the amount of data the drive claims is
8510 * available, and the amount of data the HBA says was returned.
8512 avail_len = MIN(avail_len, valid_len);
8514 used_len = sizeof(hdr->length);
8516 printf("%-6s %4s %8s ",
8517 "Opcode", "SA", "CDB len" );
8520 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8521 printf(" Description\n");
8523 while ((avail_len - used_len) > sizeof(*desc)) {
8524 struct scsi_report_supported_opcodes_timeout *td;
8526 const char *op_desc = NULL;
8528 cur_ptr = &buf[used_len];
8529 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8531 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8532 if (op_desc == NULL)
8533 op_desc = "UNKNOWN";
8535 printf("0x%02x %#4x %8u ", desc->opcode,
8536 scsi_2btoul(desc->service_action),
8537 scsi_2btoul(desc->cdb_length));
8539 used_len += sizeof(*desc);
8541 if ((desc->flags & RSO_CTDP) == 0) {
8542 printf(" %s\n", op_desc);
8547 * If we don't have enough space to fit a timeout
8548 * descriptor, then we're done.
8550 if (avail_len - used_len < sizeof(*td)) {
8551 used_len = avail_len;
8552 printf(" %s\n", op_desc);
8555 cur_ptr = &buf[used_len];
8556 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8557 td_len = scsi_2btoul(td->length);
8558 td_len += sizeof(td->length);
8562 * If the given timeout descriptor length is less than what
8563 * we understand, skip it.
8565 if (td_len < sizeof(*td)) {
8566 printf(" %s\n", op_desc);
8570 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8571 scsi_4btoul(td->nominal_time),
8572 scsi_4btoul(td->recommended_time), op_desc);
8579 scsiopcodes(struct cam_device *device, int argc, char **argv,
8580 char *combinedopt, int retry_count, int timeout, int verbosemode)
8583 uint32_t opcode = 0, service_action = 0;
8584 int td_set = 0, opcode_set = 0, sa_set = 0;
8585 int show_sa_errors = 1;
8586 uint32_t valid_len = 0;
8587 uint8_t *buf = NULL;
8591 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8597 opcode = strtoul(optarg, &endptr, 0);
8598 if (*endptr != '\0') {
8599 warnx("Invalid opcode \"%s\", must be a number",
8604 if (opcode > 0xff) {
8605 warnx("Invalid opcode 0x%#x, must be between"
8606 "0 and 0xff inclusive", opcode);
8613 service_action = strtoul(optarg, &endptr, 0);
8614 if (*endptr != '\0') {
8615 warnx("Invalid service action \"%s\", must "
8616 "be a number", optarg);
8620 if (service_action > 0xffff) {
8621 warnx("Invalid service action 0x%#x, must "
8622 "be between 0 and 0xffff inclusive",
8637 && (opcode_set == 0)) {
8638 warnx("You must specify an opcode with -o if a service "
8643 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8644 sa_set, service_action, td_set, retry_count,
8645 timeout, verbosemode, &valid_len, &buf);
8649 if ((opcode_set != 0)
8651 retval = scsiprintoneopcode(device, opcode, sa_set,
8652 service_action, buf, valid_len);
8654 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8663 #endif /* MINIMALISTIC */
8666 usage(int printlong)
8669 fprintf(printlong ? stdout : stderr,
8670 "usage: camcontrol <command> [device id][generic args][command args]\n"
8671 " camcontrol devlist [-b] [-v]\n"
8672 #ifndef MINIMALISTIC
8673 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8674 " camcontrol tur [dev_id][generic args]\n"
8675 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8676 " camcontrol identify [dev_id][generic args] [-v]\n"
8677 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8678 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8680 " camcontrol start [dev_id][generic args]\n"
8681 " camcontrol stop [dev_id][generic args]\n"
8682 " camcontrol load [dev_id][generic args]\n"
8683 " camcontrol eject [dev_id][generic args]\n"
8684 #endif /* MINIMALISTIC */
8685 " camcontrol rescan <all | bus[:target:lun]>\n"
8686 " camcontrol reset <all | bus[:target:lun]>\n"
8687 #ifndef MINIMALISTIC
8688 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8689 " [-q][-s][-S offset][-X]\n"
8690 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8691 " [-P pagectl][-e | -b][-d]\n"
8692 " camcontrol cmd [dev_id][generic args]\n"
8693 " <-a cmd [args] | -c cmd [args]>\n"
8694 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8695 " camcontrol smpcmd [dev_id][generic args]\n"
8696 " <-r len fmt [args]> <-R len fmt [args]>\n"
8697 " camcontrol smprg [dev_id][generic args][-l]\n"
8698 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8699 " [-o operation][-d name][-m rate][-M rate]\n"
8700 " [-T pp_timeout][-a enable|disable]\n"
8701 " [-A enable|disable][-s enable|disable]\n"
8702 " [-S enable|disable]\n"
8703 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8704 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8705 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8706 " <all|bus[:target[:lun]]|off>\n"
8707 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8708 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8709 " [-D <enable|disable>][-M mode][-O offset]\n"
8710 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8711 " [-U][-W bus_width]\n"
8712 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8713 " camcontrol sanitize [dev_id][generic args]\n"
8714 " [-a overwrite|block|crypto|exitfailure]\n"
8715 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8717 " camcontrol idle [dev_id][generic args][-t time]\n"
8718 " camcontrol standby [dev_id][generic args][-t time]\n"
8719 " camcontrol sleep [dev_id][generic args]\n"
8720 " camcontrol apm [dev_id][generic args][-l level]\n"
8721 " camcontrol aam [dev_id][generic args][-l level]\n"
8722 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8724 " camcontrol security [dev_id][generic args]\n"
8725 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8726 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8727 " [-U <user|master>] [-y]\n"
8728 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8729 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8730 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8731 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8732 " [-s scope][-S][-T type][-U]\n"
8733 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8734 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8735 " [-p part][-s start][-T type][-V vol]\n"
8736 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8738 #endif /* MINIMALISTIC */
8739 " camcontrol help\n");
8742 #ifndef MINIMALISTIC
8744 "Specify one of the following options:\n"
8745 "devlist list all CAM devices\n"
8746 "periphlist list all CAM peripheral drivers attached to a device\n"
8747 "tur send a test unit ready to the named device\n"
8748 "inquiry send a SCSI inquiry command to the named device\n"
8749 "identify send a ATA identify command to the named device\n"
8750 "reportluns send a SCSI report luns command to the device\n"
8751 "readcap send a SCSI read capacity command to the device\n"
8752 "start send a Start Unit command to the device\n"
8753 "stop send a Stop Unit command to the device\n"
8754 "load send a Start Unit command to the device with the load bit set\n"
8755 "eject send a Stop Unit command to the device with the eject bit set\n"
8756 "rescan rescan all busses, the given bus, or bus:target:lun\n"
8757 "reset reset all busses, the given bus, or bus:target:lun\n"
8758 "defects read the defect list of the specified device\n"
8759 "modepage display or edit (-e) the given mode page\n"
8760 "cmd send the given SCSI command, may need -i or -o as well\n"
8761 "smpcmd send the given SMP command, requires -o and -i\n"
8762 "smprg send the SMP Report General command\n"
8763 "smppc send the SMP PHY Control command, requires -p\n"
8764 "smpphylist display phys attached to a SAS expander\n"
8765 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8766 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8767 "tags report or set the number of transaction slots for a device\n"
8768 "negotiate report or set device negotiation parameters\n"
8769 "format send the SCSI FORMAT UNIT command to the named device\n"
8770 "sanitize send the SCSI SANITIZE command to the named device\n"
8771 "idle send the ATA IDLE command to the named device\n"
8772 "standby send the ATA STANDBY command to the named device\n"
8773 "sleep send the ATA SLEEP command to the named device\n"
8774 "fwdownload program firmware of the named device with the given image\n"
8775 "security report or send ATA security commands to the named device\n"
8776 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8777 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8778 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8779 "help this message\n"
8780 "Device Identifiers:\n"
8781 "bus:target specify the bus and target, lun defaults to 0\n"
8782 "bus:target:lun specify the bus, target and lun\n"
8783 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8784 "Generic arguments:\n"
8785 "-v be verbose, print out sense information\n"
8786 "-t timeout command timeout in seconds, overrides default timeout\n"
8787 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8788 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8789 "-E have the kernel attempt to perform SCSI error recovery\n"
8790 "-C count specify the SCSI command retry count (needs -E to work)\n"
8791 "modepage arguments:\n"
8792 "-l list all available mode pages\n"
8793 "-m page specify the mode page to view or edit\n"
8794 "-e edit the specified mode page\n"
8795 "-b force view to binary mode\n"
8796 "-d disable block descriptors for mode sense\n"
8797 "-P pgctl page control field 0-3\n"
8798 "defects arguments:\n"
8799 "-f format specify defect list format (block, bfi or phys)\n"
8800 "-G get the grown defect list\n"
8801 "-P get the permanent defect list\n"
8802 "inquiry arguments:\n"
8803 "-D get the standard inquiry data\n"
8804 "-S get the serial number\n"
8805 "-R get the transfer rate, etc.\n"
8806 "reportluns arguments:\n"
8807 "-c only report a count of available LUNs\n"
8808 "-l only print out luns, and not a count\n"
8809 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
8810 "readcap arguments\n"
8811 "-b only report the blocksize\n"
8812 "-h human readable device size, base 2\n"
8813 "-H human readable device size, base 10\n"
8814 "-N print the number of blocks instead of last block\n"
8815 "-q quiet, print numbers only\n"
8816 "-s only report the last block/device size\n"
8818 "-c cdb [args] specify the SCSI CDB\n"
8819 "-i len fmt specify input data and input data format\n"
8820 "-o len fmt [args] specify output data and output data fmt\n"
8821 "smpcmd arguments:\n"
8822 "-r len fmt [args] specify the SMP command to be sent\n"
8823 "-R len fmt [args] specify SMP response format\n"
8824 "smprg arguments:\n"
8825 "-l specify the long response format\n"
8826 "smppc arguments:\n"
8827 "-p phy specify the PHY to operate on\n"
8828 "-l specify the long request/response format\n"
8829 "-o operation specify the phy control operation\n"
8830 "-d name set the attached device name\n"
8831 "-m rate set the minimum physical link rate\n"
8832 "-M rate set the maximum physical link rate\n"
8833 "-T pp_timeout set the partial pathway timeout value\n"
8834 "-a enable|disable enable or disable SATA slumber\n"
8835 "-A enable|disable enable or disable SATA partial phy power\n"
8836 "-s enable|disable enable or disable SAS slumber\n"
8837 "-S enable|disable enable or disable SAS partial phy power\n"
8838 "smpphylist arguments:\n"
8839 "-l specify the long response format\n"
8840 "-q only print phys with attached devices\n"
8841 "smpmaninfo arguments:\n"
8842 "-l specify the long response format\n"
8843 "debug arguments:\n"
8844 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
8845 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
8846 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
8847 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
8849 "-N tags specify the number of tags to use for this device\n"
8850 "-q be quiet, don't report the number of tags\n"
8851 "-v report a number of tag-related parameters\n"
8852 "negotiate arguments:\n"
8853 "-a send a test unit ready after negotiation\n"
8854 "-c report/set current negotiation settings\n"
8855 "-D <arg> \"enable\" or \"disable\" disconnection\n"
8856 "-M mode set ATA mode\n"
8857 "-O offset set command delay offset\n"
8858 "-q be quiet, don't report anything\n"
8859 "-R syncrate synchronization rate in MHz\n"
8860 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
8861 "-U report/set user negotiation settings\n"
8862 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
8863 "-v also print a Path Inquiry CCB for the controller\n"
8864 "format arguments:\n"
8865 "-q be quiet, don't print status messages\n"
8866 "-r run in report only mode\n"
8867 "-w don't send immediate format command\n"
8868 "-y don't ask any questions\n"
8869 "sanitize arguments:\n"
8870 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
8871 "-c passes overwrite passes to perform (1 to 31)\n"
8872 "-I invert overwrite pattern after each pass\n"
8873 "-P pattern path to overwrite pattern file\n"
8874 "-q be quiet, don't print status messages\n"
8875 "-r run in report only mode\n"
8876 "-U run operation in unrestricted completion exit mode\n"
8877 "-w don't send immediate sanitize command\n"
8878 "-y don't ask any questions\n"
8879 "idle/standby arguments:\n"
8880 "-t <arg> number of seconds before respective state.\n"
8881 "fwdownload arguments:\n"
8882 "-f fw_image path to firmware image file\n"
8883 "-q don't print informational messages, only errors\n"
8884 "-s run in simulation mode\n"
8885 "-v print info for every firmware segment sent to device\n"
8886 "-y don't ask any questions\n"
8887 "security arguments:\n"
8888 "-d pwd disable security using the given password for the selected\n"
8890 "-e pwd erase the device using the given pwd for the selected user\n"
8891 "-f freeze the security configuration of the specified device\n"
8892 "-h pwd enhanced erase the device using the given pwd for the\n"
8894 "-k pwd unlock the device using the given pwd for the selected\n"
8896 "-l <high|maximum> specifies which security level to set: high or maximum\n"
8897 "-q be quiet, do not print any status messages\n"
8898 "-s pwd password the device (enable security) using the given\n"
8899 " pwd for the selected user\n"
8900 "-T timeout overrides the timeout (seconds) used for erase operation\n"
8901 "-U <user|master> specifies which user to set: user or master\n"
8902 "-y don't ask any questions\n"
8904 "-f freeze the HPA configuration of the device\n"
8905 "-l lock the HPA configuration of the device\n"
8906 "-P make the HPA max sectors persist\n"
8907 "-p pwd Set the HPA configuration password required for unlock\n"
8909 "-q be quiet, do not print any status messages\n"
8910 "-s sectors configures the maximum user accessible sectors of the\n"
8912 "-U pwd unlock the HPA configuration of the device\n"
8913 "-y don't ask any questions\n"
8914 "persist arguments:\n"
8915 "-i action specify read_keys, read_reservation, report_cap, or\n"
8916 " read_full_status\n"
8917 "-o action specify register, register_ignore, reserve, release,\n"
8918 " clear, preempt, preempt_abort, register_move, replace_lost\n"
8919 "-a set the All Target Ports (ALL_TG_PT) bit\n"
8920 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
8921 "-k key specify the Reservation Key\n"
8922 "-K sa_key specify the Service Action Reservation Key\n"
8923 "-p set the Activate Persist Through Power Loss bit\n"
8924 "-R rtp specify the Relative Target Port\n"
8925 "-s scope specify the scope: lun, extent, element or a number\n"
8926 "-S specify Transport ID for register, requires -I\n"
8927 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
8928 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
8929 "-U unregister the current initiator for register_move\n"
8930 "attrib arguments:\n"
8931 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
8933 "-w attr specify an attribute to write, one -w argument per attr\n"
8934 "-a attr_num only display this attribute number\n"
8935 "-c get cached attributes\n"
8936 "-e elem_addr request attributes for the given element in a changer\n"
8937 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
8938 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
8939 " field_none, field_desc, field_num, field_size, field_rw\n"
8940 "-p partition request attributes for the given partition\n"
8941 "-s start_attr request attributes starting at the given number\n"
8942 "-T elem_type specify the element type (used with -e)\n"
8943 "-V logical_vol specify the logical volume ID\n"
8944 "opcodes arguments:\n"
8945 "-o opcode specify the individual opcode to list\n"
8946 "-s service_action specify the service action for the opcode\n"
8947 "-N do not return SCSI error for unsupported SA\n"
8948 "-T request nominal and recommended timeout values\n"
8950 #endif /* MINIMALISTIC */
8954 main(int argc, char **argv)
8957 char *device = NULL;
8959 struct cam_device *cam_dev = NULL;
8960 int timeout = 0, retry_count = 1;
8961 camcontrol_optret optreturn;
8963 const char *mainopt = "C:En:t:u:v";
8964 const char *subopt = NULL;
8965 char combinedopt[256];
8966 int error = 0, optstart = 2;
8968 #ifndef MINIMALISTIC
8972 #endif /* MINIMALISTIC */
8974 cmdlist = CAM_CMD_NONE;
8975 arglist = CAM_ARG_NONE;
8983 * Get the base option.
8985 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
8987 if (optreturn == CC_OR_AMBIGUOUS) {
8988 warnx("ambiguous option %s", argv[1]);
8991 } else if (optreturn == CC_OR_NOT_FOUND) {
8992 warnx("option %s not found", argv[1]);
8998 * Ahh, getopt(3) is a pain.
9000 * This is a gross hack. There really aren't many other good
9001 * options (excuse the pun) for parsing options in a situation like
9002 * this. getopt is kinda braindead, so you end up having to run
9003 * through the options twice, and give each invocation of getopt
9004 * the option string for the other invocation.
9006 * You would think that you could just have two groups of options.
9007 * The first group would get parsed by the first invocation of
9008 * getopt, and the second group would get parsed by the second
9009 * invocation of getopt. It doesn't quite work out that way. When
9010 * the first invocation of getopt finishes, it leaves optind pointing
9011 * to the argument _after_ the first argument in the second group.
9012 * So when the second invocation of getopt comes around, it doesn't
9013 * recognize the first argument it gets and then bails out.
9015 * A nice alternative would be to have a flag for getopt that says
9016 * "just keep parsing arguments even when you encounter an unknown
9017 * argument", but there isn't one. So there's no real clean way to
9018 * easily parse two sets of arguments without having one invocation
9019 * of getopt know about the other.
9021 * Without this hack, the first invocation of getopt would work as
9022 * long as the generic arguments are first, but the second invocation
9023 * (in the subfunction) would fail in one of two ways. In the case
9024 * where you don't set optreset, it would fail because optind may be
9025 * pointing to the argument after the one it should be pointing at.
9026 * In the case where you do set optreset, and reset optind, it would
9027 * fail because getopt would run into the first set of options, which
9028 * it doesn't understand.
9030 * All of this would "sort of" work if you could somehow figure out
9031 * whether optind had been incremented one option too far. The
9032 * mechanics of that, however, are more daunting than just giving
9033 * both invocations all of the expect options for either invocation.
9035 * Needless to say, I wouldn't mind if someone invented a better
9036 * (non-GPL!) command line parsing interface than getopt. I
9037 * wouldn't mind if someone added more knobs to getopt to make it
9038 * work better. Who knows, I may talk myself into doing it someday,
9039 * if the standards weenies let me. As it is, it just leads to
9040 * hackery like this and causes people to avoid it in some cases.
9042 * KDM, September 8th, 1998
9045 sprintf(combinedopt, "%s%s", mainopt, subopt);
9047 sprintf(combinedopt, "%s", mainopt);
9050 * For these options we do not parse optional device arguments and
9051 * we do not open a passthrough device.
9053 if ((cmdlist == CAM_CMD_RESCAN)
9054 || (cmdlist == CAM_CMD_RESET)
9055 || (cmdlist == CAM_CMD_DEVTREE)
9056 || (cmdlist == CAM_CMD_USAGE)
9057 || (cmdlist == CAM_CMD_DEBUG))
9060 #ifndef MINIMALISTIC
9062 && (argc > 2 && argv[2][0] != '-')) {
9066 if (isdigit(argv[2][0])) {
9067 /* device specified as bus:target[:lun] */
9068 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9070 errx(1, "numeric device specification must "
9071 "be either bus:target, or "
9073 /* default to 0 if lun was not specified */
9074 if ((arglist & CAM_ARG_LUN) == 0) {
9076 arglist |= CAM_ARG_LUN;
9080 if (cam_get_device(argv[2], name, sizeof name, &unit)
9082 errx(1, "%s", cam_errbuf);
9083 device = strdup(name);
9084 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9088 #endif /* MINIMALISTIC */
9090 * Start getopt processing at argv[2/3], since we've already
9091 * accepted argv[1..2] as the command name, and as a possible
9097 * Now we run through the argument list looking for generic
9098 * options, and ignoring options that possibly belong to
9101 while ((c = getopt(argc, argv, combinedopt))!= -1){
9104 retry_count = strtol(optarg, NULL, 0);
9105 if (retry_count < 0)
9106 errx(1, "retry count %d is < 0",
9108 arglist |= CAM_ARG_RETRIES;
9111 arglist |= CAM_ARG_ERR_RECOVER;
9114 arglist |= CAM_ARG_DEVICE;
9116 while (isspace(*tstr) && (*tstr != '\0'))
9118 device = (char *)strdup(tstr);
9121 timeout = strtol(optarg, NULL, 0);
9123 errx(1, "invalid timeout %d", timeout);
9124 /* Convert the timeout from seconds to ms */
9126 arglist |= CAM_ARG_TIMEOUT;
9129 arglist |= CAM_ARG_UNIT;
9130 unit = strtol(optarg, NULL, 0);
9133 arglist |= CAM_ARG_VERBOSE;
9140 #ifndef MINIMALISTIC
9142 * For most commands we'll want to open the passthrough device
9143 * associated with the specified device. In the case of the rescan
9144 * commands, we don't use a passthrough device at all, just the
9145 * transport layer device.
9148 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9149 && (((arglist & CAM_ARG_DEVICE) == 0)
9150 || ((arglist & CAM_ARG_UNIT) == 0))) {
9151 errx(1, "subcommand \"%s\" requires a valid device "
9152 "identifier", argv[1]);
9155 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9156 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9157 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9159 errx(1,"%s", cam_errbuf);
9161 #endif /* MINIMALISTIC */
9164 * Reset optind to 2, and reset getopt, so these routines can parse
9165 * the arguments again.
9171 #ifndef MINIMALISTIC
9172 case CAM_CMD_DEVLIST:
9173 error = getdevlist(cam_dev);
9176 error = atahpa(cam_dev, retry_count, timeout,
9177 argc, argv, combinedopt);
9179 #endif /* MINIMALISTIC */
9180 case CAM_CMD_DEVTREE:
9181 error = getdevtree(argc, argv, combinedopt);
9183 #ifndef MINIMALISTIC
9185 error = testunitready(cam_dev, retry_count, timeout, 0);
9187 case CAM_CMD_INQUIRY:
9188 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9189 retry_count, timeout);
9191 case CAM_CMD_IDENTIFY:
9192 error = ataidentify(cam_dev, retry_count, timeout);
9194 case CAM_CMD_STARTSTOP:
9195 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9196 arglist & CAM_ARG_EJECT, retry_count,
9199 #endif /* MINIMALISTIC */
9200 case CAM_CMD_RESCAN:
9201 error = dorescan_or_reset(argc, argv, 1);
9204 error = dorescan_or_reset(argc, argv, 0);
9206 #ifndef MINIMALISTIC
9207 case CAM_CMD_READ_DEFECTS:
9208 error = readdefects(cam_dev, argc, argv, combinedopt,
9209 retry_count, timeout);
9211 case CAM_CMD_MODE_PAGE:
9212 modepage(cam_dev, argc, argv, combinedopt,
9213 retry_count, timeout);
9215 case CAM_CMD_SCSI_CMD:
9216 error = scsicmd(cam_dev, argc, argv, combinedopt,
9217 retry_count, timeout);
9219 case CAM_CMD_SMP_CMD:
9220 error = smpcmd(cam_dev, argc, argv, combinedopt,
9221 retry_count, timeout);
9223 case CAM_CMD_SMP_RG:
9224 error = smpreportgeneral(cam_dev, argc, argv,
9225 combinedopt, retry_count,
9228 case CAM_CMD_SMP_PC:
9229 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9230 retry_count, timeout);
9232 case CAM_CMD_SMP_PHYLIST:
9233 error = smpphylist(cam_dev, argc, argv, combinedopt,
9234 retry_count, timeout);
9236 case CAM_CMD_SMP_MANINFO:
9237 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9238 retry_count, timeout);
9241 error = camdebug(argc, argv, combinedopt);
9244 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9247 error = ratecontrol(cam_dev, retry_count, timeout,
9248 argc, argv, combinedopt);
9250 case CAM_CMD_FORMAT:
9251 error = scsiformat(cam_dev, argc, argv,
9252 combinedopt, retry_count, timeout);
9254 case CAM_CMD_REPORTLUNS:
9255 error = scsireportluns(cam_dev, argc, argv,
9256 combinedopt, retry_count,
9259 case CAM_CMD_READCAP:
9260 error = scsireadcapacity(cam_dev, argc, argv,
9261 combinedopt, retry_count,
9265 case CAM_CMD_STANDBY:
9267 error = atapm(cam_dev, argc, argv,
9268 combinedopt, retry_count, timeout);
9272 error = ataaxm(cam_dev, argc, argv,
9273 combinedopt, retry_count, timeout);
9275 case CAM_CMD_SECURITY:
9276 error = atasecurity(cam_dev, retry_count, timeout,
9277 argc, argv, combinedopt);
9279 case CAM_CMD_DOWNLOAD_FW:
9280 error = fwdownload(cam_dev, argc, argv, combinedopt,
9281 arglist & CAM_ARG_VERBOSE, retry_count, timeout);
9283 case CAM_CMD_SANITIZE:
9284 error = scsisanitize(cam_dev, argc, argv,
9285 combinedopt, retry_count, timeout);
9287 case CAM_CMD_PERSIST:
9288 error = scsipersist(cam_dev, argc, argv, combinedopt,
9289 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9290 arglist & CAM_ARG_ERR_RECOVER);
9292 case CAM_CMD_ATTRIB:
9293 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9294 retry_count, timeout, arglist & CAM_ARG_VERBOSE,
9295 arglist & CAM_ARG_ERR_RECOVER);
9297 case CAM_CMD_OPCODES:
9298 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9299 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9301 #endif /* MINIMALISTIC */
9311 if (cam_dev != NULL)
9312 cam_close_device(cam_dev);