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,
102 CAM_ARG_NONE = 0x00000000,
103 CAM_ARG_VERBOSE = 0x00000001,
104 CAM_ARG_DEVICE = 0x00000002,
105 CAM_ARG_BUS = 0x00000004,
106 CAM_ARG_TARGET = 0x00000008,
107 CAM_ARG_LUN = 0x00000010,
108 CAM_ARG_EJECT = 0x00000020,
109 CAM_ARG_UNIT = 0x00000040,
110 CAM_ARG_FORMAT_BLOCK = 0x00000080,
111 CAM_ARG_FORMAT_BFI = 0x00000100,
112 CAM_ARG_FORMAT_PHYS = 0x00000200,
113 CAM_ARG_PLIST = 0x00000400,
114 CAM_ARG_GLIST = 0x00000800,
115 CAM_ARG_GET_SERIAL = 0x00001000,
116 CAM_ARG_GET_STDINQ = 0x00002000,
117 CAM_ARG_GET_XFERRATE = 0x00004000,
118 CAM_ARG_INQ_MASK = 0x00007000,
119 CAM_ARG_MODE_EDIT = 0x00008000,
120 CAM_ARG_PAGE_CNTL = 0x00010000,
121 CAM_ARG_TIMEOUT = 0x00020000,
122 CAM_ARG_CMD_IN = 0x00040000,
123 CAM_ARG_CMD_OUT = 0x00080000,
124 CAM_ARG_DBD = 0x00100000,
125 CAM_ARG_ERR_RECOVER = 0x00200000,
126 CAM_ARG_RETRIES = 0x00400000,
127 CAM_ARG_START_UNIT = 0x00800000,
128 CAM_ARG_DEBUG_INFO = 0x01000000,
129 CAM_ARG_DEBUG_TRACE = 0x02000000,
130 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
131 CAM_ARG_DEBUG_CDB = 0x08000000,
132 CAM_ARG_DEBUG_XPT = 0x10000000,
133 CAM_ARG_DEBUG_PERIPH = 0x20000000,
134 CAM_ARG_DEBUG_PROBE = 0x40000000,
137 struct camcontrol_opts {
145 struct ata_res_pass16 {
146 u_int16_t reserved[5];
149 u_int8_t sector_count_exp;
150 u_int8_t sector_count;
151 u_int8_t lba_low_exp;
153 u_int8_t lba_mid_exp;
155 u_int8_t lba_high_exp;
161 struct ata_set_max_pwd
164 u_int8_t password[32];
165 u_int16_t reserved2[239];
168 static const char scsicmd_opts[] = "a:c:dfi:o:r";
169 static const char readdefect_opts[] = "f:GP";
170 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
171 static const char smprg_opts[] = "l";
172 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
173 static const char smpphylist_opts[] = "lq";
177 static struct camcontrol_opts option_table[] = {
179 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
180 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
181 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
182 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
183 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
184 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
185 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
186 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
187 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
188 #endif /* MINIMALISTIC */
189 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
190 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
192 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
193 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
194 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
195 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
196 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
197 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
198 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
199 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
200 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
201 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
202 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
203 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
204 #endif /* MINIMALISTIC */
205 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL},
207 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
208 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
209 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
210 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
211 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
212 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
213 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
214 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
215 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
216 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
217 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
218 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:ys"},
219 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
220 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
221 #endif /* MINIMALISTIC */
222 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
223 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
224 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
235 struct device_match_result dev_match;
237 struct periph_match_result *periph_matches;
238 struct scsi_vpd_device_id *device_id;
240 STAILQ_ENTRY(cam_devitem) links;
244 STAILQ_HEAD(, cam_devitem) dev_queue;
248 static cam_cmdmask cmdlist;
249 static cam_argmask arglist;
251 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
252 uint32_t *cmdnum, cam_argmask *argnum,
253 const char **subopt);
255 static int getdevlist(struct cam_device *device);
256 #endif /* MINIMALISTIC */
257 static int getdevtree(void);
259 static int testunitready(struct cam_device *device, int retry_count,
260 int timeout, int quiet);
261 static int scsistart(struct cam_device *device, int startstop, int loadeject,
262 int retry_count, int timeout);
263 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
264 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
265 static int camxferrate(struct cam_device *device);
266 #endif /* MINIMALISTIC */
267 static int parse_btl(char *tstr, int *bus, int *target, int *lun,
268 cam_argmask *arglst);
269 static int dorescan_or_reset(int argc, char **argv, int rescan);
270 static int rescan_or_reset_bus(int bus, int rescan);
271 static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
273 static int readdefects(struct cam_device *device, int argc, char **argv,
274 char *combinedopt, int retry_count, int timeout);
275 static void modepage(struct cam_device *device, int argc, char **argv,
276 char *combinedopt, int retry_count, int timeout);
277 static int scsicmd(struct cam_device *device, int argc, char **argv,
278 char *combinedopt, int retry_count, int timeout);
279 static int smpcmd(struct cam_device *device, int argc, char **argv,
280 char *combinedopt, int retry_count, int timeout);
281 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
282 char *combinedopt, int retry_count, int timeout);
283 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
284 char *combinedopt, int retry_count, int timeout);
285 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
286 char *combinedopt, int retry_count, int timeout);
287 static int getdevid(struct cam_devitem *item);
288 static int buildbusdevlist(struct cam_devlist *devlist);
289 static void freebusdevlist(struct cam_devlist *devlist);
290 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
292 static int smpphylist(struct cam_device *device, int argc, char **argv,
293 char *combinedopt, int retry_count, int timeout);
294 static int tagcontrol(struct cam_device *device, int argc, char **argv,
296 static void cts_print(struct cam_device *device,
297 struct ccb_trans_settings *cts);
298 static void cpi_print(struct ccb_pathinq *cpi);
299 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
300 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
301 static int get_print_cts(struct cam_device *device, int user_settings,
302 int quiet, struct ccb_trans_settings *cts);
303 static int ratecontrol(struct cam_device *device, int retry_count,
304 int timeout, int argc, char **argv, char *combinedopt);
305 static int scsiformat(struct cam_device *device, int argc, char **argv,
306 char *combinedopt, int retry_count, int timeout);
307 static int scsisanitize(struct cam_device *device, int argc, char **argv,
308 char *combinedopt, int retry_count, int timeout);
309 static int scsireportluns(struct cam_device *device, int argc, char **argv,
310 char *combinedopt, int retry_count, int timeout);
311 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
312 char *combinedopt, int retry_count, int timeout);
313 static int atapm(struct cam_device *device, int argc, char **argv,
314 char *combinedopt, int retry_count, int timeout);
315 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
316 int argc, char **argv, char *combinedopt);
317 static int atahpa(struct cam_device *device, int retry_count, int timeout,
318 int argc, char **argv, char *combinedopt);
320 #endif /* MINIMALISTIC */
322 #define min(a,b) (((a)<(b))?(a):(b))
325 #define max(a,b) (((a)>(b))?(a):(b))
329 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
330 cam_argmask *argnum, const char **subopt)
332 struct camcontrol_opts *opts;
335 for (opts = table; (opts != NULL) && (opts->optname != NULL);
337 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
338 *cmdnum = opts->cmdnum;
339 *argnum = opts->argnum;
340 *subopt = opts->subopt;
341 if (++num_matches > 1)
342 return(CC_OR_AMBIGUOUS);
349 return(CC_OR_NOT_FOUND);
354 getdevlist(struct cam_device *device)
360 ccb = cam_getccb(device);
362 ccb->ccb_h.func_code = XPT_GDEVLIST;
363 ccb->ccb_h.flags = CAM_DIR_NONE;
364 ccb->ccb_h.retry_count = 1;
366 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
367 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
368 if (cam_send_ccb(device, ccb) < 0) {
369 perror("error getting device list");
376 switch (ccb->cgdl.status) {
377 case CAM_GDEVLIST_MORE_DEVS:
378 strcpy(status, "MORE");
380 case CAM_GDEVLIST_LAST_DEVICE:
381 strcpy(status, "LAST");
383 case CAM_GDEVLIST_LIST_CHANGED:
384 strcpy(status, "CHANGED");
386 case CAM_GDEVLIST_ERROR:
387 strcpy(status, "ERROR");
392 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
393 ccb->cgdl.periph_name,
394 ccb->cgdl.unit_number,
395 ccb->cgdl.generation,
400 * If the list has changed, we need to start over from the
403 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
411 #endif /* MINIMALISTIC */
423 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
424 warn("couldn't open %s", XPT_DEVICE);
428 bzero(&ccb, sizeof(union ccb));
430 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
431 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
432 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
434 ccb.ccb_h.func_code = XPT_DEV_MATCH;
435 bufsize = sizeof(struct dev_match_result) * 100;
436 ccb.cdm.match_buf_len = bufsize;
437 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
438 if (ccb.cdm.matches == NULL) {
439 warnx("can't malloc memory for matches");
443 ccb.cdm.num_matches = 0;
446 * We fetch all nodes, since we display most of them in the default
447 * case, and all in the verbose case.
449 ccb.cdm.num_patterns = 0;
450 ccb.cdm.pattern_buf_len = 0;
453 * We do the ioctl multiple times if necessary, in case there are
454 * more than 100 nodes in the EDT.
457 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
458 warn("error sending CAMIOCOMMAND ioctl");
463 if ((ccb.ccb_h.status != CAM_REQ_CMP)
464 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
465 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
466 warnx("got CAM error %#x, CDM error %d\n",
467 ccb.ccb_h.status, ccb.cdm.status);
472 for (i = 0; i < ccb.cdm.num_matches; i++) {
473 switch (ccb.cdm.matches[i].type) {
474 case DEV_MATCH_BUS: {
475 struct bus_match_result *bus_result;
478 * Only print the bus information if the
479 * user turns on the verbose flag.
481 if ((arglist & CAM_ARG_VERBOSE) == 0)
485 &ccb.cdm.matches[i].result.bus_result;
488 fprintf(stdout, ")\n");
492 fprintf(stdout, "scbus%d on %s%d bus %d:\n",
494 bus_result->dev_name,
495 bus_result->unit_number,
499 case DEV_MATCH_DEVICE: {
500 struct device_match_result *dev_result;
501 char vendor[16], product[48], revision[16];
502 char fw[5], tmpstr[256];
505 &ccb.cdm.matches[i].result.device_result;
507 if ((dev_result->flags
508 & DEV_RESULT_UNCONFIGURED)
509 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
515 if (dev_result->protocol == PROTO_SCSI) {
516 cam_strvis(vendor, dev_result->inq_data.vendor,
517 sizeof(dev_result->inq_data.vendor),
520 dev_result->inq_data.product,
521 sizeof(dev_result->inq_data.product),
524 dev_result->inq_data.revision,
525 sizeof(dev_result->inq_data.revision),
527 sprintf(tmpstr, "<%s %s %s>", vendor, product,
529 } else if (dev_result->protocol == PROTO_ATA ||
530 dev_result->protocol == PROTO_SATAPM) {
532 dev_result->ident_data.model,
533 sizeof(dev_result->ident_data.model),
536 dev_result->ident_data.revision,
537 sizeof(dev_result->ident_data.revision),
539 sprintf(tmpstr, "<%s %s>", product,
541 } else if (dev_result->protocol == PROTO_SEMB) {
542 struct sep_identify_data *sid;
544 sid = (struct sep_identify_data *)
545 &dev_result->ident_data;
546 cam_strvis(vendor, sid->vendor_id,
547 sizeof(sid->vendor_id),
549 cam_strvis(product, sid->product_id,
550 sizeof(sid->product_id),
552 cam_strvis(revision, sid->product_rev,
553 sizeof(sid->product_rev),
555 cam_strvis(fw, sid->firmware_rev,
556 sizeof(sid->firmware_rev),
558 sprintf(tmpstr, "<%s %s %s %s>",
559 vendor, product, revision, fw);
561 sprintf(tmpstr, "<>");
564 fprintf(stdout, ")\n");
568 fprintf(stdout, "%-33s at scbus%d "
569 "target %d lun %d (",
572 dev_result->target_id,
573 dev_result->target_lun);
579 case DEV_MATCH_PERIPH: {
580 struct periph_match_result *periph_result;
583 &ccb.cdm.matches[i].result.periph_result;
585 if (skip_device != 0)
589 fprintf(stdout, ",");
591 fprintf(stdout, "%s%d",
592 periph_result->periph_name,
593 periph_result->unit_number);
599 fprintf(stdout, "unknown match type\n");
604 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
605 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
608 fprintf(stdout, ")\n");
617 testunitready(struct cam_device *device, int retry_count, int timeout,
623 ccb = cam_getccb(device);
625 scsi_test_unit_ready(&ccb->csio,
626 /* retries */ retry_count,
628 /* tag_action */ MSG_SIMPLE_Q_TAG,
629 /* sense_len */ SSD_FULL_SIZE,
630 /* timeout */ timeout ? timeout : 5000);
632 /* Disable freezing the device queue */
633 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
635 if (arglist & CAM_ARG_ERR_RECOVER)
636 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
638 if (cam_send_ccb(device, ccb) < 0) {
640 perror("error sending test unit ready");
642 if (arglist & CAM_ARG_VERBOSE) {
643 cam_error_print(device, ccb, CAM_ESF_ALL,
644 CAM_EPF_ALL, stderr);
651 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
653 fprintf(stdout, "Unit is ready\n");
656 fprintf(stdout, "Unit is not ready\n");
659 if (arglist & CAM_ARG_VERBOSE) {
660 cam_error_print(device, ccb, CAM_ESF_ALL,
661 CAM_EPF_ALL, stderr);
671 scsistart(struct cam_device *device, int startstop, int loadeject,
672 int retry_count, int timeout)
677 ccb = cam_getccb(device);
680 * If we're stopping, send an ordered tag so the drive in question
681 * will finish any previously queued writes before stopping. If
682 * the device isn't capable of tagged queueing, or if tagged
683 * queueing is turned off, the tag action is a no-op.
685 scsi_start_stop(&ccb->csio,
686 /* retries */ retry_count,
688 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
690 /* start/stop */ startstop,
691 /* load_eject */ loadeject,
693 /* sense_len */ SSD_FULL_SIZE,
694 /* timeout */ timeout ? timeout : 120000);
696 /* Disable freezing the device queue */
697 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
699 if (arglist & CAM_ARG_ERR_RECOVER)
700 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
702 if (cam_send_ccb(device, ccb) < 0) {
703 perror("error sending start unit");
705 if (arglist & CAM_ARG_VERBOSE) {
706 cam_error_print(device, ccb, CAM_ESF_ALL,
707 CAM_EPF_ALL, stderr);
714 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
716 fprintf(stdout, "Unit started successfully");
718 fprintf(stdout,", Media loaded\n");
720 fprintf(stdout,"\n");
722 fprintf(stdout, "Unit stopped successfully");
724 fprintf(stdout, ", Media ejected\n");
726 fprintf(stdout, "\n");
732 "Error received from start unit command\n");
735 "Error received from stop unit command\n");
737 if (arglist & CAM_ARG_VERBOSE) {
738 cam_error_print(device, ccb, CAM_ESF_ALL,
739 CAM_EPF_ALL, stderr);
749 scsidoinquiry(struct cam_device *device, int argc, char **argv,
750 char *combinedopt, int retry_count, int timeout)
755 while ((c = getopt(argc, argv, combinedopt)) != -1) {
758 arglist |= CAM_ARG_GET_STDINQ;
761 arglist |= CAM_ARG_GET_XFERRATE;
764 arglist |= CAM_ARG_GET_SERIAL;
772 * If the user didn't specify any inquiry options, he wants all of
775 if ((arglist & CAM_ARG_INQ_MASK) == 0)
776 arglist |= CAM_ARG_INQ_MASK;
778 if (arglist & CAM_ARG_GET_STDINQ)
779 error = scsiinquiry(device, retry_count, timeout);
784 if (arglist & CAM_ARG_GET_SERIAL)
785 scsiserial(device, retry_count, timeout);
790 if (arglist & CAM_ARG_GET_XFERRATE)
791 error = camxferrate(device);
797 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
800 struct scsi_inquiry_data *inq_buf;
803 ccb = cam_getccb(device);
806 warnx("couldn't allocate CCB");
810 /* cam_getccb cleans up the header, caller has to zero the payload */
811 bzero(&(&ccb->ccb_h)[1],
812 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
814 inq_buf = (struct scsi_inquiry_data *)malloc(
815 sizeof(struct scsi_inquiry_data));
817 if (inq_buf == NULL) {
819 warnx("can't malloc memory for inquiry\n");
822 bzero(inq_buf, sizeof(*inq_buf));
825 * Note that although the size of the inquiry buffer is the full
826 * 256 bytes specified in the SCSI spec, we only tell the device
827 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
828 * two reasons for this:
830 * - The SCSI spec says that when a length field is only 1 byte,
831 * a value of 0 will be interpreted as 256. Therefore
832 * scsi_inquiry() will convert an inq_len (which is passed in as
833 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
834 * to 0. Evidently, very few devices meet the spec in that
835 * regard. Some devices, like many Seagate disks, take the 0 as
836 * 0, and don't return any data. One Pioneer DVD-R drive
837 * returns more data than the command asked for.
839 * So, since there are numerous devices that just don't work
840 * right with the full inquiry size, we don't send the full size.
842 * - The second reason not to use the full inquiry data length is
843 * that we don't need it here. The only reason we issue a
844 * standard inquiry is to get the vendor name, device name,
845 * and revision so scsi_print_inquiry() can print them.
847 * If, at some point in the future, more inquiry data is needed for
848 * some reason, this code should use a procedure similar to the
849 * probe code. i.e., issue a short inquiry, and determine from
850 * the additional length passed back from the device how much
851 * inquiry data the device supports. Once the amount the device
852 * supports is determined, issue an inquiry for that amount and no
857 scsi_inquiry(&ccb->csio,
858 /* retries */ retry_count,
860 /* tag_action */ MSG_SIMPLE_Q_TAG,
861 /* inq_buf */ (u_int8_t *)inq_buf,
862 /* inq_len */ SHORT_INQUIRY_LENGTH,
865 /* sense_len */ SSD_FULL_SIZE,
866 /* timeout */ timeout ? timeout : 5000);
868 /* Disable freezing the device queue */
869 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
871 if (arglist & CAM_ARG_ERR_RECOVER)
872 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
874 if (cam_send_ccb(device, ccb) < 0) {
875 perror("error sending SCSI inquiry");
877 if (arglist & CAM_ARG_VERBOSE) {
878 cam_error_print(device, ccb, CAM_ESF_ALL,
879 CAM_EPF_ALL, stderr);
886 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
889 if (arglist & CAM_ARG_VERBOSE) {
890 cam_error_print(device, ccb, CAM_ESF_ALL,
891 CAM_EPF_ALL, stderr);
902 fprintf(stdout, "%s%d: ", device->device_name,
903 device->dev_unit_num);
904 scsi_print_inquiry(inq_buf);
912 scsiserial(struct cam_device *device, int retry_count, int timeout)
915 struct scsi_vpd_unit_serial_number *serial_buf;
916 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
919 ccb = cam_getccb(device);
922 warnx("couldn't allocate CCB");
926 /* cam_getccb cleans up the header, caller has to zero the payload */
927 bzero(&(&ccb->ccb_h)[1],
928 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
930 serial_buf = (struct scsi_vpd_unit_serial_number *)
931 malloc(sizeof(*serial_buf));
933 if (serial_buf == NULL) {
935 warnx("can't malloc memory for serial number");
939 scsi_inquiry(&ccb->csio,
940 /*retries*/ retry_count,
942 /* tag_action */ MSG_SIMPLE_Q_TAG,
943 /* inq_buf */ (u_int8_t *)serial_buf,
944 /* inq_len */ sizeof(*serial_buf),
946 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
947 /* sense_len */ SSD_FULL_SIZE,
948 /* timeout */ timeout ? timeout : 5000);
950 /* Disable freezing the device queue */
951 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
953 if (arglist & CAM_ARG_ERR_RECOVER)
954 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
956 if (cam_send_ccb(device, ccb) < 0) {
957 warn("error getting serial number");
959 if (arglist & CAM_ARG_VERBOSE) {
960 cam_error_print(device, ccb, CAM_ESF_ALL,
961 CAM_EPF_ALL, stderr);
969 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
972 if (arglist & CAM_ARG_VERBOSE) {
973 cam_error_print(device, ccb, CAM_ESF_ALL,
974 CAM_EPF_ALL, stderr);
985 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
986 serial_num[serial_buf->length] = '\0';
988 if ((arglist & CAM_ARG_GET_STDINQ)
989 || (arglist & CAM_ARG_GET_XFERRATE))
990 fprintf(stdout, "%s%d: Serial Number ",
991 device->device_name, device->dev_unit_num);
993 fprintf(stdout, "%.60s\n", serial_num);
1001 camxferrate(struct cam_device *device)
1003 struct ccb_pathinq cpi;
1005 u_int32_t speed = 0;
1010 if ((retval = get_cpi(device, &cpi)) != 0)
1013 ccb = cam_getccb(device);
1016 warnx("couldn't allocate CCB");
1020 bzero(&(&ccb->ccb_h)[1],
1021 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
1023 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1024 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1026 if (((retval = cam_send_ccb(device, ccb)) < 0)
1027 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1028 const char error_string[] = "error getting transfer settings";
1033 warnx(error_string);
1035 if (arglist & CAM_ARG_VERBOSE)
1036 cam_error_print(device, ccb, CAM_ESF_ALL,
1037 CAM_EPF_ALL, stderr);
1041 goto xferrate_bailout;
1045 speed = cpi.base_transfer_speed;
1047 if (ccb->cts.transport == XPORT_SPI) {
1048 struct ccb_trans_settings_spi *spi =
1049 &ccb->cts.xport_specific.spi;
1051 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1052 freq = scsi_calc_syncsrate(spi->sync_period);
1055 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1056 speed *= (0x01 << spi->bus_width);
1058 } else if (ccb->cts.transport == XPORT_FC) {
1059 struct ccb_trans_settings_fc *fc =
1060 &ccb->cts.xport_specific.fc;
1062 if (fc->valid & CTS_FC_VALID_SPEED)
1063 speed = fc->bitrate;
1064 } else if (ccb->cts.transport == XPORT_SAS) {
1065 struct ccb_trans_settings_sas *sas =
1066 &ccb->cts.xport_specific.sas;
1068 if (sas->valid & CTS_SAS_VALID_SPEED)
1069 speed = sas->bitrate;
1070 } else if (ccb->cts.transport == XPORT_ATA) {
1071 struct ccb_trans_settings_pata *pata =
1072 &ccb->cts.xport_specific.ata;
1074 if (pata->valid & CTS_ATA_VALID_MODE)
1075 speed = ata_mode2speed(pata->mode);
1076 } else if (ccb->cts.transport == XPORT_SATA) {
1077 struct ccb_trans_settings_sata *sata =
1078 &ccb->cts.xport_specific.sata;
1080 if (sata->valid & CTS_SATA_VALID_REVISION)
1081 speed = ata_revision2speed(sata->revision);
1086 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1087 device->device_name, device->dev_unit_num,
1090 fprintf(stdout, "%s%d: %dKB/s transfers",
1091 device->device_name, device->dev_unit_num,
1095 if (ccb->cts.transport == XPORT_SPI) {
1096 struct ccb_trans_settings_spi *spi =
1097 &ccb->cts.xport_specific.spi;
1099 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1100 && (spi->sync_offset != 0))
1101 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1102 freq % 1000, spi->sync_offset);
1104 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1105 && (spi->bus_width > 0)) {
1106 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1107 && (spi->sync_offset != 0)) {
1108 fprintf(stdout, ", ");
1110 fprintf(stdout, " (");
1112 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1113 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1114 && (spi->sync_offset != 0)) {
1115 fprintf(stdout, ")");
1117 } else if (ccb->cts.transport == XPORT_ATA) {
1118 struct ccb_trans_settings_pata *pata =
1119 &ccb->cts.xport_specific.ata;
1122 if (pata->valid & CTS_ATA_VALID_MODE)
1123 printf("%s, ", ata_mode2string(pata->mode));
1124 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1125 printf("ATAPI %dbytes, ", pata->atapi);
1126 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1127 printf("PIO %dbytes", pata->bytecount);
1129 } else if (ccb->cts.transport == XPORT_SATA) {
1130 struct ccb_trans_settings_sata *sata =
1131 &ccb->cts.xport_specific.sata;
1134 if (sata->valid & CTS_SATA_VALID_REVISION)
1135 printf("SATA %d.x, ", sata->revision);
1138 if (sata->valid & CTS_SATA_VALID_MODE)
1139 printf("%s, ", ata_mode2string(sata->mode));
1140 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1141 printf("ATAPI %dbytes, ", sata->atapi);
1142 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1143 printf("PIO %dbytes", sata->bytecount);
1147 if (ccb->cts.protocol == PROTO_SCSI) {
1148 struct ccb_trans_settings_scsi *scsi =
1149 &ccb->cts.proto_specific.scsi;
1150 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1151 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1152 fprintf(stdout, ", Command Queueing Enabled");
1157 fprintf(stdout, "\n");
1167 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1169 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1170 ((u_int32_t)parm->lba_size_2 << 16);
1172 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1173 ((u_int64_t)parm->lba_size48_2 << 16) |
1174 ((u_int64_t)parm->lba_size48_3 << 32) |
1175 ((u_int64_t)parm->lba_size48_4 << 48);
1179 "Support Enabled Value\n");
1182 printf("Host Protected Area (HPA) ");
1183 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1184 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1185 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1188 printf("HPA - Security ");
1189 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1199 atacapprint(struct ata_params *parm)
1201 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1202 ((u_int32_t)parm->lba_size_2 << 16);
1204 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1205 ((u_int64_t)parm->lba_size48_2 << 16) |
1206 ((u_int64_t)parm->lba_size48_3 << 32) |
1207 ((u_int64_t)parm->lba_size48_4 << 48);
1210 printf("protocol ");
1211 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1212 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1213 if (parm->satacapabilities & ATA_SATA_GEN3)
1214 printf(" SATA 3.x\n");
1215 else if (parm->satacapabilities & ATA_SATA_GEN2)
1216 printf(" SATA 2.x\n");
1217 else if (parm->satacapabilities & ATA_SATA_GEN1)
1218 printf(" SATA 1.x\n");
1224 printf("device model %.40s\n", parm->model);
1225 printf("firmware revision %.8s\n", parm->revision);
1226 printf("serial number %.20s\n", parm->serial);
1227 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1228 printf("WWN %04x%04x%04x%04x\n",
1229 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1231 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1232 printf("media serial number %.30s\n",
1233 parm->media_serial);
1236 printf("cylinders %d\n", parm->cylinders);
1237 printf("heads %d\n", parm->heads);
1238 printf("sectors/track %d\n", parm->sectors);
1239 printf("sector size logical %u, physical %lu, offset %lu\n",
1240 ata_logical_sector_size(parm),
1241 (unsigned long)ata_physical_sector_size(parm),
1242 (unsigned long)ata_logical_sector_offset(parm));
1244 if (parm->config == ATA_PROTO_CFA ||
1245 (parm->support.command2 & ATA_SUPPORT_CFA))
1246 printf("CFA supported\n");
1248 printf("LBA%ssupported ",
1249 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1251 printf("%d sectors\n", lbasize);
1255 printf("LBA48%ssupported ",
1256 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1258 printf("%ju sectors\n", (uintmax_t)lbasize48);
1262 printf("PIO supported PIO");
1263 switch (ata_max_pmode(parm)) {
1279 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1280 printf(" w/o IORDY");
1283 printf("DMA%ssupported ",
1284 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1285 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1286 if (parm->mwdmamodes & 0xff) {
1288 if (parm->mwdmamodes & 0x04)
1290 else if (parm->mwdmamodes & 0x02)
1292 else if (parm->mwdmamodes & 0x01)
1296 if ((parm->atavalid & ATA_FLAG_88) &&
1297 (parm->udmamodes & 0xff)) {
1299 if (parm->udmamodes & 0x40)
1301 else if (parm->udmamodes & 0x20)
1303 else if (parm->udmamodes & 0x10)
1305 else if (parm->udmamodes & 0x08)
1307 else if (parm->udmamodes & 0x04)
1309 else if (parm->udmamodes & 0x02)
1311 else if (parm->udmamodes & 0x01)
1318 if (parm->media_rotation_rate == 1) {
1319 printf("media RPM non-rotating\n");
1320 } else if (parm->media_rotation_rate >= 0x0401 &&
1321 parm->media_rotation_rate <= 0xFFFE) {
1322 printf("media RPM %d\n",
1323 parm->media_rotation_rate);
1327 "Support Enabled Value Vendor\n");
1328 printf("read ahead %s %s\n",
1329 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1330 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1331 printf("write cache %s %s\n",
1332 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1333 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1334 printf("flush cache %s %s\n",
1335 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1336 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1337 printf("overlap %s\n",
1338 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1339 printf("Tagged Command Queuing (TCQ) %s %s",
1340 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1341 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1342 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1343 printf(" %d tags\n",
1344 ATA_QUEUE_LEN(parm->queue) + 1);
1347 printf("Native Command Queuing (NCQ) ");
1348 if (parm->satacapabilities != 0xffff &&
1349 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1350 printf("yes %d tags\n",
1351 ATA_QUEUE_LEN(parm->queue) + 1);
1354 printf("SMART %s %s\n",
1355 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1356 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1357 printf("microcode download %s %s\n",
1358 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1359 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1360 printf("security %s %s\n",
1361 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1362 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1363 printf("power management %s %s\n",
1364 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1365 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1366 printf("advanced power management %s %s",
1367 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1368 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1369 if (parm->support.command2 & ATA_SUPPORT_APM) {
1370 printf(" %d/0x%02X\n",
1371 parm->apm_value, parm->apm_value);
1374 printf("automatic acoustic management %s %s",
1375 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1376 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1377 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1378 printf(" %d/0x%02X %d/0x%02X\n",
1379 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1380 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1381 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1382 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1385 printf("media status notification %s %s\n",
1386 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1387 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1388 printf("power-up in Standby %s %s\n",
1389 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1390 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1391 printf("write-read-verify %s %s",
1392 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1393 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1394 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1395 printf(" %d/0x%x\n",
1396 parm->wrv_mode, parm->wrv_mode);
1399 printf("unload %s %s\n",
1400 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1401 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1402 printf("free-fall %s %s\n",
1403 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1404 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1405 printf("Data Set Management (DSM/TRIM) ");
1406 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1408 printf("DSM - max 512byte blocks ");
1409 if (parm->max_dsm_blocks == 0x00)
1410 printf("yes not specified\n");
1413 parm->max_dsm_blocks);
1415 printf("DSM - deterministic read ");
1416 if (parm->support3 & ATA_SUPPORT_DRAT) {
1417 if (parm->support3 & ATA_SUPPORT_RZAT)
1418 printf("yes zeroed\n");
1420 printf("yes any value\n");
1430 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1432 struct ata_pass_16 *ata_pass_16;
1433 struct ata_cmd ata_cmd;
1435 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1436 ata_cmd.command = ata_pass_16->command;
1437 ata_cmd.control = ata_pass_16->control;
1438 ata_cmd.features = ata_pass_16->features;
1440 if (arglist & CAM_ARG_VERBOSE) {
1441 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1442 ata_op_string(&ata_cmd),
1443 ccb->csio.ccb_h.timeout);
1446 /* Disable freezing the device queue */
1447 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1449 if (arglist & CAM_ARG_ERR_RECOVER)
1450 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1452 if (cam_send_ccb(device, ccb) < 0) {
1453 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1454 warn("error sending ATA %s via pass_16",
1455 ata_op_string(&ata_cmd));
1458 if (arglist & CAM_ARG_VERBOSE) {
1459 cam_error_print(device, ccb, CAM_ESF_ALL,
1460 CAM_EPF_ALL, stderr);
1466 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1467 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1468 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1469 warnx("ATA %s via pass_16 failed",
1470 ata_op_string(&ata_cmd));
1472 if (arglist & CAM_ARG_VERBOSE) {
1473 cam_error_print(device, ccb, CAM_ESF_ALL,
1474 CAM_EPF_ALL, stderr);
1485 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1487 if (arglist & CAM_ARG_VERBOSE) {
1488 warnx("sending ATA %s with timeout of %u msecs",
1489 ata_op_string(&(ccb->ataio.cmd)),
1490 ccb->ataio.ccb_h.timeout);
1493 /* Disable freezing the device queue */
1494 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1496 if (arglist & CAM_ARG_ERR_RECOVER)
1497 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1499 if (cam_send_ccb(device, ccb) < 0) {
1500 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1501 warn("error sending ATA %s",
1502 ata_op_string(&(ccb->ataio.cmd)));
1505 if (arglist & CAM_ARG_VERBOSE) {
1506 cam_error_print(device, ccb, CAM_ESF_ALL,
1507 CAM_EPF_ALL, stderr);
1513 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1514 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1515 warnx("ATA %s failed: %d",
1516 ata_op_string(&(ccb->ataio.cmd)), quiet);
1519 if (arglist & CAM_ARG_VERBOSE) {
1520 cam_error_print(device, ccb, CAM_ESF_ALL,
1521 CAM_EPF_ALL, stderr);
1531 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1532 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1533 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1534 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1535 u_int16_t dxfer_len, int timeout, int quiet)
1537 if (data_ptr != NULL) {
1538 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1539 AP_FLAG_TLEN_SECT_CNT;
1540 if (flags & CAM_DIR_OUT)
1541 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1543 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1545 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1548 bzero(&(&ccb->ccb_h)[1],
1549 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1551 scsi_ata_pass_16(&ccb->csio,
1565 /*sense_len*/SSD_FULL_SIZE,
1568 return scsi_cam_pass_16_send(device, ccb, quiet);
1572 ata_try_pass_16(struct cam_device *device)
1574 struct ccb_pathinq cpi;
1576 if (get_cpi(device, &cpi) != 0) {
1577 warnx("couldn't get CPI");
1581 if (cpi.protocol == PROTO_SCSI) {
1582 /* possibly compatible with pass_16 */
1586 /* likely not compatible with pass_16 */
1591 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1592 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1593 u_int8_t command, u_int8_t features, u_int32_t lba,
1594 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1595 int timeout, int quiet)
1599 switch (ata_try_pass_16(device)) {
1603 /* Try using SCSI Passthrough */
1604 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1605 0, tag_action, command, features, lba,
1606 sector_count, data_ptr, dxfer_len,
1610 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1611 sizeof(struct ccb_hdr));
1612 cam_fill_ataio(&ccb->ataio,
1621 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1622 return ata_cam_send(device, ccb, quiet);
1626 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1627 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1628 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1629 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1630 u_int16_t dxfer_len, int timeout, int force48bit)
1634 retval = ata_try_pass_16(device);
1641 /* Try using SCSI Passthrough */
1642 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1643 ata_flags, tag_action, command, features,
1644 lba, sector_count, data_ptr, dxfer_len,
1647 if (ata_flags & AP_FLAG_CHK_COND) {
1648 /* Decode ata_res from sense data */
1649 struct ata_res_pass16 *res_pass16;
1650 struct ata_res *res;
1654 /* sense_data is 4 byte aligned */
1655 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1656 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1657 ptr[i] = le16toh(ptr[i]);
1659 /* sense_data is 4 byte aligned */
1660 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1661 &ccb->csio.sense_data;
1662 res = &ccb->ataio.res;
1663 res->flags = res_pass16->flags;
1664 res->status = res_pass16->status;
1665 res->error = res_pass16->error;
1666 res->lba_low = res_pass16->lba_low;
1667 res->lba_mid = res_pass16->lba_mid;
1668 res->lba_high = res_pass16->lba_high;
1669 res->device = res_pass16->device;
1670 res->lba_low_exp = res_pass16->lba_low_exp;
1671 res->lba_mid_exp = res_pass16->lba_mid_exp;
1672 res->lba_high_exp = res_pass16->lba_high_exp;
1673 res->sector_count = res_pass16->sector_count;
1674 res->sector_count_exp = res_pass16->sector_count_exp;
1680 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1681 sizeof(struct ccb_hdr));
1682 cam_fill_ataio(&ccb->ataio,
1691 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1692 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1694 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1696 if (ata_flags & AP_FLAG_CHK_COND)
1697 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1699 return ata_cam_send(device, ccb, 0);
1703 dump_data(uint16_t *ptr, uint32_t len)
1707 for (i = 0; i < len / 2; i++) {
1709 printf(" %3d: ", i);
1710 printf("%04hx ", ptr[i]);
1719 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1720 int is48bit, u_int64_t *hpasize)
1722 struct ata_res *res;
1724 res = &ccb->ataio.res;
1725 if (res->status & ATA_STATUS_ERROR) {
1726 if (arglist & CAM_ARG_VERBOSE) {
1727 cam_error_print(device, ccb, CAM_ESF_ALL,
1728 CAM_EPF_ALL, stderr);
1729 printf("error = 0x%02x, sector_count = 0x%04x, "
1730 "device = 0x%02x, status = 0x%02x\n",
1731 res->error, res->sector_count,
1732 res->device, res->status);
1735 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1736 warnx("Max address has already been set since "
1737 "last power-on or hardware reset");
1743 if (arglist & CAM_ARG_VERBOSE) {
1744 fprintf(stdout, "%s%d: Raw native max data:\n",
1745 device->device_name, device->dev_unit_num);
1746 /* res is 4 byte aligned */
1747 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1749 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1750 "status = 0x%02x\n", res->error, res->sector_count,
1751 res->device, res->status);
1754 if (hpasize != NULL) {
1756 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1757 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1758 ((res->lba_high << 16) | (res->lba_mid << 8) |
1761 *hpasize = (((res->device & 0x0f) << 24) |
1762 (res->lba_high << 16) | (res->lba_mid << 8) |
1771 ata_read_native_max(struct cam_device *device, int retry_count,
1772 u_int32_t timeout, union ccb *ccb,
1773 struct ata_params *parm, u_int64_t *hpasize)
1779 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1780 protocol = AP_PROTO_NON_DATA;
1783 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1784 protocol |= AP_EXTEND;
1786 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1789 error = ata_do_cmd(device,
1792 /*flags*/CAM_DIR_NONE,
1793 /*protocol*/protocol,
1794 /*ata_flags*/AP_FLAG_CHK_COND,
1795 /*tag_action*/MSG_SIMPLE_Q_TAG,
1802 timeout ? timeout : 1000,
1808 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1812 atahpa_set_max(struct cam_device *device, int retry_count,
1813 u_int32_t timeout, union ccb *ccb,
1814 int is48bit, u_int64_t maxsize, int persist)
1820 protocol = AP_PROTO_NON_DATA;
1823 cmd = ATA_SET_MAX_ADDRESS48;
1824 protocol |= AP_EXTEND;
1826 cmd = ATA_SET_MAX_ADDRESS;
1829 /* lba's are zero indexed so the max lba is requested max - 1 */
1833 error = ata_do_cmd(device,
1836 /*flags*/CAM_DIR_NONE,
1837 /*protocol*/protocol,
1838 /*ata_flags*/AP_FLAG_CHK_COND,
1839 /*tag_action*/MSG_SIMPLE_Q_TAG,
1841 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1843 /*sector_count*/persist,
1846 timeout ? timeout : 1000,
1852 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1856 atahpa_password(struct cam_device *device, int retry_count,
1857 u_int32_t timeout, union ccb *ccb,
1858 int is48bit, struct ata_set_max_pwd *pwd)
1864 protocol = AP_PROTO_PIO_OUT;
1865 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1867 error = ata_do_cmd(device,
1870 /*flags*/CAM_DIR_OUT,
1871 /*protocol*/protocol,
1872 /*ata_flags*/AP_FLAG_CHK_COND,
1873 /*tag_action*/MSG_SIMPLE_Q_TAG,
1875 /*features*/ATA_HPA_FEAT_SET_PWD,
1878 /*data_ptr*/(u_int8_t*)pwd,
1879 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1880 timeout ? timeout : 1000,
1886 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1890 atahpa_lock(struct cam_device *device, int retry_count,
1891 u_int32_t timeout, union ccb *ccb, int is48bit)
1897 protocol = AP_PROTO_NON_DATA;
1898 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1900 error = ata_do_cmd(device,
1903 /*flags*/CAM_DIR_NONE,
1904 /*protocol*/protocol,
1905 /*ata_flags*/AP_FLAG_CHK_COND,
1906 /*tag_action*/MSG_SIMPLE_Q_TAG,
1908 /*features*/ATA_HPA_FEAT_LOCK,
1913 timeout ? timeout : 1000,
1919 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1923 atahpa_unlock(struct cam_device *device, int retry_count,
1924 u_int32_t timeout, union ccb *ccb,
1925 int is48bit, struct ata_set_max_pwd *pwd)
1931 protocol = AP_PROTO_PIO_OUT;
1932 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1934 error = ata_do_cmd(device,
1937 /*flags*/CAM_DIR_OUT,
1938 /*protocol*/protocol,
1939 /*ata_flags*/AP_FLAG_CHK_COND,
1940 /*tag_action*/MSG_SIMPLE_Q_TAG,
1942 /*features*/ATA_HPA_FEAT_UNLOCK,
1945 /*data_ptr*/(u_int8_t*)pwd,
1946 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1947 timeout ? timeout : 1000,
1953 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1957 atahpa_freeze_lock(struct cam_device *device, int retry_count,
1958 u_int32_t timeout, union ccb *ccb, int is48bit)
1964 protocol = AP_PROTO_NON_DATA;
1965 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1967 error = ata_do_cmd(device,
1970 /*flags*/CAM_DIR_NONE,
1971 /*protocol*/protocol,
1972 /*ata_flags*/AP_FLAG_CHK_COND,
1973 /*tag_action*/MSG_SIMPLE_Q_TAG,
1975 /*features*/ATA_HPA_FEAT_FREEZE,
1980 timeout ? timeout : 1000,
1986 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1991 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
1992 union ccb *ccb, struct ata_params** ident_bufp)
1994 struct ata_params *ident_buf;
1995 struct ccb_pathinq cpi;
1996 struct ccb_getdev cgd;
1999 u_int8_t command, retry_command;
2001 if (get_cpi(device, &cpi) != 0) {
2002 warnx("couldn't get CPI");
2006 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2007 if (cpi.protocol == PROTO_ATA) {
2008 if (get_cgd(device, &cgd) != 0) {
2009 warnx("couldn't get CGD");
2013 command = (cgd.protocol == PROTO_ATA) ?
2014 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2017 /* We don't know which for sure so try both */
2018 command = ATA_ATA_IDENTIFY;
2019 retry_command = ATA_ATAPI_IDENTIFY;
2022 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2024 warnx("can't calloc memory for identify\n");
2028 error = ata_do_28bit_cmd(device,
2030 /*retries*/retry_count,
2031 /*flags*/CAM_DIR_IN,
2032 /*protocol*/AP_PROTO_PIO_IN,
2033 /*tag_action*/MSG_SIMPLE_Q_TAG,
2037 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2038 /*data_ptr*/(u_int8_t *)ptr,
2039 /*dxfer_len*/sizeof(struct ata_params),
2040 /*timeout*/timeout ? timeout : 30 * 1000,
2044 if (retry_command == 0) {
2048 error = ata_do_28bit_cmd(device,
2050 /*retries*/retry_count,
2051 /*flags*/CAM_DIR_IN,
2052 /*protocol*/AP_PROTO_PIO_IN,
2053 /*tag_action*/MSG_SIMPLE_Q_TAG,
2054 /*command*/retry_command,
2057 /*sector_count*/(u_int8_t)
2058 sizeof(struct ata_params),
2059 /*data_ptr*/(u_int8_t *)ptr,
2060 /*dxfer_len*/sizeof(struct ata_params),
2061 /*timeout*/timeout ? timeout : 30 * 1000,
2071 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2072 ptr[i] = le16toh(ptr[i]);
2077 if (arglist & CAM_ARG_VERBOSE) {
2078 fprintf(stdout, "%s%d: Raw identify data:\n",
2079 device->device_name, device->dev_unit_num);
2080 dump_data(ptr, sizeof(struct ata_params));
2083 /* check for invalid (all zero) response */
2085 warnx("Invalid identify response detected");
2090 ident_buf = (struct ata_params *)ptr;
2091 if (strncmp(ident_buf->model, "FX", 2) &&
2092 strncmp(ident_buf->model, "NEC", 3) &&
2093 strncmp(ident_buf->model, "Pioneer", 7) &&
2094 strncmp(ident_buf->model, "SHARP", 5)) {
2095 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2096 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2097 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2098 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2100 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2101 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2102 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2103 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2104 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2105 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2106 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2107 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2108 sizeof(ident_buf->media_serial));
2110 *ident_bufp = ident_buf;
2117 ataidentify(struct cam_device *device, int retry_count, int timeout)
2120 struct ata_params *ident_buf;
2123 if ((ccb = cam_getccb(device)) == NULL) {
2124 warnx("couldn't allocate CCB");
2128 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2133 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2134 if (ata_read_native_max(device, retry_count, timeout, ccb,
2135 ident_buf, &hpasize) != 0) {
2143 printf("%s%d: ", device->device_name, device->dev_unit_num);
2144 ata_print_ident(ident_buf);
2145 camxferrate(device);
2146 atacapprint(ident_buf);
2147 atahpa_print(ident_buf, hpasize, 0);
2154 #endif /* MINIMALISTIC */
2157 #ifndef MINIMALISTIC
2159 ATA_SECURITY_ACTION_PRINT,
2160 ATA_SECURITY_ACTION_FREEZE,
2161 ATA_SECURITY_ACTION_UNLOCK,
2162 ATA_SECURITY_ACTION_DISABLE,
2163 ATA_SECURITY_ACTION_ERASE,
2164 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2165 ATA_SECURITY_ACTION_SET_PASSWORD
2169 atasecurity_print_time(u_int16_t tw)
2173 printf("unspecified");
2175 printf("> 508 min");
2177 printf("%i min", 2 * tw);
2181 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2185 return 2 * 3600 * 1000; /* default: two hours */
2186 else if (timeout > 255)
2187 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2189 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2194 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2198 bzero(&cmd, sizeof(cmd));
2199 cmd.command = command;
2200 printf("Issuing %s", ata_op_string(&cmd));
2203 char pass[sizeof(pwd->password)+1];
2205 /* pwd->password may not be null terminated */
2206 pass[sizeof(pwd->password)] = '\0';
2207 strncpy(pass, pwd->password, sizeof(pwd->password));
2208 printf(" password='%s', user='%s'",
2210 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2213 if (command == ATA_SECURITY_SET_PASSWORD) {
2214 printf(", mode='%s'",
2215 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2216 "maximum" : "high");
2224 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2225 int retry_count, u_int32_t timeout, int quiet)
2229 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2231 return ata_do_28bit_cmd(device,
2234 /*flags*/CAM_DIR_NONE,
2235 /*protocol*/AP_PROTO_NON_DATA,
2236 /*tag_action*/MSG_SIMPLE_Q_TAG,
2237 /*command*/ATA_SECURITY_FREEZE_LOCK,
2248 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2249 int retry_count, u_int32_t timeout,
2250 struct ata_security_password *pwd, int quiet)
2254 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2256 return ata_do_28bit_cmd(device,
2259 /*flags*/CAM_DIR_OUT,
2260 /*protocol*/AP_PROTO_PIO_OUT,
2261 /*tag_action*/MSG_SIMPLE_Q_TAG,
2262 /*command*/ATA_SECURITY_UNLOCK,
2266 /*data_ptr*/(u_int8_t *)pwd,
2267 /*dxfer_len*/sizeof(*pwd),
2273 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2274 int retry_count, u_int32_t timeout,
2275 struct ata_security_password *pwd, int quiet)
2279 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2280 return ata_do_28bit_cmd(device,
2283 /*flags*/CAM_DIR_OUT,
2284 /*protocol*/AP_PROTO_PIO_OUT,
2285 /*tag_action*/MSG_SIMPLE_Q_TAG,
2286 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2290 /*data_ptr*/(u_int8_t *)pwd,
2291 /*dxfer_len*/sizeof(*pwd),
2298 atasecurity_erase_confirm(struct cam_device *device,
2299 struct ata_params* ident_buf)
2302 printf("\nYou are about to ERASE ALL DATA from the following"
2303 " device:\n%s%d,%s%d: ", device->device_name,
2304 device->dev_unit_num, device->given_dev_name,
2305 device->given_unit_number);
2306 ata_print_ident(ident_buf);
2310 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2312 if (fgets(str, sizeof(str), stdin) != NULL) {
2313 if (strncasecmp(str, "yes", 3) == 0) {
2315 } else if (strncasecmp(str, "no", 2) == 0) {
2318 printf("Please answer \"yes\" or "
2329 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2330 int retry_count, u_int32_t timeout,
2331 u_int32_t erase_timeout,
2332 struct ata_security_password *pwd, int quiet)
2337 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2339 error = ata_do_28bit_cmd(device,
2342 /*flags*/CAM_DIR_NONE,
2343 /*protocol*/AP_PROTO_NON_DATA,
2344 /*tag_action*/MSG_SIMPLE_Q_TAG,
2345 /*command*/ATA_SECURITY_ERASE_PREPARE,
2358 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2360 error = ata_do_28bit_cmd(device,
2363 /*flags*/CAM_DIR_OUT,
2364 /*protocol*/AP_PROTO_PIO_OUT,
2365 /*tag_action*/MSG_SIMPLE_Q_TAG,
2366 /*command*/ATA_SECURITY_ERASE_UNIT,
2370 /*data_ptr*/(u_int8_t *)pwd,
2371 /*dxfer_len*/sizeof(*pwd),
2372 /*timeout*/erase_timeout,
2375 if (error == 0 && quiet == 0)
2376 printf("\nErase Complete\n");
2382 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2383 int retry_count, u_int32_t timeout,
2384 struct ata_security_password *pwd, int quiet)
2388 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2390 return ata_do_28bit_cmd(device,
2393 /*flags*/CAM_DIR_OUT,
2394 /*protocol*/AP_PROTO_PIO_OUT,
2395 /*tag_action*/MSG_SIMPLE_Q_TAG,
2396 /*command*/ATA_SECURITY_SET_PASSWORD,
2400 /*data_ptr*/(u_int8_t *)pwd,
2401 /*dxfer_len*/sizeof(*pwd),
2407 atasecurity_print(struct ata_params *parm)
2410 printf("\nSecurity Option Value\n");
2411 if (arglist & CAM_ARG_VERBOSE) {
2412 printf("status %04x\n",
2413 parm->security_status);
2415 printf("supported %s\n",
2416 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2417 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2419 printf("enabled %s\n",
2420 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2421 printf("drive locked %s\n",
2422 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2423 printf("security config frozen %s\n",
2424 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2425 printf("count expired %s\n",
2426 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2427 printf("security level %s\n",
2428 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2429 printf("enhanced erase supported %s\n",
2430 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2431 printf("erase time ");
2432 atasecurity_print_time(parm->erase_time);
2434 printf("enhanced erase time ");
2435 atasecurity_print_time(parm->enhanced_erase_time);
2437 printf("master password rev %04x%s\n",
2438 parm->master_passwd_revision,
2439 parm->master_passwd_revision == 0x0000 ||
2440 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2444 * Validates and copies the password in optarg to the passed buffer.
2445 * If the password in optarg is the same length as the buffer then
2446 * the data will still be copied but no null termination will occur.
2449 ata_getpwd(u_int8_t *passwd, int max, char opt)
2453 len = strlen(optarg);
2455 warnx("-%c password is too long", opt);
2457 } else if (len == 0) {
2458 warnx("-%c password is missing", opt);
2460 } else if (optarg[0] == '-'){
2461 warnx("-%c password starts with '-' (generic arg?)", opt);
2463 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2464 warnx("-%c password conflicts with existing password from -%c",
2469 /* Callers pass in a buffer which does NOT need to be terminated */
2470 strncpy(passwd, optarg, max);
2477 ATA_HPA_ACTION_PRINT,
2478 ATA_HPA_ACTION_SET_MAX,
2479 ATA_HPA_ACTION_SET_PWD,
2480 ATA_HPA_ACTION_LOCK,
2481 ATA_HPA_ACTION_UNLOCK,
2482 ATA_HPA_ACTION_FREEZE_LOCK
2486 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2487 u_int64_t maxsize, int persist)
2489 printf("\nYou are about to configure HPA to limit the user accessible\n"
2490 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2491 persist ? "persistently" : "temporarily",
2492 device->device_name, device->dev_unit_num,
2493 device->given_dev_name, device->given_unit_number);
2494 ata_print_ident(ident_buf);
2498 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2500 if (NULL != fgets(str, sizeof(str), stdin)) {
2501 if (0 == strncasecmp(str, "yes", 3)) {
2503 } else if (0 == strncasecmp(str, "no", 2)) {
2506 printf("Please answer \"yes\" or "
2517 atahpa(struct cam_device *device, int retry_count, int timeout,
2518 int argc, char **argv, char *combinedopt)
2521 struct ata_params *ident_buf;
2522 struct ccb_getdev cgd;
2523 struct ata_set_max_pwd pwd;
2524 int error, confirm, quiet, c, action, actions, setpwd, persist;
2525 int security, is48bit, pwdsize;
2526 u_int64_t hpasize, maxsize;
2536 memset(&pwd, 0, sizeof(pwd));
2538 /* default action is to print hpa information */
2539 action = ATA_HPA_ACTION_PRINT;
2540 pwdsize = sizeof(pwd.password);
2542 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2545 action = ATA_HPA_ACTION_SET_MAX;
2546 maxsize = strtoumax(optarg, NULL, 0);
2551 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2553 action = ATA_HPA_ACTION_SET_PWD;
2559 action = ATA_HPA_ACTION_LOCK;
2565 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2567 action = ATA_HPA_ACTION_UNLOCK;
2573 action = ATA_HPA_ACTION_FREEZE_LOCK;
2593 warnx("too many hpa actions specified");
2597 if (get_cgd(device, &cgd) != 0) {
2598 warnx("couldn't get CGD");
2602 ccb = cam_getccb(device);
2604 warnx("couldn't allocate CCB");
2608 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2615 printf("%s%d: ", device->device_name, device->dev_unit_num);
2616 ata_print_ident(ident_buf);
2617 camxferrate(device);
2620 if (action == ATA_HPA_ACTION_PRINT) {
2621 error = ata_read_native_max(device, retry_count, timeout, ccb,
2622 ident_buf, &hpasize);
2624 atahpa_print(ident_buf, hpasize, 1);
2631 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2632 warnx("HPA is not supported by this device");
2638 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2639 warnx("HPA Security is not supported by this device");
2645 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2648 * The ATA spec requires:
2649 * 1. Read native max addr is called directly before set max addr
2650 * 2. Read native max addr is NOT called before any other set max call
2653 case ATA_HPA_ACTION_SET_MAX:
2655 atahpa_set_confirm(device, ident_buf, maxsize,
2662 error = ata_read_native_max(device, retry_count, timeout,
2663 ccb, ident_buf, &hpasize);
2665 error = atahpa_set_max(device, retry_count, timeout,
2666 ccb, is48bit, maxsize, persist);
2668 /* redo identify to get new lba values */
2669 error = ata_do_identify(device, retry_count,
2672 atahpa_print(ident_buf, hpasize, 1);
2677 case ATA_HPA_ACTION_SET_PWD:
2678 error = atahpa_password(device, retry_count, timeout,
2679 ccb, is48bit, &pwd);
2681 printf("HPA password has been set\n");
2684 case ATA_HPA_ACTION_LOCK:
2685 error = atahpa_lock(device, retry_count, timeout,
2688 printf("HPA has been locked\n");
2691 case ATA_HPA_ACTION_UNLOCK:
2692 error = atahpa_unlock(device, retry_count, timeout,
2693 ccb, is48bit, &pwd);
2695 printf("HPA has been unlocked\n");
2698 case ATA_HPA_ACTION_FREEZE_LOCK:
2699 error = atahpa_freeze_lock(device, retry_count, timeout,
2702 printf("HPA has been frozen\n");
2706 errx(1, "Option currently not supported");
2716 atasecurity(struct cam_device *device, int retry_count, int timeout,
2717 int argc, char **argv, char *combinedopt)
2720 struct ata_params *ident_buf;
2721 int error, confirm, quiet, c, action, actions, setpwd;
2722 int security_enabled, erase_timeout, pwdsize;
2723 struct ata_security_password pwd;
2731 memset(&pwd, 0, sizeof(pwd));
2733 /* default action is to print security information */
2734 action = ATA_SECURITY_ACTION_PRINT;
2736 /* user is master by default as its safer that way */
2737 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2738 pwdsize = sizeof(pwd.password);
2740 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2743 action = ATA_SECURITY_ACTION_FREEZE;
2748 if (strcasecmp(optarg, "user") == 0) {
2749 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2750 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2751 } else if (strcasecmp(optarg, "master") == 0) {
2752 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2753 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2755 warnx("-U argument '%s' is invalid (must be "
2756 "'user' or 'master')", optarg);
2762 if (strcasecmp(optarg, "high") == 0) {
2763 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2764 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2765 } else if (strcasecmp(optarg, "maximum") == 0) {
2766 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2767 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2769 warnx("-l argument '%s' is unknown (must be "
2770 "'high' or 'maximum')", optarg);
2776 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2778 action = ATA_SECURITY_ACTION_UNLOCK;
2783 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2785 action = ATA_SECURITY_ACTION_DISABLE;
2790 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2792 action = ATA_SECURITY_ACTION_ERASE;
2797 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2799 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2800 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2805 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2808 if (action == ATA_SECURITY_ACTION_PRINT)
2809 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2811 * Don't increment action as this can be combined
2812 * with other actions.
2825 erase_timeout = atoi(optarg) * 1000;
2831 warnx("too many security actions specified");
2835 if ((ccb = cam_getccb(device)) == NULL) {
2836 warnx("couldn't allocate CCB");
2840 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2847 printf("%s%d: ", device->device_name, device->dev_unit_num);
2848 ata_print_ident(ident_buf);
2849 camxferrate(device);
2852 if (action == ATA_SECURITY_ACTION_PRINT) {
2853 atasecurity_print(ident_buf);
2859 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2860 warnx("Security not supported");
2866 /* default timeout 15 seconds the same as linux hdparm */
2867 timeout = timeout ? timeout : 15 * 1000;
2869 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2871 /* first set the password if requested */
2873 /* confirm we can erase before setting the password if erasing */
2875 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2876 action == ATA_SECURITY_ACTION_ERASE) &&
2877 atasecurity_erase_confirm(device, ident_buf) == 0) {
2883 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2884 pwd.revision = ident_buf->master_passwd_revision;
2885 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2886 --pwd.revision == 0) {
2887 pwd.revision = 0xfffe;
2890 error = atasecurity_set_password(device, ccb, retry_count,
2891 timeout, &pwd, quiet);
2897 security_enabled = 1;
2901 case ATA_SECURITY_ACTION_FREEZE:
2902 error = atasecurity_freeze(device, ccb, retry_count,
2906 case ATA_SECURITY_ACTION_UNLOCK:
2907 if (security_enabled) {
2908 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2909 error = atasecurity_unlock(device, ccb,
2910 retry_count, timeout, &pwd, quiet);
2912 warnx("Can't unlock, drive is not locked");
2916 warnx("Can't unlock, security is disabled");
2921 case ATA_SECURITY_ACTION_DISABLE:
2922 if (security_enabled) {
2923 /* First unlock the drive if its locked */
2924 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2925 error = atasecurity_unlock(device, ccb,
2933 error = atasecurity_disable(device,
2941 warnx("Can't disable security (already disabled)");
2946 case ATA_SECURITY_ACTION_ERASE:
2947 if (security_enabled) {
2948 if (erase_timeout == 0) {
2949 erase_timeout = atasecurity_erase_timeout_msecs(
2950 ident_buf->erase_time);
2953 error = atasecurity_erase(device, ccb, retry_count,
2954 timeout, erase_timeout, &pwd,
2957 warnx("Can't secure erase (security is disabled)");
2962 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
2963 if (security_enabled) {
2964 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
2965 if (erase_timeout == 0) {
2967 atasecurity_erase_timeout_msecs(
2968 ident_buf->enhanced_erase_time);
2971 error = atasecurity_erase(device, ccb,
2972 retry_count, timeout,
2973 erase_timeout, &pwd,
2976 warnx("Enhanced erase is not supported");
2980 warnx("Can't secure erase (enhanced), "
2981 "(security is disabled)");
2992 #endif /* MINIMALISTIC */
2995 * Parse out a bus, or a bus, target and lun in the following
3001 * Returns the number of parsed components, or 0.
3004 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
3009 while (isspace(*tstr) && (*tstr != '\0'))
3012 tmpstr = (char *)strtok(tstr, ":");
3013 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3014 *bus = strtol(tmpstr, NULL, 0);
3015 *arglst |= CAM_ARG_BUS;
3017 tmpstr = (char *)strtok(NULL, ":");
3018 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3019 *target = strtol(tmpstr, NULL, 0);
3020 *arglst |= CAM_ARG_TARGET;
3022 tmpstr = (char *)strtok(NULL, ":");
3023 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3024 *lun = strtol(tmpstr, NULL, 0);
3025 *arglst |= CAM_ARG_LUN;
3035 dorescan_or_reset(int argc, char **argv, int rescan)
3037 static const char must[] =
3038 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3040 int bus = -1, target = -1, lun = -1;
3044 warnx(must, rescan? "rescan" : "reset");
3048 tstr = argv[optind];
3049 while (isspace(*tstr) && (*tstr != '\0'))
3051 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3052 arglist |= CAM_ARG_BUS;
3054 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3055 if (rv != 1 && rv != 3) {
3056 warnx(must, rescan? "rescan" : "reset");
3061 if ((arglist & CAM_ARG_BUS)
3062 && (arglist & CAM_ARG_TARGET)
3063 && (arglist & CAM_ARG_LUN))
3064 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3066 error = rescan_or_reset_bus(bus, rescan);
3072 rescan_or_reset_bus(int bus, int rescan)
3074 union ccb ccb, matchccb;
3080 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3081 warnx("error opening transport layer device %s", XPT_DEVICE);
3082 warn("%s", XPT_DEVICE);
3087 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3088 ccb.ccb_h.path_id = bus;
3089 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3090 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3091 ccb.crcn.flags = CAM_FLAG_NONE;
3093 /* run this at a low priority */
3094 ccb.ccb_h.pinfo.priority = 5;
3096 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3097 warn("CAMIOCOMMAND ioctl failed");
3102 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3103 fprintf(stdout, "%s of bus %d was successful\n",
3104 rescan ? "Re-scan" : "Reset", bus);
3106 fprintf(stdout, "%s of bus %d returned error %#x\n",
3107 rescan ? "Re-scan" : "Reset", bus,
3108 ccb.ccb_h.status & CAM_STATUS_MASK);
3119 * The right way to handle this is to modify the xpt so that it can
3120 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3121 * that isn't implemented, so instead we enumerate the busses and
3122 * send the rescan or reset to those busses in the case where the
3123 * given bus is -1 (wildcard). We don't send a rescan or reset
3124 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3125 * no-op, sending a rescan to the xpt bus would result in a status of
3128 bzero(&(&matchccb.ccb_h)[1],
3129 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3130 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3131 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3132 bufsize = sizeof(struct dev_match_result) * 20;
3133 matchccb.cdm.match_buf_len = bufsize;
3134 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3135 if (matchccb.cdm.matches == NULL) {
3136 warnx("can't malloc memory for matches");
3140 matchccb.cdm.num_matches = 0;
3142 matchccb.cdm.num_patterns = 1;
3143 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3145 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3146 matchccb.cdm.pattern_buf_len);
3147 if (matchccb.cdm.patterns == NULL) {
3148 warnx("can't malloc memory for patterns");
3152 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3153 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3158 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3159 warn("CAMIOCOMMAND ioctl failed");
3164 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3165 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3166 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3167 warnx("got CAM error %#x, CDM error %d\n",
3168 matchccb.ccb_h.status, matchccb.cdm.status);
3173 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3174 struct bus_match_result *bus_result;
3176 /* This shouldn't happen. */
3177 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3180 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3183 * We don't want to rescan or reset the xpt bus.
3186 if ((int)bus_result->path_id == -1)
3189 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3191 ccb.ccb_h.path_id = bus_result->path_id;
3192 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3193 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3194 ccb.crcn.flags = CAM_FLAG_NONE;
3196 /* run this at a low priority */
3197 ccb.ccb_h.pinfo.priority = 5;
3199 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3200 warn("CAMIOCOMMAND ioctl failed");
3205 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3206 fprintf(stdout, "%s of bus %d was successful\n",
3207 rescan? "Re-scan" : "Reset",
3208 bus_result->path_id);
3211 * Don't bail out just yet, maybe the other
3212 * rescan or reset commands will complete
3215 fprintf(stderr, "%s of bus %d returned error "
3216 "%#x\n", rescan? "Re-scan" : "Reset",
3217 bus_result->path_id,
3218 ccb.ccb_h.status & CAM_STATUS_MASK);
3222 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3223 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3230 if (matchccb.cdm.patterns != NULL)
3231 free(matchccb.cdm.patterns);
3232 if (matchccb.cdm.matches != NULL)
3233 free(matchccb.cdm.matches);
3239 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
3242 struct cam_device *device;
3248 warnx("invalid bus number %d", bus);
3253 warnx("invalid target number %d", target);
3258 warnx("invalid lun number %d", lun);
3264 bzero(&ccb, sizeof(union ccb));
3267 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3268 warnx("error opening transport layer device %s\n",
3270 warn("%s", XPT_DEVICE);
3274 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3275 if (device == NULL) {
3276 warnx("%s", cam_errbuf);
3281 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3282 ccb.ccb_h.path_id = bus;
3283 ccb.ccb_h.target_id = target;
3284 ccb.ccb_h.target_lun = lun;
3285 ccb.ccb_h.timeout = 5000;
3286 ccb.crcn.flags = CAM_FLAG_NONE;
3288 /* run this at a low priority */
3289 ccb.ccb_h.pinfo.priority = 5;
3292 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3293 warn("CAMIOCOMMAND ioctl failed");
3298 if (cam_send_ccb(device, &ccb) < 0) {
3299 warn("error sending XPT_RESET_DEV CCB");
3300 cam_close_device(device);
3308 cam_close_device(device);
3311 * An error code of CAM_BDR_SENT is normal for a BDR request.
3313 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3315 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3316 fprintf(stdout, "%s of %d:%d:%d was successful\n",
3317 scan? "Re-scan" : "Reset", bus, target, lun);
3320 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
3321 scan? "Re-scan" : "Reset", bus, target, lun,
3322 ccb.ccb_h.status & CAM_STATUS_MASK);
3327 #ifndef MINIMALISTIC
3329 readdefects(struct cam_device *device, int argc, char **argv,
3330 char *combinedopt, int retry_count, int timeout)
3332 union ccb *ccb = NULL;
3333 struct scsi_read_defect_data_10 *rdd_cdb;
3334 u_int8_t *defect_list = NULL;
3335 u_int32_t max_dlist_length = SRDD10_MAX_LENGTH, dlist_length = 0;
3336 u_int32_t returned_length = 0;
3337 u_int32_t num_returned = 0;
3338 u_int8_t returned_format;
3341 int lists_specified;
3344 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3350 while (isspace(*tstr) && (*tstr != '\0'))
3352 if (strcmp(tstr, "block") == 0)
3353 arglist |= CAM_ARG_FORMAT_BLOCK;
3354 else if (strcmp(tstr, "bfi") == 0)
3355 arglist |= CAM_ARG_FORMAT_BFI;
3356 else if (strcmp(tstr, "phys") == 0)
3357 arglist |= CAM_ARG_FORMAT_PHYS;
3360 warnx("invalid defect format %s", tstr);
3361 goto defect_bailout;
3366 arglist |= CAM_ARG_GLIST;
3369 arglist |= CAM_ARG_PLIST;
3376 ccb = cam_getccb(device);
3379 * Eventually we should probably support the 12 byte READ DEFECT
3380 * DATA command. It supports a longer parameter list, which may be
3381 * necessary on newer drives with lots of defects. According to
3382 * the SBC-3 spec, drives are supposed to return an illegal request
3383 * if they have more defect data than will fit in 64K.
3385 defect_list = malloc(max_dlist_length);
3386 if (defect_list == NULL) {
3387 warnx("can't malloc memory for defect list");
3389 goto defect_bailout;
3393 * We start off asking for just the header to determine how much
3394 * defect data is available. Some Hitachi drives return an error
3395 * if you ask for more data than the drive has. Once we know the
3396 * length, we retry the command with the returned length.
3398 dlist_length = sizeof(struct scsi_read_defect_data_hdr_10);
3400 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
3404 lists_specified = 0;
3407 * cam_getccb() zeros the CCB header only. So we need to zero the
3408 * payload portion of the ccb.
3410 bzero(&(&ccb->ccb_h)[1],
3411 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3413 cam_fill_csio(&ccb->csio,
3414 /*retries*/ retry_count,
3416 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
3417 CAM_PASS_ERR_RECOVER : 0),
3418 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3419 /*data_ptr*/ defect_list,
3420 /*dxfer_len*/ dlist_length,
3421 /*sense_len*/ SSD_FULL_SIZE,
3422 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
3423 /*timeout*/ timeout ? timeout : 5000);
3425 rdd_cdb->opcode = READ_DEFECT_DATA_10;
3426 if (arglist & CAM_ARG_FORMAT_BLOCK)
3427 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
3428 else if (arglist & CAM_ARG_FORMAT_BFI)
3429 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
3430 else if (arglist & CAM_ARG_FORMAT_PHYS)
3431 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
3434 warnx("no defect list format specified");
3435 goto defect_bailout;
3437 if (arglist & CAM_ARG_PLIST) {
3438 rdd_cdb->format |= SRDD10_PLIST;
3442 if (arglist & CAM_ARG_GLIST) {
3443 rdd_cdb->format |= SRDD10_GLIST;
3447 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
3449 /* Disable freezing the device queue */
3450 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3452 if (cam_send_ccb(device, ccb) < 0) {
3453 perror("error reading defect list");
3455 if (arglist & CAM_ARG_VERBOSE) {
3456 cam_error_print(device, ccb, CAM_ESF_ALL,
3457 CAM_EPF_ALL, stderr);
3461 goto defect_bailout;
3464 returned_length = scsi_2btoul(((struct
3465 scsi_read_defect_data_hdr_10 *)defect_list)->length);
3467 if (get_length != 0) {
3470 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3471 CAM_SCSI_STATUS_ERROR) {
3472 struct scsi_sense_data *sense;
3473 int error_code, sense_key, asc, ascq;
3475 sense = &ccb->csio.sense_data;
3476 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3477 ccb->csio.sense_resid, &error_code, &sense_key,
3478 &asc, &ascq, /*show_errors*/ 1);
3481 * If the drive is reporting that it just doesn't
3482 * support the defect list format, go ahead and use
3483 * the length it reported. Otherwise, the length
3484 * may not be valid, so use the maximum.
3486 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3487 && (asc == 0x1c) && (ascq == 0x00)
3488 && (returned_length > 0)) {
3489 dlist_length = returned_length +
3490 sizeof(struct scsi_read_defect_data_hdr_10);
3491 dlist_length = min(dlist_length,
3494 dlist_length = max_dlist_length;
3495 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3498 warnx("Error reading defect header");
3499 if (arglist & CAM_ARG_VERBOSE)
3500 cam_error_print(device, ccb, CAM_ESF_ALL,
3501 CAM_EPF_ALL, stderr);
3502 goto defect_bailout;
3504 dlist_length = returned_length +
3505 sizeof(struct scsi_read_defect_data_hdr_10);
3506 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3512 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
3513 defect_list)->format;
3515 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3516 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3517 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3518 struct scsi_sense_data *sense;
3519 int error_code, sense_key, asc, ascq;
3521 sense = &ccb->csio.sense_data;
3522 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3523 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3524 &ascq, /*show_errors*/ 1);
3527 * According to the SCSI spec, if the disk doesn't support
3528 * the requested format, it will generally return a sense
3529 * key of RECOVERED ERROR, and an additional sense code
3530 * of "DEFECT LIST NOT FOUND". So, we check for that, and
3531 * also check to make sure that the returned length is
3532 * greater than 0, and then print out whatever format the
3535 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3536 && (asc == 0x1c) && (ascq == 0x00)
3537 && (returned_length > 0)) {
3538 warnx("requested defect format not available");
3539 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
3540 case SRDD10_BLOCK_FORMAT:
3541 warnx("Device returned block format");
3543 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3544 warnx("Device returned bytes from index"
3547 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3548 warnx("Device returned physical sector format");
3552 warnx("Device returned unknown defect"
3553 " data format %#x", returned_format);
3554 goto defect_bailout;
3555 break; /* NOTREACHED */
3559 warnx("Error returned from read defect data command");
3560 if (arglist & CAM_ARG_VERBOSE)
3561 cam_error_print(device, ccb, CAM_ESF_ALL,
3562 CAM_EPF_ALL, stderr);
3563 goto defect_bailout;
3565 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3567 warnx("Error returned from read defect data command");
3568 if (arglist & CAM_ARG_VERBOSE)
3569 cam_error_print(device, ccb, CAM_ESF_ALL,
3570 CAM_EPF_ALL, stderr);
3571 goto defect_bailout;
3575 * XXX KDM I should probably clean up the printout format for the
3578 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
3579 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
3581 struct scsi_defect_desc_phys_sector *dlist;
3583 dlist = (struct scsi_defect_desc_phys_sector *)
3585 sizeof(struct scsi_read_defect_data_hdr_10));
3587 num_returned = returned_length /
3588 sizeof(struct scsi_defect_desc_phys_sector);
3590 fprintf(stderr, "Got %d defect", num_returned);
3592 if ((lists_specified == 0) || (num_returned == 0)) {
3593 fprintf(stderr, "s.\n");
3595 } else if (num_returned == 1)
3596 fprintf(stderr, ":\n");
3598 fprintf(stderr, "s:\n");
3600 for (i = 0; i < num_returned; i++) {
3601 fprintf(stdout, "%d:%d:%d\n",
3602 scsi_3btoul(dlist[i].cylinder),
3604 scsi_4btoul(dlist[i].sector));
3608 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
3610 struct scsi_defect_desc_bytes_from_index *dlist;
3612 dlist = (struct scsi_defect_desc_bytes_from_index *)
3614 sizeof(struct scsi_read_defect_data_hdr_10));
3616 num_returned = returned_length /
3617 sizeof(struct scsi_defect_desc_bytes_from_index);
3619 fprintf(stderr, "Got %d defect", num_returned);
3621 if ((lists_specified == 0) || (num_returned == 0)) {
3622 fprintf(stderr, "s.\n");
3624 } else if (num_returned == 1)
3625 fprintf(stderr, ":\n");
3627 fprintf(stderr, "s:\n");
3629 for (i = 0; i < num_returned; i++) {
3630 fprintf(stdout, "%d:%d:%d\n",
3631 scsi_3btoul(dlist[i].cylinder),
3633 scsi_4btoul(dlist[i].bytes_from_index));
3637 case SRDDH10_BLOCK_FORMAT:
3639 struct scsi_defect_desc_block *dlist;
3641 dlist = (struct scsi_defect_desc_block *)(defect_list +
3642 sizeof(struct scsi_read_defect_data_hdr_10));
3644 num_returned = returned_length /
3645 sizeof(struct scsi_defect_desc_block);
3647 fprintf(stderr, "Got %d defect", num_returned);
3649 if ((lists_specified == 0) || (num_returned == 0)) {
3650 fprintf(stderr, "s.\n");
3652 } else if (num_returned == 1)
3653 fprintf(stderr, ":\n");
3655 fprintf(stderr, "s:\n");
3657 for (i = 0; i < num_returned; i++)
3658 fprintf(stdout, "%u\n",
3659 scsi_4btoul(dlist[i].address));
3663 fprintf(stderr, "Unknown defect format %d\n",
3664 returned_format & SRDDH10_DLIST_FORMAT_MASK);
3670 if (defect_list != NULL)
3678 #endif /* MINIMALISTIC */
3682 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3686 ccb = cam_getccb(device);
3692 #ifndef MINIMALISTIC
3694 mode_sense(struct cam_device *device, int mode_page, int page_control,
3695 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3700 ccb = cam_getccb(device);
3703 errx(1, "mode_sense: couldn't allocate CCB");
3705 bzero(&(&ccb->ccb_h)[1],
3706 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3708 scsi_mode_sense(&ccb->csio,
3709 /* retries */ retry_count,
3711 /* tag_action */ MSG_SIMPLE_Q_TAG,
3713 /* page_code */ page_control << 6,
3714 /* page */ mode_page,
3715 /* param_buf */ data,
3716 /* param_len */ datalen,
3717 /* sense_len */ SSD_FULL_SIZE,
3718 /* timeout */ timeout ? timeout : 5000);
3720 if (arglist & CAM_ARG_ERR_RECOVER)
3721 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3723 /* Disable freezing the device queue */
3724 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3726 if (((retval = cam_send_ccb(device, ccb)) < 0)
3727 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3728 if (arglist & CAM_ARG_VERBOSE) {
3729 cam_error_print(device, ccb, CAM_ESF_ALL,
3730 CAM_EPF_ALL, stderr);
3733 cam_close_device(device);
3735 err(1, "error sending mode sense command");
3737 errx(1, "error sending mode sense command");
3744 mode_select(struct cam_device *device, int save_pages, int retry_count,
3745 int timeout, u_int8_t *data, int datalen)
3750 ccb = cam_getccb(device);
3753 errx(1, "mode_select: couldn't allocate CCB");
3755 bzero(&(&ccb->ccb_h)[1],
3756 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3758 scsi_mode_select(&ccb->csio,
3759 /* retries */ retry_count,
3761 /* tag_action */ MSG_SIMPLE_Q_TAG,
3762 /* scsi_page_fmt */ 1,
3763 /* save_pages */ save_pages,
3764 /* param_buf */ data,
3765 /* param_len */ datalen,
3766 /* sense_len */ SSD_FULL_SIZE,
3767 /* timeout */ timeout ? timeout : 5000);
3769 if (arglist & CAM_ARG_ERR_RECOVER)
3770 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3772 /* Disable freezing the device queue */
3773 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3775 if (((retval = cam_send_ccb(device, ccb)) < 0)
3776 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3777 if (arglist & CAM_ARG_VERBOSE) {
3778 cam_error_print(device, ccb, CAM_ESF_ALL,
3779 CAM_EPF_ALL, stderr);
3782 cam_close_device(device);
3785 err(1, "error sending mode select command");
3787 errx(1, "error sending mode select command");
3795 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
3796 int retry_count, int timeout)
3798 int c, mode_page = -1, page_control = 0;
3799 int binary = 0, list = 0;
3801 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3807 arglist |= CAM_ARG_DBD;
3810 arglist |= CAM_ARG_MODE_EDIT;
3816 mode_page = strtol(optarg, NULL, 0);
3818 errx(1, "invalid mode page %d", mode_page);
3821 page_control = strtol(optarg, NULL, 0);
3822 if ((page_control < 0) || (page_control > 3))
3823 errx(1, "invalid page control field %d",
3825 arglist |= CAM_ARG_PAGE_CNTL;
3832 if (mode_page == -1 && list == 0)
3833 errx(1, "you must specify a mode page!");
3836 mode_list(device, page_control, arglist & CAM_ARG_DBD,
3837 retry_count, timeout);
3839 mode_edit(device, mode_page, page_control,
3840 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
3841 retry_count, timeout);
3846 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
3847 int retry_count, int timeout)
3850 u_int32_t flags = CAM_DIR_NONE;
3851 u_int8_t *data_ptr = NULL;
3853 u_int8_t atacmd[12];
3854 struct get_hook hook;
3855 int c, data_bytes = 0;
3861 char *datastr = NULL, *tstr, *resstr = NULL;
3863 int fd_data = 0, fd_res = 0;
3866 ccb = cam_getccb(device);
3869 warnx("scsicmd: error allocating ccb");
3873 bzero(&(&ccb->ccb_h)[1],
3874 sizeof(union ccb) - sizeof(struct ccb_hdr));
3876 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3880 while (isspace(*tstr) && (*tstr != '\0'))
3882 hook.argc = argc - optind;
3883 hook.argv = argv + optind;
3885 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
3888 * Increment optind by the number of arguments the
3889 * encoding routine processed. After each call to
3890 * getopt(3), optind points to the argument that
3891 * getopt should process _next_. In this case,
3892 * that means it points to the first command string
3893 * argument, if there is one. Once we increment
3894 * this, it should point to either the next command
3895 * line argument, or it should be past the end of
3902 while (isspace(*tstr) && (*tstr != '\0'))
3904 hook.argc = argc - optind;
3905 hook.argv = argv + optind;
3907 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
3910 * Increment optind by the number of arguments the
3911 * encoding routine processed. After each call to
3912 * getopt(3), optind points to the argument that
3913 * getopt should process _next_. In this case,
3914 * that means it points to the first command string
3915 * argument, if there is one. Once we increment
3916 * this, it should point to either the next command
3917 * line argument, or it should be past the end of
3929 if (arglist & CAM_ARG_CMD_OUT) {
3930 warnx("command must either be "
3931 "read or write, not both");
3933 goto scsicmd_bailout;
3935 arglist |= CAM_ARG_CMD_IN;
3937 data_bytes = strtol(optarg, NULL, 0);
3938 if (data_bytes <= 0) {
3939 warnx("invalid number of input bytes %d",
3942 goto scsicmd_bailout;
3944 hook.argc = argc - optind;
3945 hook.argv = argv + optind;
3948 datastr = cget(&hook, NULL);
3950 * If the user supplied "-" instead of a format, he
3951 * wants the data to be written to stdout.
3953 if ((datastr != NULL)
3954 && (datastr[0] == '-'))
3957 data_ptr = (u_int8_t *)malloc(data_bytes);
3958 if (data_ptr == NULL) {
3959 warnx("can't malloc memory for data_ptr");
3961 goto scsicmd_bailout;
3965 if (arglist & CAM_ARG_CMD_IN) {
3966 warnx("command must either be "
3967 "read or write, not both");
3969 goto scsicmd_bailout;
3971 arglist |= CAM_ARG_CMD_OUT;
3972 flags = CAM_DIR_OUT;
3973 data_bytes = strtol(optarg, NULL, 0);
3974 if (data_bytes <= 0) {
3975 warnx("invalid number of output bytes %d",
3978 goto scsicmd_bailout;
3980 hook.argc = argc - optind;
3981 hook.argv = argv + optind;
3983 datastr = cget(&hook, NULL);
3984 data_ptr = (u_int8_t *)malloc(data_bytes);
3985 if (data_ptr == NULL) {
3986 warnx("can't malloc memory for data_ptr");
3988 goto scsicmd_bailout;
3990 bzero(data_ptr, data_bytes);
3992 * If the user supplied "-" instead of a format, he
3993 * wants the data to be read from stdin.
3995 if ((datastr != NULL)
3996 && (datastr[0] == '-'))
3999 buff_encode_visit(data_ptr, data_bytes, datastr,
4005 hook.argc = argc - optind;
4006 hook.argv = argv + optind;
4008 resstr = cget(&hook, NULL);
4009 if ((resstr != NULL) && (resstr[0] == '-'))
4019 * If fd_data is set, and we're writing to the device, we need to
4020 * read the data the user wants written from stdin.
4022 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4024 int amt_to_read = data_bytes;
4025 u_int8_t *buf_ptr = data_ptr;
4027 for (amt_read = 0; amt_to_read > 0;
4028 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4029 if (amt_read == -1) {
4030 warn("error reading data from stdin");
4032 goto scsicmd_bailout;
4034 amt_to_read -= amt_read;
4035 buf_ptr += amt_read;
4039 if (arglist & CAM_ARG_ERR_RECOVER)
4040 flags |= CAM_PASS_ERR_RECOVER;
4042 /* Disable freezing the device queue */
4043 flags |= CAM_DEV_QFRZDIS;
4047 * This is taken from the SCSI-3 draft spec.
4048 * (T10/1157D revision 0.3)
4049 * The top 3 bits of an opcode are the group code.
4050 * The next 5 bits are the command code.
4051 * Group 0: six byte commands
4052 * Group 1: ten byte commands
4053 * Group 2: ten byte commands
4055 * Group 4: sixteen byte commands
4056 * Group 5: twelve byte commands
4057 * Group 6: vendor specific
4058 * Group 7: vendor specific
4060 switch((cdb[0] >> 5) & 0x7) {
4071 /* computed by buff_encode_visit */
4082 * We should probably use csio_build_visit or something like that
4083 * here, but it's easier to encode arguments as you go. The
4084 * alternative would be skipping the CDB argument and then encoding
4085 * it here, since we've got the data buffer argument by now.
4087 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4089 cam_fill_csio(&ccb->csio,
4090 /*retries*/ retry_count,
4093 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4094 /*data_ptr*/ data_ptr,
4095 /*dxfer_len*/ data_bytes,
4096 /*sense_len*/ SSD_FULL_SIZE,
4097 /*cdb_len*/ cdb_len,
4098 /*timeout*/ timeout ? timeout : 5000);
4101 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4103 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4105 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4107 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4109 cam_fill_ataio(&ccb->ataio,
4110 /*retries*/ retry_count,
4114 /*data_ptr*/ data_ptr,
4115 /*dxfer_len*/ data_bytes,
4116 /*timeout*/ timeout ? timeout : 5000);
4119 if (((retval = cam_send_ccb(device, ccb)) < 0)
4120 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4121 const char warnstr[] = "error sending command";
4128 if (arglist & CAM_ARG_VERBOSE) {
4129 cam_error_print(device, ccb, CAM_ESF_ALL,
4130 CAM_EPF_ALL, stderr);
4134 goto scsicmd_bailout;
4137 if (atacmd_len && need_res) {
4139 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4141 fprintf(stdout, "\n");
4144 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4145 ccb->ataio.res.status,
4146 ccb->ataio.res.error,
4147 ccb->ataio.res.lba_low,
4148 ccb->ataio.res.lba_mid,
4149 ccb->ataio.res.lba_high,
4150 ccb->ataio.res.device,
4151 ccb->ataio.res.lba_low_exp,
4152 ccb->ataio.res.lba_mid_exp,
4153 ccb->ataio.res.lba_high_exp,
4154 ccb->ataio.res.sector_count,
4155 ccb->ataio.res.sector_count_exp);
4160 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4161 && (arglist & CAM_ARG_CMD_IN)
4162 && (data_bytes > 0)) {
4164 buff_decode_visit(data_ptr, data_bytes, datastr,
4166 fprintf(stdout, "\n");
4168 ssize_t amt_written;
4169 int amt_to_write = data_bytes;
4170 u_int8_t *buf_ptr = data_ptr;
4172 for (amt_written = 0; (amt_to_write > 0) &&
4173 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4174 amt_to_write -= amt_written;
4175 buf_ptr += amt_written;
4177 if (amt_written == -1) {
4178 warn("error writing data to stdout");
4180 goto scsicmd_bailout;
4181 } else if ((amt_written == 0)
4182 && (amt_to_write > 0)) {
4183 warnx("only wrote %u bytes out of %u",
4184 data_bytes - amt_to_write, data_bytes);
4191 if ((data_bytes > 0) && (data_ptr != NULL))
4200 camdebug(int argc, char **argv, char *combinedopt)
4203 int bus = -1, target = -1, lun = -1;
4204 char *tstr, *tmpstr = NULL;
4208 bzero(&ccb, sizeof(union ccb));
4210 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4213 arglist |= CAM_ARG_DEBUG_INFO;
4214 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4217 arglist |= CAM_ARG_DEBUG_PERIPH;
4218 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4221 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4222 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4225 arglist |= CAM_ARG_DEBUG_TRACE;
4226 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4229 arglist |= CAM_ARG_DEBUG_XPT;
4230 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4233 arglist |= CAM_ARG_DEBUG_CDB;
4234 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4237 arglist |= CAM_ARG_DEBUG_PROBE;
4238 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4245 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4246 warnx("error opening transport layer device %s", XPT_DEVICE);
4247 warn("%s", XPT_DEVICE);
4254 warnx("you must specify \"off\", \"all\" or a bus,");
4255 warnx("bus:target, or bus:target:lun");
4262 while (isspace(*tstr) && (*tstr != '\0'))
4265 if (strncmp(tstr, "off", 3) == 0) {
4266 ccb.cdbg.flags = CAM_DEBUG_NONE;
4267 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4268 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4269 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4270 } else if (strncmp(tstr, "all", 3) != 0) {
4271 tmpstr = (char *)strtok(tstr, ":");
4272 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4273 bus = strtol(tmpstr, NULL, 0);
4274 arglist |= CAM_ARG_BUS;
4275 tmpstr = (char *)strtok(NULL, ":");
4276 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4277 target = strtol(tmpstr, NULL, 0);
4278 arglist |= CAM_ARG_TARGET;
4279 tmpstr = (char *)strtok(NULL, ":");
4280 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4281 lun = strtol(tmpstr, NULL, 0);
4282 arglist |= CAM_ARG_LUN;
4287 warnx("you must specify \"all\", \"off\", or a bus,");
4288 warnx("bus:target, or bus:target:lun to debug");
4294 ccb.ccb_h.func_code = XPT_DEBUG;
4295 ccb.ccb_h.path_id = bus;
4296 ccb.ccb_h.target_id = target;
4297 ccb.ccb_h.target_lun = lun;
4299 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4300 warn("CAMIOCOMMAND ioctl failed");
4305 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4306 CAM_FUNC_NOTAVAIL) {
4307 warnx("CAM debugging not available");
4308 warnx("you need to put options CAMDEBUG in"
4309 " your kernel config file!");
4311 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4313 warnx("XPT_DEBUG CCB failed with status %#x",
4317 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4319 "Debugging turned off\n");
4322 "Debugging enabled for "
4335 tagcontrol(struct cam_device *device, int argc, char **argv,
4345 ccb = cam_getccb(device);
4348 warnx("tagcontrol: error allocating ccb");
4352 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4355 numtags = strtol(optarg, NULL, 0);
4357 warnx("tag count %d is < 0", numtags);
4359 goto tagcontrol_bailout;
4370 cam_path_string(device, pathstr, sizeof(pathstr));
4373 bzero(&(&ccb->ccb_h)[1],
4374 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4375 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4376 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4377 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4378 ccb->crs.openings = numtags;
4381 if (cam_send_ccb(device, ccb) < 0) {
4382 perror("error sending XPT_REL_SIMQ CCB");
4384 goto tagcontrol_bailout;
4387 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4388 warnx("XPT_REL_SIMQ CCB failed");
4389 cam_error_print(device, ccb, CAM_ESF_ALL,
4390 CAM_EPF_ALL, stderr);
4392 goto tagcontrol_bailout;
4397 fprintf(stdout, "%stagged openings now %d\n",
4398 pathstr, ccb->crs.openings);
4401 bzero(&(&ccb->ccb_h)[1],
4402 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4404 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4406 if (cam_send_ccb(device, ccb) < 0) {
4407 perror("error sending XPT_GDEV_STATS CCB");
4409 goto tagcontrol_bailout;
4412 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4413 warnx("XPT_GDEV_STATS CCB failed");
4414 cam_error_print(device, ccb, CAM_ESF_ALL,
4415 CAM_EPF_ALL, stderr);
4417 goto tagcontrol_bailout;
4420 if (arglist & CAM_ARG_VERBOSE) {
4421 fprintf(stdout, "%s", pathstr);
4422 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4423 fprintf(stdout, "%s", pathstr);
4424 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4425 fprintf(stdout, "%s", pathstr);
4426 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
4427 fprintf(stdout, "%s", pathstr);
4428 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
4429 fprintf(stdout, "%s", pathstr);
4430 fprintf(stdout, "held %d\n", ccb->cgds.held);
4431 fprintf(stdout, "%s", pathstr);
4432 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4433 fprintf(stdout, "%s", pathstr);
4434 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4437 fprintf(stdout, "%s", pathstr);
4438 fprintf(stdout, "device openings: ");
4440 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4441 ccb->cgds.dev_active);
4451 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4455 cam_path_string(device, pathstr, sizeof(pathstr));
4457 if (cts->transport == XPORT_SPI) {
4458 struct ccb_trans_settings_spi *spi =
4459 &cts->xport_specific.spi;
4461 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4463 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4466 if (spi->sync_offset != 0) {
4469 freq = scsi_calc_syncsrate(spi->sync_period);
4470 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4471 pathstr, freq / 1000, freq % 1000);
4475 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4476 fprintf(stdout, "%soffset: %d\n", pathstr,
4480 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4481 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4482 (0x01 << spi->bus_width) * 8);
4485 if (spi->valid & CTS_SPI_VALID_DISC) {
4486 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4487 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4488 "enabled" : "disabled");
4491 if (cts->transport == XPORT_FC) {
4492 struct ccb_trans_settings_fc *fc =
4493 &cts->xport_specific.fc;
4495 if (fc->valid & CTS_FC_VALID_WWNN)
4496 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4497 (long long) fc->wwnn);
4498 if (fc->valid & CTS_FC_VALID_WWPN)
4499 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4500 (long long) fc->wwpn);
4501 if (fc->valid & CTS_FC_VALID_PORT)
4502 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4503 if (fc->valid & CTS_FC_VALID_SPEED)
4504 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4505 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4507 if (cts->transport == XPORT_SAS) {
4508 struct ccb_trans_settings_sas *sas =
4509 &cts->xport_specific.sas;
4511 if (sas->valid & CTS_SAS_VALID_SPEED)
4512 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4513 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4515 if (cts->transport == XPORT_ATA) {
4516 struct ccb_trans_settings_pata *pata =
4517 &cts->xport_specific.ata;
4519 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4520 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4521 ata_mode2string(pata->mode));
4523 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4524 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4527 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4528 fprintf(stdout, "%sPIO transaction length: %d\n",
4529 pathstr, pata->bytecount);
4532 if (cts->transport == XPORT_SATA) {
4533 struct ccb_trans_settings_sata *sata =
4534 &cts->xport_specific.sata;
4536 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4537 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4540 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4541 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4542 ata_mode2string(sata->mode));
4544 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4545 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4548 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4549 fprintf(stdout, "%sPIO transaction length: %d\n",
4550 pathstr, sata->bytecount);
4552 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4553 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4556 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4557 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4560 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4561 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4565 if (cts->protocol == PROTO_ATA) {
4566 struct ccb_trans_settings_ata *ata=
4567 &cts->proto_specific.ata;
4569 if (ata->valid & CTS_ATA_VALID_TQ) {
4570 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4571 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4572 "enabled" : "disabled");
4575 if (cts->protocol == PROTO_SCSI) {
4576 struct ccb_trans_settings_scsi *scsi=
4577 &cts->proto_specific.scsi;
4579 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4580 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4581 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4582 "enabled" : "disabled");
4589 * Get a path inquiry CCB for the specified device.
4592 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4597 ccb = cam_getccb(device);
4599 warnx("get_cpi: couldn't allocate CCB");
4602 bzero(&(&ccb->ccb_h)[1],
4603 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4604 ccb->ccb_h.func_code = XPT_PATH_INQ;
4605 if (cam_send_ccb(device, ccb) < 0) {
4606 warn("get_cpi: error sending Path Inquiry CCB");
4607 if (arglist & CAM_ARG_VERBOSE)
4608 cam_error_print(device, ccb, CAM_ESF_ALL,
4609 CAM_EPF_ALL, stderr);
4611 goto get_cpi_bailout;
4613 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4614 if (arglist & CAM_ARG_VERBOSE)
4615 cam_error_print(device, ccb, CAM_ESF_ALL,
4616 CAM_EPF_ALL, stderr);
4618 goto get_cpi_bailout;
4620 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4628 * Get a get device CCB for the specified device.
4631 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4636 ccb = cam_getccb(device);
4638 warnx("get_cgd: couldn't allocate CCB");
4641 bzero(&(&ccb->ccb_h)[1],
4642 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4643 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4644 if (cam_send_ccb(device, ccb) < 0) {
4645 warn("get_cgd: error sending Path Inquiry CCB");
4646 if (arglist & CAM_ARG_VERBOSE)
4647 cam_error_print(device, ccb, CAM_ESF_ALL,
4648 CAM_EPF_ALL, stderr);
4650 goto get_cgd_bailout;
4652 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4653 if (arglist & CAM_ARG_VERBOSE)
4654 cam_error_print(device, ccb, CAM_ESF_ALL,
4655 CAM_EPF_ALL, stderr);
4657 goto get_cgd_bailout;
4659 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4666 /* return the type of disk (really the command type) */
4668 get_disk_type(struct cam_device *device)
4670 struct ccb_getdev cgd;
4672 (void) memset(&cgd, 0x0, sizeof(cgd));
4673 get_cgd(device, &cgd);
4674 switch(cgd.protocol) {
4687 cpi_print(struct ccb_pathinq *cpi)
4689 char adapter_str[1024];
4692 snprintf(adapter_str, sizeof(adapter_str),
4693 "%s%d:", cpi->dev_name, cpi->unit_number);
4695 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
4698 for (i = 1; i < 0xff; i = i << 1) {
4701 if ((i & cpi->hba_inquiry) == 0)
4704 fprintf(stdout, "%s supports ", adapter_str);
4708 str = "MDP message";
4711 str = "32 bit wide SCSI";
4714 str = "16 bit wide SCSI";
4717 str = "SDTR message";
4720 str = "linked CDBs";
4723 str = "tag queue messages";
4726 str = "soft reset alternative";
4729 str = "SATA Port Multiplier";
4732 str = "unknown PI bit set";
4735 fprintf(stdout, "%s\n", str);
4738 for (i = 1; i < 0xff; i = i << 1) {
4741 if ((i & cpi->hba_misc) == 0)
4744 fprintf(stdout, "%s ", adapter_str);
4748 str = "bus scans from high ID to low ID";
4751 str = "removable devices not included in scan";
4753 case PIM_NOINITIATOR:
4754 str = "initiator role not supported";
4756 case PIM_NOBUSRESET:
4757 str = "user has disabled initial BUS RESET or"
4758 " controller is in target/mixed mode";
4761 str = "do not send 6-byte commands";
4764 str = "scan bus sequentially";
4767 str = "unknown PIM bit set";
4770 fprintf(stdout, "%s\n", str);
4773 for (i = 1; i < 0xff; i = i << 1) {
4776 if ((i & cpi->target_sprt) == 0)
4779 fprintf(stdout, "%s supports ", adapter_str);
4782 str = "target mode processor mode";
4785 str = "target mode phase cog. mode";
4787 case PIT_DISCONNECT:
4788 str = "disconnects in target mode";
4791 str = "terminate I/O message in target mode";
4794 str = "group 6 commands in target mode";
4797 str = "group 7 commands in target mode";
4800 str = "unknown PIT bit set";
4804 fprintf(stdout, "%s\n", str);
4806 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
4808 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
4810 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
4812 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
4813 adapter_str, cpi->hpath_id);
4814 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
4816 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
4817 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
4818 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
4819 adapter_str, cpi->hba_vendor);
4820 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
4821 adapter_str, cpi->hba_device);
4822 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
4823 adapter_str, cpi->hba_subvendor);
4824 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
4825 adapter_str, cpi->hba_subdevice);
4826 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
4827 fprintf(stdout, "%s base transfer speed: ", adapter_str);
4828 if (cpi->base_transfer_speed > 1000)
4829 fprintf(stdout, "%d.%03dMB/sec\n",
4830 cpi->base_transfer_speed / 1000,
4831 cpi->base_transfer_speed % 1000);
4833 fprintf(stdout, "%dKB/sec\n",
4834 (cpi->base_transfer_speed % 1000) * 1000);
4835 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
4836 adapter_str, cpi->maxio);
4840 get_print_cts(struct cam_device *device, int user_settings, int quiet,
4841 struct ccb_trans_settings *cts)
4847 ccb = cam_getccb(device);
4850 warnx("get_print_cts: error allocating ccb");
4854 bzero(&(&ccb->ccb_h)[1],
4855 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4857 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
4859 if (user_settings == 0)
4860 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
4862 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
4864 if (cam_send_ccb(device, ccb) < 0) {
4865 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
4866 if (arglist & CAM_ARG_VERBOSE)
4867 cam_error_print(device, ccb, CAM_ESF_ALL,
4868 CAM_EPF_ALL, stderr);
4870 goto get_print_cts_bailout;
4873 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4874 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
4875 if (arglist & CAM_ARG_VERBOSE)
4876 cam_error_print(device, ccb, CAM_ESF_ALL,
4877 CAM_EPF_ALL, stderr);
4879 goto get_print_cts_bailout;
4883 cts_print(device, &ccb->cts);
4886 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
4888 get_print_cts_bailout:
4896 ratecontrol(struct cam_device *device, int retry_count, int timeout,
4897 int argc, char **argv, char *combinedopt)
4901 int user_settings = 0;
4903 int disc_enable = -1, tag_enable = -1;
4906 double syncrate = -1;
4909 int change_settings = 0, send_tur = 0;
4910 struct ccb_pathinq cpi;
4912 ccb = cam_getccb(device);
4914 warnx("ratecontrol: error allocating ccb");
4917 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4926 if (strncasecmp(optarg, "enable", 6) == 0)
4928 else if (strncasecmp(optarg, "disable", 7) == 0)
4931 warnx("-D argument \"%s\" is unknown", optarg);
4933 goto ratecontrol_bailout;
4935 change_settings = 1;
4938 mode = ata_string2mode(optarg);
4940 warnx("unknown mode '%s'", optarg);
4942 goto ratecontrol_bailout;
4944 change_settings = 1;
4947 offset = strtol(optarg, NULL, 0);
4949 warnx("offset value %d is < 0", offset);
4951 goto ratecontrol_bailout;
4953 change_settings = 1;
4959 syncrate = atof(optarg);
4961 warnx("sync rate %f is < 0", syncrate);
4963 goto ratecontrol_bailout;
4965 change_settings = 1;
4968 if (strncasecmp(optarg, "enable", 6) == 0)
4970 else if (strncasecmp(optarg, "disable", 7) == 0)
4973 warnx("-T argument \"%s\" is unknown", optarg);
4975 goto ratecontrol_bailout;
4977 change_settings = 1;
4983 bus_width = strtol(optarg, NULL, 0);
4984 if (bus_width < 0) {
4985 warnx("bus width %d is < 0", bus_width);
4987 goto ratecontrol_bailout;
4989 change_settings = 1;
4995 bzero(&(&ccb->ccb_h)[1],
4996 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4998 * Grab path inquiry information, so we can determine whether
4999 * or not the initiator is capable of the things that the user
5002 ccb->ccb_h.func_code = XPT_PATH_INQ;
5003 if (cam_send_ccb(device, ccb) < 0) {
5004 perror("error sending XPT_PATH_INQ CCB");
5005 if (arglist & CAM_ARG_VERBOSE) {
5006 cam_error_print(device, ccb, CAM_ESF_ALL,
5007 CAM_EPF_ALL, stderr);
5010 goto ratecontrol_bailout;
5012 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5013 warnx("XPT_PATH_INQ CCB failed");
5014 if (arglist & CAM_ARG_VERBOSE) {
5015 cam_error_print(device, ccb, CAM_ESF_ALL,
5016 CAM_EPF_ALL, stderr);
5019 goto ratecontrol_bailout;
5021 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5022 bzero(&(&ccb->ccb_h)[1],
5023 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5025 fprintf(stdout, "%s parameters:\n",
5026 user_settings ? "User" : "Current");
5028 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5030 goto ratecontrol_bailout;
5032 if (arglist & CAM_ARG_VERBOSE)
5035 if (change_settings) {
5036 int didsettings = 0;
5037 struct ccb_trans_settings_spi *spi = NULL;
5038 struct ccb_trans_settings_pata *pata = NULL;
5039 struct ccb_trans_settings_sata *sata = NULL;
5040 struct ccb_trans_settings_ata *ata = NULL;
5041 struct ccb_trans_settings_scsi *scsi = NULL;
5043 if (ccb->cts.transport == XPORT_SPI)
5044 spi = &ccb->cts.xport_specific.spi;
5045 if (ccb->cts.transport == XPORT_ATA)
5046 pata = &ccb->cts.xport_specific.ata;
5047 if (ccb->cts.transport == XPORT_SATA)
5048 sata = &ccb->cts.xport_specific.sata;
5049 if (ccb->cts.protocol == PROTO_ATA)
5050 ata = &ccb->cts.proto_specific.ata;
5051 if (ccb->cts.protocol == PROTO_SCSI)
5052 scsi = &ccb->cts.proto_specific.scsi;
5053 ccb->cts.xport_specific.valid = 0;
5054 ccb->cts.proto_specific.valid = 0;
5055 if (spi && disc_enable != -1) {
5056 spi->valid |= CTS_SPI_VALID_DISC;
5057 if (disc_enable == 0)
5058 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5060 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5063 if (tag_enable != -1) {
5064 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5065 warnx("HBA does not support tagged queueing, "
5066 "so you cannot modify tag settings");
5068 goto ratecontrol_bailout;
5071 ata->valid |= CTS_SCSI_VALID_TQ;
5072 if (tag_enable == 0)
5073 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5075 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5078 scsi->valid |= CTS_SCSI_VALID_TQ;
5079 if (tag_enable == 0)
5080 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5082 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5086 if (spi && offset != -1) {
5087 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5088 warnx("HBA is not capable of changing offset");
5090 goto ratecontrol_bailout;
5092 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5093 spi->sync_offset = offset;
5096 if (spi && syncrate != -1) {
5097 int prelim_sync_period;
5099 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5100 warnx("HBA is not capable of changing "
5103 goto ratecontrol_bailout;
5105 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5107 * The sync rate the user gives us is in MHz.
5108 * We need to translate it into KHz for this
5113 * Next, we calculate a "preliminary" sync period
5114 * in tenths of a nanosecond.
5117 prelim_sync_period = 0;
5119 prelim_sync_period = 10000000 / syncrate;
5121 scsi_calc_syncparam(prelim_sync_period);
5124 if (sata && syncrate != -1) {
5125 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5126 warnx("HBA is not capable of changing "
5129 goto ratecontrol_bailout;
5131 if (!user_settings) {
5132 warnx("You can modify only user rate "
5133 "settings for SATA");
5135 goto ratecontrol_bailout;
5137 sata->revision = ata_speed2revision(syncrate * 100);
5138 if (sata->revision < 0) {
5139 warnx("Invalid rate %f", syncrate);
5141 goto ratecontrol_bailout;
5143 sata->valid |= CTS_SATA_VALID_REVISION;
5146 if ((pata || sata) && mode != -1) {
5147 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5148 warnx("HBA is not capable of changing "
5151 goto ratecontrol_bailout;
5153 if (!user_settings) {
5154 warnx("You can modify only user mode "
5155 "settings for ATA/SATA");
5157 goto ratecontrol_bailout;
5161 pata->valid |= CTS_ATA_VALID_MODE;
5164 sata->valid |= CTS_SATA_VALID_MODE;
5169 * The bus_width argument goes like this:
5173 * Therefore, if you shift the number of bits given on the
5174 * command line right by 4, you should get the correct
5177 if (spi && bus_width != -1) {
5179 * We might as well validate things here with a
5180 * decipherable error message, rather than what
5181 * will probably be an indecipherable error message
5182 * by the time it gets back to us.
5184 if ((bus_width == 16)
5185 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5186 warnx("HBA does not support 16 bit bus width");
5188 goto ratecontrol_bailout;
5189 } else if ((bus_width == 32)
5190 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5191 warnx("HBA does not support 32 bit bus width");
5193 goto ratecontrol_bailout;
5194 } else if ((bus_width != 8)
5195 && (bus_width != 16)
5196 && (bus_width != 32)) {
5197 warnx("Invalid bus width %d", bus_width);
5199 goto ratecontrol_bailout;
5201 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5202 spi->bus_width = bus_width >> 4;
5205 if (didsettings == 0) {
5206 goto ratecontrol_bailout;
5208 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5209 if (cam_send_ccb(device, ccb) < 0) {
5210 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5211 if (arglist & CAM_ARG_VERBOSE) {
5212 cam_error_print(device, ccb, CAM_ESF_ALL,
5213 CAM_EPF_ALL, stderr);
5216 goto ratecontrol_bailout;
5218 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5219 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5220 if (arglist & CAM_ARG_VERBOSE) {
5221 cam_error_print(device, ccb, CAM_ESF_ALL,
5222 CAM_EPF_ALL, stderr);
5225 goto ratecontrol_bailout;
5229 retval = testunitready(device, retry_count, timeout,
5230 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5232 * If the TUR didn't succeed, just bail.
5236 fprintf(stderr, "Test Unit Ready failed\n");
5237 goto ratecontrol_bailout;
5240 if ((change_settings || send_tur) && !quiet &&
5241 (ccb->cts.transport == XPORT_ATA ||
5242 ccb->cts.transport == XPORT_SATA || send_tur)) {
5243 fprintf(stdout, "New parameters:\n");
5244 retval = get_print_cts(device, user_settings, 0, NULL);
5247 ratecontrol_bailout:
5253 scsiformat(struct cam_device *device, int argc, char **argv,
5254 char *combinedopt, int retry_count, int timeout)
5258 int ycount = 0, quiet = 0;
5259 int error = 0, retval = 0;
5260 int use_timeout = 10800 * 1000;
5262 struct format_defect_list_header fh;
5263 u_int8_t *data_ptr = NULL;
5264 u_int32_t dxfer_len = 0;
5266 int num_warnings = 0;
5269 ccb = cam_getccb(device);
5272 warnx("scsiformat: error allocating ccb");
5276 bzero(&(&ccb->ccb_h)[1],
5277 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5279 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5300 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5301 "following device:\n");
5303 error = scsidoinquiry(device, argc, argv, combinedopt,
5304 retry_count, timeout);
5307 warnx("scsiformat: error sending inquiry");
5308 goto scsiformat_bailout;
5313 if (!get_confirmation()) {
5315 goto scsiformat_bailout;
5320 use_timeout = timeout;
5323 fprintf(stdout, "Current format timeout is %d seconds\n",
5324 use_timeout / 1000);
5328 * If the user hasn't disabled questions and didn't specify a
5329 * timeout on the command line, ask them if they want the current
5333 && (timeout == 0)) {
5335 int new_timeout = 0;
5337 fprintf(stdout, "Enter new timeout in seconds or press\n"
5338 "return to keep the current timeout [%d] ",
5339 use_timeout / 1000);
5341 if (fgets(str, sizeof(str), stdin) != NULL) {
5343 new_timeout = atoi(str);
5346 if (new_timeout != 0) {
5347 use_timeout = new_timeout * 1000;
5348 fprintf(stdout, "Using new timeout value %d\n",
5349 use_timeout / 1000);
5354 * Keep this outside the if block below to silence any unused
5355 * variable warnings.
5357 bzero(&fh, sizeof(fh));
5360 * If we're in immediate mode, we've got to include the format
5363 if (immediate != 0) {
5364 fh.byte2 = FU_DLH_IMMED;
5365 data_ptr = (u_int8_t *)&fh;
5366 dxfer_len = sizeof(fh);
5367 byte2 = FU_FMT_DATA;
5368 } else if (quiet == 0) {
5369 fprintf(stdout, "Formatting...");
5373 scsi_format_unit(&ccb->csio,
5374 /* retries */ retry_count,
5376 /* tag_action */ MSG_SIMPLE_Q_TAG,
5379 /* data_ptr */ data_ptr,
5380 /* dxfer_len */ dxfer_len,
5381 /* sense_len */ SSD_FULL_SIZE,
5382 /* timeout */ use_timeout);
5384 /* Disable freezing the device queue */
5385 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5387 if (arglist & CAM_ARG_ERR_RECOVER)
5388 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5390 if (((retval = cam_send_ccb(device, ccb)) < 0)
5391 || ((immediate == 0)
5392 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5393 const char errstr[] = "error sending format command";
5400 if (arglist & CAM_ARG_VERBOSE) {
5401 cam_error_print(device, ccb, CAM_ESF_ALL,
5402 CAM_EPF_ALL, stderr);
5405 goto scsiformat_bailout;
5409 * If we ran in non-immediate mode, we already checked for errors
5410 * above and printed out any necessary information. If we're in
5411 * immediate mode, we need to loop through and get status
5412 * information periodically.
5414 if (immediate == 0) {
5416 fprintf(stdout, "Format Complete\n");
5418 goto scsiformat_bailout;
5425 bzero(&(&ccb->ccb_h)[1],
5426 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5429 * There's really no need to do error recovery or
5430 * retries here, since we're just going to sit in a
5431 * loop and wait for the device to finish formatting.
5433 scsi_test_unit_ready(&ccb->csio,
5436 /* tag_action */ MSG_SIMPLE_Q_TAG,
5437 /* sense_len */ SSD_FULL_SIZE,
5438 /* timeout */ 5000);
5440 /* Disable freezing the device queue */
5441 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5443 retval = cam_send_ccb(device, ccb);
5446 * If we get an error from the ioctl, bail out. SCSI
5447 * errors are expected.
5450 warn("error sending CAMIOCOMMAND ioctl");
5451 if (arglist & CAM_ARG_VERBOSE) {
5452 cam_error_print(device, ccb, CAM_ESF_ALL,
5453 CAM_EPF_ALL, stderr);
5456 goto scsiformat_bailout;
5459 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5461 if ((status != CAM_REQ_CMP)
5462 && (status == CAM_SCSI_STATUS_ERROR)
5463 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5464 struct scsi_sense_data *sense;
5465 int error_code, sense_key, asc, ascq;
5467 sense = &ccb->csio.sense_data;
5468 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5469 ccb->csio.sense_resid, &error_code, &sense_key,
5470 &asc, &ascq, /*show_errors*/ 1);
5473 * According to the SCSI-2 and SCSI-3 specs, a
5474 * drive that is in the middle of a format should
5475 * return NOT READY with an ASC of "logical unit
5476 * not ready, format in progress". The sense key
5477 * specific bytes will then be a progress indicator.
5479 if ((sense_key == SSD_KEY_NOT_READY)
5480 && (asc == 0x04) && (ascq == 0x04)) {
5483 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5484 ccb->csio.sense_resid, sks) == 0)
5487 u_int64_t percentage;
5489 val = scsi_2btoul(&sks[1]);
5490 percentage = 10000 * val;
5493 "\rFormatting: %ju.%02u %% "
5495 (uintmax_t)(percentage /
5497 (unsigned)((percentage /
5501 } else if ((quiet == 0)
5502 && (++num_warnings <= 1)) {
5503 warnx("Unexpected SCSI Sense Key "
5504 "Specific value returned "
5506 scsi_sense_print(device, &ccb->csio,
5508 warnx("Unable to print status "
5509 "information, but format will "
5511 warnx("will exit when format is "
5516 warnx("Unexpected SCSI error during format");
5517 cam_error_print(device, ccb, CAM_ESF_ALL,
5518 CAM_EPF_ALL, stderr);
5520 goto scsiformat_bailout;
5523 } else if (status != CAM_REQ_CMP) {
5524 warnx("Unexpected CAM status %#x", status);
5525 if (arglist & CAM_ARG_VERBOSE)
5526 cam_error_print(device, ccb, CAM_ESF_ALL,
5527 CAM_EPF_ALL, stderr);
5529 goto scsiformat_bailout;
5532 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5535 fprintf(stdout, "\nFormat Complete\n");
5545 scsisanitize(struct cam_device *device, int argc, char **argv,
5546 char *combinedopt, int retry_count, int timeout)
5549 u_int8_t action = 0;
5551 int ycount = 0, quiet = 0;
5552 int error = 0, retval = 0;
5553 int use_timeout = 10800 * 1000;
5559 const char *pattern = NULL;
5560 u_int8_t *data_ptr = NULL;
5561 u_int32_t dxfer_len = 0;
5563 int num_warnings = 0;
5566 ccb = cam_getccb(device);
5569 warnx("scsisanitize: error allocating ccb");
5573 bzero(&(&ccb->ccb_h)[1],
5574 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5576 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5579 if (strcasecmp(optarg, "overwrite") == 0)
5580 action = SSZ_SERVICE_ACTION_OVERWRITE;
5581 else if (strcasecmp(optarg, "block") == 0)
5582 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
5583 else if (strcasecmp(optarg, "crypto") == 0)
5584 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
5585 else if (strcasecmp(optarg, "exitfailure") == 0)
5586 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
5588 warnx("invalid service operation \"%s\"",
5591 goto scsisanitize_bailout;
5595 passes = strtol(optarg, NULL, 0);
5596 if (passes < 1 || passes > 31) {
5597 warnx("invalid passes value %d", passes);
5599 goto scsisanitize_bailout;
5630 warnx("an action is required");
5632 goto scsisanitize_bailout;
5633 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
5634 struct scsi_sanitize_parameter_list *pl;
5638 if (pattern == NULL) {
5639 warnx("overwrite action requires -P argument");
5641 goto scsisanitize_bailout;
5643 fd = open(pattern, O_RDONLY);
5645 warn("cannot open pattern file %s", pattern);
5647 goto scsisanitize_bailout;
5649 if (fstat(fd, &sb) < 0) {
5650 warn("cannot stat pattern file %s", pattern);
5652 goto scsisanitize_bailout;
5655 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
5656 warnx("pattern file size exceeds maximum value %d",
5657 SSZPL_MAX_PATTERN_LENGTH);
5659 goto scsisanitize_bailout;
5661 dxfer_len = sizeof(*pl) + sz;
5662 data_ptr = calloc(1, dxfer_len);
5663 if (data_ptr == NULL) {
5664 warnx("cannot allocate parameter list buffer");
5666 goto scsisanitize_bailout;
5669 amt = read(fd, data_ptr + sizeof(*pl), sz);
5671 warn("cannot read pattern file");
5673 goto scsisanitize_bailout;
5674 } else if (amt != sz) {
5675 warnx("short pattern file read");
5677 goto scsisanitize_bailout;
5680 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
5686 pl->byte1 |= SSZPL_INVERT;
5687 scsi_ulto2b(sz, pl->length);
5693 else if (invert != 0)
5695 else if (pattern != NULL)
5700 warnx("%s argument only valid with overwrite "
5703 goto scsisanitize_bailout;
5708 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5709 "following device:\n");
5711 error = scsidoinquiry(device, argc, argv, combinedopt,
5712 retry_count, timeout);
5715 warnx("scsisanitize: error sending inquiry");
5716 goto scsisanitize_bailout;
5721 if (!get_confirmation()) {
5723 goto scsisanitize_bailout;
5728 use_timeout = timeout;
5731 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
5732 use_timeout / 1000);
5736 * If the user hasn't disabled questions and didn't specify a
5737 * timeout on the command line, ask them if they want the current
5741 && (timeout == 0)) {
5743 int new_timeout = 0;
5745 fprintf(stdout, "Enter new timeout in seconds or press\n"
5746 "return to keep the current timeout [%d] ",
5747 use_timeout / 1000);
5749 if (fgets(str, sizeof(str), stdin) != NULL) {
5751 new_timeout = atoi(str);
5754 if (new_timeout != 0) {
5755 use_timeout = new_timeout * 1000;
5756 fprintf(stdout, "Using new timeout value %d\n",
5757 use_timeout / 1000);
5763 byte2 |= SSZ_UNRESTRICTED_EXIT;
5767 scsi_sanitize(&ccb->csio,
5768 /* retries */ retry_count,
5770 /* tag_action */ MSG_SIMPLE_Q_TAG,
5773 /* data_ptr */ data_ptr,
5774 /* dxfer_len */ dxfer_len,
5775 /* sense_len */ SSD_FULL_SIZE,
5776 /* timeout */ use_timeout);
5778 /* Disable freezing the device queue */
5779 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5781 if (arglist & CAM_ARG_ERR_RECOVER)
5782 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5784 if (((retval = cam_send_ccb(device, ccb)) < 0)
5785 || ((immediate == 0)
5786 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5787 const char errstr[] = "error sending sanitize command";
5794 if (arglist & CAM_ARG_VERBOSE) {
5795 cam_error_print(device, ccb, CAM_ESF_ALL,
5796 CAM_EPF_ALL, stderr);
5799 goto scsisanitize_bailout;
5803 * If we ran in non-immediate mode, we already checked for errors
5804 * above and printed out any necessary information. If we're in
5805 * immediate mode, we need to loop through and get status
5806 * information periodically.
5808 if (immediate == 0) {
5810 fprintf(stdout, "Sanitize Complete\n");
5812 goto scsisanitize_bailout;
5819 bzero(&(&ccb->ccb_h)[1],
5820 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5823 * There's really no need to do error recovery or
5824 * retries here, since we're just going to sit in a
5825 * loop and wait for the device to finish sanitizing.
5827 scsi_test_unit_ready(&ccb->csio,
5830 /* tag_action */ MSG_SIMPLE_Q_TAG,
5831 /* sense_len */ SSD_FULL_SIZE,
5832 /* timeout */ 5000);
5834 /* Disable freezing the device queue */
5835 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5837 retval = cam_send_ccb(device, ccb);
5840 * If we get an error from the ioctl, bail out. SCSI
5841 * errors are expected.
5844 warn("error sending CAMIOCOMMAND ioctl");
5845 if (arglist & CAM_ARG_VERBOSE) {
5846 cam_error_print(device, ccb, CAM_ESF_ALL,
5847 CAM_EPF_ALL, stderr);
5850 goto scsisanitize_bailout;
5853 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5855 if ((status != CAM_REQ_CMP)
5856 && (status == CAM_SCSI_STATUS_ERROR)
5857 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5858 struct scsi_sense_data *sense;
5859 int error_code, sense_key, asc, ascq;
5861 sense = &ccb->csio.sense_data;
5862 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5863 ccb->csio.sense_resid, &error_code, &sense_key,
5864 &asc, &ascq, /*show_errors*/ 1);
5867 * According to the SCSI-3 spec, a drive that is in the
5868 * middle of a sanitize should return NOT READY with an
5869 * ASC of "logical unit not ready, sanitize in
5870 * progress". The sense key specific bytes will then
5871 * be a progress indicator.
5873 if ((sense_key == SSD_KEY_NOT_READY)
5874 && (asc == 0x04) && (ascq == 0x1b)) {
5877 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5878 ccb->csio.sense_resid, sks) == 0)
5881 u_int64_t percentage;
5883 val = scsi_2btoul(&sks[1]);
5884 percentage = 10000 * val;
5887 "\rSanitizing: %ju.%02u %% "
5889 (uintmax_t)(percentage /
5891 (unsigned)((percentage /
5895 } else if ((quiet == 0)
5896 && (++num_warnings <= 1)) {
5897 warnx("Unexpected SCSI Sense Key "
5898 "Specific value returned "
5899 "during sanitize:");
5900 scsi_sense_print(device, &ccb->csio,
5902 warnx("Unable to print status "
5903 "information, but sanitze will "
5905 warnx("will exit when sanitize is "
5910 warnx("Unexpected SCSI error during sanitize");
5911 cam_error_print(device, ccb, CAM_ESF_ALL,
5912 CAM_EPF_ALL, stderr);
5914 goto scsisanitize_bailout;
5917 } else if (status != CAM_REQ_CMP) {
5918 warnx("Unexpected CAM status %#x", status);
5919 if (arglist & CAM_ARG_VERBOSE)
5920 cam_error_print(device, ccb, CAM_ESF_ALL,
5921 CAM_EPF_ALL, stderr);
5923 goto scsisanitize_bailout;
5925 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5928 fprintf(stdout, "\nSanitize Complete\n");
5930 scsisanitize_bailout:
5933 if (data_ptr != NULL)
5941 scsireportluns(struct cam_device *device, int argc, char **argv,
5942 char *combinedopt, int retry_count, int timeout)
5945 int c, countonly, lunsonly;
5946 struct scsi_report_luns_data *lundata;
5948 uint8_t report_type;
5949 uint32_t list_len, i, j;
5954 report_type = RPL_REPORT_DEFAULT;
5955 ccb = cam_getccb(device);
5958 warnx("%s: error allocating ccb", __func__);
5962 bzero(&(&ccb->ccb_h)[1],
5963 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5968 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5977 if (strcasecmp(optarg, "default") == 0)
5978 report_type = RPL_REPORT_DEFAULT;
5979 else if (strcasecmp(optarg, "wellknown") == 0)
5980 report_type = RPL_REPORT_WELLKNOWN;
5981 else if (strcasecmp(optarg, "all") == 0)
5982 report_type = RPL_REPORT_ALL;
5984 warnx("%s: invalid report type \"%s\"",
5995 if ((countonly != 0)
5996 && (lunsonly != 0)) {
5997 warnx("%s: you can only specify one of -c or -l", __func__);
6002 * According to SPC-4, the allocation length must be at least 16
6003 * bytes -- enough for the header and one LUN.
6005 alloc_len = sizeof(*lundata) + 8;
6009 lundata = malloc(alloc_len);
6011 if (lundata == NULL) {
6012 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6017 scsi_report_luns(&ccb->csio,
6018 /*retries*/ retry_count,
6020 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6021 /*select_report*/ report_type,
6022 /*rpl_buf*/ lundata,
6023 /*alloc_len*/ alloc_len,
6024 /*sense_len*/ SSD_FULL_SIZE,
6025 /*timeout*/ timeout ? timeout : 5000);
6027 /* Disable freezing the device queue */
6028 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6030 if (arglist & CAM_ARG_ERR_RECOVER)
6031 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6033 if (cam_send_ccb(device, ccb) < 0) {
6034 warn("error sending REPORT LUNS command");
6036 if (arglist & CAM_ARG_VERBOSE)
6037 cam_error_print(device, ccb, CAM_ESF_ALL,
6038 CAM_EPF_ALL, stderr);
6044 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6045 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6051 list_len = scsi_4btoul(lundata->length);
6054 * If we need to list the LUNs, and our allocation
6055 * length was too short, reallocate and retry.
6057 if ((countonly == 0)
6058 && (list_len > (alloc_len - sizeof(*lundata)))) {
6059 alloc_len = list_len + sizeof(*lundata);
6065 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6066 ((list_len / 8) > 1) ? "s" : "");
6071 for (i = 0; i < (list_len / 8); i++) {
6075 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6077 fprintf(stdout, ",");
6078 switch (lundata->luns[i].lundata[j] &
6079 RPL_LUNDATA_ATYP_MASK) {
6080 case RPL_LUNDATA_ATYP_PERIPH:
6081 if ((lundata->luns[i].lundata[j] &
6082 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6083 fprintf(stdout, "%d:",
6084 lundata->luns[i].lundata[j] &
6085 RPL_LUNDATA_PERIPH_BUS_MASK);
6087 && ((lundata->luns[i].lundata[j+2] &
6088 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6091 fprintf(stdout, "%d",
6092 lundata->luns[i].lundata[j+1]);
6094 case RPL_LUNDATA_ATYP_FLAT: {
6096 tmplun[0] = lundata->luns[i].lundata[j] &
6097 RPL_LUNDATA_FLAT_LUN_MASK;
6098 tmplun[1] = lundata->luns[i].lundata[j+1];
6100 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6104 case RPL_LUNDATA_ATYP_LUN:
6105 fprintf(stdout, "%d:%d:%d",
6106 (lundata->luns[i].lundata[j+1] &
6107 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6108 lundata->luns[i].lundata[j] &
6109 RPL_LUNDATA_LUN_TARG_MASK,
6110 lundata->luns[i].lundata[j+1] &
6111 RPL_LUNDATA_LUN_LUN_MASK);
6113 case RPL_LUNDATA_ATYP_EXTLUN: {
6114 int field_len_code, eam_code;
6116 eam_code = lundata->luns[i].lundata[j] &
6117 RPL_LUNDATA_EXT_EAM_MASK;
6118 field_len_code = (lundata->luns[i].lundata[j] &
6119 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6121 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6122 && (field_len_code == 0x00)) {
6123 fprintf(stdout, "%d",
6124 lundata->luns[i].lundata[j+1]);
6125 } else if ((eam_code ==
6126 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6127 && (field_len_code == 0x03)) {
6131 * This format takes up all 8 bytes.
6132 * If we aren't starting at offset 0,
6136 fprintf(stdout, "Invalid "
6139 "specified format", j);
6143 bzero(tmp_lun, sizeof(tmp_lun));
6144 bcopy(&lundata->luns[i].lundata[j+1],
6145 &tmp_lun[1], sizeof(tmp_lun) - 1);
6146 fprintf(stdout, "%#jx",
6147 (intmax_t)scsi_8btou64(tmp_lun));
6150 fprintf(stderr, "Unknown Extended LUN"
6151 "Address method %#x, length "
6152 "code %#x", eam_code,
6159 fprintf(stderr, "Unknown LUN address method "
6160 "%#x\n", lundata->luns[i].lundata[0] &
6161 RPL_LUNDATA_ATYP_MASK);
6165 * For the flat addressing method, there are no
6166 * other levels after it.
6171 fprintf(stdout, "\n");
6184 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6185 char *combinedopt, int retry_count, int timeout)
6188 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6189 struct scsi_read_capacity_data rcap;
6190 struct scsi_read_capacity_data_long rcaplong;
6204 ccb = cam_getccb(device);
6207 warnx("%s: error allocating ccb", __func__);
6211 bzero(&(&ccb->ccb_h)[1],
6212 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6214 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6241 if ((blocksizeonly != 0)
6242 && (numblocks != 0)) {
6243 warnx("%s: you can only specify one of -b or -N", __func__);
6248 if ((blocksizeonly != 0)
6249 && (sizeonly != 0)) {
6250 warnx("%s: you can only specify one of -b or -s", __func__);
6257 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6263 && (blocksizeonly != 0)) {
6264 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6269 scsi_read_capacity(&ccb->csio,
6270 /*retries*/ retry_count,
6272 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6275 /*timeout*/ timeout ? timeout : 5000);
6277 /* Disable freezing the device queue */
6278 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6280 if (arglist & CAM_ARG_ERR_RECOVER)
6281 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6283 if (cam_send_ccb(device, ccb) < 0) {
6284 warn("error sending READ CAPACITY command");
6286 if (arglist & CAM_ARG_VERBOSE)
6287 cam_error_print(device, ccb, CAM_ESF_ALL,
6288 CAM_EPF_ALL, stderr);
6294 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6295 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6300 maxsector = scsi_4btoul(rcap.addr);
6301 block_len = scsi_4btoul(rcap.length);
6304 * A last block of 2^32-1 means that the true capacity is over 2TB,
6305 * and we need to issue the long READ CAPACITY to get the real
6306 * capacity. Otherwise, we're all set.
6308 if (maxsector != 0xffffffff)
6311 scsi_read_capacity_16(&ccb->csio,
6312 /*retries*/ retry_count,
6314 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6318 /*rcap_buf*/ (uint8_t *)&rcaplong,
6319 /*rcap_buf_len*/ sizeof(rcaplong),
6320 /*sense_len*/ SSD_FULL_SIZE,
6321 /*timeout*/ timeout ? timeout : 5000);
6323 /* Disable freezing the device queue */
6324 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6326 if (arglist & CAM_ARG_ERR_RECOVER)
6327 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6329 if (cam_send_ccb(device, ccb) < 0) {
6330 warn("error sending READ CAPACITY (16) command");
6332 if (arglist & CAM_ARG_VERBOSE)
6333 cam_error_print(device, ccb, CAM_ESF_ALL,
6334 CAM_EPF_ALL, stderr);
6340 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6341 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6346 maxsector = scsi_8btou64(rcaplong.addr);
6347 block_len = scsi_4btoul(rcaplong.length);
6350 if (blocksizeonly == 0) {
6352 * Humanize implies !quiet, and also implies numblocks.
6354 if (humanize != 0) {
6359 tmpbytes = (maxsector + 1) * block_len;
6360 ret = humanize_number(tmpstr, sizeof(tmpstr),
6361 tmpbytes, "", HN_AUTOSCALE,
6364 HN_DIVISOR_1000 : 0));
6366 warnx("%s: humanize_number failed!", __func__);
6370 fprintf(stdout, "Device Size: %s%s", tmpstr,
6371 (sizeonly == 0) ? ", " : "\n");
6372 } else if (numblocks != 0) {
6373 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6374 "Blocks: " : "", (uintmax_t)maxsector + 1,
6375 (sizeonly == 0) ? ", " : "\n");
6377 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6378 "Last Block: " : "", (uintmax_t)maxsector,
6379 (sizeonly == 0) ? ", " : "\n");
6383 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6384 "Block Length: " : "", block_len, (quiet == 0) ?
6393 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6394 int retry_count, int timeout)
6398 uint8_t *smp_request = NULL, *smp_response = NULL;
6399 int request_size = 0, response_size = 0;
6400 int fd_request = 0, fd_response = 0;
6401 char *datastr = NULL;
6402 struct get_hook hook;
6407 * Note that at the moment we don't support sending SMP CCBs to
6408 * devices that aren't probed by CAM.
6410 ccb = cam_getccb(device);
6412 warnx("%s: error allocating CCB", __func__);
6416 bzero(&(&ccb->ccb_h)[1],
6417 sizeof(union ccb) - sizeof(struct ccb_hdr));
6419 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6422 arglist |= CAM_ARG_CMD_IN;
6423 response_size = strtol(optarg, NULL, 0);
6424 if (response_size <= 0) {
6425 warnx("invalid number of response bytes %d",
6428 goto smpcmd_bailout;
6430 hook.argc = argc - optind;
6431 hook.argv = argv + optind;
6434 datastr = cget(&hook, NULL);
6436 * If the user supplied "-" instead of a format, he
6437 * wants the data to be written to stdout.
6439 if ((datastr != NULL)
6440 && (datastr[0] == '-'))
6443 smp_response = (u_int8_t *)malloc(response_size);
6444 if (smp_response == NULL) {
6445 warn("can't malloc memory for SMP response");
6447 goto smpcmd_bailout;
6451 arglist |= CAM_ARG_CMD_OUT;
6452 request_size = strtol(optarg, NULL, 0);
6453 if (request_size <= 0) {
6454 warnx("invalid number of request bytes %d",
6457 goto smpcmd_bailout;
6459 hook.argc = argc - optind;
6460 hook.argv = argv + optind;
6462 datastr = cget(&hook, NULL);
6463 smp_request = (u_int8_t *)malloc(request_size);
6464 if (smp_request == NULL) {
6465 warn("can't malloc memory for SMP request");
6467 goto smpcmd_bailout;
6469 bzero(smp_request, request_size);
6471 * If the user supplied "-" instead of a format, he
6472 * wants the data to be read from stdin.
6474 if ((datastr != NULL)
6475 && (datastr[0] == '-'))
6478 buff_encode_visit(smp_request, request_size,
6489 * If fd_data is set, and we're writing to the device, we need to
6490 * read the data the user wants written from stdin.
6492 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6494 int amt_to_read = request_size;
6495 u_int8_t *buf_ptr = smp_request;
6497 for (amt_read = 0; amt_to_read > 0;
6498 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6499 if (amt_read == -1) {
6500 warn("error reading data from stdin");
6502 goto smpcmd_bailout;
6504 amt_to_read -= amt_read;
6505 buf_ptr += amt_read;
6509 if (((arglist & CAM_ARG_CMD_IN) == 0)
6510 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6511 warnx("%s: need both the request (-r) and response (-R) "
6512 "arguments", __func__);
6514 goto smpcmd_bailout;
6517 flags |= CAM_DEV_QFRZDIS;
6519 cam_fill_smpio(&ccb->smpio,
6520 /*retries*/ retry_count,
6523 /*smp_request*/ smp_request,
6524 /*smp_request_len*/ request_size,
6525 /*smp_response*/ smp_response,
6526 /*smp_response_len*/ response_size,
6527 /*timeout*/ timeout ? timeout : 5000);
6529 ccb->smpio.flags = SMP_FLAG_NONE;
6531 if (((retval = cam_send_ccb(device, ccb)) < 0)
6532 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6533 const char warnstr[] = "error sending command";
6540 if (arglist & CAM_ARG_VERBOSE) {
6541 cam_error_print(device, ccb, CAM_ESF_ALL,
6542 CAM_EPF_ALL, stderr);
6546 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6547 && (response_size > 0)) {
6548 if (fd_response == 0) {
6549 buff_decode_visit(smp_response, response_size,
6550 datastr, arg_put, NULL);
6551 fprintf(stdout, "\n");
6553 ssize_t amt_written;
6554 int amt_to_write = response_size;
6555 u_int8_t *buf_ptr = smp_response;
6557 for (amt_written = 0; (amt_to_write > 0) &&
6558 (amt_written = write(STDOUT_FILENO, buf_ptr,
6559 amt_to_write)) > 0;){
6560 amt_to_write -= amt_written;
6561 buf_ptr += amt_written;
6563 if (amt_written == -1) {
6564 warn("error writing data to stdout");
6566 goto smpcmd_bailout;
6567 } else if ((amt_written == 0)
6568 && (amt_to_write > 0)) {
6569 warnx("only wrote %u bytes out of %u",
6570 response_size - amt_to_write,
6579 if (smp_request != NULL)
6582 if (smp_response != NULL)
6589 smpreportgeneral(struct cam_device *device, int argc, char **argv,
6590 char *combinedopt, int retry_count, int timeout)
6593 struct smp_report_general_request *request = NULL;
6594 struct smp_report_general_response *response = NULL;
6595 struct sbuf *sb = NULL;
6597 int c, long_response = 0;
6601 * Note that at the moment we don't support sending SMP CCBs to
6602 * devices that aren't probed by CAM.
6604 ccb = cam_getccb(device);
6606 warnx("%s: error allocating CCB", __func__);
6610 bzero(&(&ccb->ccb_h)[1],
6611 sizeof(union ccb) - sizeof(struct ccb_hdr));
6613 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6622 request = malloc(sizeof(*request));
6623 if (request == NULL) {
6624 warn("%s: unable to allocate %zd bytes", __func__,
6630 response = malloc(sizeof(*response));
6631 if (response == NULL) {
6632 warn("%s: unable to allocate %zd bytes", __func__,
6639 smp_report_general(&ccb->smpio,
6643 /*request_len*/ sizeof(*request),
6644 (uint8_t *)response,
6645 /*response_len*/ sizeof(*response),
6646 /*long_response*/ long_response,
6649 if (((retval = cam_send_ccb(device, ccb)) < 0)
6650 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6651 const char warnstr[] = "error sending command";
6658 if (arglist & CAM_ARG_VERBOSE) {
6659 cam_error_print(device, ccb, CAM_ESF_ALL,
6660 CAM_EPF_ALL, stderr);
6667 * If the device supports the long response bit, try again and see
6668 * if we can get all of the data.
6670 if ((response->long_response & SMP_RG_LONG_RESPONSE)
6671 && (long_response == 0)) {
6672 ccb->ccb_h.status = CAM_REQ_INPROG;
6673 bzero(&(&ccb->ccb_h)[1],
6674 sizeof(union ccb) - sizeof(struct ccb_hdr));
6680 * XXX KDM detect and decode SMP errors here.
6682 sb = sbuf_new_auto();
6684 warnx("%s: error allocating sbuf", __func__);
6688 smp_report_general_sbuf(response, sizeof(*response), sb);
6690 if (sbuf_finish(sb) != 0) {
6691 warnx("%s: sbuf_finish", __func__);
6695 printf("%s", sbuf_data(sb));
6701 if (request != NULL)
6704 if (response != NULL)
6713 static struct camcontrol_opts phy_ops[] = {
6714 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
6715 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
6716 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
6717 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
6718 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
6719 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
6720 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
6721 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
6722 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
6727 smpphycontrol(struct cam_device *device, int argc, char **argv,
6728 char *combinedopt, int retry_count, int timeout)
6731 struct smp_phy_control_request *request = NULL;
6732 struct smp_phy_control_response *response = NULL;
6733 int long_response = 0;
6736 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
6738 uint64_t attached_dev_name = 0;
6739 int dev_name_set = 0;
6740 uint32_t min_plr = 0, max_plr = 0;
6741 uint32_t pp_timeout_val = 0;
6742 int slumber_partial = 0;
6743 int set_pp_timeout_val = 0;
6747 * Note that at the moment we don't support sending SMP CCBs to
6748 * devices that aren't probed by CAM.
6750 ccb = cam_getccb(device);
6752 warnx("%s: error allocating CCB", __func__);
6756 bzero(&(&ccb->ccb_h)[1],
6757 sizeof(union ccb) - sizeof(struct ccb_hdr));
6759 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6767 if (strcasecmp(optarg, "enable") == 0)
6769 else if (strcasecmp(optarg, "disable") == 0)
6772 warnx("%s: Invalid argument %s", __func__,
6779 slumber_partial |= enable <<
6780 SMP_PC_SAS_SLUMBER_SHIFT;
6783 slumber_partial |= enable <<
6784 SMP_PC_SAS_PARTIAL_SHIFT;
6787 slumber_partial |= enable <<
6788 SMP_PC_SATA_SLUMBER_SHIFT;
6791 slumber_partial |= enable <<
6792 SMP_PC_SATA_PARTIAL_SHIFT;
6795 warnx("%s: programmer error", __func__);
6798 break; /*NOTREACHED*/
6803 attached_dev_name = (uintmax_t)strtoumax(optarg,
6812 * We don't do extensive checking here, so this
6813 * will continue to work when new speeds come out.
6815 min_plr = strtoul(optarg, NULL, 0);
6817 || (min_plr > 0xf)) {
6818 warnx("%s: invalid link rate %x",
6826 * We don't do extensive checking here, so this
6827 * will continue to work when new speeds come out.
6829 max_plr = strtoul(optarg, NULL, 0);
6831 || (max_plr > 0xf)) {
6832 warnx("%s: invalid link rate %x",
6839 camcontrol_optret optreturn;
6840 cam_argmask argnums;
6843 if (phy_op_set != 0) {
6844 warnx("%s: only one phy operation argument "
6845 "(-o) allowed", __func__);
6853 * Allow the user to specify the phy operation
6854 * numerically, as well as with a name. This will
6855 * future-proof it a bit, so options that are added
6856 * in future specs can be used.
6858 if (isdigit(optarg[0])) {
6859 phy_operation = strtoul(optarg, NULL, 0);
6860 if ((phy_operation == 0)
6861 || (phy_operation > 0xff)) {
6862 warnx("%s: invalid phy operation %#x",
6863 __func__, phy_operation);
6869 optreturn = getoption(phy_ops, optarg, &phy_operation,
6872 if (optreturn == CC_OR_AMBIGUOUS) {
6873 warnx("%s: ambiguous option %s", __func__,
6878 } else if (optreturn == CC_OR_NOT_FOUND) {
6879 warnx("%s: option %s not found", __func__,
6891 pp_timeout_val = strtoul(optarg, NULL, 0);
6892 if (pp_timeout_val > 15) {
6893 warnx("%s: invalid partial pathway timeout "
6894 "value %u, need a value less than 16",
6895 __func__, pp_timeout_val);
6899 set_pp_timeout_val = 1;
6907 warnx("%s: a PHY (-p phy) argument is required",__func__);
6912 if (((dev_name_set != 0)
6913 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
6914 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
6915 && (dev_name_set == 0))) {
6916 warnx("%s: -d name and -o setdevname arguments both "
6917 "required to set device name", __func__);
6922 request = malloc(sizeof(*request));
6923 if (request == NULL) {
6924 warn("%s: unable to allocate %zd bytes", __func__,
6930 response = malloc(sizeof(*response));
6931 if (response == NULL) {
6932 warn("%s: unable to allocate %zd bytes", __func__,
6938 smp_phy_control(&ccb->smpio,
6943 (uint8_t *)response,
6946 /*expected_exp_change_count*/ 0,
6949 (set_pp_timeout_val != 0) ? 1 : 0,
6957 if (((retval = cam_send_ccb(device, ccb)) < 0)
6958 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6959 const char warnstr[] = "error sending command";
6966 if (arglist & CAM_ARG_VERBOSE) {
6968 * Use CAM_EPF_NORMAL so we only get one line of
6969 * SMP command decoding.
6971 cam_error_print(device, ccb, CAM_ESF_ALL,
6972 CAM_EPF_NORMAL, stderr);
6978 /* XXX KDM print out something here for success? */
6983 if (request != NULL)
6986 if (response != NULL)
6993 smpmaninfo(struct cam_device *device, int argc, char **argv,
6994 char *combinedopt, int retry_count, int timeout)
6997 struct smp_report_manuf_info_request request;
6998 struct smp_report_manuf_info_response response;
6999 struct sbuf *sb = NULL;
7000 int long_response = 0;
7005 * Note that at the moment we don't support sending SMP CCBs to
7006 * devices that aren't probed by CAM.
7008 ccb = cam_getccb(device);
7010 warnx("%s: error allocating CCB", __func__);
7014 bzero(&(&ccb->ccb_h)[1],
7015 sizeof(union ccb) - sizeof(struct ccb_hdr));
7017 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7026 bzero(&request, sizeof(request));
7027 bzero(&response, sizeof(response));
7029 smp_report_manuf_info(&ccb->smpio,
7034 (uint8_t *)&response,
7039 if (((retval = cam_send_ccb(device, ccb)) < 0)
7040 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7041 const char warnstr[] = "error sending command";
7048 if (arglist & CAM_ARG_VERBOSE) {
7049 cam_error_print(device, ccb, CAM_ESF_ALL,
7050 CAM_EPF_ALL, stderr);
7056 sb = sbuf_new_auto();
7058 warnx("%s: error allocating sbuf", __func__);
7062 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7064 if (sbuf_finish(sb) != 0) {
7065 warnx("%s: sbuf_finish", __func__);
7069 printf("%s", sbuf_data(sb));
7083 getdevid(struct cam_devitem *item)
7086 union ccb *ccb = NULL;
7088 struct cam_device *dev;
7090 dev = cam_open_btl(item->dev_match.path_id,
7091 item->dev_match.target_id,
7092 item->dev_match.target_lun, O_RDWR, NULL);
7095 warnx("%s", cam_errbuf);
7100 item->device_id_len = 0;
7102 ccb = cam_getccb(dev);
7104 warnx("%s: error allocating CCB", __func__);
7109 bzero(&(&ccb->ccb_h)[1],
7110 sizeof(union ccb) - sizeof(struct ccb_hdr));
7113 * On the first try, we just probe for the size of the data, and
7114 * then allocate that much memory and try again.
7117 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7118 ccb->ccb_h.flags = CAM_DIR_IN;
7119 ccb->cdai.flags = 0;
7120 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7121 ccb->cdai.bufsiz = item->device_id_len;
7122 if (item->device_id_len != 0)
7123 ccb->cdai.buf = (uint8_t *)item->device_id;
7125 if (cam_send_ccb(dev, ccb) < 0) {
7126 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7131 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7132 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7137 if (item->device_id_len == 0) {
7139 * This is our first time through. Allocate the buffer,
7140 * and then go back to get the data.
7142 if (ccb->cdai.provsiz == 0) {
7143 warnx("%s: invalid .provsiz field returned with "
7144 "XPT_GDEV_ADVINFO CCB", __func__);
7148 item->device_id_len = ccb->cdai.provsiz;
7149 item->device_id = malloc(item->device_id_len);
7150 if (item->device_id == NULL) {
7151 warn("%s: unable to allocate %d bytes", __func__,
7152 item->device_id_len);
7156 ccb->ccb_h.status = CAM_REQ_INPROG;
7162 cam_close_device(dev);
7171 * XXX KDM merge this code with getdevtree()?
7174 buildbusdevlist(struct cam_devlist *devlist)
7177 int bufsize, fd = -1;
7178 struct dev_match_pattern *patterns;
7179 struct cam_devitem *item = NULL;
7180 int skip_device = 0;
7183 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7184 warn("couldn't open %s", XPT_DEVICE);
7188 bzero(&ccb, sizeof(union ccb));
7190 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7191 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7192 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7194 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7195 bufsize = sizeof(struct dev_match_result) * 100;
7196 ccb.cdm.match_buf_len = bufsize;
7197 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7198 if (ccb.cdm.matches == NULL) {
7199 warnx("can't malloc memory for matches");
7203 ccb.cdm.num_matches = 0;
7204 ccb.cdm.num_patterns = 2;
7205 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7206 ccb.cdm.num_patterns;
7208 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7209 if (patterns == NULL) {
7210 warnx("can't malloc memory for patterns");
7215 ccb.cdm.patterns = patterns;
7216 bzero(patterns, ccb.cdm.pattern_buf_len);
7218 patterns[0].type = DEV_MATCH_DEVICE;
7219 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7220 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7221 patterns[1].type = DEV_MATCH_PERIPH;
7222 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7223 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7226 * We do the ioctl multiple times if necessary, in case there are
7227 * more than 100 nodes in the EDT.
7232 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7233 warn("error sending CAMIOCOMMAND ioctl");
7238 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7239 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7240 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7241 warnx("got CAM error %#x, CDM error %d\n",
7242 ccb.ccb_h.status, ccb.cdm.status);
7247 for (i = 0; i < ccb.cdm.num_matches; i++) {
7248 switch (ccb.cdm.matches[i].type) {
7249 case DEV_MATCH_DEVICE: {
7250 struct device_match_result *dev_result;
7253 &ccb.cdm.matches[i].result.device_result;
7255 if (dev_result->flags &
7256 DEV_RESULT_UNCONFIGURED) {
7262 item = malloc(sizeof(*item));
7264 warn("%s: unable to allocate %zd bytes",
7265 __func__, sizeof(*item));
7269 bzero(item, sizeof(*item));
7270 bcopy(dev_result, &item->dev_match,
7271 sizeof(*dev_result));
7272 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7275 if (getdevid(item) != 0) {
7281 case DEV_MATCH_PERIPH: {
7282 struct periph_match_result *periph_result;
7285 &ccb.cdm.matches[i].result.periph_result;
7287 if (skip_device != 0)
7289 item->num_periphs++;
7290 item->periph_matches = realloc(
7291 item->periph_matches,
7293 sizeof(struct periph_match_result));
7294 if (item->periph_matches == NULL) {
7295 warn("%s: error allocating periph "
7300 bcopy(periph_result, &item->periph_matches[
7301 item->num_periphs - 1],
7302 sizeof(*periph_result));
7306 fprintf(stderr, "%s: unexpected match "
7307 "type %d\n", __func__,
7308 ccb.cdm.matches[i].type);
7311 break; /*NOTREACHED*/
7314 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7315 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7323 free(ccb.cdm.matches);
7326 freebusdevlist(devlist);
7332 freebusdevlist(struct cam_devlist *devlist)
7334 struct cam_devitem *item, *item2;
7336 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7337 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7339 free(item->device_id);
7340 free(item->periph_matches);
7345 static struct cam_devitem *
7346 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7348 struct cam_devitem *item;
7350 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7351 struct scsi_vpd_id_descriptor *idd;
7354 * XXX KDM look for LUN IDs as well?
7356 idd = scsi_get_devid(item->device_id,
7357 item->device_id_len,
7358 scsi_devid_is_sas_target);
7362 if (scsi_8btou64(idd->identifier) == sasaddr)
7370 smpphylist(struct cam_device *device, int argc, char **argv,
7371 char *combinedopt, int retry_count, int timeout)
7373 struct smp_report_general_request *rgrequest = NULL;
7374 struct smp_report_general_response *rgresponse = NULL;
7375 struct smp_discover_request *disrequest = NULL;
7376 struct smp_discover_response *disresponse = NULL;
7377 struct cam_devlist devlist;
7379 int long_response = 0;
7386 * Note that at the moment we don't support sending SMP CCBs to
7387 * devices that aren't probed by CAM.
7389 ccb = cam_getccb(device);
7391 warnx("%s: error allocating CCB", __func__);
7395 bzero(&(&ccb->ccb_h)[1],
7396 sizeof(union ccb) - sizeof(struct ccb_hdr));
7397 STAILQ_INIT(&devlist.dev_queue);
7399 rgrequest = malloc(sizeof(*rgrequest));
7400 if (rgrequest == NULL) {
7401 warn("%s: unable to allocate %zd bytes", __func__,
7402 sizeof(*rgrequest));
7407 rgresponse = malloc(sizeof(*rgresponse));
7408 if (rgresponse == NULL) {
7409 warn("%s: unable to allocate %zd bytes", __func__,
7410 sizeof(*rgresponse));
7415 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7428 smp_report_general(&ccb->smpio,
7432 /*request_len*/ sizeof(*rgrequest),
7433 (uint8_t *)rgresponse,
7434 /*response_len*/ sizeof(*rgresponse),
7435 /*long_response*/ long_response,
7438 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7440 if (((retval = cam_send_ccb(device, ccb)) < 0)
7441 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7442 const char warnstr[] = "error sending command";
7449 if (arglist & CAM_ARG_VERBOSE) {
7450 cam_error_print(device, ccb, CAM_ESF_ALL,
7451 CAM_EPF_ALL, stderr);
7457 num_phys = rgresponse->num_phys;
7459 if (num_phys == 0) {
7461 fprintf(stdout, "%s: No Phys reported\n", __func__);
7466 devlist.path_id = device->path_id;
7468 retval = buildbusdevlist(&devlist);
7473 fprintf(stdout, "%d PHYs:\n", num_phys);
7474 fprintf(stdout, "PHY Attached SAS Address\n");
7477 disrequest = malloc(sizeof(*disrequest));
7478 if (disrequest == NULL) {
7479 warn("%s: unable to allocate %zd bytes", __func__,
7480 sizeof(*disrequest));
7485 disresponse = malloc(sizeof(*disresponse));
7486 if (disresponse == NULL) {
7487 warn("%s: unable to allocate %zd bytes", __func__,
7488 sizeof(*disresponse));
7493 for (i = 0; i < num_phys; i++) {
7494 struct cam_devitem *item;
7495 struct device_match_result *dev_match;
7496 char vendor[16], product[48], revision[16];
7500 bzero(&(&ccb->ccb_h)[1],
7501 sizeof(union ccb) - sizeof(struct ccb_hdr));
7503 ccb->ccb_h.status = CAM_REQ_INPROG;
7504 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7506 smp_discover(&ccb->smpio,
7510 sizeof(*disrequest),
7511 (uint8_t *)disresponse,
7512 sizeof(*disresponse),
7514 /*ignore_zone_group*/ 0,
7518 if (((retval = cam_send_ccb(device, ccb)) < 0)
7519 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7520 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7521 const char warnstr[] = "error sending command";
7528 if (arglist & CAM_ARG_VERBOSE) {
7529 cam_error_print(device, ccb, CAM_ESF_ALL,
7530 CAM_EPF_ALL, stderr);
7536 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7538 fprintf(stdout, "%3d <vacant>\n", i);
7542 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7545 item = findsasdevice(&devlist,
7546 scsi_8btou64(disresponse->attached_sas_address));
7550 || (item != NULL)) {
7551 fprintf(stdout, "%3d 0x%016jx", i,
7552 (uintmax_t)scsi_8btou64(
7553 disresponse->attached_sas_address));
7555 fprintf(stdout, "\n");
7558 } else if (quiet != 0)
7561 dev_match = &item->dev_match;
7563 if (dev_match->protocol == PROTO_SCSI) {
7564 cam_strvis(vendor, dev_match->inq_data.vendor,
7565 sizeof(dev_match->inq_data.vendor),
7567 cam_strvis(product, dev_match->inq_data.product,
7568 sizeof(dev_match->inq_data.product),
7570 cam_strvis(revision, dev_match->inq_data.revision,
7571 sizeof(dev_match->inq_data.revision),
7573 sprintf(tmpstr, "<%s %s %s>", vendor, product,
7575 } else if ((dev_match->protocol == PROTO_ATA)
7576 || (dev_match->protocol == PROTO_SATAPM)) {
7577 cam_strvis(product, dev_match->ident_data.model,
7578 sizeof(dev_match->ident_data.model),
7580 cam_strvis(revision, dev_match->ident_data.revision,
7581 sizeof(dev_match->ident_data.revision),
7583 sprintf(tmpstr, "<%s %s>", product, revision);
7585 sprintf(tmpstr, "<>");
7587 fprintf(stdout, " %-33s ", tmpstr);
7590 * If we have 0 periphs, that's a bug...
7592 if (item->num_periphs == 0) {
7593 fprintf(stdout, "\n");
7597 fprintf(stdout, "(");
7598 for (j = 0; j < item->num_periphs; j++) {
7600 fprintf(stdout, ",");
7602 fprintf(stdout, "%s%d",
7603 item->periph_matches[j].periph_name,
7604 item->periph_matches[j].unit_number);
7607 fprintf(stdout, ")\n");
7621 freebusdevlist(&devlist);
7627 atapm(struct cam_device *device, int argc, char **argv,
7628 char *combinedopt, int retry_count, int timeout)
7636 ccb = cam_getccb(device);
7639 warnx("%s: error allocating ccb", __func__);
7643 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7652 if (strcmp(argv[1], "idle") == 0) {
7654 cmd = ATA_IDLE_IMMEDIATE;
7657 } else if (strcmp(argv[1], "standby") == 0) {
7659 cmd = ATA_STANDBY_IMMEDIATE;
7661 cmd = ATA_STANDBY_CMD;
7669 else if (t <= (240 * 5))
7671 else if (t <= (252 * 5))
7672 /* special encoding for 21 minutes */
7674 else if (t <= (11 * 30 * 60))
7675 sc = (t - 1) / (30 * 60) + 241;
7679 cam_fill_ataio(&ccb->ataio,
7682 /*flags*/CAM_DIR_NONE,
7686 timeout ? timeout : 30 * 1000);
7687 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
7689 /* Disable freezing the device queue */
7690 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7692 if (arglist & CAM_ARG_ERR_RECOVER)
7693 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7695 if (cam_send_ccb(device, ccb) < 0) {
7696 warn("error sending command");
7698 if (arglist & CAM_ARG_VERBOSE)
7699 cam_error_print(device, ccb, CAM_ESF_ALL,
7700 CAM_EPF_ALL, stderr);
7706 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7707 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7716 #endif /* MINIMALISTIC */
7719 usage(int printlong)
7722 fprintf(printlong ? stdout : stderr,
7723 "usage: camcontrol <command> [device id][generic args][command args]\n"
7724 " camcontrol devlist [-v]\n"
7725 #ifndef MINIMALISTIC
7726 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
7727 " camcontrol tur [dev_id][generic args]\n"
7728 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
7729 " camcontrol identify [dev_id][generic args] [-v]\n"
7730 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
7731 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
7733 " camcontrol start [dev_id][generic args]\n"
7734 " camcontrol stop [dev_id][generic args]\n"
7735 " camcontrol load [dev_id][generic args]\n"
7736 " camcontrol eject [dev_id][generic args]\n"
7737 #endif /* MINIMALISTIC */
7738 " camcontrol rescan <all | bus[:target:lun]>\n"
7739 " camcontrol reset <all | bus[:target:lun]>\n"
7740 #ifndef MINIMALISTIC
7741 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
7742 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
7743 " [-P pagectl][-e | -b][-d]\n"
7744 " camcontrol cmd [dev_id][generic args]\n"
7745 " <-a cmd [args] | -c cmd [args]>\n"
7746 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
7747 " camcontrol smpcmd [dev_id][generic args]\n"
7748 " <-r len fmt [args]> <-R len fmt [args]>\n"
7749 " camcontrol smprg [dev_id][generic args][-l]\n"
7750 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
7751 " [-o operation][-d name][-m rate][-M rate]\n"
7752 " [-T pp_timeout][-a enable|disable]\n"
7753 " [-A enable|disable][-s enable|disable]\n"
7754 " [-S enable|disable]\n"
7755 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
7756 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
7757 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
7758 " <all|bus[:target[:lun]]|off>\n"
7759 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
7760 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
7761 " [-D <enable|disable>][-M mode][-O offset]\n"
7762 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
7763 " [-U][-W bus_width]\n"
7764 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
7765 " camcontrol sanitize [dev_id][generic args]\n"
7766 " [-a overwrite|block|crypto|exitfailure]\n"
7767 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
7769 " camcontrol idle [dev_id][generic args][-t time]\n"
7770 " camcontrol standby [dev_id][generic args][-t time]\n"
7771 " camcontrol sleep [dev_id][generic args]\n"
7772 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
7773 " camcontrol security [dev_id][generic args]\n"
7774 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
7775 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
7776 " [-U <user|master>] [-y]\n"
7777 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
7778 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
7779 #endif /* MINIMALISTIC */
7780 " camcontrol help\n");
7783 #ifndef MINIMALISTIC
7785 "Specify one of the following options:\n"
7786 "devlist list all CAM devices\n"
7787 "periphlist list all CAM peripheral drivers attached to a device\n"
7788 "tur send a test unit ready to the named device\n"
7789 "inquiry send a SCSI inquiry command to the named device\n"
7790 "identify send a ATA identify command to the named device\n"
7791 "reportluns send a SCSI report luns command to the device\n"
7792 "readcap send a SCSI read capacity command to the device\n"
7793 "start send a Start Unit command to the device\n"
7794 "stop send a Stop Unit command to the device\n"
7795 "load send a Start Unit command to the device with the load bit set\n"
7796 "eject send a Stop Unit command to the device with the eject bit set\n"
7797 "rescan rescan all busses, the given bus, or bus:target:lun\n"
7798 "reset reset all busses, the given bus, or bus:target:lun\n"
7799 "defects read the defect list of the specified device\n"
7800 "modepage display or edit (-e) the given mode page\n"
7801 "cmd send the given SCSI command, may need -i or -o as well\n"
7802 "smpcmd send the given SMP command, requires -o and -i\n"
7803 "smprg send the SMP Report General command\n"
7804 "smppc send the SMP PHY Control command, requires -p\n"
7805 "smpphylist display phys attached to a SAS expander\n"
7806 "smpmaninfo send the SMP Report Manufacturer Info command\n"
7807 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
7808 "tags report or set the number of transaction slots for a device\n"
7809 "negotiate report or set device negotiation parameters\n"
7810 "format send the SCSI FORMAT UNIT command to the named device\n"
7811 "sanitize send the SCSI SANITIZE command to the named device\n"
7812 "idle send the ATA IDLE command to the named device\n"
7813 "standby send the ATA STANDBY command to the named device\n"
7814 "sleep send the ATA SLEEP command to the named device\n"
7815 "fwdownload program firmware of the named device with the given image"
7816 "security report or send ATA security commands to the named device\n"
7817 "help this message\n"
7818 "Device Identifiers:\n"
7819 "bus:target specify the bus and target, lun defaults to 0\n"
7820 "bus:target:lun specify the bus, target and lun\n"
7821 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
7822 "Generic arguments:\n"
7823 "-v be verbose, print out sense information\n"
7824 "-t timeout command timeout in seconds, overrides default timeout\n"
7825 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
7826 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
7827 "-E have the kernel attempt to perform SCSI error recovery\n"
7828 "-C count specify the SCSI command retry count (needs -E to work)\n"
7829 "modepage arguments:\n"
7830 "-l list all available mode pages\n"
7831 "-m page specify the mode page to view or edit\n"
7832 "-e edit the specified mode page\n"
7833 "-b force view to binary mode\n"
7834 "-d disable block descriptors for mode sense\n"
7835 "-P pgctl page control field 0-3\n"
7836 "defects arguments:\n"
7837 "-f format specify defect list format (block, bfi or phys)\n"
7838 "-G get the grown defect list\n"
7839 "-P get the permanent defect list\n"
7840 "inquiry arguments:\n"
7841 "-D get the standard inquiry data\n"
7842 "-S get the serial number\n"
7843 "-R get the transfer rate, etc.\n"
7844 "reportluns arguments:\n"
7845 "-c only report a count of available LUNs\n"
7846 "-l only print out luns, and not a count\n"
7847 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
7848 "readcap arguments\n"
7849 "-b only report the blocksize\n"
7850 "-h human readable device size, base 2\n"
7851 "-H human readable device size, base 10\n"
7852 "-N print the number of blocks instead of last block\n"
7853 "-q quiet, print numbers only\n"
7854 "-s only report the last block/device size\n"
7856 "-c cdb [args] specify the SCSI CDB\n"
7857 "-i len fmt specify input data and input data format\n"
7858 "-o len fmt [args] specify output data and output data fmt\n"
7859 "smpcmd arguments:\n"
7860 "-r len fmt [args] specify the SMP command to be sent\n"
7861 "-R len fmt [args] specify SMP response format\n"
7862 "smprg arguments:\n"
7863 "-l specify the long response format\n"
7864 "smppc arguments:\n"
7865 "-p phy specify the PHY to operate on\n"
7866 "-l specify the long request/response format\n"
7867 "-o operation specify the phy control operation\n"
7868 "-d name set the attached device name\n"
7869 "-m rate set the minimum physical link rate\n"
7870 "-M rate set the maximum physical link rate\n"
7871 "-T pp_timeout set the partial pathway timeout value\n"
7872 "-a enable|disable enable or disable SATA slumber\n"
7873 "-A enable|disable enable or disable SATA partial phy power\n"
7874 "-s enable|disable enable or disable SAS slumber\n"
7875 "-S enable|disable enable or disable SAS partial phy power\n"
7876 "smpphylist arguments:\n"
7877 "-l specify the long response format\n"
7878 "-q only print phys with attached devices\n"
7879 "smpmaninfo arguments:\n"
7880 "-l specify the long response format\n"
7881 "debug arguments:\n"
7882 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
7883 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
7884 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
7885 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
7887 "-N tags specify the number of tags to use for this device\n"
7888 "-q be quiet, don't report the number of tags\n"
7889 "-v report a number of tag-related parameters\n"
7890 "negotiate arguments:\n"
7891 "-a send a test unit ready after negotiation\n"
7892 "-c report/set current negotiation settings\n"
7893 "-D <arg> \"enable\" or \"disable\" disconnection\n"
7894 "-M mode set ATA mode\n"
7895 "-O offset set command delay offset\n"
7896 "-q be quiet, don't report anything\n"
7897 "-R syncrate synchronization rate in MHz\n"
7898 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
7899 "-U report/set user negotiation settings\n"
7900 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
7901 "-v also print a Path Inquiry CCB for the controller\n"
7902 "format arguments:\n"
7903 "-q be quiet, don't print status messages\n"
7904 "-r run in report only mode\n"
7905 "-w don't send immediate format command\n"
7906 "-y don't ask any questions\n"
7907 "sanitize arguments:\n"
7908 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
7909 "-c passes overwrite passes to perform (1 to 31)\n"
7910 "-I invert overwrite pattern after each pass\n"
7911 "-P pattern path to overwrite pattern file\n"
7912 "-q be quiet, don't print status messages\n"
7913 "-r run in report only mode\n"
7914 "-U run operation in unrestricted completion exit mode\n"
7915 "-w don't send immediate sanitize command\n"
7916 "-y don't ask any questions\n"
7917 "idle/standby arguments:\n"
7918 "-t <arg> number of seconds before respective state.\n"
7919 "fwdownload arguments:\n"
7920 "-f fw_image path to firmware image file\n"
7921 "-y don't ask any questions\n"
7922 "-s run in simulation mode\n"
7923 "-v print info for every firmware segment sent to device\n"
7924 "security arguments:\n"
7925 "-d pwd disable security using the given password for the selected\n"
7927 "-e pwd erase the device using the given pwd for the selected user\n"
7928 "-f freeze the security configuration of the specified device\n"
7929 "-h pwd enhanced erase the device using the given pwd for the\n"
7931 "-k pwd unlock the device using the given pwd for the selected\n"
7933 "-l <high|maximum> specifies which security level to set: high or maximum\n"
7934 "-q be quiet, do not print any status messages\n"
7935 "-s pwd password the device (enable security) using the given\n"
7936 " pwd for the selected user\n"
7937 "-T timeout overrides the timeout (seconds) used for erase operation\n"
7938 "-U <user|master> specifies which user to set: user or master\n"
7939 "-y don't ask any questions\n"
7941 "-f freeze the HPA configuration of the device\n"
7942 "-l lock the HPA configuration of the device\n"
7943 "-P make the HPA max sectors persist\n"
7944 "-p pwd Set the HPA configuration password required for unlock\n"
7946 "-q be quiet, do not print any status messages\n"
7947 "-s sectors configures the maximum user accessible sectors of the\n"
7949 "-U pwd unlock the HPA configuration of the device\n"
7950 "-y don't ask any questions\n"
7952 #endif /* MINIMALISTIC */
7956 main(int argc, char **argv)
7959 char *device = NULL;
7961 struct cam_device *cam_dev = NULL;
7962 int timeout = 0, retry_count = 1;
7963 camcontrol_optret optreturn;
7965 const char *mainopt = "C:En:t:u:v";
7966 const char *subopt = NULL;
7967 char combinedopt[256];
7968 int error = 0, optstart = 2;
7970 #ifndef MINIMALISTIC
7971 int bus, target, lun;
7972 #endif /* MINIMALISTIC */
7974 cmdlist = CAM_CMD_NONE;
7975 arglist = CAM_ARG_NONE;
7983 * Get the base option.
7985 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
7987 if (optreturn == CC_OR_AMBIGUOUS) {
7988 warnx("ambiguous option %s", argv[1]);
7991 } else if (optreturn == CC_OR_NOT_FOUND) {
7992 warnx("option %s not found", argv[1]);
7998 * Ahh, getopt(3) is a pain.
8000 * This is a gross hack. There really aren't many other good
8001 * options (excuse the pun) for parsing options in a situation like
8002 * this. getopt is kinda braindead, so you end up having to run
8003 * through the options twice, and give each invocation of getopt
8004 * the option string for the other invocation.
8006 * You would think that you could just have two groups of options.
8007 * The first group would get parsed by the first invocation of
8008 * getopt, and the second group would get parsed by the second
8009 * invocation of getopt. It doesn't quite work out that way. When
8010 * the first invocation of getopt finishes, it leaves optind pointing
8011 * to the argument _after_ the first argument in the second group.
8012 * So when the second invocation of getopt comes around, it doesn't
8013 * recognize the first argument it gets and then bails out.
8015 * A nice alternative would be to have a flag for getopt that says
8016 * "just keep parsing arguments even when you encounter an unknown
8017 * argument", but there isn't one. So there's no real clean way to
8018 * easily parse two sets of arguments without having one invocation
8019 * of getopt know about the other.
8021 * Without this hack, the first invocation of getopt would work as
8022 * long as the generic arguments are first, but the second invocation
8023 * (in the subfunction) would fail in one of two ways. In the case
8024 * where you don't set optreset, it would fail because optind may be
8025 * pointing to the argument after the one it should be pointing at.
8026 * In the case where you do set optreset, and reset optind, it would
8027 * fail because getopt would run into the first set of options, which
8028 * it doesn't understand.
8030 * All of this would "sort of" work if you could somehow figure out
8031 * whether optind had been incremented one option too far. The
8032 * mechanics of that, however, are more daunting than just giving
8033 * both invocations all of the expect options for either invocation.
8035 * Needless to say, I wouldn't mind if someone invented a better
8036 * (non-GPL!) command line parsing interface than getopt. I
8037 * wouldn't mind if someone added more knobs to getopt to make it
8038 * work better. Who knows, I may talk myself into doing it someday,
8039 * if the standards weenies let me. As it is, it just leads to
8040 * hackery like this and causes people to avoid it in some cases.
8042 * KDM, September 8th, 1998
8045 sprintf(combinedopt, "%s%s", mainopt, subopt);
8047 sprintf(combinedopt, "%s", mainopt);
8050 * For these options we do not parse optional device arguments and
8051 * we do not open a passthrough device.
8053 if ((cmdlist == CAM_CMD_RESCAN)
8054 || (cmdlist == CAM_CMD_RESET)
8055 || (cmdlist == CAM_CMD_DEVTREE)
8056 || (cmdlist == CAM_CMD_USAGE)
8057 || (cmdlist == CAM_CMD_DEBUG))
8060 #ifndef MINIMALISTIC
8062 && (argc > 2 && argv[2][0] != '-')) {
8066 if (isdigit(argv[2][0])) {
8067 /* device specified as bus:target[:lun] */
8068 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
8070 errx(1, "numeric device specification must "
8071 "be either bus:target, or "
8073 /* default to 0 if lun was not specified */
8074 if ((arglist & CAM_ARG_LUN) == 0) {
8076 arglist |= CAM_ARG_LUN;
8080 if (cam_get_device(argv[2], name, sizeof name, &unit)
8082 errx(1, "%s", cam_errbuf);
8083 device = strdup(name);
8084 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
8088 #endif /* MINIMALISTIC */
8090 * Start getopt processing at argv[2/3], since we've already
8091 * accepted argv[1..2] as the command name, and as a possible
8097 * Now we run through the argument list looking for generic
8098 * options, and ignoring options that possibly belong to
8101 while ((c = getopt(argc, argv, combinedopt))!= -1){
8104 retry_count = strtol(optarg, NULL, 0);
8105 if (retry_count < 0)
8106 errx(1, "retry count %d is < 0",
8108 arglist |= CAM_ARG_RETRIES;
8111 arglist |= CAM_ARG_ERR_RECOVER;
8114 arglist |= CAM_ARG_DEVICE;
8116 while (isspace(*tstr) && (*tstr != '\0'))
8118 device = (char *)strdup(tstr);
8121 timeout = strtol(optarg, NULL, 0);
8123 errx(1, "invalid timeout %d", timeout);
8124 /* Convert the timeout from seconds to ms */
8126 arglist |= CAM_ARG_TIMEOUT;
8129 arglist |= CAM_ARG_UNIT;
8130 unit = strtol(optarg, NULL, 0);
8133 arglist |= CAM_ARG_VERBOSE;
8140 #ifndef MINIMALISTIC
8142 * For most commands we'll want to open the passthrough device
8143 * associated with the specified device. In the case of the rescan
8144 * commands, we don't use a passthrough device at all, just the
8145 * transport layer device.
8148 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
8149 && (((arglist & CAM_ARG_DEVICE) == 0)
8150 || ((arglist & CAM_ARG_UNIT) == 0))) {
8151 errx(1, "subcommand \"%s\" requires a valid device "
8152 "identifier", argv[1]);
8155 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
8156 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
8157 cam_open_spec_device(device,unit,O_RDWR,NULL)))
8159 errx(1,"%s", cam_errbuf);
8161 #endif /* MINIMALISTIC */
8164 * Reset optind to 2, and reset getopt, so these routines can parse
8165 * the arguments again.
8171 #ifndef MINIMALISTIC
8172 case CAM_CMD_DEVLIST:
8173 error = getdevlist(cam_dev);
8176 error = atahpa(cam_dev, retry_count, timeout,
8177 argc, argv, combinedopt);
8179 #endif /* MINIMALISTIC */
8180 case CAM_CMD_DEVTREE:
8181 error = getdevtree();
8183 #ifndef MINIMALISTIC
8185 error = testunitready(cam_dev, retry_count, timeout, 0);
8187 case CAM_CMD_INQUIRY:
8188 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
8189 retry_count, timeout);
8191 case CAM_CMD_IDENTIFY:
8192 error = ataidentify(cam_dev, retry_count, timeout);
8194 case CAM_CMD_STARTSTOP:
8195 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
8196 arglist & CAM_ARG_EJECT, retry_count,
8199 #endif /* MINIMALISTIC */
8200 case CAM_CMD_RESCAN:
8201 error = dorescan_or_reset(argc, argv, 1);
8204 error = dorescan_or_reset(argc, argv, 0);
8206 #ifndef MINIMALISTIC
8207 case CAM_CMD_READ_DEFECTS:
8208 error = readdefects(cam_dev, argc, argv, combinedopt,
8209 retry_count, timeout);
8211 case CAM_CMD_MODE_PAGE:
8212 modepage(cam_dev, argc, argv, combinedopt,
8213 retry_count, timeout);
8215 case CAM_CMD_SCSI_CMD:
8216 error = scsicmd(cam_dev, argc, argv, combinedopt,
8217 retry_count, timeout);
8219 case CAM_CMD_SMP_CMD:
8220 error = smpcmd(cam_dev, argc, argv, combinedopt,
8221 retry_count, timeout);
8223 case CAM_CMD_SMP_RG:
8224 error = smpreportgeneral(cam_dev, argc, argv,
8225 combinedopt, retry_count,
8228 case CAM_CMD_SMP_PC:
8229 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
8230 retry_count, timeout);
8232 case CAM_CMD_SMP_PHYLIST:
8233 error = smpphylist(cam_dev, argc, argv, combinedopt,
8234 retry_count, timeout);
8236 case CAM_CMD_SMP_MANINFO:
8237 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
8238 retry_count, timeout);
8241 error = camdebug(argc, argv, combinedopt);
8244 error = tagcontrol(cam_dev, argc, argv, combinedopt);
8247 error = ratecontrol(cam_dev, retry_count, timeout,
8248 argc, argv, combinedopt);
8250 case CAM_CMD_FORMAT:
8251 error = scsiformat(cam_dev, argc, argv,
8252 combinedopt, retry_count, timeout);
8254 case CAM_CMD_REPORTLUNS:
8255 error = scsireportluns(cam_dev, argc, argv,
8256 combinedopt, retry_count,
8259 case CAM_CMD_READCAP:
8260 error = scsireadcapacity(cam_dev, argc, argv,
8261 combinedopt, retry_count,
8265 case CAM_CMD_STANDBY:
8267 error = atapm(cam_dev, argc, argv,
8268 combinedopt, retry_count, timeout);
8270 case CAM_CMD_SECURITY:
8271 error = atasecurity(cam_dev, retry_count, timeout,
8272 argc, argv, combinedopt);
8274 case CAM_CMD_DOWNLOAD_FW:
8275 error = fwdownload(cam_dev, argc, argv, combinedopt,
8276 arglist & CAM_ARG_VERBOSE, retry_count, timeout,
8277 get_disk_type(cam_dev));
8279 case CAM_CMD_SANITIZE:
8280 error = scsisanitize(cam_dev, argc, argv,
8281 combinedopt, retry_count, timeout);
8283 #endif /* MINIMALISTIC */
8293 if (cam_dev != NULL)
8294 cam_close_device(cam_dev);