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, path_id_t *bus, target_id_t *target,
268 lun_id_t *lun, cam_argmask *arglst);
269 static int dorescan_or_reset(int argc, char **argv, int rescan);
270 static int rescan_or_reset_bus(path_id_t bus, int rescan);
271 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
272 lun_id_t lun, int scan);
274 static int readdefects(struct cam_device *device, int argc, char **argv,
275 char *combinedopt, int retry_count, int timeout);
276 static void modepage(struct cam_device *device, int argc, char **argv,
277 char *combinedopt, int retry_count, int timeout);
278 static int scsicmd(struct cam_device *device, int argc, char **argv,
279 char *combinedopt, int retry_count, int timeout);
280 static int smpcmd(struct cam_device *device, int argc, char **argv,
281 char *combinedopt, int retry_count, int timeout);
282 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
283 char *combinedopt, int retry_count, int timeout);
284 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
285 char *combinedopt, int retry_count, int timeout);
286 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
287 char *combinedopt, int retry_count, int timeout);
288 static int getdevid(struct cam_devitem *item);
289 static int buildbusdevlist(struct cam_devlist *devlist);
290 static void freebusdevlist(struct cam_devlist *devlist);
291 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
293 static int smpphylist(struct cam_device *device, int argc, char **argv,
294 char *combinedopt, int retry_count, int timeout);
295 static int tagcontrol(struct cam_device *device, int argc, char **argv,
297 static void cts_print(struct cam_device *device,
298 struct ccb_trans_settings *cts);
299 static void cpi_print(struct ccb_pathinq *cpi);
300 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
301 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
302 static int get_print_cts(struct cam_device *device, int user_settings,
303 int quiet, struct ccb_trans_settings *cts);
304 static int ratecontrol(struct cam_device *device, int retry_count,
305 int timeout, int argc, char **argv, char *combinedopt);
306 static int scsiformat(struct cam_device *device, int argc, char **argv,
307 char *combinedopt, int retry_count, int timeout);
308 static int scsisanitize(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int retry_count, int timeout);
310 static int scsireportluns(struct cam_device *device, int argc, char **argv,
311 char *combinedopt, int retry_count, int timeout);
312 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
313 char *combinedopt, int retry_count, int timeout);
314 static int atapm(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int retry_count, int timeout);
316 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
317 int argc, char **argv, char *combinedopt);
318 static int atahpa(struct cam_device *device, int retry_count, int timeout,
319 int argc, char **argv, char *combinedopt);
321 #endif /* MINIMALISTIC */
323 #define min(a,b) (((a)<(b))?(a):(b))
326 #define max(a,b) (((a)>(b))?(a):(b))
330 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
331 cam_argmask *argnum, const char **subopt)
333 struct camcontrol_opts *opts;
336 for (opts = table; (opts != NULL) && (opts->optname != NULL);
338 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
339 *cmdnum = opts->cmdnum;
340 *argnum = opts->argnum;
341 *subopt = opts->subopt;
342 if (++num_matches > 1)
343 return(CC_OR_AMBIGUOUS);
350 return(CC_OR_NOT_FOUND);
355 getdevlist(struct cam_device *device)
361 ccb = cam_getccb(device);
363 ccb->ccb_h.func_code = XPT_GDEVLIST;
364 ccb->ccb_h.flags = CAM_DIR_NONE;
365 ccb->ccb_h.retry_count = 1;
367 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
368 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
369 if (cam_send_ccb(device, ccb) < 0) {
370 perror("error getting device list");
377 switch (ccb->cgdl.status) {
378 case CAM_GDEVLIST_MORE_DEVS:
379 strcpy(status, "MORE");
381 case CAM_GDEVLIST_LAST_DEVICE:
382 strcpy(status, "LAST");
384 case CAM_GDEVLIST_LIST_CHANGED:
385 strcpy(status, "CHANGED");
387 case CAM_GDEVLIST_ERROR:
388 strcpy(status, "ERROR");
393 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
394 ccb->cgdl.periph_name,
395 ccb->cgdl.unit_number,
396 ccb->cgdl.generation,
401 * If the list has changed, we need to start over from the
404 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
412 #endif /* MINIMALISTIC */
424 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
425 warn("couldn't open %s", XPT_DEVICE);
429 bzero(&ccb, sizeof(union ccb));
431 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
432 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
433 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
435 ccb.ccb_h.func_code = XPT_DEV_MATCH;
436 bufsize = sizeof(struct dev_match_result) * 100;
437 ccb.cdm.match_buf_len = bufsize;
438 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
439 if (ccb.cdm.matches == NULL) {
440 warnx("can't malloc memory for matches");
444 ccb.cdm.num_matches = 0;
447 * We fetch all nodes, since we display most of them in the default
448 * case, and all in the verbose case.
450 ccb.cdm.num_patterns = 0;
451 ccb.cdm.pattern_buf_len = 0;
454 * We do the ioctl multiple times if necessary, in case there are
455 * more than 100 nodes in the EDT.
458 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
459 warn("error sending CAMIOCOMMAND ioctl");
464 if ((ccb.ccb_h.status != CAM_REQ_CMP)
465 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
466 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
467 warnx("got CAM error %#x, CDM error %d\n",
468 ccb.ccb_h.status, ccb.cdm.status);
473 for (i = 0; i < ccb.cdm.num_matches; i++) {
474 switch (ccb.cdm.matches[i].type) {
475 case DEV_MATCH_BUS: {
476 struct bus_match_result *bus_result;
479 * Only print the bus information if the
480 * user turns on the verbose flag.
482 if ((arglist & CAM_ARG_VERBOSE) == 0)
486 &ccb.cdm.matches[i].result.bus_result;
489 fprintf(stdout, ")\n");
493 fprintf(stdout, "scbus%d on %s%d bus %d:\n",
495 bus_result->dev_name,
496 bus_result->unit_number,
500 case DEV_MATCH_DEVICE: {
501 struct device_match_result *dev_result;
502 char vendor[16], product[48], revision[16];
503 char fw[5], tmpstr[256];
506 &ccb.cdm.matches[i].result.device_result;
508 if ((dev_result->flags
509 & DEV_RESULT_UNCONFIGURED)
510 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
516 if (dev_result->protocol == PROTO_SCSI) {
517 cam_strvis(vendor, dev_result->inq_data.vendor,
518 sizeof(dev_result->inq_data.vendor),
521 dev_result->inq_data.product,
522 sizeof(dev_result->inq_data.product),
525 dev_result->inq_data.revision,
526 sizeof(dev_result->inq_data.revision),
528 sprintf(tmpstr, "<%s %s %s>", vendor, product,
530 } else if (dev_result->protocol == PROTO_ATA ||
531 dev_result->protocol == PROTO_SATAPM) {
533 dev_result->ident_data.model,
534 sizeof(dev_result->ident_data.model),
537 dev_result->ident_data.revision,
538 sizeof(dev_result->ident_data.revision),
540 sprintf(tmpstr, "<%s %s>", product,
542 } else if (dev_result->protocol == PROTO_SEMB) {
543 struct sep_identify_data *sid;
545 sid = (struct sep_identify_data *)
546 &dev_result->ident_data;
547 cam_strvis(vendor, sid->vendor_id,
548 sizeof(sid->vendor_id),
550 cam_strvis(product, sid->product_id,
551 sizeof(sid->product_id),
553 cam_strvis(revision, sid->product_rev,
554 sizeof(sid->product_rev),
556 cam_strvis(fw, sid->firmware_rev,
557 sizeof(sid->firmware_rev),
559 sprintf(tmpstr, "<%s %s %s %s>",
560 vendor, product, revision, fw);
562 sprintf(tmpstr, "<>");
565 fprintf(stdout, ")\n");
569 fprintf(stdout, "%-33s at scbus%d "
570 "target %d lun %d (",
573 dev_result->target_id,
574 dev_result->target_lun);
580 case DEV_MATCH_PERIPH: {
581 struct periph_match_result *periph_result;
584 &ccb.cdm.matches[i].result.periph_result;
586 if (skip_device != 0)
590 fprintf(stdout, ",");
592 fprintf(stdout, "%s%d",
593 periph_result->periph_name,
594 periph_result->unit_number);
600 fprintf(stdout, "unknown match type\n");
605 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
606 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
609 fprintf(stdout, ")\n");
618 testunitready(struct cam_device *device, int retry_count, int timeout,
624 ccb = cam_getccb(device);
626 scsi_test_unit_ready(&ccb->csio,
627 /* retries */ retry_count,
629 /* tag_action */ MSG_SIMPLE_Q_TAG,
630 /* sense_len */ SSD_FULL_SIZE,
631 /* timeout */ timeout ? timeout : 5000);
633 /* Disable freezing the device queue */
634 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
636 if (arglist & CAM_ARG_ERR_RECOVER)
637 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
639 if (cam_send_ccb(device, ccb) < 0) {
641 perror("error sending test unit ready");
643 if (arglist & CAM_ARG_VERBOSE) {
644 cam_error_print(device, ccb, CAM_ESF_ALL,
645 CAM_EPF_ALL, stderr);
652 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
654 fprintf(stdout, "Unit is ready\n");
657 fprintf(stdout, "Unit is not ready\n");
660 if (arglist & CAM_ARG_VERBOSE) {
661 cam_error_print(device, ccb, CAM_ESF_ALL,
662 CAM_EPF_ALL, stderr);
672 scsistart(struct cam_device *device, int startstop, int loadeject,
673 int retry_count, int timeout)
678 ccb = cam_getccb(device);
681 * If we're stopping, send an ordered tag so the drive in question
682 * will finish any previously queued writes before stopping. If
683 * the device isn't capable of tagged queueing, or if tagged
684 * queueing is turned off, the tag action is a no-op.
686 scsi_start_stop(&ccb->csio,
687 /* retries */ retry_count,
689 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
691 /* start/stop */ startstop,
692 /* load_eject */ loadeject,
694 /* sense_len */ SSD_FULL_SIZE,
695 /* timeout */ timeout ? timeout : 120000);
697 /* Disable freezing the device queue */
698 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
700 if (arglist & CAM_ARG_ERR_RECOVER)
701 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
703 if (cam_send_ccb(device, ccb) < 0) {
704 perror("error sending start unit");
706 if (arglist & CAM_ARG_VERBOSE) {
707 cam_error_print(device, ccb, CAM_ESF_ALL,
708 CAM_EPF_ALL, stderr);
715 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
717 fprintf(stdout, "Unit started successfully");
719 fprintf(stdout,", Media loaded\n");
721 fprintf(stdout,"\n");
723 fprintf(stdout, "Unit stopped successfully");
725 fprintf(stdout, ", Media ejected\n");
727 fprintf(stdout, "\n");
733 "Error received from start unit command\n");
736 "Error received from stop unit command\n");
738 if (arglist & CAM_ARG_VERBOSE) {
739 cam_error_print(device, ccb, CAM_ESF_ALL,
740 CAM_EPF_ALL, stderr);
750 scsidoinquiry(struct cam_device *device, int argc, char **argv,
751 char *combinedopt, int retry_count, int timeout)
756 while ((c = getopt(argc, argv, combinedopt)) != -1) {
759 arglist |= CAM_ARG_GET_STDINQ;
762 arglist |= CAM_ARG_GET_XFERRATE;
765 arglist |= CAM_ARG_GET_SERIAL;
773 * If the user didn't specify any inquiry options, he wants all of
776 if ((arglist & CAM_ARG_INQ_MASK) == 0)
777 arglist |= CAM_ARG_INQ_MASK;
779 if (arglist & CAM_ARG_GET_STDINQ)
780 error = scsiinquiry(device, retry_count, timeout);
785 if (arglist & CAM_ARG_GET_SERIAL)
786 scsiserial(device, retry_count, timeout);
791 if (arglist & CAM_ARG_GET_XFERRATE)
792 error = camxferrate(device);
798 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
801 struct scsi_inquiry_data *inq_buf;
804 ccb = cam_getccb(device);
807 warnx("couldn't allocate CCB");
811 /* cam_getccb cleans up the header, caller has to zero the payload */
812 bzero(&(&ccb->ccb_h)[1],
813 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
815 inq_buf = (struct scsi_inquiry_data *)malloc(
816 sizeof(struct scsi_inquiry_data));
818 if (inq_buf == NULL) {
820 warnx("can't malloc memory for inquiry\n");
823 bzero(inq_buf, sizeof(*inq_buf));
826 * Note that although the size of the inquiry buffer is the full
827 * 256 bytes specified in the SCSI spec, we only tell the device
828 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
829 * two reasons for this:
831 * - The SCSI spec says that when a length field is only 1 byte,
832 * a value of 0 will be interpreted as 256. Therefore
833 * scsi_inquiry() will convert an inq_len (which is passed in as
834 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
835 * to 0. Evidently, very few devices meet the spec in that
836 * regard. Some devices, like many Seagate disks, take the 0 as
837 * 0, and don't return any data. One Pioneer DVD-R drive
838 * returns more data than the command asked for.
840 * So, since there are numerous devices that just don't work
841 * right with the full inquiry size, we don't send the full size.
843 * - The second reason not to use the full inquiry data length is
844 * that we don't need it here. The only reason we issue a
845 * standard inquiry is to get the vendor name, device name,
846 * and revision so scsi_print_inquiry() can print them.
848 * If, at some point in the future, more inquiry data is needed for
849 * some reason, this code should use a procedure similar to the
850 * probe code. i.e., issue a short inquiry, and determine from
851 * the additional length passed back from the device how much
852 * inquiry data the device supports. Once the amount the device
853 * supports is determined, issue an inquiry for that amount and no
858 scsi_inquiry(&ccb->csio,
859 /* retries */ retry_count,
861 /* tag_action */ MSG_SIMPLE_Q_TAG,
862 /* inq_buf */ (u_int8_t *)inq_buf,
863 /* inq_len */ SHORT_INQUIRY_LENGTH,
866 /* sense_len */ SSD_FULL_SIZE,
867 /* timeout */ timeout ? timeout : 5000);
869 /* Disable freezing the device queue */
870 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
872 if (arglist & CAM_ARG_ERR_RECOVER)
873 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
875 if (cam_send_ccb(device, ccb) < 0) {
876 perror("error sending SCSI inquiry");
878 if (arglist & CAM_ARG_VERBOSE) {
879 cam_error_print(device, ccb, CAM_ESF_ALL,
880 CAM_EPF_ALL, stderr);
887 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
890 if (arglist & CAM_ARG_VERBOSE) {
891 cam_error_print(device, ccb, CAM_ESF_ALL,
892 CAM_EPF_ALL, stderr);
903 fprintf(stdout, "%s%d: ", device->device_name,
904 device->dev_unit_num);
905 scsi_print_inquiry(inq_buf);
913 scsiserial(struct cam_device *device, int retry_count, int timeout)
916 struct scsi_vpd_unit_serial_number *serial_buf;
917 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
920 ccb = cam_getccb(device);
923 warnx("couldn't allocate CCB");
927 /* cam_getccb cleans up the header, caller has to zero the payload */
928 bzero(&(&ccb->ccb_h)[1],
929 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
931 serial_buf = (struct scsi_vpd_unit_serial_number *)
932 malloc(sizeof(*serial_buf));
934 if (serial_buf == NULL) {
936 warnx("can't malloc memory for serial number");
940 scsi_inquiry(&ccb->csio,
941 /*retries*/ retry_count,
943 /* tag_action */ MSG_SIMPLE_Q_TAG,
944 /* inq_buf */ (u_int8_t *)serial_buf,
945 /* inq_len */ sizeof(*serial_buf),
947 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
948 /* sense_len */ SSD_FULL_SIZE,
949 /* timeout */ timeout ? timeout : 5000);
951 /* Disable freezing the device queue */
952 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
954 if (arglist & CAM_ARG_ERR_RECOVER)
955 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
957 if (cam_send_ccb(device, ccb) < 0) {
958 warn("error getting serial number");
960 if (arglist & CAM_ARG_VERBOSE) {
961 cam_error_print(device, ccb, CAM_ESF_ALL,
962 CAM_EPF_ALL, stderr);
970 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
973 if (arglist & CAM_ARG_VERBOSE) {
974 cam_error_print(device, ccb, CAM_ESF_ALL,
975 CAM_EPF_ALL, stderr);
986 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
987 serial_num[serial_buf->length] = '\0';
989 if ((arglist & CAM_ARG_GET_STDINQ)
990 || (arglist & CAM_ARG_GET_XFERRATE))
991 fprintf(stdout, "%s%d: Serial Number ",
992 device->device_name, device->dev_unit_num);
994 fprintf(stdout, "%.60s\n", serial_num);
1002 camxferrate(struct cam_device *device)
1004 struct ccb_pathinq cpi;
1006 u_int32_t speed = 0;
1011 if ((retval = get_cpi(device, &cpi)) != 0)
1014 ccb = cam_getccb(device);
1017 warnx("couldn't allocate CCB");
1021 bzero(&(&ccb->ccb_h)[1],
1022 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
1024 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1025 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1027 if (((retval = cam_send_ccb(device, ccb)) < 0)
1028 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1029 const char error_string[] = "error getting transfer settings";
1034 warnx(error_string);
1036 if (arglist & CAM_ARG_VERBOSE)
1037 cam_error_print(device, ccb, CAM_ESF_ALL,
1038 CAM_EPF_ALL, stderr);
1042 goto xferrate_bailout;
1046 speed = cpi.base_transfer_speed;
1048 if (ccb->cts.transport == XPORT_SPI) {
1049 struct ccb_trans_settings_spi *spi =
1050 &ccb->cts.xport_specific.spi;
1052 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1053 freq = scsi_calc_syncsrate(spi->sync_period);
1056 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1057 speed *= (0x01 << spi->bus_width);
1059 } else if (ccb->cts.transport == XPORT_FC) {
1060 struct ccb_trans_settings_fc *fc =
1061 &ccb->cts.xport_specific.fc;
1063 if (fc->valid & CTS_FC_VALID_SPEED)
1064 speed = fc->bitrate;
1065 } else if (ccb->cts.transport == XPORT_SAS) {
1066 struct ccb_trans_settings_sas *sas =
1067 &ccb->cts.xport_specific.sas;
1069 if (sas->valid & CTS_SAS_VALID_SPEED)
1070 speed = sas->bitrate;
1071 } else if (ccb->cts.transport == XPORT_ATA) {
1072 struct ccb_trans_settings_pata *pata =
1073 &ccb->cts.xport_specific.ata;
1075 if (pata->valid & CTS_ATA_VALID_MODE)
1076 speed = ata_mode2speed(pata->mode);
1077 } else if (ccb->cts.transport == XPORT_SATA) {
1078 struct ccb_trans_settings_sata *sata =
1079 &ccb->cts.xport_specific.sata;
1081 if (sata->valid & CTS_SATA_VALID_REVISION)
1082 speed = ata_revision2speed(sata->revision);
1087 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1088 device->device_name, device->dev_unit_num,
1091 fprintf(stdout, "%s%d: %dKB/s transfers",
1092 device->device_name, device->dev_unit_num,
1096 if (ccb->cts.transport == XPORT_SPI) {
1097 struct ccb_trans_settings_spi *spi =
1098 &ccb->cts.xport_specific.spi;
1100 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1101 && (spi->sync_offset != 0))
1102 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1103 freq % 1000, spi->sync_offset);
1105 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1106 && (spi->bus_width > 0)) {
1107 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1108 && (spi->sync_offset != 0)) {
1109 fprintf(stdout, ", ");
1111 fprintf(stdout, " (");
1113 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1114 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1115 && (spi->sync_offset != 0)) {
1116 fprintf(stdout, ")");
1118 } else if (ccb->cts.transport == XPORT_ATA) {
1119 struct ccb_trans_settings_pata *pata =
1120 &ccb->cts.xport_specific.ata;
1123 if (pata->valid & CTS_ATA_VALID_MODE)
1124 printf("%s, ", ata_mode2string(pata->mode));
1125 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1126 printf("ATAPI %dbytes, ", pata->atapi);
1127 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1128 printf("PIO %dbytes", pata->bytecount);
1130 } else if (ccb->cts.transport == XPORT_SATA) {
1131 struct ccb_trans_settings_sata *sata =
1132 &ccb->cts.xport_specific.sata;
1135 if (sata->valid & CTS_SATA_VALID_REVISION)
1136 printf("SATA %d.x, ", sata->revision);
1139 if (sata->valid & CTS_SATA_VALID_MODE)
1140 printf("%s, ", ata_mode2string(sata->mode));
1141 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1142 printf("ATAPI %dbytes, ", sata->atapi);
1143 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1144 printf("PIO %dbytes", sata->bytecount);
1148 if (ccb->cts.protocol == PROTO_SCSI) {
1149 struct ccb_trans_settings_scsi *scsi =
1150 &ccb->cts.proto_specific.scsi;
1151 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1152 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1153 fprintf(stdout, ", Command Queueing Enabled");
1158 fprintf(stdout, "\n");
1168 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1170 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1171 ((u_int32_t)parm->lba_size_2 << 16);
1173 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1174 ((u_int64_t)parm->lba_size48_2 << 16) |
1175 ((u_int64_t)parm->lba_size48_3 << 32) |
1176 ((u_int64_t)parm->lba_size48_4 << 48);
1180 "Support Enabled Value\n");
1183 printf("Host Protected Area (HPA) ");
1184 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1185 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1186 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1189 printf("HPA - Security ");
1190 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1200 atacapprint(struct ata_params *parm)
1202 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1203 ((u_int32_t)parm->lba_size_2 << 16);
1205 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1206 ((u_int64_t)parm->lba_size48_2 << 16) |
1207 ((u_int64_t)parm->lba_size48_3 << 32) |
1208 ((u_int64_t)parm->lba_size48_4 << 48);
1211 printf("protocol ");
1212 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1213 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1214 if (parm->satacapabilities & ATA_SATA_GEN3)
1215 printf(" SATA 3.x\n");
1216 else if (parm->satacapabilities & ATA_SATA_GEN2)
1217 printf(" SATA 2.x\n");
1218 else if (parm->satacapabilities & ATA_SATA_GEN1)
1219 printf(" SATA 1.x\n");
1225 printf("device model %.40s\n", parm->model);
1226 printf("firmware revision %.8s\n", parm->revision);
1227 printf("serial number %.20s\n", parm->serial);
1228 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1229 printf("WWN %04x%04x%04x%04x\n",
1230 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1232 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1233 printf("media serial number %.30s\n",
1234 parm->media_serial);
1237 printf("cylinders %d\n", parm->cylinders);
1238 printf("heads %d\n", parm->heads);
1239 printf("sectors/track %d\n", parm->sectors);
1240 printf("sector size logical %u, physical %lu, offset %lu\n",
1241 ata_logical_sector_size(parm),
1242 (unsigned long)ata_physical_sector_size(parm),
1243 (unsigned long)ata_logical_sector_offset(parm));
1245 if (parm->config == ATA_PROTO_CFA ||
1246 (parm->support.command2 & ATA_SUPPORT_CFA))
1247 printf("CFA supported\n");
1249 printf("LBA%ssupported ",
1250 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1252 printf("%d sectors\n", lbasize);
1256 printf("LBA48%ssupported ",
1257 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1259 printf("%ju sectors\n", (uintmax_t)lbasize48);
1263 printf("PIO supported PIO");
1264 switch (ata_max_pmode(parm)) {
1280 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1281 printf(" w/o IORDY");
1284 printf("DMA%ssupported ",
1285 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1286 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1287 if (parm->mwdmamodes & 0xff) {
1289 if (parm->mwdmamodes & 0x04)
1291 else if (parm->mwdmamodes & 0x02)
1293 else if (parm->mwdmamodes & 0x01)
1297 if ((parm->atavalid & ATA_FLAG_88) &&
1298 (parm->udmamodes & 0xff)) {
1300 if (parm->udmamodes & 0x40)
1302 else if (parm->udmamodes & 0x20)
1304 else if (parm->udmamodes & 0x10)
1306 else if (parm->udmamodes & 0x08)
1308 else if (parm->udmamodes & 0x04)
1310 else if (parm->udmamodes & 0x02)
1312 else if (parm->udmamodes & 0x01)
1319 if (parm->media_rotation_rate == 1) {
1320 printf("media RPM non-rotating\n");
1321 } else if (parm->media_rotation_rate >= 0x0401 &&
1322 parm->media_rotation_rate <= 0xFFFE) {
1323 printf("media RPM %d\n",
1324 parm->media_rotation_rate);
1328 "Support Enabled Value Vendor\n");
1329 printf("read ahead %s %s\n",
1330 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1331 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1332 printf("write cache %s %s\n",
1333 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1334 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1335 printf("flush cache %s %s\n",
1336 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1337 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1338 printf("overlap %s\n",
1339 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1340 printf("Tagged Command Queuing (TCQ) %s %s",
1341 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1342 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1343 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1344 printf(" %d tags\n",
1345 ATA_QUEUE_LEN(parm->queue) + 1);
1348 printf("Native Command Queuing (NCQ) ");
1349 if (parm->satacapabilities != 0xffff &&
1350 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1351 printf("yes %d tags\n",
1352 ATA_QUEUE_LEN(parm->queue) + 1);
1355 printf("SMART %s %s\n",
1356 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1357 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1358 printf("microcode download %s %s\n",
1359 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1360 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1361 printf("security %s %s\n",
1362 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1363 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1364 printf("power management %s %s\n",
1365 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1366 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1367 printf("advanced power management %s %s",
1368 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1369 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1370 if (parm->support.command2 & ATA_SUPPORT_APM) {
1371 printf(" %d/0x%02X\n",
1372 parm->apm_value, parm->apm_value);
1375 printf("automatic acoustic management %s %s",
1376 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1377 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1378 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1379 printf(" %d/0x%02X %d/0x%02X\n",
1380 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1381 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1382 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1383 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1386 printf("media status notification %s %s\n",
1387 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1388 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1389 printf("power-up in Standby %s %s\n",
1390 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1391 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1392 printf("write-read-verify %s %s",
1393 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1394 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1395 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1396 printf(" %d/0x%x\n",
1397 parm->wrv_mode, parm->wrv_mode);
1400 printf("unload %s %s\n",
1401 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1402 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1403 printf("free-fall %s %s\n",
1404 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1405 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1406 printf("Data Set Management (DSM/TRIM) ");
1407 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1409 printf("DSM - max 512byte blocks ");
1410 if (parm->max_dsm_blocks == 0x00)
1411 printf("yes not specified\n");
1414 parm->max_dsm_blocks);
1416 printf("DSM - deterministic read ");
1417 if (parm->support3 & ATA_SUPPORT_DRAT) {
1418 if (parm->support3 & ATA_SUPPORT_RZAT)
1419 printf("yes zeroed\n");
1421 printf("yes any value\n");
1431 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1433 struct ata_pass_16 *ata_pass_16;
1434 struct ata_cmd ata_cmd;
1436 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1437 ata_cmd.command = ata_pass_16->command;
1438 ata_cmd.control = ata_pass_16->control;
1439 ata_cmd.features = ata_pass_16->features;
1441 if (arglist & CAM_ARG_VERBOSE) {
1442 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1443 ata_op_string(&ata_cmd),
1444 ccb->csio.ccb_h.timeout);
1447 /* Disable freezing the device queue */
1448 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1450 if (arglist & CAM_ARG_ERR_RECOVER)
1451 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1453 if (cam_send_ccb(device, ccb) < 0) {
1454 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1455 warn("error sending ATA %s via pass_16",
1456 ata_op_string(&ata_cmd));
1459 if (arglist & CAM_ARG_VERBOSE) {
1460 cam_error_print(device, ccb, CAM_ESF_ALL,
1461 CAM_EPF_ALL, stderr);
1467 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1468 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1469 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1470 warnx("ATA %s via pass_16 failed",
1471 ata_op_string(&ata_cmd));
1473 if (arglist & CAM_ARG_VERBOSE) {
1474 cam_error_print(device, ccb, CAM_ESF_ALL,
1475 CAM_EPF_ALL, stderr);
1486 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1488 if (arglist & CAM_ARG_VERBOSE) {
1489 warnx("sending ATA %s with timeout of %u msecs",
1490 ata_op_string(&(ccb->ataio.cmd)),
1491 ccb->ataio.ccb_h.timeout);
1494 /* Disable freezing the device queue */
1495 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1497 if (arglist & CAM_ARG_ERR_RECOVER)
1498 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1500 if (cam_send_ccb(device, ccb) < 0) {
1501 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1502 warn("error sending ATA %s",
1503 ata_op_string(&(ccb->ataio.cmd)));
1506 if (arglist & CAM_ARG_VERBOSE) {
1507 cam_error_print(device, ccb, CAM_ESF_ALL,
1508 CAM_EPF_ALL, stderr);
1514 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1515 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1516 warnx("ATA %s failed: %d",
1517 ata_op_string(&(ccb->ataio.cmd)), quiet);
1520 if (arglist & CAM_ARG_VERBOSE) {
1521 cam_error_print(device, ccb, CAM_ESF_ALL,
1522 CAM_EPF_ALL, stderr);
1532 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1533 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1534 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1535 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1536 u_int16_t dxfer_len, int timeout, int quiet)
1538 if (data_ptr != NULL) {
1539 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1540 AP_FLAG_TLEN_SECT_CNT;
1541 if (flags & CAM_DIR_OUT)
1542 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1544 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1546 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1549 bzero(&(&ccb->ccb_h)[1],
1550 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1552 scsi_ata_pass_16(&ccb->csio,
1566 /*sense_len*/SSD_FULL_SIZE,
1569 return scsi_cam_pass_16_send(device, ccb, quiet);
1573 ata_try_pass_16(struct cam_device *device)
1575 struct ccb_pathinq cpi;
1577 if (get_cpi(device, &cpi) != 0) {
1578 warnx("couldn't get CPI");
1582 if (cpi.protocol == PROTO_SCSI) {
1583 /* possibly compatible with pass_16 */
1587 /* likely not compatible with pass_16 */
1592 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1593 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1594 u_int8_t command, u_int8_t features, u_int32_t lba,
1595 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1596 int timeout, int quiet)
1600 switch (ata_try_pass_16(device)) {
1604 /* Try using SCSI Passthrough */
1605 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1606 0, tag_action, command, features, lba,
1607 sector_count, data_ptr, dxfer_len,
1611 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1612 sizeof(struct ccb_hdr));
1613 cam_fill_ataio(&ccb->ataio,
1622 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1623 return ata_cam_send(device, ccb, quiet);
1627 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1628 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1629 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1630 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1631 u_int16_t dxfer_len, int timeout, int force48bit)
1635 retval = ata_try_pass_16(device);
1642 /* Try using SCSI Passthrough */
1643 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1644 ata_flags, tag_action, command, features,
1645 lba, sector_count, data_ptr, dxfer_len,
1648 if (ata_flags & AP_FLAG_CHK_COND) {
1649 /* Decode ata_res from sense data */
1650 struct ata_res_pass16 *res_pass16;
1651 struct ata_res *res;
1655 /* sense_data is 4 byte aligned */
1656 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1657 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1658 ptr[i] = le16toh(ptr[i]);
1660 /* sense_data is 4 byte aligned */
1661 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1662 &ccb->csio.sense_data;
1663 res = &ccb->ataio.res;
1664 res->flags = res_pass16->flags;
1665 res->status = res_pass16->status;
1666 res->error = res_pass16->error;
1667 res->lba_low = res_pass16->lba_low;
1668 res->lba_mid = res_pass16->lba_mid;
1669 res->lba_high = res_pass16->lba_high;
1670 res->device = res_pass16->device;
1671 res->lba_low_exp = res_pass16->lba_low_exp;
1672 res->lba_mid_exp = res_pass16->lba_mid_exp;
1673 res->lba_high_exp = res_pass16->lba_high_exp;
1674 res->sector_count = res_pass16->sector_count;
1675 res->sector_count_exp = res_pass16->sector_count_exp;
1681 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1682 sizeof(struct ccb_hdr));
1683 cam_fill_ataio(&ccb->ataio,
1692 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1693 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1695 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1697 if (ata_flags & AP_FLAG_CHK_COND)
1698 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1700 return ata_cam_send(device, ccb, 0);
1704 dump_data(uint16_t *ptr, uint32_t len)
1708 for (i = 0; i < len / 2; i++) {
1710 printf(" %3d: ", i);
1711 printf("%04hx ", ptr[i]);
1720 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1721 int is48bit, u_int64_t *hpasize)
1723 struct ata_res *res;
1725 res = &ccb->ataio.res;
1726 if (res->status & ATA_STATUS_ERROR) {
1727 if (arglist & CAM_ARG_VERBOSE) {
1728 cam_error_print(device, ccb, CAM_ESF_ALL,
1729 CAM_EPF_ALL, stderr);
1730 printf("error = 0x%02x, sector_count = 0x%04x, "
1731 "device = 0x%02x, status = 0x%02x\n",
1732 res->error, res->sector_count,
1733 res->device, res->status);
1736 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1737 warnx("Max address has already been set since "
1738 "last power-on or hardware reset");
1744 if (arglist & CAM_ARG_VERBOSE) {
1745 fprintf(stdout, "%s%d: Raw native max data:\n",
1746 device->device_name, device->dev_unit_num);
1747 /* res is 4 byte aligned */
1748 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1750 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1751 "status = 0x%02x\n", res->error, res->sector_count,
1752 res->device, res->status);
1755 if (hpasize != NULL) {
1757 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1758 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1759 ((res->lba_high << 16) | (res->lba_mid << 8) |
1762 *hpasize = (((res->device & 0x0f) << 24) |
1763 (res->lba_high << 16) | (res->lba_mid << 8) |
1772 ata_read_native_max(struct cam_device *device, int retry_count,
1773 u_int32_t timeout, union ccb *ccb,
1774 struct ata_params *parm, u_int64_t *hpasize)
1780 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1781 protocol = AP_PROTO_NON_DATA;
1784 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1785 protocol |= AP_EXTEND;
1787 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1790 error = ata_do_cmd(device,
1793 /*flags*/CAM_DIR_NONE,
1794 /*protocol*/protocol,
1795 /*ata_flags*/AP_FLAG_CHK_COND,
1796 /*tag_action*/MSG_SIMPLE_Q_TAG,
1803 timeout ? timeout : 1000,
1809 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1813 atahpa_set_max(struct cam_device *device, int retry_count,
1814 u_int32_t timeout, union ccb *ccb,
1815 int is48bit, u_int64_t maxsize, int persist)
1821 protocol = AP_PROTO_NON_DATA;
1824 cmd = ATA_SET_MAX_ADDRESS48;
1825 protocol |= AP_EXTEND;
1827 cmd = ATA_SET_MAX_ADDRESS;
1830 /* lba's are zero indexed so the max lba is requested max - 1 */
1834 error = ata_do_cmd(device,
1837 /*flags*/CAM_DIR_NONE,
1838 /*protocol*/protocol,
1839 /*ata_flags*/AP_FLAG_CHK_COND,
1840 /*tag_action*/MSG_SIMPLE_Q_TAG,
1842 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1844 /*sector_count*/persist,
1847 timeout ? timeout : 1000,
1853 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1857 atahpa_password(struct cam_device *device, int retry_count,
1858 u_int32_t timeout, union ccb *ccb,
1859 int is48bit, struct ata_set_max_pwd *pwd)
1865 protocol = AP_PROTO_PIO_OUT;
1866 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1868 error = ata_do_cmd(device,
1871 /*flags*/CAM_DIR_OUT,
1872 /*protocol*/protocol,
1873 /*ata_flags*/AP_FLAG_CHK_COND,
1874 /*tag_action*/MSG_SIMPLE_Q_TAG,
1876 /*features*/ATA_HPA_FEAT_SET_PWD,
1879 /*data_ptr*/(u_int8_t*)pwd,
1880 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1881 timeout ? timeout : 1000,
1887 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1891 atahpa_lock(struct cam_device *device, int retry_count,
1892 u_int32_t timeout, union ccb *ccb, int is48bit)
1898 protocol = AP_PROTO_NON_DATA;
1899 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1901 error = ata_do_cmd(device,
1904 /*flags*/CAM_DIR_NONE,
1905 /*protocol*/protocol,
1906 /*ata_flags*/AP_FLAG_CHK_COND,
1907 /*tag_action*/MSG_SIMPLE_Q_TAG,
1909 /*features*/ATA_HPA_FEAT_LOCK,
1914 timeout ? timeout : 1000,
1920 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1924 atahpa_unlock(struct cam_device *device, int retry_count,
1925 u_int32_t timeout, union ccb *ccb,
1926 int is48bit, struct ata_set_max_pwd *pwd)
1932 protocol = AP_PROTO_PIO_OUT;
1933 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1935 error = ata_do_cmd(device,
1938 /*flags*/CAM_DIR_OUT,
1939 /*protocol*/protocol,
1940 /*ata_flags*/AP_FLAG_CHK_COND,
1941 /*tag_action*/MSG_SIMPLE_Q_TAG,
1943 /*features*/ATA_HPA_FEAT_UNLOCK,
1946 /*data_ptr*/(u_int8_t*)pwd,
1947 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1948 timeout ? timeout : 1000,
1954 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1958 atahpa_freeze_lock(struct cam_device *device, int retry_count,
1959 u_int32_t timeout, union ccb *ccb, int is48bit)
1965 protocol = AP_PROTO_NON_DATA;
1966 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1968 error = ata_do_cmd(device,
1971 /*flags*/CAM_DIR_NONE,
1972 /*protocol*/protocol,
1973 /*ata_flags*/AP_FLAG_CHK_COND,
1974 /*tag_action*/MSG_SIMPLE_Q_TAG,
1976 /*features*/ATA_HPA_FEAT_FREEZE,
1981 timeout ? timeout : 1000,
1987 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1992 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
1993 union ccb *ccb, struct ata_params** ident_bufp)
1995 struct ata_params *ident_buf;
1996 struct ccb_pathinq cpi;
1997 struct ccb_getdev cgd;
2000 u_int8_t command, retry_command;
2002 if (get_cpi(device, &cpi) != 0) {
2003 warnx("couldn't get CPI");
2007 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2008 if (cpi.protocol == PROTO_ATA) {
2009 if (get_cgd(device, &cgd) != 0) {
2010 warnx("couldn't get CGD");
2014 command = (cgd.protocol == PROTO_ATA) ?
2015 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2018 /* We don't know which for sure so try both */
2019 command = ATA_ATA_IDENTIFY;
2020 retry_command = ATA_ATAPI_IDENTIFY;
2023 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2025 warnx("can't calloc memory for identify\n");
2029 error = ata_do_28bit_cmd(device,
2031 /*retries*/retry_count,
2032 /*flags*/CAM_DIR_IN,
2033 /*protocol*/AP_PROTO_PIO_IN,
2034 /*tag_action*/MSG_SIMPLE_Q_TAG,
2038 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2039 /*data_ptr*/(u_int8_t *)ptr,
2040 /*dxfer_len*/sizeof(struct ata_params),
2041 /*timeout*/timeout ? timeout : 30 * 1000,
2045 if (retry_command == 0) {
2049 error = ata_do_28bit_cmd(device,
2051 /*retries*/retry_count,
2052 /*flags*/CAM_DIR_IN,
2053 /*protocol*/AP_PROTO_PIO_IN,
2054 /*tag_action*/MSG_SIMPLE_Q_TAG,
2055 /*command*/retry_command,
2058 /*sector_count*/(u_int8_t)
2059 sizeof(struct ata_params),
2060 /*data_ptr*/(u_int8_t *)ptr,
2061 /*dxfer_len*/sizeof(struct ata_params),
2062 /*timeout*/timeout ? timeout : 30 * 1000,
2072 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2073 ptr[i] = le16toh(ptr[i]);
2078 if (arglist & CAM_ARG_VERBOSE) {
2079 fprintf(stdout, "%s%d: Raw identify data:\n",
2080 device->device_name, device->dev_unit_num);
2081 dump_data(ptr, sizeof(struct ata_params));
2084 /* check for invalid (all zero) response */
2086 warnx("Invalid identify response detected");
2091 ident_buf = (struct ata_params *)ptr;
2092 if (strncmp(ident_buf->model, "FX", 2) &&
2093 strncmp(ident_buf->model, "NEC", 3) &&
2094 strncmp(ident_buf->model, "Pioneer", 7) &&
2095 strncmp(ident_buf->model, "SHARP", 5)) {
2096 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2097 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2098 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2099 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2101 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2102 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2103 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2104 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2105 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2106 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2107 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2108 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2109 sizeof(ident_buf->media_serial));
2111 *ident_bufp = ident_buf;
2118 ataidentify(struct cam_device *device, int retry_count, int timeout)
2121 struct ata_params *ident_buf;
2124 if ((ccb = cam_getccb(device)) == NULL) {
2125 warnx("couldn't allocate CCB");
2129 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2134 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2135 if (ata_read_native_max(device, retry_count, timeout, ccb,
2136 ident_buf, &hpasize) != 0) {
2144 printf("%s%d: ", device->device_name, device->dev_unit_num);
2145 ata_print_ident(ident_buf);
2146 camxferrate(device);
2147 atacapprint(ident_buf);
2148 atahpa_print(ident_buf, hpasize, 0);
2155 #endif /* MINIMALISTIC */
2158 #ifndef MINIMALISTIC
2160 ATA_SECURITY_ACTION_PRINT,
2161 ATA_SECURITY_ACTION_FREEZE,
2162 ATA_SECURITY_ACTION_UNLOCK,
2163 ATA_SECURITY_ACTION_DISABLE,
2164 ATA_SECURITY_ACTION_ERASE,
2165 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2166 ATA_SECURITY_ACTION_SET_PASSWORD
2167 } atasecurity_action;
2170 atasecurity_print_time(u_int16_t tw)
2174 printf("unspecified");
2176 printf("> 508 min");
2178 printf("%i min", 2 * tw);
2182 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2186 return 2 * 3600 * 1000; /* default: two hours */
2187 else if (timeout > 255)
2188 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2190 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2195 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2199 bzero(&cmd, sizeof(cmd));
2200 cmd.command = command;
2201 printf("Issuing %s", ata_op_string(&cmd));
2204 char pass[sizeof(pwd->password)+1];
2206 /* pwd->password may not be null terminated */
2207 pass[sizeof(pwd->password)] = '\0';
2208 strncpy(pass, pwd->password, sizeof(pwd->password));
2209 printf(" password='%s', user='%s'",
2211 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2214 if (command == ATA_SECURITY_SET_PASSWORD) {
2215 printf(", mode='%s'",
2216 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2217 "maximum" : "high");
2225 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2226 int retry_count, u_int32_t timeout, int quiet)
2230 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2232 return ata_do_28bit_cmd(device,
2235 /*flags*/CAM_DIR_NONE,
2236 /*protocol*/AP_PROTO_NON_DATA,
2237 /*tag_action*/MSG_SIMPLE_Q_TAG,
2238 /*command*/ATA_SECURITY_FREEZE_LOCK,
2249 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2250 int retry_count, u_int32_t timeout,
2251 struct ata_security_password *pwd, int quiet)
2255 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2257 return ata_do_28bit_cmd(device,
2260 /*flags*/CAM_DIR_OUT,
2261 /*protocol*/AP_PROTO_PIO_OUT,
2262 /*tag_action*/MSG_SIMPLE_Q_TAG,
2263 /*command*/ATA_SECURITY_UNLOCK,
2267 /*data_ptr*/(u_int8_t *)pwd,
2268 /*dxfer_len*/sizeof(*pwd),
2274 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2275 int retry_count, u_int32_t timeout,
2276 struct ata_security_password *pwd, int quiet)
2280 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2281 return ata_do_28bit_cmd(device,
2284 /*flags*/CAM_DIR_OUT,
2285 /*protocol*/AP_PROTO_PIO_OUT,
2286 /*tag_action*/MSG_SIMPLE_Q_TAG,
2287 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2291 /*data_ptr*/(u_int8_t *)pwd,
2292 /*dxfer_len*/sizeof(*pwd),
2299 atasecurity_erase_confirm(struct cam_device *device,
2300 struct ata_params* ident_buf)
2303 printf("\nYou are about to ERASE ALL DATA from the following"
2304 " device:\n%s%d,%s%d: ", device->device_name,
2305 device->dev_unit_num, device->given_dev_name,
2306 device->given_unit_number);
2307 ata_print_ident(ident_buf);
2311 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2313 if (fgets(str, sizeof(str), stdin) != NULL) {
2314 if (strncasecmp(str, "yes", 3) == 0) {
2316 } else if (strncasecmp(str, "no", 2) == 0) {
2319 printf("Please answer \"yes\" or "
2330 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2331 int retry_count, u_int32_t timeout,
2332 u_int32_t erase_timeout,
2333 struct ata_security_password *pwd, int quiet)
2338 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2340 error = ata_do_28bit_cmd(device,
2343 /*flags*/CAM_DIR_NONE,
2344 /*protocol*/AP_PROTO_NON_DATA,
2345 /*tag_action*/MSG_SIMPLE_Q_TAG,
2346 /*command*/ATA_SECURITY_ERASE_PREPARE,
2359 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2361 error = ata_do_28bit_cmd(device,
2364 /*flags*/CAM_DIR_OUT,
2365 /*protocol*/AP_PROTO_PIO_OUT,
2366 /*tag_action*/MSG_SIMPLE_Q_TAG,
2367 /*command*/ATA_SECURITY_ERASE_UNIT,
2371 /*data_ptr*/(u_int8_t *)pwd,
2372 /*dxfer_len*/sizeof(*pwd),
2373 /*timeout*/erase_timeout,
2376 if (error == 0 && quiet == 0)
2377 printf("\nErase Complete\n");
2383 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2384 int retry_count, u_int32_t timeout,
2385 struct ata_security_password *pwd, int quiet)
2389 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2391 return ata_do_28bit_cmd(device,
2394 /*flags*/CAM_DIR_OUT,
2395 /*protocol*/AP_PROTO_PIO_OUT,
2396 /*tag_action*/MSG_SIMPLE_Q_TAG,
2397 /*command*/ATA_SECURITY_SET_PASSWORD,
2401 /*data_ptr*/(u_int8_t *)pwd,
2402 /*dxfer_len*/sizeof(*pwd),
2408 atasecurity_print(struct ata_params *parm)
2411 printf("\nSecurity Option Value\n");
2412 if (arglist & CAM_ARG_VERBOSE) {
2413 printf("status %04x\n",
2414 parm->security_status);
2416 printf("supported %s\n",
2417 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2418 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2420 printf("enabled %s\n",
2421 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2422 printf("drive locked %s\n",
2423 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2424 printf("security config frozen %s\n",
2425 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2426 printf("count expired %s\n",
2427 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2428 printf("security level %s\n",
2429 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2430 printf("enhanced erase supported %s\n",
2431 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2432 printf("erase time ");
2433 atasecurity_print_time(parm->erase_time);
2435 printf("enhanced erase time ");
2436 atasecurity_print_time(parm->enhanced_erase_time);
2438 printf("master password rev %04x%s\n",
2439 parm->master_passwd_revision,
2440 parm->master_passwd_revision == 0x0000 ||
2441 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2445 * Validates and copies the password in optarg to the passed buffer.
2446 * If the password in optarg is the same length as the buffer then
2447 * the data will still be copied but no null termination will occur.
2450 ata_getpwd(u_int8_t *passwd, int max, char opt)
2454 len = strlen(optarg);
2456 warnx("-%c password is too long", opt);
2458 } else if (len == 0) {
2459 warnx("-%c password is missing", opt);
2461 } else if (optarg[0] == '-'){
2462 warnx("-%c password starts with '-' (generic arg?)", opt);
2464 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2465 warnx("-%c password conflicts with existing password from -%c",
2470 /* Callers pass in a buffer which does NOT need to be terminated */
2471 strncpy(passwd, optarg, max);
2478 ATA_HPA_ACTION_PRINT,
2479 ATA_HPA_ACTION_SET_MAX,
2480 ATA_HPA_ACTION_SET_PWD,
2481 ATA_HPA_ACTION_LOCK,
2482 ATA_HPA_ACTION_UNLOCK,
2483 ATA_HPA_ACTION_FREEZE_LOCK
2487 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2488 u_int64_t maxsize, int persist)
2490 printf("\nYou are about to configure HPA to limit the user accessible\n"
2491 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2492 persist ? "persistently" : "temporarily",
2493 device->device_name, device->dev_unit_num,
2494 device->given_dev_name, device->given_unit_number);
2495 ata_print_ident(ident_buf);
2499 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2501 if (NULL != fgets(str, sizeof(str), stdin)) {
2502 if (0 == strncasecmp(str, "yes", 3)) {
2504 } else if (0 == strncasecmp(str, "no", 2)) {
2507 printf("Please answer \"yes\" or "
2518 atahpa(struct cam_device *device, int retry_count, int timeout,
2519 int argc, char **argv, char *combinedopt)
2522 struct ata_params *ident_buf;
2523 struct ccb_getdev cgd;
2524 struct ata_set_max_pwd pwd;
2525 int error, confirm, quiet, c, action, actions, setpwd, persist;
2526 int security, is48bit, pwdsize;
2527 u_int64_t hpasize, maxsize;
2537 memset(&pwd, 0, sizeof(pwd));
2539 /* default action is to print hpa information */
2540 action = ATA_HPA_ACTION_PRINT;
2541 pwdsize = sizeof(pwd.password);
2543 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2546 action = ATA_HPA_ACTION_SET_MAX;
2547 maxsize = strtoumax(optarg, NULL, 0);
2552 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2554 action = ATA_HPA_ACTION_SET_PWD;
2560 action = ATA_HPA_ACTION_LOCK;
2566 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2568 action = ATA_HPA_ACTION_UNLOCK;
2574 action = ATA_HPA_ACTION_FREEZE_LOCK;
2594 warnx("too many hpa actions specified");
2598 if (get_cgd(device, &cgd) != 0) {
2599 warnx("couldn't get CGD");
2603 ccb = cam_getccb(device);
2605 warnx("couldn't allocate CCB");
2609 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2616 printf("%s%d: ", device->device_name, device->dev_unit_num);
2617 ata_print_ident(ident_buf);
2618 camxferrate(device);
2621 if (action == ATA_HPA_ACTION_PRINT) {
2622 error = ata_read_native_max(device, retry_count, timeout, ccb,
2623 ident_buf, &hpasize);
2625 atahpa_print(ident_buf, hpasize, 1);
2632 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2633 warnx("HPA is not supported by this device");
2639 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2640 warnx("HPA Security is not supported by this device");
2646 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2649 * The ATA spec requires:
2650 * 1. Read native max addr is called directly before set max addr
2651 * 2. Read native max addr is NOT called before any other set max call
2654 case ATA_HPA_ACTION_SET_MAX:
2656 atahpa_set_confirm(device, ident_buf, maxsize,
2663 error = ata_read_native_max(device, retry_count, timeout,
2664 ccb, ident_buf, &hpasize);
2666 error = atahpa_set_max(device, retry_count, timeout,
2667 ccb, is48bit, maxsize, persist);
2669 /* redo identify to get new lba values */
2670 error = ata_do_identify(device, retry_count,
2673 atahpa_print(ident_buf, hpasize, 1);
2678 case ATA_HPA_ACTION_SET_PWD:
2679 error = atahpa_password(device, retry_count, timeout,
2680 ccb, is48bit, &pwd);
2682 printf("HPA password has been set\n");
2685 case ATA_HPA_ACTION_LOCK:
2686 error = atahpa_lock(device, retry_count, timeout,
2689 printf("HPA has been locked\n");
2692 case ATA_HPA_ACTION_UNLOCK:
2693 error = atahpa_unlock(device, retry_count, timeout,
2694 ccb, is48bit, &pwd);
2696 printf("HPA has been unlocked\n");
2699 case ATA_HPA_ACTION_FREEZE_LOCK:
2700 error = atahpa_freeze_lock(device, retry_count, timeout,
2703 printf("HPA has been frozen\n");
2707 errx(1, "Option currently not supported");
2717 atasecurity(struct cam_device *device, int retry_count, int timeout,
2718 int argc, char **argv, char *combinedopt)
2721 struct ata_params *ident_buf;
2722 int error, confirm, quiet, c, action, actions, setpwd;
2723 int security_enabled, erase_timeout, pwdsize;
2724 struct ata_security_password pwd;
2732 memset(&pwd, 0, sizeof(pwd));
2734 /* default action is to print security information */
2735 action = ATA_SECURITY_ACTION_PRINT;
2737 /* user is master by default as its safer that way */
2738 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2739 pwdsize = sizeof(pwd.password);
2741 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2744 action = ATA_SECURITY_ACTION_FREEZE;
2749 if (strcasecmp(optarg, "user") == 0) {
2750 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2751 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2752 } else if (strcasecmp(optarg, "master") == 0) {
2753 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2754 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2756 warnx("-U argument '%s' is invalid (must be "
2757 "'user' or 'master')", optarg);
2763 if (strcasecmp(optarg, "high") == 0) {
2764 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2765 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2766 } else if (strcasecmp(optarg, "maximum") == 0) {
2767 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2768 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2770 warnx("-l argument '%s' is unknown (must be "
2771 "'high' or 'maximum')", optarg);
2777 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2779 action = ATA_SECURITY_ACTION_UNLOCK;
2784 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2786 action = ATA_SECURITY_ACTION_DISABLE;
2791 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2793 action = ATA_SECURITY_ACTION_ERASE;
2798 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2800 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2801 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2806 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2809 if (action == ATA_SECURITY_ACTION_PRINT)
2810 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2812 * Don't increment action as this can be combined
2813 * with other actions.
2826 erase_timeout = atoi(optarg) * 1000;
2832 warnx("too many security actions specified");
2836 if ((ccb = cam_getccb(device)) == NULL) {
2837 warnx("couldn't allocate CCB");
2841 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2848 printf("%s%d: ", device->device_name, device->dev_unit_num);
2849 ata_print_ident(ident_buf);
2850 camxferrate(device);
2853 if (action == ATA_SECURITY_ACTION_PRINT) {
2854 atasecurity_print(ident_buf);
2860 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2861 warnx("Security not supported");
2867 /* default timeout 15 seconds the same as linux hdparm */
2868 timeout = timeout ? timeout : 15 * 1000;
2870 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2872 /* first set the password if requested */
2874 /* confirm we can erase before setting the password if erasing */
2876 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2877 action == ATA_SECURITY_ACTION_ERASE) &&
2878 atasecurity_erase_confirm(device, ident_buf) == 0) {
2884 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2885 pwd.revision = ident_buf->master_passwd_revision;
2886 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2887 --pwd.revision == 0) {
2888 pwd.revision = 0xfffe;
2891 error = atasecurity_set_password(device, ccb, retry_count,
2892 timeout, &pwd, quiet);
2898 security_enabled = 1;
2902 case ATA_SECURITY_ACTION_FREEZE:
2903 error = atasecurity_freeze(device, ccb, retry_count,
2907 case ATA_SECURITY_ACTION_UNLOCK:
2908 if (security_enabled) {
2909 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2910 error = atasecurity_unlock(device, ccb,
2911 retry_count, timeout, &pwd, quiet);
2913 warnx("Can't unlock, drive is not locked");
2917 warnx("Can't unlock, security is disabled");
2922 case ATA_SECURITY_ACTION_DISABLE:
2923 if (security_enabled) {
2924 /* First unlock the drive if its locked */
2925 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2926 error = atasecurity_unlock(device, ccb,
2934 error = atasecurity_disable(device,
2942 warnx("Can't disable security (already disabled)");
2947 case ATA_SECURITY_ACTION_ERASE:
2948 if (security_enabled) {
2949 if (erase_timeout == 0) {
2950 erase_timeout = atasecurity_erase_timeout_msecs(
2951 ident_buf->erase_time);
2954 error = atasecurity_erase(device, ccb, retry_count,
2955 timeout, erase_timeout, &pwd,
2958 warnx("Can't secure erase (security is disabled)");
2963 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
2964 if (security_enabled) {
2965 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
2966 if (erase_timeout == 0) {
2968 atasecurity_erase_timeout_msecs(
2969 ident_buf->enhanced_erase_time);
2972 error = atasecurity_erase(device, ccb,
2973 retry_count, timeout,
2974 erase_timeout, &pwd,
2977 warnx("Enhanced erase is not supported");
2981 warnx("Can't secure erase (enhanced), "
2982 "(security is disabled)");
2993 #endif /* MINIMALISTIC */
2996 * Parse out a bus, or a bus, target and lun in the following
3002 * Returns the number of parsed components, or 0.
3005 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3006 cam_argmask *arglst)
3011 while (isspace(*tstr) && (*tstr != '\0'))
3014 tmpstr = (char *)strtok(tstr, ":");
3015 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3016 *bus = strtol(tmpstr, NULL, 0);
3017 *arglst |= CAM_ARG_BUS;
3019 tmpstr = (char *)strtok(NULL, ":");
3020 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3021 *target = strtol(tmpstr, NULL, 0);
3022 *arglst |= CAM_ARG_TARGET;
3024 tmpstr = (char *)strtok(NULL, ":");
3025 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3026 *lun = strtol(tmpstr, NULL, 0);
3027 *arglst |= CAM_ARG_LUN;
3037 dorescan_or_reset(int argc, char **argv, int rescan)
3039 static const char must[] =
3040 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3042 path_id_t bus = CAM_BUS_WILDCARD;
3043 target_id_t target = CAM_TARGET_WILDCARD;
3044 lun_id_t lun = CAM_LUN_WILDCARD;
3048 warnx(must, rescan? "rescan" : "reset");
3052 tstr = argv[optind];
3053 while (isspace(*tstr) && (*tstr != '\0'))
3055 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3056 arglist |= CAM_ARG_BUS;
3058 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3059 if (rv != 1 && rv != 3) {
3060 warnx(must, rescan? "rescan" : "reset");
3065 if ((arglist & CAM_ARG_BUS)
3066 && (arglist & CAM_ARG_TARGET)
3067 && (arglist & CAM_ARG_LUN))
3068 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3070 error = rescan_or_reset_bus(bus, rescan);
3076 rescan_or_reset_bus(path_id_t bus, int rescan)
3078 union ccb ccb, matchccb;
3084 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3085 warnx("error opening transport layer device %s", XPT_DEVICE);
3086 warn("%s", XPT_DEVICE);
3090 if (bus != CAM_BUS_WILDCARD) {
3091 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3092 ccb.ccb_h.path_id = bus;
3093 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3094 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3095 ccb.crcn.flags = CAM_FLAG_NONE;
3097 /* run this at a low priority */
3098 ccb.ccb_h.pinfo.priority = 5;
3100 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3101 warn("CAMIOCOMMAND ioctl failed");
3106 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3107 fprintf(stdout, "%s of bus %d was successful\n",
3108 rescan ? "Re-scan" : "Reset", bus);
3110 fprintf(stdout, "%s of bus %d returned error %#x\n",
3111 rescan ? "Re-scan" : "Reset", bus,
3112 ccb.ccb_h.status & CAM_STATUS_MASK);
3123 * The right way to handle this is to modify the xpt so that it can
3124 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3125 * that isn't implemented, so instead we enumerate the busses and
3126 * send the rescan or reset to those busses in the case where the
3127 * given bus is -1 (wildcard). We don't send a rescan or reset
3128 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3129 * no-op, sending a rescan to the xpt bus would result in a status of
3132 bzero(&(&matchccb.ccb_h)[1],
3133 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3134 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3135 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3136 bufsize = sizeof(struct dev_match_result) * 20;
3137 matchccb.cdm.match_buf_len = bufsize;
3138 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3139 if (matchccb.cdm.matches == NULL) {
3140 warnx("can't malloc memory for matches");
3144 matchccb.cdm.num_matches = 0;
3146 matchccb.cdm.num_patterns = 1;
3147 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3149 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3150 matchccb.cdm.pattern_buf_len);
3151 if (matchccb.cdm.patterns == NULL) {
3152 warnx("can't malloc memory for patterns");
3156 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3157 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3162 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3163 warn("CAMIOCOMMAND ioctl failed");
3168 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3169 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3170 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3171 warnx("got CAM error %#x, CDM error %d\n",
3172 matchccb.ccb_h.status, matchccb.cdm.status);
3177 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3178 struct bus_match_result *bus_result;
3180 /* This shouldn't happen. */
3181 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3184 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3187 * We don't want to rescan or reset the xpt bus.
3190 if (bus_result->path_id == CAM_XPT_PATH_ID)
3193 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3195 ccb.ccb_h.path_id = bus_result->path_id;
3196 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3197 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3198 ccb.crcn.flags = CAM_FLAG_NONE;
3200 /* run this at a low priority */
3201 ccb.ccb_h.pinfo.priority = 5;
3203 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3204 warn("CAMIOCOMMAND ioctl failed");
3209 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3210 fprintf(stdout, "%s of bus %d was successful\n",
3211 rescan? "Re-scan" : "Reset",
3212 bus_result->path_id);
3215 * Don't bail out just yet, maybe the other
3216 * rescan or reset commands will complete
3219 fprintf(stderr, "%s of bus %d returned error "
3220 "%#x\n", rescan? "Re-scan" : "Reset",
3221 bus_result->path_id,
3222 ccb.ccb_h.status & CAM_STATUS_MASK);
3226 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3227 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3234 if (matchccb.cdm.patterns != NULL)
3235 free(matchccb.cdm.patterns);
3236 if (matchccb.cdm.matches != NULL)
3237 free(matchccb.cdm.matches);
3243 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3246 struct cam_device *device;
3251 if (bus == CAM_BUS_WILDCARD) {
3252 warnx("invalid bus number %d", bus);
3256 if (target == CAM_TARGET_WILDCARD) {
3257 warnx("invalid target number %d", target);
3261 if (lun == CAM_LUN_WILDCARD) {
3262 warnx("invalid lun number %jx", (uintmax_t)lun);
3268 bzero(&ccb, sizeof(union ccb));
3271 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3272 warnx("error opening transport layer device %s\n",
3274 warn("%s", XPT_DEVICE);
3278 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3279 if (device == NULL) {
3280 warnx("%s", cam_errbuf);
3285 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3286 ccb.ccb_h.path_id = bus;
3287 ccb.ccb_h.target_id = target;
3288 ccb.ccb_h.target_lun = lun;
3289 ccb.ccb_h.timeout = 5000;
3290 ccb.crcn.flags = CAM_FLAG_NONE;
3292 /* run this at a low priority */
3293 ccb.ccb_h.pinfo.priority = 5;
3296 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3297 warn("CAMIOCOMMAND ioctl failed");
3302 if (cam_send_ccb(device, &ccb) < 0) {
3303 warn("error sending XPT_RESET_DEV CCB");
3304 cam_close_device(device);
3312 cam_close_device(device);
3315 * An error code of CAM_BDR_SENT is normal for a BDR request.
3317 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3319 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3320 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3321 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3324 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3325 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3326 ccb.ccb_h.status & CAM_STATUS_MASK);
3331 #ifndef MINIMALISTIC
3333 readdefects(struct cam_device *device, int argc, char **argv,
3334 char *combinedopt, int retry_count, int timeout)
3336 union ccb *ccb = NULL;
3337 struct scsi_read_defect_data_10 *rdd_cdb;
3338 u_int8_t *defect_list = NULL;
3339 u_int32_t max_dlist_length = SRDD10_MAX_LENGTH, dlist_length = 0;
3340 u_int32_t returned_length = 0;
3341 u_int32_t num_returned = 0;
3342 u_int8_t returned_format;
3345 int lists_specified;
3348 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3354 while (isspace(*tstr) && (*tstr != '\0'))
3356 if (strcmp(tstr, "block") == 0)
3357 arglist |= CAM_ARG_FORMAT_BLOCK;
3358 else if (strcmp(tstr, "bfi") == 0)
3359 arglist |= CAM_ARG_FORMAT_BFI;
3360 else if (strcmp(tstr, "phys") == 0)
3361 arglist |= CAM_ARG_FORMAT_PHYS;
3364 warnx("invalid defect format %s", tstr);
3365 goto defect_bailout;
3370 arglist |= CAM_ARG_GLIST;
3373 arglist |= CAM_ARG_PLIST;
3380 ccb = cam_getccb(device);
3383 * Eventually we should probably support the 12 byte READ DEFECT
3384 * DATA command. It supports a longer parameter list, which may be
3385 * necessary on newer drives with lots of defects. According to
3386 * the SBC-3 spec, drives are supposed to return an illegal request
3387 * if they have more defect data than will fit in 64K.
3389 defect_list = malloc(max_dlist_length);
3390 if (defect_list == NULL) {
3391 warnx("can't malloc memory for defect list");
3393 goto defect_bailout;
3397 * We start off asking for just the header to determine how much
3398 * defect data is available. Some Hitachi drives return an error
3399 * if you ask for more data than the drive has. Once we know the
3400 * length, we retry the command with the returned length.
3402 dlist_length = sizeof(struct scsi_read_defect_data_hdr_10);
3404 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
3408 lists_specified = 0;
3411 * cam_getccb() zeros the CCB header only. So we need to zero the
3412 * payload portion of the ccb.
3414 bzero(&(&ccb->ccb_h)[1],
3415 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3417 cam_fill_csio(&ccb->csio,
3418 /*retries*/ retry_count,
3420 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
3421 CAM_PASS_ERR_RECOVER : 0),
3422 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3423 /*data_ptr*/ defect_list,
3424 /*dxfer_len*/ dlist_length,
3425 /*sense_len*/ SSD_FULL_SIZE,
3426 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
3427 /*timeout*/ timeout ? timeout : 5000);
3429 rdd_cdb->opcode = READ_DEFECT_DATA_10;
3430 if (arglist & CAM_ARG_FORMAT_BLOCK)
3431 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
3432 else if (arglist & CAM_ARG_FORMAT_BFI)
3433 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
3434 else if (arglist & CAM_ARG_FORMAT_PHYS)
3435 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
3438 warnx("no defect list format specified");
3439 goto defect_bailout;
3441 if (arglist & CAM_ARG_PLIST) {
3442 rdd_cdb->format |= SRDD10_PLIST;
3446 if (arglist & CAM_ARG_GLIST) {
3447 rdd_cdb->format |= SRDD10_GLIST;
3451 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
3453 /* Disable freezing the device queue */
3454 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3456 if (cam_send_ccb(device, ccb) < 0) {
3457 perror("error reading defect list");
3459 if (arglist & CAM_ARG_VERBOSE) {
3460 cam_error_print(device, ccb, CAM_ESF_ALL,
3461 CAM_EPF_ALL, stderr);
3465 goto defect_bailout;
3468 returned_length = scsi_2btoul(((struct
3469 scsi_read_defect_data_hdr_10 *)defect_list)->length);
3471 if (get_length != 0) {
3474 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3475 CAM_SCSI_STATUS_ERROR) {
3476 struct scsi_sense_data *sense;
3477 int error_code, sense_key, asc, ascq;
3479 sense = &ccb->csio.sense_data;
3480 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3481 ccb->csio.sense_resid, &error_code, &sense_key,
3482 &asc, &ascq, /*show_errors*/ 1);
3485 * If the drive is reporting that it just doesn't
3486 * support the defect list format, go ahead and use
3487 * the length it reported. Otherwise, the length
3488 * may not be valid, so use the maximum.
3490 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3491 && (asc == 0x1c) && (ascq == 0x00)
3492 && (returned_length > 0)) {
3493 dlist_length = returned_length +
3494 sizeof(struct scsi_read_defect_data_hdr_10);
3495 dlist_length = min(dlist_length,
3498 dlist_length = max_dlist_length;
3499 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3502 warnx("Error reading defect header");
3503 if (arglist & CAM_ARG_VERBOSE)
3504 cam_error_print(device, ccb, CAM_ESF_ALL,
3505 CAM_EPF_ALL, stderr);
3506 goto defect_bailout;
3508 dlist_length = returned_length +
3509 sizeof(struct scsi_read_defect_data_hdr_10);
3510 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3516 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
3517 defect_list)->format;
3519 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3520 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3521 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3522 struct scsi_sense_data *sense;
3523 int error_code, sense_key, asc, ascq;
3525 sense = &ccb->csio.sense_data;
3526 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3527 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3528 &ascq, /*show_errors*/ 1);
3531 * According to the SCSI spec, if the disk doesn't support
3532 * the requested format, it will generally return a sense
3533 * key of RECOVERED ERROR, and an additional sense code
3534 * of "DEFECT LIST NOT FOUND". So, we check for that, and
3535 * also check to make sure that the returned length is
3536 * greater than 0, and then print out whatever format the
3539 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3540 && (asc == 0x1c) && (ascq == 0x00)
3541 && (returned_length > 0)) {
3542 warnx("requested defect format not available");
3543 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
3544 case SRDD10_BLOCK_FORMAT:
3545 warnx("Device returned block format");
3547 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3548 warnx("Device returned bytes from index"
3551 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3552 warnx("Device returned physical sector format");
3556 warnx("Device returned unknown defect"
3557 " data format %#x", returned_format);
3558 goto defect_bailout;
3559 break; /* NOTREACHED */
3563 warnx("Error returned from read defect data command");
3564 if (arglist & CAM_ARG_VERBOSE)
3565 cam_error_print(device, ccb, CAM_ESF_ALL,
3566 CAM_EPF_ALL, stderr);
3567 goto defect_bailout;
3569 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3571 warnx("Error returned from read defect data command");
3572 if (arglist & CAM_ARG_VERBOSE)
3573 cam_error_print(device, ccb, CAM_ESF_ALL,
3574 CAM_EPF_ALL, stderr);
3575 goto defect_bailout;
3579 * XXX KDM I should probably clean up the printout format for the
3582 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
3583 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
3585 struct scsi_defect_desc_phys_sector *dlist;
3587 dlist = (struct scsi_defect_desc_phys_sector *)
3589 sizeof(struct scsi_read_defect_data_hdr_10));
3591 num_returned = returned_length /
3592 sizeof(struct scsi_defect_desc_phys_sector);
3594 fprintf(stderr, "Got %d defect", num_returned);
3596 if ((lists_specified == 0) || (num_returned == 0)) {
3597 fprintf(stderr, "s.\n");
3599 } else if (num_returned == 1)
3600 fprintf(stderr, ":\n");
3602 fprintf(stderr, "s:\n");
3604 for (i = 0; i < num_returned; i++) {
3605 fprintf(stdout, "%d:%d:%d\n",
3606 scsi_3btoul(dlist[i].cylinder),
3608 scsi_4btoul(dlist[i].sector));
3612 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
3614 struct scsi_defect_desc_bytes_from_index *dlist;
3616 dlist = (struct scsi_defect_desc_bytes_from_index *)
3618 sizeof(struct scsi_read_defect_data_hdr_10));
3620 num_returned = returned_length /
3621 sizeof(struct scsi_defect_desc_bytes_from_index);
3623 fprintf(stderr, "Got %d defect", num_returned);
3625 if ((lists_specified == 0) || (num_returned == 0)) {
3626 fprintf(stderr, "s.\n");
3628 } else if (num_returned == 1)
3629 fprintf(stderr, ":\n");
3631 fprintf(stderr, "s:\n");
3633 for (i = 0; i < num_returned; i++) {
3634 fprintf(stdout, "%d:%d:%d\n",
3635 scsi_3btoul(dlist[i].cylinder),
3637 scsi_4btoul(dlist[i].bytes_from_index));
3641 case SRDDH10_BLOCK_FORMAT:
3643 struct scsi_defect_desc_block *dlist;
3645 dlist = (struct scsi_defect_desc_block *)(defect_list +
3646 sizeof(struct scsi_read_defect_data_hdr_10));
3648 num_returned = returned_length /
3649 sizeof(struct scsi_defect_desc_block);
3651 fprintf(stderr, "Got %d defect", num_returned);
3653 if ((lists_specified == 0) || (num_returned == 0)) {
3654 fprintf(stderr, "s.\n");
3656 } else if (num_returned == 1)
3657 fprintf(stderr, ":\n");
3659 fprintf(stderr, "s:\n");
3661 for (i = 0; i < num_returned; i++)
3662 fprintf(stdout, "%u\n",
3663 scsi_4btoul(dlist[i].address));
3667 fprintf(stderr, "Unknown defect format %d\n",
3668 returned_format & SRDDH10_DLIST_FORMAT_MASK);
3674 if (defect_list != NULL)
3682 #endif /* MINIMALISTIC */
3686 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3690 ccb = cam_getccb(device);
3696 #ifndef MINIMALISTIC
3698 mode_sense(struct cam_device *device, int mode_page, int page_control,
3699 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3704 ccb = cam_getccb(device);
3707 errx(1, "mode_sense: couldn't allocate CCB");
3709 bzero(&(&ccb->ccb_h)[1],
3710 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3712 scsi_mode_sense(&ccb->csio,
3713 /* retries */ retry_count,
3715 /* tag_action */ MSG_SIMPLE_Q_TAG,
3717 /* page_code */ page_control << 6,
3718 /* page */ mode_page,
3719 /* param_buf */ data,
3720 /* param_len */ datalen,
3721 /* sense_len */ SSD_FULL_SIZE,
3722 /* timeout */ timeout ? timeout : 5000);
3724 if (arglist & CAM_ARG_ERR_RECOVER)
3725 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3727 /* Disable freezing the device queue */
3728 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3730 if (((retval = cam_send_ccb(device, ccb)) < 0)
3731 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3732 if (arglist & CAM_ARG_VERBOSE) {
3733 cam_error_print(device, ccb, CAM_ESF_ALL,
3734 CAM_EPF_ALL, stderr);
3737 cam_close_device(device);
3739 err(1, "error sending mode sense command");
3741 errx(1, "error sending mode sense command");
3748 mode_select(struct cam_device *device, int save_pages, int retry_count,
3749 int timeout, u_int8_t *data, int datalen)
3754 ccb = cam_getccb(device);
3757 errx(1, "mode_select: couldn't allocate CCB");
3759 bzero(&(&ccb->ccb_h)[1],
3760 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3762 scsi_mode_select(&ccb->csio,
3763 /* retries */ retry_count,
3765 /* tag_action */ MSG_SIMPLE_Q_TAG,
3766 /* scsi_page_fmt */ 1,
3767 /* save_pages */ save_pages,
3768 /* param_buf */ data,
3769 /* param_len */ datalen,
3770 /* sense_len */ SSD_FULL_SIZE,
3771 /* timeout */ timeout ? timeout : 5000);
3773 if (arglist & CAM_ARG_ERR_RECOVER)
3774 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3776 /* Disable freezing the device queue */
3777 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3779 if (((retval = cam_send_ccb(device, ccb)) < 0)
3780 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3781 if (arglist & CAM_ARG_VERBOSE) {
3782 cam_error_print(device, ccb, CAM_ESF_ALL,
3783 CAM_EPF_ALL, stderr);
3786 cam_close_device(device);
3789 err(1, "error sending mode select command");
3791 errx(1, "error sending mode select command");
3799 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
3800 int retry_count, int timeout)
3802 int c, mode_page = -1, page_control = 0;
3803 int binary = 0, list = 0;
3805 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3811 arglist |= CAM_ARG_DBD;
3814 arglist |= CAM_ARG_MODE_EDIT;
3820 mode_page = strtol(optarg, NULL, 0);
3822 errx(1, "invalid mode page %d", mode_page);
3825 page_control = strtol(optarg, NULL, 0);
3826 if ((page_control < 0) || (page_control > 3))
3827 errx(1, "invalid page control field %d",
3829 arglist |= CAM_ARG_PAGE_CNTL;
3836 if (mode_page == -1 && list == 0)
3837 errx(1, "you must specify a mode page!");
3840 mode_list(device, page_control, arglist & CAM_ARG_DBD,
3841 retry_count, timeout);
3843 mode_edit(device, mode_page, page_control,
3844 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
3845 retry_count, timeout);
3850 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
3851 int retry_count, int timeout)
3854 u_int32_t flags = CAM_DIR_NONE;
3855 u_int8_t *data_ptr = NULL;
3857 u_int8_t atacmd[12];
3858 struct get_hook hook;
3859 int c, data_bytes = 0;
3865 char *datastr = NULL, *tstr, *resstr = NULL;
3867 int fd_data = 0, fd_res = 0;
3870 ccb = cam_getccb(device);
3873 warnx("scsicmd: error allocating ccb");
3877 bzero(&(&ccb->ccb_h)[1],
3878 sizeof(union ccb) - sizeof(struct ccb_hdr));
3880 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3884 while (isspace(*tstr) && (*tstr != '\0'))
3886 hook.argc = argc - optind;
3887 hook.argv = argv + optind;
3889 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
3892 * Increment optind by the number of arguments the
3893 * encoding routine processed. After each call to
3894 * getopt(3), optind points to the argument that
3895 * getopt should process _next_. In this case,
3896 * that means it points to the first command string
3897 * argument, if there is one. Once we increment
3898 * this, it should point to either the next command
3899 * line argument, or it should be past the end of
3906 while (isspace(*tstr) && (*tstr != '\0'))
3908 hook.argc = argc - optind;
3909 hook.argv = argv + optind;
3911 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
3914 * Increment optind by the number of arguments the
3915 * encoding routine processed. After each call to
3916 * getopt(3), optind points to the argument that
3917 * getopt should process _next_. In this case,
3918 * that means it points to the first command string
3919 * argument, if there is one. Once we increment
3920 * this, it should point to either the next command
3921 * line argument, or it should be past the end of
3933 if (arglist & CAM_ARG_CMD_OUT) {
3934 warnx("command must either be "
3935 "read or write, not both");
3937 goto scsicmd_bailout;
3939 arglist |= CAM_ARG_CMD_IN;
3941 data_bytes = strtol(optarg, NULL, 0);
3942 if (data_bytes <= 0) {
3943 warnx("invalid number of input bytes %d",
3946 goto scsicmd_bailout;
3948 hook.argc = argc - optind;
3949 hook.argv = argv + optind;
3952 datastr = cget(&hook, NULL);
3954 * If the user supplied "-" instead of a format, he
3955 * wants the data to be written to stdout.
3957 if ((datastr != NULL)
3958 && (datastr[0] == '-'))
3961 data_ptr = (u_int8_t *)malloc(data_bytes);
3962 if (data_ptr == NULL) {
3963 warnx("can't malloc memory for data_ptr");
3965 goto scsicmd_bailout;
3969 if (arglist & CAM_ARG_CMD_IN) {
3970 warnx("command must either be "
3971 "read or write, not both");
3973 goto scsicmd_bailout;
3975 arglist |= CAM_ARG_CMD_OUT;
3976 flags = CAM_DIR_OUT;
3977 data_bytes = strtol(optarg, NULL, 0);
3978 if (data_bytes <= 0) {
3979 warnx("invalid number of output bytes %d",
3982 goto scsicmd_bailout;
3984 hook.argc = argc - optind;
3985 hook.argv = argv + optind;
3987 datastr = cget(&hook, NULL);
3988 data_ptr = (u_int8_t *)malloc(data_bytes);
3989 if (data_ptr == NULL) {
3990 warnx("can't malloc memory for data_ptr");
3992 goto scsicmd_bailout;
3994 bzero(data_ptr, data_bytes);
3996 * If the user supplied "-" instead of a format, he
3997 * wants the data to be read from stdin.
3999 if ((datastr != NULL)
4000 && (datastr[0] == '-'))
4003 buff_encode_visit(data_ptr, data_bytes, datastr,
4009 hook.argc = argc - optind;
4010 hook.argv = argv + optind;
4012 resstr = cget(&hook, NULL);
4013 if ((resstr != NULL) && (resstr[0] == '-'))
4023 * If fd_data is set, and we're writing to the device, we need to
4024 * read the data the user wants written from stdin.
4026 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4028 int amt_to_read = data_bytes;
4029 u_int8_t *buf_ptr = data_ptr;
4031 for (amt_read = 0; amt_to_read > 0;
4032 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4033 if (amt_read == -1) {
4034 warn("error reading data from stdin");
4036 goto scsicmd_bailout;
4038 amt_to_read -= amt_read;
4039 buf_ptr += amt_read;
4043 if (arglist & CAM_ARG_ERR_RECOVER)
4044 flags |= CAM_PASS_ERR_RECOVER;
4046 /* Disable freezing the device queue */
4047 flags |= CAM_DEV_QFRZDIS;
4051 * This is taken from the SCSI-3 draft spec.
4052 * (T10/1157D revision 0.3)
4053 * The top 3 bits of an opcode are the group code.
4054 * The next 5 bits are the command code.
4055 * Group 0: six byte commands
4056 * Group 1: ten byte commands
4057 * Group 2: ten byte commands
4059 * Group 4: sixteen byte commands
4060 * Group 5: twelve byte commands
4061 * Group 6: vendor specific
4062 * Group 7: vendor specific
4064 switch((cdb[0] >> 5) & 0x7) {
4075 /* computed by buff_encode_visit */
4086 * We should probably use csio_build_visit or something like that
4087 * here, but it's easier to encode arguments as you go. The
4088 * alternative would be skipping the CDB argument and then encoding
4089 * it here, since we've got the data buffer argument by now.
4091 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4093 cam_fill_csio(&ccb->csio,
4094 /*retries*/ retry_count,
4097 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4098 /*data_ptr*/ data_ptr,
4099 /*dxfer_len*/ data_bytes,
4100 /*sense_len*/ SSD_FULL_SIZE,
4101 /*cdb_len*/ cdb_len,
4102 /*timeout*/ timeout ? timeout : 5000);
4105 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4107 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4109 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4111 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4113 cam_fill_ataio(&ccb->ataio,
4114 /*retries*/ retry_count,
4118 /*data_ptr*/ data_ptr,
4119 /*dxfer_len*/ data_bytes,
4120 /*timeout*/ timeout ? timeout : 5000);
4123 if (((retval = cam_send_ccb(device, ccb)) < 0)
4124 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4125 const char warnstr[] = "error sending command";
4132 if (arglist & CAM_ARG_VERBOSE) {
4133 cam_error_print(device, ccb, CAM_ESF_ALL,
4134 CAM_EPF_ALL, stderr);
4138 goto scsicmd_bailout;
4141 if (atacmd_len && need_res) {
4143 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4145 fprintf(stdout, "\n");
4148 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4149 ccb->ataio.res.status,
4150 ccb->ataio.res.error,
4151 ccb->ataio.res.lba_low,
4152 ccb->ataio.res.lba_mid,
4153 ccb->ataio.res.lba_high,
4154 ccb->ataio.res.device,
4155 ccb->ataio.res.lba_low_exp,
4156 ccb->ataio.res.lba_mid_exp,
4157 ccb->ataio.res.lba_high_exp,
4158 ccb->ataio.res.sector_count,
4159 ccb->ataio.res.sector_count_exp);
4164 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4165 && (arglist & CAM_ARG_CMD_IN)
4166 && (data_bytes > 0)) {
4168 buff_decode_visit(data_ptr, data_bytes, datastr,
4170 fprintf(stdout, "\n");
4172 ssize_t amt_written;
4173 int amt_to_write = data_bytes;
4174 u_int8_t *buf_ptr = data_ptr;
4176 for (amt_written = 0; (amt_to_write > 0) &&
4177 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4178 amt_to_write -= amt_written;
4179 buf_ptr += amt_written;
4181 if (amt_written == -1) {
4182 warn("error writing data to stdout");
4184 goto scsicmd_bailout;
4185 } else if ((amt_written == 0)
4186 && (amt_to_write > 0)) {
4187 warnx("only wrote %u bytes out of %u",
4188 data_bytes - amt_to_write, data_bytes);
4195 if ((data_bytes > 0) && (data_ptr != NULL))
4204 camdebug(int argc, char **argv, char *combinedopt)
4207 path_id_t bus = CAM_BUS_WILDCARD;
4208 target_id_t target = CAM_TARGET_WILDCARD;
4209 lun_id_t lun = CAM_LUN_WILDCARD;
4210 char *tstr, *tmpstr = NULL;
4214 bzero(&ccb, sizeof(union ccb));
4216 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4219 arglist |= CAM_ARG_DEBUG_INFO;
4220 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4223 arglist |= CAM_ARG_DEBUG_PERIPH;
4224 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4227 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4228 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4231 arglist |= CAM_ARG_DEBUG_TRACE;
4232 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4235 arglist |= CAM_ARG_DEBUG_XPT;
4236 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4239 arglist |= CAM_ARG_DEBUG_CDB;
4240 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4243 arglist |= CAM_ARG_DEBUG_PROBE;
4244 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4251 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4252 warnx("error opening transport layer device %s", XPT_DEVICE);
4253 warn("%s", XPT_DEVICE);
4260 warnx("you must specify \"off\", \"all\" or a bus,");
4261 warnx("bus:target, or bus:target:lun");
4268 while (isspace(*tstr) && (*tstr != '\0'))
4271 if (strncmp(tstr, "off", 3) == 0) {
4272 ccb.cdbg.flags = CAM_DEBUG_NONE;
4273 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4274 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4275 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4276 } else if (strncmp(tstr, "all", 3) != 0) {
4277 tmpstr = (char *)strtok(tstr, ":");
4278 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4279 bus = strtol(tmpstr, NULL, 0);
4280 arglist |= CAM_ARG_BUS;
4281 tmpstr = (char *)strtok(NULL, ":");
4282 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4283 target = strtol(tmpstr, NULL, 0);
4284 arglist |= CAM_ARG_TARGET;
4285 tmpstr = (char *)strtok(NULL, ":");
4286 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4287 lun = strtol(tmpstr, NULL, 0);
4288 arglist |= CAM_ARG_LUN;
4293 warnx("you must specify \"all\", \"off\", or a bus,");
4294 warnx("bus:target, or bus:target:lun to debug");
4300 ccb.ccb_h.func_code = XPT_DEBUG;
4301 ccb.ccb_h.path_id = bus;
4302 ccb.ccb_h.target_id = target;
4303 ccb.ccb_h.target_lun = lun;
4305 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4306 warn("CAMIOCOMMAND ioctl failed");
4311 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4312 CAM_FUNC_NOTAVAIL) {
4313 warnx("CAM debugging not available");
4314 warnx("you need to put options CAMDEBUG in"
4315 " your kernel config file!");
4317 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4319 warnx("XPT_DEBUG CCB failed with status %#x",
4323 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4325 "Debugging turned off\n");
4328 "Debugging enabled for "
4330 bus, target, (uintmax_t)lun);
4341 tagcontrol(struct cam_device *device, int argc, char **argv,
4351 ccb = cam_getccb(device);
4354 warnx("tagcontrol: error allocating ccb");
4358 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4361 numtags = strtol(optarg, NULL, 0);
4363 warnx("tag count %d is < 0", numtags);
4365 goto tagcontrol_bailout;
4376 cam_path_string(device, pathstr, sizeof(pathstr));
4379 bzero(&(&ccb->ccb_h)[1],
4380 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4381 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4382 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4383 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4384 ccb->crs.openings = numtags;
4387 if (cam_send_ccb(device, ccb) < 0) {
4388 perror("error sending XPT_REL_SIMQ CCB");
4390 goto tagcontrol_bailout;
4393 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4394 warnx("XPT_REL_SIMQ CCB failed");
4395 cam_error_print(device, ccb, CAM_ESF_ALL,
4396 CAM_EPF_ALL, stderr);
4398 goto tagcontrol_bailout;
4403 fprintf(stdout, "%stagged openings now %d\n",
4404 pathstr, ccb->crs.openings);
4407 bzero(&(&ccb->ccb_h)[1],
4408 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4410 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4412 if (cam_send_ccb(device, ccb) < 0) {
4413 perror("error sending XPT_GDEV_STATS CCB");
4415 goto tagcontrol_bailout;
4418 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4419 warnx("XPT_GDEV_STATS CCB failed");
4420 cam_error_print(device, ccb, CAM_ESF_ALL,
4421 CAM_EPF_ALL, stderr);
4423 goto tagcontrol_bailout;
4426 if (arglist & CAM_ARG_VERBOSE) {
4427 fprintf(stdout, "%s", pathstr);
4428 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4429 fprintf(stdout, "%s", pathstr);
4430 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4431 fprintf(stdout, "%s", pathstr);
4432 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
4433 fprintf(stdout, "%s", pathstr);
4434 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
4435 fprintf(stdout, "%s", pathstr);
4436 fprintf(stdout, "held %d\n", ccb->cgds.held);
4437 fprintf(stdout, "%s", pathstr);
4438 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4439 fprintf(stdout, "%s", pathstr);
4440 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4443 fprintf(stdout, "%s", pathstr);
4444 fprintf(stdout, "device openings: ");
4446 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4447 ccb->cgds.dev_active);
4457 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4461 cam_path_string(device, pathstr, sizeof(pathstr));
4463 if (cts->transport == XPORT_SPI) {
4464 struct ccb_trans_settings_spi *spi =
4465 &cts->xport_specific.spi;
4467 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4469 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4472 if (spi->sync_offset != 0) {
4475 freq = scsi_calc_syncsrate(spi->sync_period);
4476 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4477 pathstr, freq / 1000, freq % 1000);
4481 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4482 fprintf(stdout, "%soffset: %d\n", pathstr,
4486 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4487 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4488 (0x01 << spi->bus_width) * 8);
4491 if (spi->valid & CTS_SPI_VALID_DISC) {
4492 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4493 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4494 "enabled" : "disabled");
4497 if (cts->transport == XPORT_FC) {
4498 struct ccb_trans_settings_fc *fc =
4499 &cts->xport_specific.fc;
4501 if (fc->valid & CTS_FC_VALID_WWNN)
4502 fprintf(stdout, "%sWWNN: 0x%llx", pathstr,
4503 (long long) fc->wwnn);
4504 if (fc->valid & CTS_FC_VALID_WWPN)
4505 fprintf(stdout, "%sWWPN: 0x%llx", pathstr,
4506 (long long) fc->wwpn);
4507 if (fc->valid & CTS_FC_VALID_PORT)
4508 fprintf(stdout, "%sPortID: 0x%x", pathstr, fc->port);
4509 if (fc->valid & CTS_FC_VALID_SPEED)
4510 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4511 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4513 if (cts->transport == XPORT_SAS) {
4514 struct ccb_trans_settings_sas *sas =
4515 &cts->xport_specific.sas;
4517 if (sas->valid & CTS_SAS_VALID_SPEED)
4518 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4519 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4521 if (cts->transport == XPORT_ATA) {
4522 struct ccb_trans_settings_pata *pata =
4523 &cts->xport_specific.ata;
4525 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4526 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4527 ata_mode2string(pata->mode));
4529 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4530 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4533 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4534 fprintf(stdout, "%sPIO transaction length: %d\n",
4535 pathstr, pata->bytecount);
4538 if (cts->transport == XPORT_SATA) {
4539 struct ccb_trans_settings_sata *sata =
4540 &cts->xport_specific.sata;
4542 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4543 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4546 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4547 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4548 ata_mode2string(sata->mode));
4550 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4551 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4554 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4555 fprintf(stdout, "%sPIO transaction length: %d\n",
4556 pathstr, sata->bytecount);
4558 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4559 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4562 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4563 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4566 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4567 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4571 if (cts->protocol == PROTO_ATA) {
4572 struct ccb_trans_settings_ata *ata=
4573 &cts->proto_specific.ata;
4575 if (ata->valid & CTS_ATA_VALID_TQ) {
4576 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4577 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4578 "enabled" : "disabled");
4581 if (cts->protocol == PROTO_SCSI) {
4582 struct ccb_trans_settings_scsi *scsi=
4583 &cts->proto_specific.scsi;
4585 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4586 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4587 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4588 "enabled" : "disabled");
4595 * Get a path inquiry CCB for the specified device.
4598 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4603 ccb = cam_getccb(device);
4605 warnx("get_cpi: couldn't allocate CCB");
4608 bzero(&(&ccb->ccb_h)[1],
4609 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4610 ccb->ccb_h.func_code = XPT_PATH_INQ;
4611 if (cam_send_ccb(device, ccb) < 0) {
4612 warn("get_cpi: error sending Path Inquiry CCB");
4613 if (arglist & CAM_ARG_VERBOSE)
4614 cam_error_print(device, ccb, CAM_ESF_ALL,
4615 CAM_EPF_ALL, stderr);
4617 goto get_cpi_bailout;
4619 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4620 if (arglist & CAM_ARG_VERBOSE)
4621 cam_error_print(device, ccb, CAM_ESF_ALL,
4622 CAM_EPF_ALL, stderr);
4624 goto get_cpi_bailout;
4626 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4634 * Get a get device CCB for the specified device.
4637 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4642 ccb = cam_getccb(device);
4644 warnx("get_cgd: couldn't allocate CCB");
4647 bzero(&(&ccb->ccb_h)[1],
4648 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4649 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4650 if (cam_send_ccb(device, ccb) < 0) {
4651 warn("get_cgd: error sending Path Inquiry CCB");
4652 if (arglist & CAM_ARG_VERBOSE)
4653 cam_error_print(device, ccb, CAM_ESF_ALL,
4654 CAM_EPF_ALL, stderr);
4656 goto get_cgd_bailout;
4658 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4659 if (arglist & CAM_ARG_VERBOSE)
4660 cam_error_print(device, ccb, CAM_ESF_ALL,
4661 CAM_EPF_ALL, stderr);
4663 goto get_cgd_bailout;
4665 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4672 /* return the type of disk (really the command type) */
4674 get_disk_type(struct cam_device *device)
4676 struct ccb_getdev cgd;
4678 (void) memset(&cgd, 0x0, sizeof(cgd));
4679 get_cgd(device, &cgd);
4680 switch(cgd.protocol) {
4693 cpi_print(struct ccb_pathinq *cpi)
4695 char adapter_str[1024];
4698 snprintf(adapter_str, sizeof(adapter_str),
4699 "%s%d:", cpi->dev_name, cpi->unit_number);
4701 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
4704 for (i = 1; i < 0xff; i = i << 1) {
4707 if ((i & cpi->hba_inquiry) == 0)
4710 fprintf(stdout, "%s supports ", adapter_str);
4714 str = "MDP message";
4717 str = "32 bit wide SCSI";
4720 str = "16 bit wide SCSI";
4723 str = "SDTR message";
4726 str = "linked CDBs";
4729 str = "tag queue messages";
4732 str = "soft reset alternative";
4735 str = "SATA Port Multiplier";
4738 str = "unknown PI bit set";
4741 fprintf(stdout, "%s\n", str);
4744 for (i = 1; i < 0xff; i = i << 1) {
4747 if ((i & cpi->hba_misc) == 0)
4750 fprintf(stdout, "%s ", adapter_str);
4754 str = "bus scans from high ID to low ID";
4757 str = "removable devices not included in scan";
4759 case PIM_NOINITIATOR:
4760 str = "initiator role not supported";
4762 case PIM_NOBUSRESET:
4763 str = "user has disabled initial BUS RESET or"
4764 " controller is in target/mixed mode";
4767 str = "do not send 6-byte commands";
4770 str = "scan bus sequentially";
4773 str = "unknown PIM bit set";
4776 fprintf(stdout, "%s\n", str);
4779 for (i = 1; i < 0xff; i = i << 1) {
4782 if ((i & cpi->target_sprt) == 0)
4785 fprintf(stdout, "%s supports ", adapter_str);
4788 str = "target mode processor mode";
4791 str = "target mode phase cog. mode";
4793 case PIT_DISCONNECT:
4794 str = "disconnects in target mode";
4797 str = "terminate I/O message in target mode";
4800 str = "group 6 commands in target mode";
4803 str = "group 7 commands in target mode";
4806 str = "unknown PIT bit set";
4810 fprintf(stdout, "%s\n", str);
4812 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
4814 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
4816 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
4818 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
4819 adapter_str, cpi->hpath_id);
4820 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
4822 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
4823 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
4824 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
4825 adapter_str, cpi->hba_vendor);
4826 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
4827 adapter_str, cpi->hba_device);
4828 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
4829 adapter_str, cpi->hba_subvendor);
4830 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
4831 adapter_str, cpi->hba_subdevice);
4832 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
4833 fprintf(stdout, "%s base transfer speed: ", adapter_str);
4834 if (cpi->base_transfer_speed > 1000)
4835 fprintf(stdout, "%d.%03dMB/sec\n",
4836 cpi->base_transfer_speed / 1000,
4837 cpi->base_transfer_speed % 1000);
4839 fprintf(stdout, "%dKB/sec\n",
4840 (cpi->base_transfer_speed % 1000) * 1000);
4841 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
4842 adapter_str, cpi->maxio);
4846 get_print_cts(struct cam_device *device, int user_settings, int quiet,
4847 struct ccb_trans_settings *cts)
4853 ccb = cam_getccb(device);
4856 warnx("get_print_cts: error allocating ccb");
4860 bzero(&(&ccb->ccb_h)[1],
4861 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4863 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
4865 if (user_settings == 0)
4866 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
4868 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
4870 if (cam_send_ccb(device, ccb) < 0) {
4871 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
4872 if (arglist & CAM_ARG_VERBOSE)
4873 cam_error_print(device, ccb, CAM_ESF_ALL,
4874 CAM_EPF_ALL, stderr);
4876 goto get_print_cts_bailout;
4879 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4880 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
4881 if (arglist & CAM_ARG_VERBOSE)
4882 cam_error_print(device, ccb, CAM_ESF_ALL,
4883 CAM_EPF_ALL, stderr);
4885 goto get_print_cts_bailout;
4889 cts_print(device, &ccb->cts);
4892 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
4894 get_print_cts_bailout:
4902 ratecontrol(struct cam_device *device, int retry_count, int timeout,
4903 int argc, char **argv, char *combinedopt)
4907 int user_settings = 0;
4909 int disc_enable = -1, tag_enable = -1;
4912 double syncrate = -1;
4915 int change_settings = 0, send_tur = 0;
4916 struct ccb_pathinq cpi;
4918 ccb = cam_getccb(device);
4920 warnx("ratecontrol: error allocating ccb");
4923 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4932 if (strncasecmp(optarg, "enable", 6) == 0)
4934 else if (strncasecmp(optarg, "disable", 7) == 0)
4937 warnx("-D argument \"%s\" is unknown", optarg);
4939 goto ratecontrol_bailout;
4941 change_settings = 1;
4944 mode = ata_string2mode(optarg);
4946 warnx("unknown mode '%s'", optarg);
4948 goto ratecontrol_bailout;
4950 change_settings = 1;
4953 offset = strtol(optarg, NULL, 0);
4955 warnx("offset value %d is < 0", offset);
4957 goto ratecontrol_bailout;
4959 change_settings = 1;
4965 syncrate = atof(optarg);
4967 warnx("sync rate %f is < 0", syncrate);
4969 goto ratecontrol_bailout;
4971 change_settings = 1;
4974 if (strncasecmp(optarg, "enable", 6) == 0)
4976 else if (strncasecmp(optarg, "disable", 7) == 0)
4979 warnx("-T argument \"%s\" is unknown", optarg);
4981 goto ratecontrol_bailout;
4983 change_settings = 1;
4989 bus_width = strtol(optarg, NULL, 0);
4990 if (bus_width < 0) {
4991 warnx("bus width %d is < 0", bus_width);
4993 goto ratecontrol_bailout;
4995 change_settings = 1;
5001 bzero(&(&ccb->ccb_h)[1],
5002 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
5004 * Grab path inquiry information, so we can determine whether
5005 * or not the initiator is capable of the things that the user
5008 ccb->ccb_h.func_code = XPT_PATH_INQ;
5009 if (cam_send_ccb(device, ccb) < 0) {
5010 perror("error sending XPT_PATH_INQ CCB");
5011 if (arglist & CAM_ARG_VERBOSE) {
5012 cam_error_print(device, ccb, CAM_ESF_ALL,
5013 CAM_EPF_ALL, stderr);
5016 goto ratecontrol_bailout;
5018 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5019 warnx("XPT_PATH_INQ CCB failed");
5020 if (arglist & CAM_ARG_VERBOSE) {
5021 cam_error_print(device, ccb, CAM_ESF_ALL,
5022 CAM_EPF_ALL, stderr);
5025 goto ratecontrol_bailout;
5027 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5028 bzero(&(&ccb->ccb_h)[1],
5029 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5031 fprintf(stdout, "%s parameters:\n",
5032 user_settings ? "User" : "Current");
5034 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5036 goto ratecontrol_bailout;
5038 if (arglist & CAM_ARG_VERBOSE)
5041 if (change_settings) {
5042 int didsettings = 0;
5043 struct ccb_trans_settings_spi *spi = NULL;
5044 struct ccb_trans_settings_pata *pata = NULL;
5045 struct ccb_trans_settings_sata *sata = NULL;
5046 struct ccb_trans_settings_ata *ata = NULL;
5047 struct ccb_trans_settings_scsi *scsi = NULL;
5049 if (ccb->cts.transport == XPORT_SPI)
5050 spi = &ccb->cts.xport_specific.spi;
5051 if (ccb->cts.transport == XPORT_ATA)
5052 pata = &ccb->cts.xport_specific.ata;
5053 if (ccb->cts.transport == XPORT_SATA)
5054 sata = &ccb->cts.xport_specific.sata;
5055 if (ccb->cts.protocol == PROTO_ATA)
5056 ata = &ccb->cts.proto_specific.ata;
5057 if (ccb->cts.protocol == PROTO_SCSI)
5058 scsi = &ccb->cts.proto_specific.scsi;
5059 ccb->cts.xport_specific.valid = 0;
5060 ccb->cts.proto_specific.valid = 0;
5061 if (spi && disc_enable != -1) {
5062 spi->valid |= CTS_SPI_VALID_DISC;
5063 if (disc_enable == 0)
5064 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5066 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5069 if (tag_enable != -1) {
5070 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5071 warnx("HBA does not support tagged queueing, "
5072 "so you cannot modify tag settings");
5074 goto ratecontrol_bailout;
5077 ata->valid |= CTS_SCSI_VALID_TQ;
5078 if (tag_enable == 0)
5079 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5081 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5084 scsi->valid |= CTS_SCSI_VALID_TQ;
5085 if (tag_enable == 0)
5086 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5088 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5092 if (spi && offset != -1) {
5093 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5094 warnx("HBA is not capable of changing offset");
5096 goto ratecontrol_bailout;
5098 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5099 spi->sync_offset = offset;
5102 if (spi && syncrate != -1) {
5103 int prelim_sync_period;
5105 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5106 warnx("HBA is not capable of changing "
5109 goto ratecontrol_bailout;
5111 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5113 * The sync rate the user gives us is in MHz.
5114 * We need to translate it into KHz for this
5119 * Next, we calculate a "preliminary" sync period
5120 * in tenths of a nanosecond.
5123 prelim_sync_period = 0;
5125 prelim_sync_period = 10000000 / syncrate;
5127 scsi_calc_syncparam(prelim_sync_period);
5130 if (sata && syncrate != -1) {
5131 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5132 warnx("HBA is not capable of changing "
5135 goto ratecontrol_bailout;
5137 if (!user_settings) {
5138 warnx("You can modify only user rate "
5139 "settings for SATA");
5141 goto ratecontrol_bailout;
5143 sata->revision = ata_speed2revision(syncrate * 100);
5144 if (sata->revision < 0) {
5145 warnx("Invalid rate %f", syncrate);
5147 goto ratecontrol_bailout;
5149 sata->valid |= CTS_SATA_VALID_REVISION;
5152 if ((pata || sata) && mode != -1) {
5153 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5154 warnx("HBA is not capable of changing "
5157 goto ratecontrol_bailout;
5159 if (!user_settings) {
5160 warnx("You can modify only user mode "
5161 "settings for ATA/SATA");
5163 goto ratecontrol_bailout;
5167 pata->valid |= CTS_ATA_VALID_MODE;
5170 sata->valid |= CTS_SATA_VALID_MODE;
5175 * The bus_width argument goes like this:
5179 * Therefore, if you shift the number of bits given on the
5180 * command line right by 4, you should get the correct
5183 if (spi && bus_width != -1) {
5185 * We might as well validate things here with a
5186 * decipherable error message, rather than what
5187 * will probably be an indecipherable error message
5188 * by the time it gets back to us.
5190 if ((bus_width == 16)
5191 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5192 warnx("HBA does not support 16 bit bus width");
5194 goto ratecontrol_bailout;
5195 } else if ((bus_width == 32)
5196 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5197 warnx("HBA does not support 32 bit bus width");
5199 goto ratecontrol_bailout;
5200 } else if ((bus_width != 8)
5201 && (bus_width != 16)
5202 && (bus_width != 32)) {
5203 warnx("Invalid bus width %d", bus_width);
5205 goto ratecontrol_bailout;
5207 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5208 spi->bus_width = bus_width >> 4;
5211 if (didsettings == 0) {
5212 goto ratecontrol_bailout;
5214 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5215 if (cam_send_ccb(device, ccb) < 0) {
5216 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5217 if (arglist & CAM_ARG_VERBOSE) {
5218 cam_error_print(device, ccb, CAM_ESF_ALL,
5219 CAM_EPF_ALL, stderr);
5222 goto ratecontrol_bailout;
5224 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5225 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5226 if (arglist & CAM_ARG_VERBOSE) {
5227 cam_error_print(device, ccb, CAM_ESF_ALL,
5228 CAM_EPF_ALL, stderr);
5231 goto ratecontrol_bailout;
5235 retval = testunitready(device, retry_count, timeout,
5236 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5238 * If the TUR didn't succeed, just bail.
5242 fprintf(stderr, "Test Unit Ready failed\n");
5243 goto ratecontrol_bailout;
5246 if ((change_settings || send_tur) && !quiet &&
5247 (ccb->cts.transport == XPORT_ATA ||
5248 ccb->cts.transport == XPORT_SATA || send_tur)) {
5249 fprintf(stdout, "New parameters:\n");
5250 retval = get_print_cts(device, user_settings, 0, NULL);
5253 ratecontrol_bailout:
5259 scsiformat(struct cam_device *device, int argc, char **argv,
5260 char *combinedopt, int retry_count, int timeout)
5264 int ycount = 0, quiet = 0;
5265 int error = 0, retval = 0;
5266 int use_timeout = 10800 * 1000;
5268 struct format_defect_list_header fh;
5269 u_int8_t *data_ptr = NULL;
5270 u_int32_t dxfer_len = 0;
5272 int num_warnings = 0;
5275 ccb = cam_getccb(device);
5278 warnx("scsiformat: error allocating ccb");
5282 bzero(&(&ccb->ccb_h)[1],
5283 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5285 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5306 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5307 "following device:\n");
5309 error = scsidoinquiry(device, argc, argv, combinedopt,
5310 retry_count, timeout);
5313 warnx("scsiformat: error sending inquiry");
5314 goto scsiformat_bailout;
5319 if (!get_confirmation()) {
5321 goto scsiformat_bailout;
5326 use_timeout = timeout;
5329 fprintf(stdout, "Current format timeout is %d seconds\n",
5330 use_timeout / 1000);
5334 * If the user hasn't disabled questions and didn't specify a
5335 * timeout on the command line, ask them if they want the current
5339 && (timeout == 0)) {
5341 int new_timeout = 0;
5343 fprintf(stdout, "Enter new timeout in seconds or press\n"
5344 "return to keep the current timeout [%d] ",
5345 use_timeout / 1000);
5347 if (fgets(str, sizeof(str), stdin) != NULL) {
5349 new_timeout = atoi(str);
5352 if (new_timeout != 0) {
5353 use_timeout = new_timeout * 1000;
5354 fprintf(stdout, "Using new timeout value %d\n",
5355 use_timeout / 1000);
5360 * Keep this outside the if block below to silence any unused
5361 * variable warnings.
5363 bzero(&fh, sizeof(fh));
5366 * If we're in immediate mode, we've got to include the format
5369 if (immediate != 0) {
5370 fh.byte2 = FU_DLH_IMMED;
5371 data_ptr = (u_int8_t *)&fh;
5372 dxfer_len = sizeof(fh);
5373 byte2 = FU_FMT_DATA;
5374 } else if (quiet == 0) {
5375 fprintf(stdout, "Formatting...");
5379 scsi_format_unit(&ccb->csio,
5380 /* retries */ retry_count,
5382 /* tag_action */ MSG_SIMPLE_Q_TAG,
5385 /* data_ptr */ data_ptr,
5386 /* dxfer_len */ dxfer_len,
5387 /* sense_len */ SSD_FULL_SIZE,
5388 /* timeout */ use_timeout);
5390 /* Disable freezing the device queue */
5391 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5393 if (arglist & CAM_ARG_ERR_RECOVER)
5394 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5396 if (((retval = cam_send_ccb(device, ccb)) < 0)
5397 || ((immediate == 0)
5398 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5399 const char errstr[] = "error sending format command";
5406 if (arglist & CAM_ARG_VERBOSE) {
5407 cam_error_print(device, ccb, CAM_ESF_ALL,
5408 CAM_EPF_ALL, stderr);
5411 goto scsiformat_bailout;
5415 * If we ran in non-immediate mode, we already checked for errors
5416 * above and printed out any necessary information. If we're in
5417 * immediate mode, we need to loop through and get status
5418 * information periodically.
5420 if (immediate == 0) {
5422 fprintf(stdout, "Format Complete\n");
5424 goto scsiformat_bailout;
5431 bzero(&(&ccb->ccb_h)[1],
5432 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5435 * There's really no need to do error recovery or
5436 * retries here, since we're just going to sit in a
5437 * loop and wait for the device to finish formatting.
5439 scsi_test_unit_ready(&ccb->csio,
5442 /* tag_action */ MSG_SIMPLE_Q_TAG,
5443 /* sense_len */ SSD_FULL_SIZE,
5444 /* timeout */ 5000);
5446 /* Disable freezing the device queue */
5447 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5449 retval = cam_send_ccb(device, ccb);
5452 * If we get an error from the ioctl, bail out. SCSI
5453 * errors are expected.
5456 warn("error sending CAMIOCOMMAND ioctl");
5457 if (arglist & CAM_ARG_VERBOSE) {
5458 cam_error_print(device, ccb, CAM_ESF_ALL,
5459 CAM_EPF_ALL, stderr);
5462 goto scsiformat_bailout;
5465 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5467 if ((status != CAM_REQ_CMP)
5468 && (status == CAM_SCSI_STATUS_ERROR)
5469 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5470 struct scsi_sense_data *sense;
5471 int error_code, sense_key, asc, ascq;
5473 sense = &ccb->csio.sense_data;
5474 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5475 ccb->csio.sense_resid, &error_code, &sense_key,
5476 &asc, &ascq, /*show_errors*/ 1);
5479 * According to the SCSI-2 and SCSI-3 specs, a
5480 * drive that is in the middle of a format should
5481 * return NOT READY with an ASC of "logical unit
5482 * not ready, format in progress". The sense key
5483 * specific bytes will then be a progress indicator.
5485 if ((sense_key == SSD_KEY_NOT_READY)
5486 && (asc == 0x04) && (ascq == 0x04)) {
5489 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5490 ccb->csio.sense_resid, sks) == 0)
5493 u_int64_t percentage;
5495 val = scsi_2btoul(&sks[1]);
5496 percentage = 10000 * val;
5499 "\rFormatting: %ju.%02u %% "
5501 (uintmax_t)(percentage /
5503 (unsigned)((percentage /
5507 } else if ((quiet == 0)
5508 && (++num_warnings <= 1)) {
5509 warnx("Unexpected SCSI Sense Key "
5510 "Specific value returned "
5512 scsi_sense_print(device, &ccb->csio,
5514 warnx("Unable to print status "
5515 "information, but format will "
5517 warnx("will exit when format is "
5522 warnx("Unexpected SCSI error during format");
5523 cam_error_print(device, ccb, CAM_ESF_ALL,
5524 CAM_EPF_ALL, stderr);
5526 goto scsiformat_bailout;
5529 } else if (status != CAM_REQ_CMP) {
5530 warnx("Unexpected CAM status %#x", status);
5531 if (arglist & CAM_ARG_VERBOSE)
5532 cam_error_print(device, ccb, CAM_ESF_ALL,
5533 CAM_EPF_ALL, stderr);
5535 goto scsiformat_bailout;
5538 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5541 fprintf(stdout, "\nFormat Complete\n");
5551 scsisanitize(struct cam_device *device, int argc, char **argv,
5552 char *combinedopt, int retry_count, int timeout)
5555 u_int8_t action = 0;
5557 int ycount = 0, quiet = 0;
5558 int error = 0, retval = 0;
5559 int use_timeout = 10800 * 1000;
5565 const char *pattern = NULL;
5566 u_int8_t *data_ptr = NULL;
5567 u_int32_t dxfer_len = 0;
5569 int num_warnings = 0;
5572 ccb = cam_getccb(device);
5575 warnx("scsisanitize: error allocating ccb");
5579 bzero(&(&ccb->ccb_h)[1],
5580 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5582 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5585 if (strcasecmp(optarg, "overwrite") == 0)
5586 action = SSZ_SERVICE_ACTION_OVERWRITE;
5587 else if (strcasecmp(optarg, "block") == 0)
5588 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
5589 else if (strcasecmp(optarg, "crypto") == 0)
5590 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
5591 else if (strcasecmp(optarg, "exitfailure") == 0)
5592 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
5594 warnx("invalid service operation \"%s\"",
5597 goto scsisanitize_bailout;
5601 passes = strtol(optarg, NULL, 0);
5602 if (passes < 1 || passes > 31) {
5603 warnx("invalid passes value %d", passes);
5605 goto scsisanitize_bailout;
5636 warnx("an action is required");
5638 goto scsisanitize_bailout;
5639 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
5640 struct scsi_sanitize_parameter_list *pl;
5644 if (pattern == NULL) {
5645 warnx("overwrite action requires -P argument");
5647 goto scsisanitize_bailout;
5649 fd = open(pattern, O_RDONLY);
5651 warn("cannot open pattern file %s", pattern);
5653 goto scsisanitize_bailout;
5655 if (fstat(fd, &sb) < 0) {
5656 warn("cannot stat pattern file %s", pattern);
5658 goto scsisanitize_bailout;
5661 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
5662 warnx("pattern file size exceeds maximum value %d",
5663 SSZPL_MAX_PATTERN_LENGTH);
5665 goto scsisanitize_bailout;
5667 dxfer_len = sizeof(*pl) + sz;
5668 data_ptr = calloc(1, dxfer_len);
5669 if (data_ptr == NULL) {
5670 warnx("cannot allocate parameter list buffer");
5672 goto scsisanitize_bailout;
5675 amt = read(fd, data_ptr + sizeof(*pl), sz);
5677 warn("cannot read pattern file");
5679 goto scsisanitize_bailout;
5680 } else if (amt != sz) {
5681 warnx("short pattern file read");
5683 goto scsisanitize_bailout;
5686 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
5692 pl->byte1 |= SSZPL_INVERT;
5693 scsi_ulto2b(sz, pl->length);
5699 else if (invert != 0)
5701 else if (pattern != NULL)
5706 warnx("%s argument only valid with overwrite "
5709 goto scsisanitize_bailout;
5714 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5715 "following device:\n");
5717 error = scsidoinquiry(device, argc, argv, combinedopt,
5718 retry_count, timeout);
5721 warnx("scsisanitize: error sending inquiry");
5722 goto scsisanitize_bailout;
5727 if (!get_confirmation()) {
5729 goto scsisanitize_bailout;
5734 use_timeout = timeout;
5737 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
5738 use_timeout / 1000);
5742 * If the user hasn't disabled questions and didn't specify a
5743 * timeout on the command line, ask them if they want the current
5747 && (timeout == 0)) {
5749 int new_timeout = 0;
5751 fprintf(stdout, "Enter new timeout in seconds or press\n"
5752 "return to keep the current timeout [%d] ",
5753 use_timeout / 1000);
5755 if (fgets(str, sizeof(str), stdin) != NULL) {
5757 new_timeout = atoi(str);
5760 if (new_timeout != 0) {
5761 use_timeout = new_timeout * 1000;
5762 fprintf(stdout, "Using new timeout value %d\n",
5763 use_timeout / 1000);
5769 byte2 |= SSZ_UNRESTRICTED_EXIT;
5773 scsi_sanitize(&ccb->csio,
5774 /* retries */ retry_count,
5776 /* tag_action */ MSG_SIMPLE_Q_TAG,
5779 /* data_ptr */ data_ptr,
5780 /* dxfer_len */ dxfer_len,
5781 /* sense_len */ SSD_FULL_SIZE,
5782 /* timeout */ use_timeout);
5784 /* Disable freezing the device queue */
5785 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5787 if (arglist & CAM_ARG_ERR_RECOVER)
5788 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5790 if (((retval = cam_send_ccb(device, ccb)) < 0)
5791 || ((immediate == 0)
5792 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5793 const char errstr[] = "error sending sanitize command";
5800 if (arglist & CAM_ARG_VERBOSE) {
5801 cam_error_print(device, ccb, CAM_ESF_ALL,
5802 CAM_EPF_ALL, stderr);
5805 goto scsisanitize_bailout;
5809 * If we ran in non-immediate mode, we already checked for errors
5810 * above and printed out any necessary information. If we're in
5811 * immediate mode, we need to loop through and get status
5812 * information periodically.
5814 if (immediate == 0) {
5816 fprintf(stdout, "Sanitize Complete\n");
5818 goto scsisanitize_bailout;
5825 bzero(&(&ccb->ccb_h)[1],
5826 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5829 * There's really no need to do error recovery or
5830 * retries here, since we're just going to sit in a
5831 * loop and wait for the device to finish sanitizing.
5833 scsi_test_unit_ready(&ccb->csio,
5836 /* tag_action */ MSG_SIMPLE_Q_TAG,
5837 /* sense_len */ SSD_FULL_SIZE,
5838 /* timeout */ 5000);
5840 /* Disable freezing the device queue */
5841 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5843 retval = cam_send_ccb(device, ccb);
5846 * If we get an error from the ioctl, bail out. SCSI
5847 * errors are expected.
5850 warn("error sending CAMIOCOMMAND ioctl");
5851 if (arglist & CAM_ARG_VERBOSE) {
5852 cam_error_print(device, ccb, CAM_ESF_ALL,
5853 CAM_EPF_ALL, stderr);
5856 goto scsisanitize_bailout;
5859 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5861 if ((status != CAM_REQ_CMP)
5862 && (status == CAM_SCSI_STATUS_ERROR)
5863 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5864 struct scsi_sense_data *sense;
5865 int error_code, sense_key, asc, ascq;
5867 sense = &ccb->csio.sense_data;
5868 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5869 ccb->csio.sense_resid, &error_code, &sense_key,
5870 &asc, &ascq, /*show_errors*/ 1);
5873 * According to the SCSI-3 spec, a drive that is in the
5874 * middle of a sanitize should return NOT READY with an
5875 * ASC of "logical unit not ready, sanitize in
5876 * progress". The sense key specific bytes will then
5877 * be a progress indicator.
5879 if ((sense_key == SSD_KEY_NOT_READY)
5880 && (asc == 0x04) && (ascq == 0x1b)) {
5883 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5884 ccb->csio.sense_resid, sks) == 0)
5887 u_int64_t percentage;
5889 val = scsi_2btoul(&sks[1]);
5890 percentage = 10000 * val;
5893 "\rSanitizing: %ju.%02u %% "
5895 (uintmax_t)(percentage /
5897 (unsigned)((percentage /
5901 } else if ((quiet == 0)
5902 && (++num_warnings <= 1)) {
5903 warnx("Unexpected SCSI Sense Key "
5904 "Specific value returned "
5905 "during sanitize:");
5906 scsi_sense_print(device, &ccb->csio,
5908 warnx("Unable to print status "
5909 "information, but sanitze will "
5911 warnx("will exit when sanitize is "
5916 warnx("Unexpected SCSI error during sanitize");
5917 cam_error_print(device, ccb, CAM_ESF_ALL,
5918 CAM_EPF_ALL, stderr);
5920 goto scsisanitize_bailout;
5923 } else if (status != CAM_REQ_CMP) {
5924 warnx("Unexpected CAM status %#x", status);
5925 if (arglist & CAM_ARG_VERBOSE)
5926 cam_error_print(device, ccb, CAM_ESF_ALL,
5927 CAM_EPF_ALL, stderr);
5929 goto scsisanitize_bailout;
5931 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5934 fprintf(stdout, "\nSanitize Complete\n");
5936 scsisanitize_bailout:
5939 if (data_ptr != NULL)
5947 scsireportluns(struct cam_device *device, int argc, char **argv,
5948 char *combinedopt, int retry_count, int timeout)
5951 int c, countonly, lunsonly;
5952 struct scsi_report_luns_data *lundata;
5954 uint8_t report_type;
5955 uint32_t list_len, i, j;
5960 report_type = RPL_REPORT_DEFAULT;
5961 ccb = cam_getccb(device);
5964 warnx("%s: error allocating ccb", __func__);
5968 bzero(&(&ccb->ccb_h)[1],
5969 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5974 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5983 if (strcasecmp(optarg, "default") == 0)
5984 report_type = RPL_REPORT_DEFAULT;
5985 else if (strcasecmp(optarg, "wellknown") == 0)
5986 report_type = RPL_REPORT_WELLKNOWN;
5987 else if (strcasecmp(optarg, "all") == 0)
5988 report_type = RPL_REPORT_ALL;
5990 warnx("%s: invalid report type \"%s\"",
6001 if ((countonly != 0)
6002 && (lunsonly != 0)) {
6003 warnx("%s: you can only specify one of -c or -l", __func__);
6008 * According to SPC-4, the allocation length must be at least 16
6009 * bytes -- enough for the header and one LUN.
6011 alloc_len = sizeof(*lundata) + 8;
6015 lundata = malloc(alloc_len);
6017 if (lundata == NULL) {
6018 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6023 scsi_report_luns(&ccb->csio,
6024 /*retries*/ retry_count,
6026 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6027 /*select_report*/ report_type,
6028 /*rpl_buf*/ lundata,
6029 /*alloc_len*/ alloc_len,
6030 /*sense_len*/ SSD_FULL_SIZE,
6031 /*timeout*/ timeout ? timeout : 5000);
6033 /* Disable freezing the device queue */
6034 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6036 if (arglist & CAM_ARG_ERR_RECOVER)
6037 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6039 if (cam_send_ccb(device, ccb) < 0) {
6040 warn("error sending REPORT LUNS command");
6042 if (arglist & CAM_ARG_VERBOSE)
6043 cam_error_print(device, ccb, CAM_ESF_ALL,
6044 CAM_EPF_ALL, stderr);
6050 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6051 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6057 list_len = scsi_4btoul(lundata->length);
6060 * If we need to list the LUNs, and our allocation
6061 * length was too short, reallocate and retry.
6063 if ((countonly == 0)
6064 && (list_len > (alloc_len - sizeof(*lundata)))) {
6065 alloc_len = list_len + sizeof(*lundata);
6071 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6072 ((list_len / 8) > 1) ? "s" : "");
6077 for (i = 0; i < (list_len / 8); i++) {
6081 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6083 fprintf(stdout, ",");
6084 switch (lundata->luns[i].lundata[j] &
6085 RPL_LUNDATA_ATYP_MASK) {
6086 case RPL_LUNDATA_ATYP_PERIPH:
6087 if ((lundata->luns[i].lundata[j] &
6088 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6089 fprintf(stdout, "%d:",
6090 lundata->luns[i].lundata[j] &
6091 RPL_LUNDATA_PERIPH_BUS_MASK);
6093 && ((lundata->luns[i].lundata[j+2] &
6094 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6097 fprintf(stdout, "%d",
6098 lundata->luns[i].lundata[j+1]);
6100 case RPL_LUNDATA_ATYP_FLAT: {
6102 tmplun[0] = lundata->luns[i].lundata[j] &
6103 RPL_LUNDATA_FLAT_LUN_MASK;
6104 tmplun[1] = lundata->luns[i].lundata[j+1];
6106 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6110 case RPL_LUNDATA_ATYP_LUN:
6111 fprintf(stdout, "%d:%d:%d",
6112 (lundata->luns[i].lundata[j+1] &
6113 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6114 lundata->luns[i].lundata[j] &
6115 RPL_LUNDATA_LUN_TARG_MASK,
6116 lundata->luns[i].lundata[j+1] &
6117 RPL_LUNDATA_LUN_LUN_MASK);
6119 case RPL_LUNDATA_ATYP_EXTLUN: {
6120 int field_len_code, eam_code;
6122 eam_code = lundata->luns[i].lundata[j] &
6123 RPL_LUNDATA_EXT_EAM_MASK;
6124 field_len_code = (lundata->luns[i].lundata[j] &
6125 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6127 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6128 && (field_len_code == 0x00)) {
6129 fprintf(stdout, "%d",
6130 lundata->luns[i].lundata[j+1]);
6131 } else if ((eam_code ==
6132 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6133 && (field_len_code == 0x03)) {
6137 * This format takes up all 8 bytes.
6138 * If we aren't starting at offset 0,
6142 fprintf(stdout, "Invalid "
6145 "specified format", j);
6149 bzero(tmp_lun, sizeof(tmp_lun));
6150 bcopy(&lundata->luns[i].lundata[j+1],
6151 &tmp_lun[1], sizeof(tmp_lun) - 1);
6152 fprintf(stdout, "%#jx",
6153 (intmax_t)scsi_8btou64(tmp_lun));
6156 fprintf(stderr, "Unknown Extended LUN"
6157 "Address method %#x, length "
6158 "code %#x", eam_code,
6165 fprintf(stderr, "Unknown LUN address method "
6166 "%#x\n", lundata->luns[i].lundata[0] &
6167 RPL_LUNDATA_ATYP_MASK);
6171 * For the flat addressing method, there are no
6172 * other levels after it.
6177 fprintf(stdout, "\n");
6190 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6191 char *combinedopt, int retry_count, int timeout)
6194 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6195 struct scsi_read_capacity_data rcap;
6196 struct scsi_read_capacity_data_long rcaplong;
6210 ccb = cam_getccb(device);
6213 warnx("%s: error allocating ccb", __func__);
6217 bzero(&(&ccb->ccb_h)[1],
6218 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6220 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6247 if ((blocksizeonly != 0)
6248 && (numblocks != 0)) {
6249 warnx("%s: you can only specify one of -b or -N", __func__);
6254 if ((blocksizeonly != 0)
6255 && (sizeonly != 0)) {
6256 warnx("%s: you can only specify one of -b or -s", __func__);
6263 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6269 && (blocksizeonly != 0)) {
6270 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6275 scsi_read_capacity(&ccb->csio,
6276 /*retries*/ retry_count,
6278 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6281 /*timeout*/ timeout ? timeout : 5000);
6283 /* Disable freezing the device queue */
6284 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6286 if (arglist & CAM_ARG_ERR_RECOVER)
6287 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6289 if (cam_send_ccb(device, ccb) < 0) {
6290 warn("error sending READ CAPACITY command");
6292 if (arglist & CAM_ARG_VERBOSE)
6293 cam_error_print(device, ccb, CAM_ESF_ALL,
6294 CAM_EPF_ALL, stderr);
6300 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6301 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6306 maxsector = scsi_4btoul(rcap.addr);
6307 block_len = scsi_4btoul(rcap.length);
6310 * A last block of 2^32-1 means that the true capacity is over 2TB,
6311 * and we need to issue the long READ CAPACITY to get the real
6312 * capacity. Otherwise, we're all set.
6314 if (maxsector != 0xffffffff)
6317 scsi_read_capacity_16(&ccb->csio,
6318 /*retries*/ retry_count,
6320 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6325 /*sense_len*/ SSD_FULL_SIZE,
6326 /*timeout*/ timeout ? timeout : 5000);
6328 /* Disable freezing the device queue */
6329 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6331 if (arglist & CAM_ARG_ERR_RECOVER)
6332 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6334 if (cam_send_ccb(device, ccb) < 0) {
6335 warn("error sending READ CAPACITY (16) command");
6337 if (arglist & CAM_ARG_VERBOSE)
6338 cam_error_print(device, ccb, CAM_ESF_ALL,
6339 CAM_EPF_ALL, stderr);
6345 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6346 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6351 maxsector = scsi_8btou64(rcaplong.addr);
6352 block_len = scsi_4btoul(rcaplong.length);
6355 if (blocksizeonly == 0) {
6357 * Humanize implies !quiet, and also implies numblocks.
6359 if (humanize != 0) {
6364 tmpbytes = (maxsector + 1) * block_len;
6365 ret = humanize_number(tmpstr, sizeof(tmpstr),
6366 tmpbytes, "", HN_AUTOSCALE,
6369 HN_DIVISOR_1000 : 0));
6371 warnx("%s: humanize_number failed!", __func__);
6375 fprintf(stdout, "Device Size: %s%s", tmpstr,
6376 (sizeonly == 0) ? ", " : "\n");
6377 } else if (numblocks != 0) {
6378 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6379 "Blocks: " : "", (uintmax_t)maxsector + 1,
6380 (sizeonly == 0) ? ", " : "\n");
6382 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6383 "Last Block: " : "", (uintmax_t)maxsector,
6384 (sizeonly == 0) ? ", " : "\n");
6388 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6389 "Block Length: " : "", block_len, (quiet == 0) ?
6398 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6399 int retry_count, int timeout)
6403 uint8_t *smp_request = NULL, *smp_response = NULL;
6404 int request_size = 0, response_size = 0;
6405 int fd_request = 0, fd_response = 0;
6406 char *datastr = NULL;
6407 struct get_hook hook;
6412 * Note that at the moment we don't support sending SMP CCBs to
6413 * devices that aren't probed by CAM.
6415 ccb = cam_getccb(device);
6417 warnx("%s: error allocating CCB", __func__);
6421 bzero(&(&ccb->ccb_h)[1],
6422 sizeof(union ccb) - sizeof(struct ccb_hdr));
6424 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6427 arglist |= CAM_ARG_CMD_IN;
6428 response_size = strtol(optarg, NULL, 0);
6429 if (response_size <= 0) {
6430 warnx("invalid number of response bytes %d",
6433 goto smpcmd_bailout;
6435 hook.argc = argc - optind;
6436 hook.argv = argv + optind;
6439 datastr = cget(&hook, NULL);
6441 * If the user supplied "-" instead of a format, he
6442 * wants the data to be written to stdout.
6444 if ((datastr != NULL)
6445 && (datastr[0] == '-'))
6448 smp_response = (u_int8_t *)malloc(response_size);
6449 if (smp_response == NULL) {
6450 warn("can't malloc memory for SMP response");
6452 goto smpcmd_bailout;
6456 arglist |= CAM_ARG_CMD_OUT;
6457 request_size = strtol(optarg, NULL, 0);
6458 if (request_size <= 0) {
6459 warnx("invalid number of request bytes %d",
6462 goto smpcmd_bailout;
6464 hook.argc = argc - optind;
6465 hook.argv = argv + optind;
6467 datastr = cget(&hook, NULL);
6468 smp_request = (u_int8_t *)malloc(request_size);
6469 if (smp_request == NULL) {
6470 warn("can't malloc memory for SMP request");
6472 goto smpcmd_bailout;
6474 bzero(smp_request, request_size);
6476 * If the user supplied "-" instead of a format, he
6477 * wants the data to be read from stdin.
6479 if ((datastr != NULL)
6480 && (datastr[0] == '-'))
6483 buff_encode_visit(smp_request, request_size,
6494 * If fd_data is set, and we're writing to the device, we need to
6495 * read the data the user wants written from stdin.
6497 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6499 int amt_to_read = request_size;
6500 u_int8_t *buf_ptr = smp_request;
6502 for (amt_read = 0; amt_to_read > 0;
6503 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6504 if (amt_read == -1) {
6505 warn("error reading data from stdin");
6507 goto smpcmd_bailout;
6509 amt_to_read -= amt_read;
6510 buf_ptr += amt_read;
6514 if (((arglist & CAM_ARG_CMD_IN) == 0)
6515 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6516 warnx("%s: need both the request (-r) and response (-R) "
6517 "arguments", __func__);
6519 goto smpcmd_bailout;
6522 flags |= CAM_DEV_QFRZDIS;
6524 cam_fill_smpio(&ccb->smpio,
6525 /*retries*/ retry_count,
6528 /*smp_request*/ smp_request,
6529 /*smp_request_len*/ request_size,
6530 /*smp_response*/ smp_response,
6531 /*smp_response_len*/ response_size,
6532 /*timeout*/ timeout ? timeout : 5000);
6534 ccb->smpio.flags = SMP_FLAG_NONE;
6536 if (((retval = cam_send_ccb(device, ccb)) < 0)
6537 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6538 const char warnstr[] = "error sending command";
6545 if (arglist & CAM_ARG_VERBOSE) {
6546 cam_error_print(device, ccb, CAM_ESF_ALL,
6547 CAM_EPF_ALL, stderr);
6551 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6552 && (response_size > 0)) {
6553 if (fd_response == 0) {
6554 buff_decode_visit(smp_response, response_size,
6555 datastr, arg_put, NULL);
6556 fprintf(stdout, "\n");
6558 ssize_t amt_written;
6559 int amt_to_write = response_size;
6560 u_int8_t *buf_ptr = smp_response;
6562 for (amt_written = 0; (amt_to_write > 0) &&
6563 (amt_written = write(STDOUT_FILENO, buf_ptr,
6564 amt_to_write)) > 0;){
6565 amt_to_write -= amt_written;
6566 buf_ptr += amt_written;
6568 if (amt_written == -1) {
6569 warn("error writing data to stdout");
6571 goto smpcmd_bailout;
6572 } else if ((amt_written == 0)
6573 && (amt_to_write > 0)) {
6574 warnx("only wrote %u bytes out of %u",
6575 response_size - amt_to_write,
6584 if (smp_request != NULL)
6587 if (smp_response != NULL)
6594 smpreportgeneral(struct cam_device *device, int argc, char **argv,
6595 char *combinedopt, int retry_count, int timeout)
6598 struct smp_report_general_request *request = NULL;
6599 struct smp_report_general_response *response = NULL;
6600 struct sbuf *sb = NULL;
6602 int c, long_response = 0;
6606 * Note that at the moment we don't support sending SMP CCBs to
6607 * devices that aren't probed by CAM.
6609 ccb = cam_getccb(device);
6611 warnx("%s: error allocating CCB", __func__);
6615 bzero(&(&ccb->ccb_h)[1],
6616 sizeof(union ccb) - sizeof(struct ccb_hdr));
6618 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6627 request = malloc(sizeof(*request));
6628 if (request == NULL) {
6629 warn("%s: unable to allocate %zd bytes", __func__,
6635 response = malloc(sizeof(*response));
6636 if (response == NULL) {
6637 warn("%s: unable to allocate %zd bytes", __func__,
6644 smp_report_general(&ccb->smpio,
6648 /*request_len*/ sizeof(*request),
6649 (uint8_t *)response,
6650 /*response_len*/ sizeof(*response),
6651 /*long_response*/ long_response,
6654 if (((retval = cam_send_ccb(device, ccb)) < 0)
6655 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6656 const char warnstr[] = "error sending command";
6663 if (arglist & CAM_ARG_VERBOSE) {
6664 cam_error_print(device, ccb, CAM_ESF_ALL,
6665 CAM_EPF_ALL, stderr);
6672 * If the device supports the long response bit, try again and see
6673 * if we can get all of the data.
6675 if ((response->long_response & SMP_RG_LONG_RESPONSE)
6676 && (long_response == 0)) {
6677 ccb->ccb_h.status = CAM_REQ_INPROG;
6678 bzero(&(&ccb->ccb_h)[1],
6679 sizeof(union ccb) - sizeof(struct ccb_hdr));
6685 * XXX KDM detect and decode SMP errors here.
6687 sb = sbuf_new_auto();
6689 warnx("%s: error allocating sbuf", __func__);
6693 smp_report_general_sbuf(response, sizeof(*response), sb);
6695 if (sbuf_finish(sb) != 0) {
6696 warnx("%s: sbuf_finish", __func__);
6700 printf("%s", sbuf_data(sb));
6706 if (request != NULL)
6709 if (response != NULL)
6718 static struct camcontrol_opts phy_ops[] = {
6719 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
6720 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
6721 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
6722 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
6723 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
6724 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
6725 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
6726 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
6727 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
6732 smpphycontrol(struct cam_device *device, int argc, char **argv,
6733 char *combinedopt, int retry_count, int timeout)
6736 struct smp_phy_control_request *request = NULL;
6737 struct smp_phy_control_response *response = NULL;
6738 int long_response = 0;
6741 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
6743 uint64_t attached_dev_name = 0;
6744 int dev_name_set = 0;
6745 uint32_t min_plr = 0, max_plr = 0;
6746 uint32_t pp_timeout_val = 0;
6747 int slumber_partial = 0;
6748 int set_pp_timeout_val = 0;
6752 * Note that at the moment we don't support sending SMP CCBs to
6753 * devices that aren't probed by CAM.
6755 ccb = cam_getccb(device);
6757 warnx("%s: error allocating CCB", __func__);
6761 bzero(&(&ccb->ccb_h)[1],
6762 sizeof(union ccb) - sizeof(struct ccb_hdr));
6764 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6772 if (strcasecmp(optarg, "enable") == 0)
6774 else if (strcasecmp(optarg, "disable") == 0)
6777 warnx("%s: Invalid argument %s", __func__,
6784 slumber_partial |= enable <<
6785 SMP_PC_SAS_SLUMBER_SHIFT;
6788 slumber_partial |= enable <<
6789 SMP_PC_SAS_PARTIAL_SHIFT;
6792 slumber_partial |= enable <<
6793 SMP_PC_SATA_SLUMBER_SHIFT;
6796 slumber_partial |= enable <<
6797 SMP_PC_SATA_PARTIAL_SHIFT;
6800 warnx("%s: programmer error", __func__);
6803 break; /*NOTREACHED*/
6808 attached_dev_name = (uintmax_t)strtoumax(optarg,
6817 * We don't do extensive checking here, so this
6818 * will continue to work when new speeds come out.
6820 min_plr = strtoul(optarg, NULL, 0);
6822 || (min_plr > 0xf)) {
6823 warnx("%s: invalid link rate %x",
6831 * We don't do extensive checking here, so this
6832 * will continue to work when new speeds come out.
6834 max_plr = strtoul(optarg, NULL, 0);
6836 || (max_plr > 0xf)) {
6837 warnx("%s: invalid link rate %x",
6844 camcontrol_optret optreturn;
6845 cam_argmask argnums;
6848 if (phy_op_set != 0) {
6849 warnx("%s: only one phy operation argument "
6850 "(-o) allowed", __func__);
6858 * Allow the user to specify the phy operation
6859 * numerically, as well as with a name. This will
6860 * future-proof it a bit, so options that are added
6861 * in future specs can be used.
6863 if (isdigit(optarg[0])) {
6864 phy_operation = strtoul(optarg, NULL, 0);
6865 if ((phy_operation == 0)
6866 || (phy_operation > 0xff)) {
6867 warnx("%s: invalid phy operation %#x",
6868 __func__, phy_operation);
6874 optreturn = getoption(phy_ops, optarg, &phy_operation,
6877 if (optreturn == CC_OR_AMBIGUOUS) {
6878 warnx("%s: ambiguous option %s", __func__,
6883 } else if (optreturn == CC_OR_NOT_FOUND) {
6884 warnx("%s: option %s not found", __func__,
6896 pp_timeout_val = strtoul(optarg, NULL, 0);
6897 if (pp_timeout_val > 15) {
6898 warnx("%s: invalid partial pathway timeout "
6899 "value %u, need a value less than 16",
6900 __func__, pp_timeout_val);
6904 set_pp_timeout_val = 1;
6912 warnx("%s: a PHY (-p phy) argument is required",__func__);
6917 if (((dev_name_set != 0)
6918 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
6919 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
6920 && (dev_name_set == 0))) {
6921 warnx("%s: -d name and -o setdevname arguments both "
6922 "required to set device name", __func__);
6927 request = malloc(sizeof(*request));
6928 if (request == NULL) {
6929 warn("%s: unable to allocate %zd bytes", __func__,
6935 response = malloc(sizeof(*response));
6936 if (response == NULL) {
6937 warn("%s: unable to allocate %zd bytes", __func__,
6943 smp_phy_control(&ccb->smpio,
6948 (uint8_t *)response,
6951 /*expected_exp_change_count*/ 0,
6954 (set_pp_timeout_val != 0) ? 1 : 0,
6962 if (((retval = cam_send_ccb(device, ccb)) < 0)
6963 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6964 const char warnstr[] = "error sending command";
6971 if (arglist & CAM_ARG_VERBOSE) {
6973 * Use CAM_EPF_NORMAL so we only get one line of
6974 * SMP command decoding.
6976 cam_error_print(device, ccb, CAM_ESF_ALL,
6977 CAM_EPF_NORMAL, stderr);
6983 /* XXX KDM print out something here for success? */
6988 if (request != NULL)
6991 if (response != NULL)
6998 smpmaninfo(struct cam_device *device, int argc, char **argv,
6999 char *combinedopt, int retry_count, int timeout)
7002 struct smp_report_manuf_info_request request;
7003 struct smp_report_manuf_info_response response;
7004 struct sbuf *sb = NULL;
7005 int long_response = 0;
7010 * Note that at the moment we don't support sending SMP CCBs to
7011 * devices that aren't probed by CAM.
7013 ccb = cam_getccb(device);
7015 warnx("%s: error allocating CCB", __func__);
7019 bzero(&(&ccb->ccb_h)[1],
7020 sizeof(union ccb) - sizeof(struct ccb_hdr));
7022 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7031 bzero(&request, sizeof(request));
7032 bzero(&response, sizeof(response));
7034 smp_report_manuf_info(&ccb->smpio,
7039 (uint8_t *)&response,
7044 if (((retval = cam_send_ccb(device, ccb)) < 0)
7045 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7046 const char warnstr[] = "error sending command";
7053 if (arglist & CAM_ARG_VERBOSE) {
7054 cam_error_print(device, ccb, CAM_ESF_ALL,
7055 CAM_EPF_ALL, stderr);
7061 sb = sbuf_new_auto();
7063 warnx("%s: error allocating sbuf", __func__);
7067 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7069 if (sbuf_finish(sb) != 0) {
7070 warnx("%s: sbuf_finish", __func__);
7074 printf("%s", sbuf_data(sb));
7088 getdevid(struct cam_devitem *item)
7091 union ccb *ccb = NULL;
7093 struct cam_device *dev;
7095 dev = cam_open_btl(item->dev_match.path_id,
7096 item->dev_match.target_id,
7097 item->dev_match.target_lun, O_RDWR, NULL);
7100 warnx("%s", cam_errbuf);
7105 item->device_id_len = 0;
7107 ccb = cam_getccb(dev);
7109 warnx("%s: error allocating CCB", __func__);
7114 bzero(&(&ccb->ccb_h)[1],
7115 sizeof(union ccb) - sizeof(struct ccb_hdr));
7118 * On the first try, we just probe for the size of the data, and
7119 * then allocate that much memory and try again.
7122 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7123 ccb->ccb_h.flags = CAM_DIR_IN;
7124 ccb->cdai.flags = 0;
7125 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7126 ccb->cdai.bufsiz = item->device_id_len;
7127 if (item->device_id_len != 0)
7128 ccb->cdai.buf = (uint8_t *)item->device_id;
7130 if (cam_send_ccb(dev, ccb) < 0) {
7131 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7136 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7137 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7142 if (item->device_id_len == 0) {
7144 * This is our first time through. Allocate the buffer,
7145 * and then go back to get the data.
7147 if (ccb->cdai.provsiz == 0) {
7148 warnx("%s: invalid .provsiz field returned with "
7149 "XPT_GDEV_ADVINFO CCB", __func__);
7153 item->device_id_len = ccb->cdai.provsiz;
7154 item->device_id = malloc(item->device_id_len);
7155 if (item->device_id == NULL) {
7156 warn("%s: unable to allocate %d bytes", __func__,
7157 item->device_id_len);
7161 ccb->ccb_h.status = CAM_REQ_INPROG;
7167 cam_close_device(dev);
7176 * XXX KDM merge this code with getdevtree()?
7179 buildbusdevlist(struct cam_devlist *devlist)
7182 int bufsize, fd = -1;
7183 struct dev_match_pattern *patterns;
7184 struct cam_devitem *item = NULL;
7185 int skip_device = 0;
7188 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7189 warn("couldn't open %s", XPT_DEVICE);
7193 bzero(&ccb, sizeof(union ccb));
7195 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7196 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7197 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7199 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7200 bufsize = sizeof(struct dev_match_result) * 100;
7201 ccb.cdm.match_buf_len = bufsize;
7202 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7203 if (ccb.cdm.matches == NULL) {
7204 warnx("can't malloc memory for matches");
7208 ccb.cdm.num_matches = 0;
7209 ccb.cdm.num_patterns = 2;
7210 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7211 ccb.cdm.num_patterns;
7213 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7214 if (patterns == NULL) {
7215 warnx("can't malloc memory for patterns");
7220 ccb.cdm.patterns = patterns;
7221 bzero(patterns, ccb.cdm.pattern_buf_len);
7223 patterns[0].type = DEV_MATCH_DEVICE;
7224 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7225 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7226 patterns[1].type = DEV_MATCH_PERIPH;
7227 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7228 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7231 * We do the ioctl multiple times if necessary, in case there are
7232 * more than 100 nodes in the EDT.
7237 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7238 warn("error sending CAMIOCOMMAND ioctl");
7243 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7244 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7245 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7246 warnx("got CAM error %#x, CDM error %d\n",
7247 ccb.ccb_h.status, ccb.cdm.status);
7252 for (i = 0; i < ccb.cdm.num_matches; i++) {
7253 switch (ccb.cdm.matches[i].type) {
7254 case DEV_MATCH_DEVICE: {
7255 struct device_match_result *dev_result;
7258 &ccb.cdm.matches[i].result.device_result;
7260 if (dev_result->flags &
7261 DEV_RESULT_UNCONFIGURED) {
7267 item = malloc(sizeof(*item));
7269 warn("%s: unable to allocate %zd bytes",
7270 __func__, sizeof(*item));
7274 bzero(item, sizeof(*item));
7275 bcopy(dev_result, &item->dev_match,
7276 sizeof(*dev_result));
7277 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7280 if (getdevid(item) != 0) {
7286 case DEV_MATCH_PERIPH: {
7287 struct periph_match_result *periph_result;
7290 &ccb.cdm.matches[i].result.periph_result;
7292 if (skip_device != 0)
7294 item->num_periphs++;
7295 item->periph_matches = realloc(
7296 item->periph_matches,
7298 sizeof(struct periph_match_result));
7299 if (item->periph_matches == NULL) {
7300 warn("%s: error allocating periph "
7305 bcopy(periph_result, &item->periph_matches[
7306 item->num_periphs - 1],
7307 sizeof(*periph_result));
7311 fprintf(stderr, "%s: unexpected match "
7312 "type %d\n", __func__,
7313 ccb.cdm.matches[i].type);
7316 break; /*NOTREACHED*/
7319 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7320 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7328 free(ccb.cdm.matches);
7331 freebusdevlist(devlist);
7337 freebusdevlist(struct cam_devlist *devlist)
7339 struct cam_devitem *item, *item2;
7341 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7342 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7344 free(item->device_id);
7345 free(item->periph_matches);
7350 static struct cam_devitem *
7351 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7353 struct cam_devitem *item;
7355 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7356 struct scsi_vpd_id_descriptor *idd;
7359 * XXX KDM look for LUN IDs as well?
7361 idd = scsi_get_devid(item->device_id,
7362 item->device_id_len,
7363 scsi_devid_is_sas_target);
7367 if (scsi_8btou64(idd->identifier) == sasaddr)
7375 smpphylist(struct cam_device *device, int argc, char **argv,
7376 char *combinedopt, int retry_count, int timeout)
7378 struct smp_report_general_request *rgrequest = NULL;
7379 struct smp_report_general_response *rgresponse = NULL;
7380 struct smp_discover_request *disrequest = NULL;
7381 struct smp_discover_response *disresponse = NULL;
7382 struct cam_devlist devlist;
7384 int long_response = 0;
7391 * Note that at the moment we don't support sending SMP CCBs to
7392 * devices that aren't probed by CAM.
7394 ccb = cam_getccb(device);
7396 warnx("%s: error allocating CCB", __func__);
7400 bzero(&(&ccb->ccb_h)[1],
7401 sizeof(union ccb) - sizeof(struct ccb_hdr));
7402 STAILQ_INIT(&devlist.dev_queue);
7404 rgrequest = malloc(sizeof(*rgrequest));
7405 if (rgrequest == NULL) {
7406 warn("%s: unable to allocate %zd bytes", __func__,
7407 sizeof(*rgrequest));
7412 rgresponse = malloc(sizeof(*rgresponse));
7413 if (rgresponse == NULL) {
7414 warn("%s: unable to allocate %zd bytes", __func__,
7415 sizeof(*rgresponse));
7420 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7433 smp_report_general(&ccb->smpio,
7437 /*request_len*/ sizeof(*rgrequest),
7438 (uint8_t *)rgresponse,
7439 /*response_len*/ sizeof(*rgresponse),
7440 /*long_response*/ long_response,
7443 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7445 if (((retval = cam_send_ccb(device, ccb)) < 0)
7446 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7447 const char warnstr[] = "error sending command";
7454 if (arglist & CAM_ARG_VERBOSE) {
7455 cam_error_print(device, ccb, CAM_ESF_ALL,
7456 CAM_EPF_ALL, stderr);
7462 num_phys = rgresponse->num_phys;
7464 if (num_phys == 0) {
7466 fprintf(stdout, "%s: No Phys reported\n", __func__);
7471 devlist.path_id = device->path_id;
7473 retval = buildbusdevlist(&devlist);
7478 fprintf(stdout, "%d PHYs:\n", num_phys);
7479 fprintf(stdout, "PHY Attached SAS Address\n");
7482 disrequest = malloc(sizeof(*disrequest));
7483 if (disrequest == NULL) {
7484 warn("%s: unable to allocate %zd bytes", __func__,
7485 sizeof(*disrequest));
7490 disresponse = malloc(sizeof(*disresponse));
7491 if (disresponse == NULL) {
7492 warn("%s: unable to allocate %zd bytes", __func__,
7493 sizeof(*disresponse));
7498 for (i = 0; i < num_phys; i++) {
7499 struct cam_devitem *item;
7500 struct device_match_result *dev_match;
7501 char vendor[16], product[48], revision[16];
7505 bzero(&(&ccb->ccb_h)[1],
7506 sizeof(union ccb) - sizeof(struct ccb_hdr));
7508 ccb->ccb_h.status = CAM_REQ_INPROG;
7509 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7511 smp_discover(&ccb->smpio,
7515 sizeof(*disrequest),
7516 (uint8_t *)disresponse,
7517 sizeof(*disresponse),
7519 /*ignore_zone_group*/ 0,
7523 if (((retval = cam_send_ccb(device, ccb)) < 0)
7524 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7525 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7526 const char warnstr[] = "error sending command";
7533 if (arglist & CAM_ARG_VERBOSE) {
7534 cam_error_print(device, ccb, CAM_ESF_ALL,
7535 CAM_EPF_ALL, stderr);
7541 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7543 fprintf(stdout, "%3d <vacant>\n", i);
7547 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7550 item = findsasdevice(&devlist,
7551 scsi_8btou64(disresponse->attached_sas_address));
7555 || (item != NULL)) {
7556 fprintf(stdout, "%3d 0x%016jx", i,
7557 (uintmax_t)scsi_8btou64(
7558 disresponse->attached_sas_address));
7560 fprintf(stdout, "\n");
7563 } else if (quiet != 0)
7566 dev_match = &item->dev_match;
7568 if (dev_match->protocol == PROTO_SCSI) {
7569 cam_strvis(vendor, dev_match->inq_data.vendor,
7570 sizeof(dev_match->inq_data.vendor),
7572 cam_strvis(product, dev_match->inq_data.product,
7573 sizeof(dev_match->inq_data.product),
7575 cam_strvis(revision, dev_match->inq_data.revision,
7576 sizeof(dev_match->inq_data.revision),
7578 sprintf(tmpstr, "<%s %s %s>", vendor, product,
7580 } else if ((dev_match->protocol == PROTO_ATA)
7581 || (dev_match->protocol == PROTO_SATAPM)) {
7582 cam_strvis(product, dev_match->ident_data.model,
7583 sizeof(dev_match->ident_data.model),
7585 cam_strvis(revision, dev_match->ident_data.revision,
7586 sizeof(dev_match->ident_data.revision),
7588 sprintf(tmpstr, "<%s %s>", product, revision);
7590 sprintf(tmpstr, "<>");
7592 fprintf(stdout, " %-33s ", tmpstr);
7595 * If we have 0 periphs, that's a bug...
7597 if (item->num_periphs == 0) {
7598 fprintf(stdout, "\n");
7602 fprintf(stdout, "(");
7603 for (j = 0; j < item->num_periphs; j++) {
7605 fprintf(stdout, ",");
7607 fprintf(stdout, "%s%d",
7608 item->periph_matches[j].periph_name,
7609 item->periph_matches[j].unit_number);
7612 fprintf(stdout, ")\n");
7626 freebusdevlist(&devlist);
7632 atapm(struct cam_device *device, int argc, char **argv,
7633 char *combinedopt, int retry_count, int timeout)
7641 ccb = cam_getccb(device);
7644 warnx("%s: error allocating ccb", __func__);
7648 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7657 if (strcmp(argv[1], "idle") == 0) {
7659 cmd = ATA_IDLE_IMMEDIATE;
7662 } else if (strcmp(argv[1], "standby") == 0) {
7664 cmd = ATA_STANDBY_IMMEDIATE;
7666 cmd = ATA_STANDBY_CMD;
7674 else if (t <= (240 * 5))
7676 else if (t <= (252 * 5))
7677 /* special encoding for 21 minutes */
7679 else if (t <= (11 * 30 * 60))
7680 sc = (t - 1) / (30 * 60) + 241;
7684 cam_fill_ataio(&ccb->ataio,
7687 /*flags*/CAM_DIR_NONE,
7691 timeout ? timeout : 30 * 1000);
7692 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
7694 /* Disable freezing the device queue */
7695 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7697 if (arglist & CAM_ARG_ERR_RECOVER)
7698 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7700 if (cam_send_ccb(device, ccb) < 0) {
7701 warn("error sending command");
7703 if (arglist & CAM_ARG_VERBOSE)
7704 cam_error_print(device, ccb, CAM_ESF_ALL,
7705 CAM_EPF_ALL, stderr);
7711 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7712 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7721 #endif /* MINIMALISTIC */
7724 usage(int printlong)
7727 fprintf(printlong ? stdout : stderr,
7728 "usage: camcontrol <command> [device id][generic args][command args]\n"
7729 " camcontrol devlist [-v]\n"
7730 #ifndef MINIMALISTIC
7731 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
7732 " camcontrol tur [dev_id][generic args]\n"
7733 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
7734 " camcontrol identify [dev_id][generic args] [-v]\n"
7735 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
7736 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
7738 " camcontrol start [dev_id][generic args]\n"
7739 " camcontrol stop [dev_id][generic args]\n"
7740 " camcontrol load [dev_id][generic args]\n"
7741 " camcontrol eject [dev_id][generic args]\n"
7742 #endif /* MINIMALISTIC */
7743 " camcontrol rescan <all | bus[:target:lun]>\n"
7744 " camcontrol reset <all | bus[:target:lun]>\n"
7745 #ifndef MINIMALISTIC
7746 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
7747 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
7748 " [-P pagectl][-e | -b][-d]\n"
7749 " camcontrol cmd [dev_id][generic args]\n"
7750 " <-a cmd [args] | -c cmd [args]>\n"
7751 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
7752 " camcontrol smpcmd [dev_id][generic args]\n"
7753 " <-r len fmt [args]> <-R len fmt [args]>\n"
7754 " camcontrol smprg [dev_id][generic args][-l]\n"
7755 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
7756 " [-o operation][-d name][-m rate][-M rate]\n"
7757 " [-T pp_timeout][-a enable|disable]\n"
7758 " [-A enable|disable][-s enable|disable]\n"
7759 " [-S enable|disable]\n"
7760 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
7761 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
7762 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
7763 " <all|bus[:target[:lun]]|off>\n"
7764 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
7765 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
7766 " [-D <enable|disable>][-M mode][-O offset]\n"
7767 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
7768 " [-U][-W bus_width]\n"
7769 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
7770 " camcontrol sanitize [dev_id][generic args]\n"
7771 " [-a overwrite|block|crypto|exitfailure]\n"
7772 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
7774 " camcontrol idle [dev_id][generic args][-t time]\n"
7775 " camcontrol standby [dev_id][generic args][-t time]\n"
7776 " camcontrol sleep [dev_id][generic args]\n"
7777 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
7778 " camcontrol security [dev_id][generic args]\n"
7779 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
7780 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
7781 " [-U <user|master>] [-y]\n"
7782 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
7783 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
7784 #endif /* MINIMALISTIC */
7785 " camcontrol help\n");
7788 #ifndef MINIMALISTIC
7790 "Specify one of the following options:\n"
7791 "devlist list all CAM devices\n"
7792 "periphlist list all CAM peripheral drivers attached to a device\n"
7793 "tur send a test unit ready to the named device\n"
7794 "inquiry send a SCSI inquiry command to the named device\n"
7795 "identify send a ATA identify command to the named device\n"
7796 "reportluns send a SCSI report luns command to the device\n"
7797 "readcap send a SCSI read capacity command to the device\n"
7798 "start send a Start Unit command to the device\n"
7799 "stop send a Stop Unit command to the device\n"
7800 "load send a Start Unit command to the device with the load bit set\n"
7801 "eject send a Stop Unit command to the device with the eject bit set\n"
7802 "rescan rescan all busses, the given bus, or bus:target:lun\n"
7803 "reset reset all busses, the given bus, or bus:target:lun\n"
7804 "defects read the defect list of the specified device\n"
7805 "modepage display or edit (-e) the given mode page\n"
7806 "cmd send the given SCSI command, may need -i or -o as well\n"
7807 "smpcmd send the given SMP command, requires -o and -i\n"
7808 "smprg send the SMP Report General command\n"
7809 "smppc send the SMP PHY Control command, requires -p\n"
7810 "smpphylist display phys attached to a SAS expander\n"
7811 "smpmaninfo send the SMP Report Manufacturer Info command\n"
7812 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
7813 "tags report or set the number of transaction slots for a device\n"
7814 "negotiate report or set device negotiation parameters\n"
7815 "format send the SCSI FORMAT UNIT command to the named device\n"
7816 "sanitize send the SCSI SANITIZE command to the named device\n"
7817 "idle send the ATA IDLE command to the named device\n"
7818 "standby send the ATA STANDBY command to the named device\n"
7819 "sleep send the ATA SLEEP command to the named device\n"
7820 "fwdownload program firmware of the named device with the given image"
7821 "security report or send ATA security commands to the named device\n"
7822 "help this message\n"
7823 "Device Identifiers:\n"
7824 "bus:target specify the bus and target, lun defaults to 0\n"
7825 "bus:target:lun specify the bus, target and lun\n"
7826 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
7827 "Generic arguments:\n"
7828 "-v be verbose, print out sense information\n"
7829 "-t timeout command timeout in seconds, overrides default timeout\n"
7830 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
7831 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
7832 "-E have the kernel attempt to perform SCSI error recovery\n"
7833 "-C count specify the SCSI command retry count (needs -E to work)\n"
7834 "modepage arguments:\n"
7835 "-l list all available mode pages\n"
7836 "-m page specify the mode page to view or edit\n"
7837 "-e edit the specified mode page\n"
7838 "-b force view to binary mode\n"
7839 "-d disable block descriptors for mode sense\n"
7840 "-P pgctl page control field 0-3\n"
7841 "defects arguments:\n"
7842 "-f format specify defect list format (block, bfi or phys)\n"
7843 "-G get the grown defect list\n"
7844 "-P get the permanent defect list\n"
7845 "inquiry arguments:\n"
7846 "-D get the standard inquiry data\n"
7847 "-S get the serial number\n"
7848 "-R get the transfer rate, etc.\n"
7849 "reportluns arguments:\n"
7850 "-c only report a count of available LUNs\n"
7851 "-l only print out luns, and not a count\n"
7852 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
7853 "readcap arguments\n"
7854 "-b only report the blocksize\n"
7855 "-h human readable device size, base 2\n"
7856 "-H human readable device size, base 10\n"
7857 "-N print the number of blocks instead of last block\n"
7858 "-q quiet, print numbers only\n"
7859 "-s only report the last block/device size\n"
7861 "-c cdb [args] specify the SCSI CDB\n"
7862 "-i len fmt specify input data and input data format\n"
7863 "-o len fmt [args] specify output data and output data fmt\n"
7864 "smpcmd arguments:\n"
7865 "-r len fmt [args] specify the SMP command to be sent\n"
7866 "-R len fmt [args] specify SMP response format\n"
7867 "smprg arguments:\n"
7868 "-l specify the long response format\n"
7869 "smppc arguments:\n"
7870 "-p phy specify the PHY to operate on\n"
7871 "-l specify the long request/response format\n"
7872 "-o operation specify the phy control operation\n"
7873 "-d name set the attached device name\n"
7874 "-m rate set the minimum physical link rate\n"
7875 "-M rate set the maximum physical link rate\n"
7876 "-T pp_timeout set the partial pathway timeout value\n"
7877 "-a enable|disable enable or disable SATA slumber\n"
7878 "-A enable|disable enable or disable SATA partial phy power\n"
7879 "-s enable|disable enable or disable SAS slumber\n"
7880 "-S enable|disable enable or disable SAS partial phy power\n"
7881 "smpphylist arguments:\n"
7882 "-l specify the long response format\n"
7883 "-q only print phys with attached devices\n"
7884 "smpmaninfo arguments:\n"
7885 "-l specify the long response format\n"
7886 "debug arguments:\n"
7887 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
7888 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
7889 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
7890 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
7892 "-N tags specify the number of tags to use for this device\n"
7893 "-q be quiet, don't report the number of tags\n"
7894 "-v report a number of tag-related parameters\n"
7895 "negotiate arguments:\n"
7896 "-a send a test unit ready after negotiation\n"
7897 "-c report/set current negotiation settings\n"
7898 "-D <arg> \"enable\" or \"disable\" disconnection\n"
7899 "-M mode set ATA mode\n"
7900 "-O offset set command delay offset\n"
7901 "-q be quiet, don't report anything\n"
7902 "-R syncrate synchronization rate in MHz\n"
7903 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
7904 "-U report/set user negotiation settings\n"
7905 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
7906 "-v also print a Path Inquiry CCB for the controller\n"
7907 "format arguments:\n"
7908 "-q be quiet, don't print status messages\n"
7909 "-r run in report only mode\n"
7910 "-w don't send immediate format command\n"
7911 "-y don't ask any questions\n"
7912 "sanitize arguments:\n"
7913 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
7914 "-c passes overwrite passes to perform (1 to 31)\n"
7915 "-I invert overwrite pattern after each pass\n"
7916 "-P pattern path to overwrite pattern file\n"
7917 "-q be quiet, don't print status messages\n"
7918 "-r run in report only mode\n"
7919 "-U run operation in unrestricted completion exit mode\n"
7920 "-w don't send immediate sanitize command\n"
7921 "-y don't ask any questions\n"
7922 "idle/standby arguments:\n"
7923 "-t <arg> number of seconds before respective state.\n"
7924 "fwdownload arguments:\n"
7925 "-f fw_image path to firmware image file\n"
7926 "-y don't ask any questions\n"
7927 "-s run in simulation mode\n"
7928 "-v print info for every firmware segment sent to device\n"
7929 "security arguments:\n"
7930 "-d pwd disable security using the given password for the selected\n"
7932 "-e pwd erase the device using the given pwd for the selected user\n"
7933 "-f freeze the security configuration of the specified device\n"
7934 "-h pwd enhanced erase the device using the given pwd for the\n"
7936 "-k pwd unlock the device using the given pwd for the selected\n"
7938 "-l <high|maximum> specifies which security level to set: high or maximum\n"
7939 "-q be quiet, do not print any status messages\n"
7940 "-s pwd password the device (enable security) using the given\n"
7941 " pwd for the selected user\n"
7942 "-T timeout overrides the timeout (seconds) used for erase operation\n"
7943 "-U <user|master> specifies which user to set: user or master\n"
7944 "-y don't ask any questions\n"
7946 "-f freeze the HPA configuration of the device\n"
7947 "-l lock the HPA configuration of the device\n"
7948 "-P make the HPA max sectors persist\n"
7949 "-p pwd Set the HPA configuration password required for unlock\n"
7951 "-q be quiet, do not print any status messages\n"
7952 "-s sectors configures the maximum user accessible sectors of the\n"
7954 "-U pwd unlock the HPA configuration of the device\n"
7955 "-y don't ask any questions\n"
7957 #endif /* MINIMALISTIC */
7961 main(int argc, char **argv)
7964 char *device = NULL;
7966 struct cam_device *cam_dev = NULL;
7967 int timeout = 0, retry_count = 1;
7968 camcontrol_optret optreturn;
7970 const char *mainopt = "C:En:t:u:v";
7971 const char *subopt = NULL;
7972 char combinedopt[256];
7973 int error = 0, optstart = 2;
7975 #ifndef MINIMALISTIC
7979 #endif /* MINIMALISTIC */
7981 cmdlist = CAM_CMD_NONE;
7982 arglist = CAM_ARG_NONE;
7990 * Get the base option.
7992 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
7994 if (optreturn == CC_OR_AMBIGUOUS) {
7995 warnx("ambiguous option %s", argv[1]);
7998 } else if (optreturn == CC_OR_NOT_FOUND) {
7999 warnx("option %s not found", argv[1]);
8005 * Ahh, getopt(3) is a pain.
8007 * This is a gross hack. There really aren't many other good
8008 * options (excuse the pun) for parsing options in a situation like
8009 * this. getopt is kinda braindead, so you end up having to run
8010 * through the options twice, and give each invocation of getopt
8011 * the option string for the other invocation.
8013 * You would think that you could just have two groups of options.
8014 * The first group would get parsed by the first invocation of
8015 * getopt, and the second group would get parsed by the second
8016 * invocation of getopt. It doesn't quite work out that way. When
8017 * the first invocation of getopt finishes, it leaves optind pointing
8018 * to the argument _after_ the first argument in the second group.
8019 * So when the second invocation of getopt comes around, it doesn't
8020 * recognize the first argument it gets and then bails out.
8022 * A nice alternative would be to have a flag for getopt that says
8023 * "just keep parsing arguments even when you encounter an unknown
8024 * argument", but there isn't one. So there's no real clean way to
8025 * easily parse two sets of arguments without having one invocation
8026 * of getopt know about the other.
8028 * Without this hack, the first invocation of getopt would work as
8029 * long as the generic arguments are first, but the second invocation
8030 * (in the subfunction) would fail in one of two ways. In the case
8031 * where you don't set optreset, it would fail because optind may be
8032 * pointing to the argument after the one it should be pointing at.
8033 * In the case where you do set optreset, and reset optind, it would
8034 * fail because getopt would run into the first set of options, which
8035 * it doesn't understand.
8037 * All of this would "sort of" work if you could somehow figure out
8038 * whether optind had been incremented one option too far. The
8039 * mechanics of that, however, are more daunting than just giving
8040 * both invocations all of the expect options for either invocation.
8042 * Needless to say, I wouldn't mind if someone invented a better
8043 * (non-GPL!) command line parsing interface than getopt. I
8044 * wouldn't mind if someone added more knobs to getopt to make it
8045 * work better. Who knows, I may talk myself into doing it someday,
8046 * if the standards weenies let me. As it is, it just leads to
8047 * hackery like this and causes people to avoid it in some cases.
8049 * KDM, September 8th, 1998
8052 sprintf(combinedopt, "%s%s", mainopt, subopt);
8054 sprintf(combinedopt, "%s", mainopt);
8057 * For these options we do not parse optional device arguments and
8058 * we do not open a passthrough device.
8060 if ((cmdlist == CAM_CMD_RESCAN)
8061 || (cmdlist == CAM_CMD_RESET)
8062 || (cmdlist == CAM_CMD_DEVTREE)
8063 || (cmdlist == CAM_CMD_USAGE)
8064 || (cmdlist == CAM_CMD_DEBUG))
8067 #ifndef MINIMALISTIC
8069 && (argc > 2 && argv[2][0] != '-')) {
8073 if (isdigit(argv[2][0])) {
8074 /* device specified as bus:target[:lun] */
8075 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
8077 errx(1, "numeric device specification must "
8078 "be either bus:target, or "
8080 /* default to 0 if lun was not specified */
8081 if ((arglist & CAM_ARG_LUN) == 0) {
8083 arglist |= CAM_ARG_LUN;
8087 if (cam_get_device(argv[2], name, sizeof name, &unit)
8089 errx(1, "%s", cam_errbuf);
8090 device = strdup(name);
8091 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
8095 #endif /* MINIMALISTIC */
8097 * Start getopt processing at argv[2/3], since we've already
8098 * accepted argv[1..2] as the command name, and as a possible
8104 * Now we run through the argument list looking for generic
8105 * options, and ignoring options that possibly belong to
8108 while ((c = getopt(argc, argv, combinedopt))!= -1){
8111 retry_count = strtol(optarg, NULL, 0);
8112 if (retry_count < 0)
8113 errx(1, "retry count %d is < 0",
8115 arglist |= CAM_ARG_RETRIES;
8118 arglist |= CAM_ARG_ERR_RECOVER;
8121 arglist |= CAM_ARG_DEVICE;
8123 while (isspace(*tstr) && (*tstr != '\0'))
8125 device = (char *)strdup(tstr);
8128 timeout = strtol(optarg, NULL, 0);
8130 errx(1, "invalid timeout %d", timeout);
8131 /* Convert the timeout from seconds to ms */
8133 arglist |= CAM_ARG_TIMEOUT;
8136 arglist |= CAM_ARG_UNIT;
8137 unit = strtol(optarg, NULL, 0);
8140 arglist |= CAM_ARG_VERBOSE;
8147 #ifndef MINIMALISTIC
8149 * For most commands we'll want to open the passthrough device
8150 * associated with the specified device. In the case of the rescan
8151 * commands, we don't use a passthrough device at all, just the
8152 * transport layer device.
8155 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
8156 && (((arglist & CAM_ARG_DEVICE) == 0)
8157 || ((arglist & CAM_ARG_UNIT) == 0))) {
8158 errx(1, "subcommand \"%s\" requires a valid device "
8159 "identifier", argv[1]);
8162 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
8163 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
8164 cam_open_spec_device(device,unit,O_RDWR,NULL)))
8166 errx(1,"%s", cam_errbuf);
8168 #endif /* MINIMALISTIC */
8171 * Reset optind to 2, and reset getopt, so these routines can parse
8172 * the arguments again.
8178 #ifndef MINIMALISTIC
8179 case CAM_CMD_DEVLIST:
8180 error = getdevlist(cam_dev);
8183 error = atahpa(cam_dev, retry_count, timeout,
8184 argc, argv, combinedopt);
8186 #endif /* MINIMALISTIC */
8187 case CAM_CMD_DEVTREE:
8188 error = getdevtree();
8190 #ifndef MINIMALISTIC
8192 error = testunitready(cam_dev, retry_count, timeout, 0);
8194 case CAM_CMD_INQUIRY:
8195 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
8196 retry_count, timeout);
8198 case CAM_CMD_IDENTIFY:
8199 error = ataidentify(cam_dev, retry_count, timeout);
8201 case CAM_CMD_STARTSTOP:
8202 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
8203 arglist & CAM_ARG_EJECT, retry_count,
8206 #endif /* MINIMALISTIC */
8207 case CAM_CMD_RESCAN:
8208 error = dorescan_or_reset(argc, argv, 1);
8211 error = dorescan_or_reset(argc, argv, 0);
8213 #ifndef MINIMALISTIC
8214 case CAM_CMD_READ_DEFECTS:
8215 error = readdefects(cam_dev, argc, argv, combinedopt,
8216 retry_count, timeout);
8218 case CAM_CMD_MODE_PAGE:
8219 modepage(cam_dev, argc, argv, combinedopt,
8220 retry_count, timeout);
8222 case CAM_CMD_SCSI_CMD:
8223 error = scsicmd(cam_dev, argc, argv, combinedopt,
8224 retry_count, timeout);
8226 case CAM_CMD_SMP_CMD:
8227 error = smpcmd(cam_dev, argc, argv, combinedopt,
8228 retry_count, timeout);
8230 case CAM_CMD_SMP_RG:
8231 error = smpreportgeneral(cam_dev, argc, argv,
8232 combinedopt, retry_count,
8235 case CAM_CMD_SMP_PC:
8236 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
8237 retry_count, timeout);
8239 case CAM_CMD_SMP_PHYLIST:
8240 error = smpphylist(cam_dev, argc, argv, combinedopt,
8241 retry_count, timeout);
8243 case CAM_CMD_SMP_MANINFO:
8244 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
8245 retry_count, timeout);
8248 error = camdebug(argc, argv, combinedopt);
8251 error = tagcontrol(cam_dev, argc, argv, combinedopt);
8254 error = ratecontrol(cam_dev, retry_count, timeout,
8255 argc, argv, combinedopt);
8257 case CAM_CMD_FORMAT:
8258 error = scsiformat(cam_dev, argc, argv,
8259 combinedopt, retry_count, timeout);
8261 case CAM_CMD_REPORTLUNS:
8262 error = scsireportluns(cam_dev, argc, argv,
8263 combinedopt, retry_count,
8266 case CAM_CMD_READCAP:
8267 error = scsireadcapacity(cam_dev, argc, argv,
8268 combinedopt, retry_count,
8272 case CAM_CMD_STANDBY:
8274 error = atapm(cam_dev, argc, argv,
8275 combinedopt, retry_count, timeout);
8277 case CAM_CMD_SECURITY:
8278 error = atasecurity(cam_dev, retry_count, timeout,
8279 argc, argv, combinedopt);
8281 case CAM_CMD_DOWNLOAD_FW:
8282 error = fwdownload(cam_dev, argc, argv, combinedopt,
8283 arglist & CAM_ARG_VERBOSE, retry_count, timeout,
8284 get_disk_type(cam_dev));
8286 case CAM_CMD_SANITIZE:
8287 error = scsisanitize(cam_dev, argc, argv,
8288 combinedopt, retry_count, timeout);
8290 #endif /* MINIMALISTIC */
8300 if (cam_dev != NULL)
8301 cam_close_device(cam_dev);