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, "-b"},
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(int argc, char **argv, char *combinedopt);
259 static int testunitready(struct cam_device *device, int retry_count,
260 int timeout, int quiet);
261 static int scsistart(struct cam_device *device, int startstop, int loadeject,
262 int retry_count, int timeout);
263 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
264 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
265 static int camxferrate(struct cam_device *device);
266 #endif /* MINIMALISTIC */
267 static int parse_btl(char *tstr, int *bus, int *target, int *lun,
268 cam_argmask *arglst);
269 static int dorescan_or_reset(int argc, char **argv, int rescan);
270 static int rescan_or_reset_bus(int bus, int rescan);
271 static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
273 static int readdefects(struct cam_device *device, int argc, char **argv,
274 char *combinedopt, int retry_count, int timeout);
275 static void modepage(struct cam_device *device, int argc, char **argv,
276 char *combinedopt, int retry_count, int timeout);
277 static int scsicmd(struct cam_device *device, int argc, char **argv,
278 char *combinedopt, int retry_count, int timeout);
279 static int smpcmd(struct cam_device *device, int argc, char **argv,
280 char *combinedopt, int retry_count, int timeout);
281 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
282 char *combinedopt, int retry_count, int timeout);
283 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
284 char *combinedopt, int retry_count, int timeout);
285 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
286 char *combinedopt, int retry_count, int timeout);
287 static int getdevid(struct cam_devitem *item);
288 static int buildbusdevlist(struct cam_devlist *devlist);
289 static void freebusdevlist(struct cam_devlist *devlist);
290 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
292 static int smpphylist(struct cam_device *device, int argc, char **argv,
293 char *combinedopt, int retry_count, int timeout);
294 static int tagcontrol(struct cam_device *device, int argc, char **argv,
296 static void cts_print(struct cam_device *device,
297 struct ccb_trans_settings *cts);
298 static void cpi_print(struct ccb_pathinq *cpi);
299 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
300 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
301 static int get_print_cts(struct cam_device *device, int user_settings,
302 int quiet, struct ccb_trans_settings *cts);
303 static int ratecontrol(struct cam_device *device, int retry_count,
304 int timeout, int argc, char **argv, char *combinedopt);
305 static int scsiformat(struct cam_device *device, int argc, char **argv,
306 char *combinedopt, int retry_count, int timeout);
307 static int scsisanitize(struct cam_device *device, int argc, char **argv,
308 char *combinedopt, int retry_count, int timeout);
309 static int scsireportluns(struct cam_device *device, int argc, char **argv,
310 char *combinedopt, int retry_count, int timeout);
311 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
312 char *combinedopt, int retry_count, int timeout);
313 static int atapm(struct cam_device *device, int argc, char **argv,
314 char *combinedopt, int retry_count, int timeout);
315 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
316 int argc, char **argv, char *combinedopt);
317 static int atahpa(struct cam_device *device, int retry_count, int timeout,
318 int argc, char **argv, char *combinedopt);
320 #endif /* MINIMALISTIC */
322 #define min(a,b) (((a)<(b))?(a):(b))
325 #define max(a,b) (((a)>(b))?(a):(b))
329 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
330 cam_argmask *argnum, const char **subopt)
332 struct camcontrol_opts *opts;
335 for (opts = table; (opts != NULL) && (opts->optname != NULL);
337 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
338 *cmdnum = opts->cmdnum;
339 *argnum = opts->argnum;
340 *subopt = opts->subopt;
341 if (++num_matches > 1)
342 return(CC_OR_AMBIGUOUS);
349 return(CC_OR_NOT_FOUND);
354 getdevlist(struct cam_device *device)
360 ccb = cam_getccb(device);
362 ccb->ccb_h.func_code = XPT_GDEVLIST;
363 ccb->ccb_h.flags = CAM_DIR_NONE;
364 ccb->ccb_h.retry_count = 1;
366 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
367 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
368 if (cam_send_ccb(device, ccb) < 0) {
369 perror("error getting device list");
376 switch (ccb->cgdl.status) {
377 case CAM_GDEVLIST_MORE_DEVS:
378 strcpy(status, "MORE");
380 case CAM_GDEVLIST_LAST_DEVICE:
381 strcpy(status, "LAST");
383 case CAM_GDEVLIST_LIST_CHANGED:
384 strcpy(status, "CHANGED");
386 case CAM_GDEVLIST_ERROR:
387 strcpy(status, "ERROR");
392 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
393 ccb->cgdl.periph_name,
394 ccb->cgdl.unit_number,
395 ccb->cgdl.generation,
400 * If the list has changed, we need to start over from the
403 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
411 #endif /* MINIMALISTIC */
414 getdevtree(int argc, char **argv, char *combinedopt)
425 while ((c = getopt(argc, argv, combinedopt)) != -1) {
428 if ((arglist & CAM_ARG_VERBOSE) == 0)
436 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
437 warn("couldn't open %s", XPT_DEVICE);
441 bzero(&ccb, sizeof(union ccb));
443 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
444 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
445 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
447 ccb.ccb_h.func_code = XPT_DEV_MATCH;
448 bufsize = sizeof(struct dev_match_result) * 100;
449 ccb.cdm.match_buf_len = bufsize;
450 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
451 if (ccb.cdm.matches == NULL) {
452 warnx("can't malloc memory for matches");
456 ccb.cdm.num_matches = 0;
459 * We fetch all nodes, since we display most of them in the default
460 * case, and all in the verbose case.
462 ccb.cdm.num_patterns = 0;
463 ccb.cdm.pattern_buf_len = 0;
466 * We do the ioctl multiple times if necessary, in case there are
467 * more than 100 nodes in the EDT.
470 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
471 warn("error sending CAMIOCOMMAND ioctl");
476 if ((ccb.ccb_h.status != CAM_REQ_CMP)
477 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
478 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
479 warnx("got CAM error %#x, CDM error %d\n",
480 ccb.ccb_h.status, ccb.cdm.status);
485 for (i = 0; i < ccb.cdm.num_matches; i++) {
486 switch (ccb.cdm.matches[i].type) {
487 case DEV_MATCH_BUS: {
488 struct bus_match_result *bus_result;
491 * Only print the bus information if the
492 * user turns on the verbose flag.
494 if ((busonly == 0) &&
495 (arglist & CAM_ARG_VERBOSE) == 0)
499 &ccb.cdm.matches[i].result.bus_result;
502 fprintf(stdout, ")\n");
506 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
508 bus_result->dev_name,
509 bus_result->unit_number,
511 (busonly ? "" : ":"));
514 case DEV_MATCH_DEVICE: {
515 struct device_match_result *dev_result;
516 char vendor[16], product[48], revision[16];
517 char fw[5], tmpstr[256];
523 &ccb.cdm.matches[i].result.device_result;
525 if ((dev_result->flags
526 & DEV_RESULT_UNCONFIGURED)
527 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
533 if (dev_result->protocol == PROTO_SCSI) {
534 cam_strvis(vendor, dev_result->inq_data.vendor,
535 sizeof(dev_result->inq_data.vendor),
538 dev_result->inq_data.product,
539 sizeof(dev_result->inq_data.product),
542 dev_result->inq_data.revision,
543 sizeof(dev_result->inq_data.revision),
545 sprintf(tmpstr, "<%s %s %s>", vendor, product,
547 } else if (dev_result->protocol == PROTO_ATA ||
548 dev_result->protocol == PROTO_SATAPM) {
550 dev_result->ident_data.model,
551 sizeof(dev_result->ident_data.model),
554 dev_result->ident_data.revision,
555 sizeof(dev_result->ident_data.revision),
557 sprintf(tmpstr, "<%s %s>", product,
559 } else if (dev_result->protocol == PROTO_SEMB) {
560 struct sep_identify_data *sid;
562 sid = (struct sep_identify_data *)
563 &dev_result->ident_data;
564 cam_strvis(vendor, sid->vendor_id,
565 sizeof(sid->vendor_id),
567 cam_strvis(product, sid->product_id,
568 sizeof(sid->product_id),
570 cam_strvis(revision, sid->product_rev,
571 sizeof(sid->product_rev),
573 cam_strvis(fw, sid->firmware_rev,
574 sizeof(sid->firmware_rev),
576 sprintf(tmpstr, "<%s %s %s %s>",
577 vendor, product, revision, fw);
579 sprintf(tmpstr, "<>");
582 fprintf(stdout, ")\n");
586 fprintf(stdout, "%-33s at scbus%d "
587 "target %d lun %jx (",
590 dev_result->target_id,
591 (uintmax_t)dev_result->target_lun);
597 case DEV_MATCH_PERIPH: {
598 struct periph_match_result *periph_result;
601 &ccb.cdm.matches[i].result.periph_result;
603 if (busonly || skip_device != 0)
607 fprintf(stdout, ",");
609 fprintf(stdout, "%s%d",
610 periph_result->periph_name,
611 periph_result->unit_number);
617 fprintf(stdout, "unknown match type\n");
622 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
623 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
626 fprintf(stdout, ")\n");
635 testunitready(struct cam_device *device, int retry_count, int timeout,
641 ccb = cam_getccb(device);
643 scsi_test_unit_ready(&ccb->csio,
644 /* retries */ retry_count,
646 /* tag_action */ MSG_SIMPLE_Q_TAG,
647 /* sense_len */ SSD_FULL_SIZE,
648 /* timeout */ timeout ? timeout : 5000);
650 /* Disable freezing the device queue */
651 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
653 if (arglist & CAM_ARG_ERR_RECOVER)
654 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
656 if (cam_send_ccb(device, ccb) < 0) {
658 perror("error sending test unit ready");
660 if (arglist & CAM_ARG_VERBOSE) {
661 cam_error_print(device, ccb, CAM_ESF_ALL,
662 CAM_EPF_ALL, stderr);
669 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
671 fprintf(stdout, "Unit is ready\n");
674 fprintf(stdout, "Unit is not ready\n");
677 if (arglist & CAM_ARG_VERBOSE) {
678 cam_error_print(device, ccb, CAM_ESF_ALL,
679 CAM_EPF_ALL, stderr);
689 scsistart(struct cam_device *device, int startstop, int loadeject,
690 int retry_count, int timeout)
695 ccb = cam_getccb(device);
698 * If we're stopping, send an ordered tag so the drive in question
699 * will finish any previously queued writes before stopping. If
700 * the device isn't capable of tagged queueing, or if tagged
701 * queueing is turned off, the tag action is a no-op.
703 scsi_start_stop(&ccb->csio,
704 /* retries */ retry_count,
706 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
708 /* start/stop */ startstop,
709 /* load_eject */ loadeject,
711 /* sense_len */ SSD_FULL_SIZE,
712 /* timeout */ timeout ? timeout : 120000);
714 /* Disable freezing the device queue */
715 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
717 if (arglist & CAM_ARG_ERR_RECOVER)
718 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
720 if (cam_send_ccb(device, ccb) < 0) {
721 perror("error sending start unit");
723 if (arglist & CAM_ARG_VERBOSE) {
724 cam_error_print(device, ccb, CAM_ESF_ALL,
725 CAM_EPF_ALL, stderr);
732 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
734 fprintf(stdout, "Unit started successfully");
736 fprintf(stdout,", Media loaded\n");
738 fprintf(stdout,"\n");
740 fprintf(stdout, "Unit stopped successfully");
742 fprintf(stdout, ", Media ejected\n");
744 fprintf(stdout, "\n");
750 "Error received from start unit command\n");
753 "Error received from stop unit command\n");
755 if (arglist & CAM_ARG_VERBOSE) {
756 cam_error_print(device, ccb, CAM_ESF_ALL,
757 CAM_EPF_ALL, stderr);
767 scsidoinquiry(struct cam_device *device, int argc, char **argv,
768 char *combinedopt, int retry_count, int timeout)
773 while ((c = getopt(argc, argv, combinedopt)) != -1) {
776 arglist |= CAM_ARG_GET_STDINQ;
779 arglist |= CAM_ARG_GET_XFERRATE;
782 arglist |= CAM_ARG_GET_SERIAL;
790 * If the user didn't specify any inquiry options, he wants all of
793 if ((arglist & CAM_ARG_INQ_MASK) == 0)
794 arglist |= CAM_ARG_INQ_MASK;
796 if (arglist & CAM_ARG_GET_STDINQ)
797 error = scsiinquiry(device, retry_count, timeout);
802 if (arglist & CAM_ARG_GET_SERIAL)
803 scsiserial(device, retry_count, timeout);
808 if (arglist & CAM_ARG_GET_XFERRATE)
809 error = camxferrate(device);
815 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
818 struct scsi_inquiry_data *inq_buf;
821 ccb = cam_getccb(device);
824 warnx("couldn't allocate CCB");
828 /* cam_getccb cleans up the header, caller has to zero the payload */
829 bzero(&(&ccb->ccb_h)[1],
830 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
832 inq_buf = (struct scsi_inquiry_data *)malloc(
833 sizeof(struct scsi_inquiry_data));
835 if (inq_buf == NULL) {
837 warnx("can't malloc memory for inquiry\n");
840 bzero(inq_buf, sizeof(*inq_buf));
843 * Note that although the size of the inquiry buffer is the full
844 * 256 bytes specified in the SCSI spec, we only tell the device
845 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
846 * two reasons for this:
848 * - The SCSI spec says that when a length field is only 1 byte,
849 * a value of 0 will be interpreted as 256. Therefore
850 * scsi_inquiry() will convert an inq_len (which is passed in as
851 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
852 * to 0. Evidently, very few devices meet the spec in that
853 * regard. Some devices, like many Seagate disks, take the 0 as
854 * 0, and don't return any data. One Pioneer DVD-R drive
855 * returns more data than the command asked for.
857 * So, since there are numerous devices that just don't work
858 * right with the full inquiry size, we don't send the full size.
860 * - The second reason not to use the full inquiry data length is
861 * that we don't need it here. The only reason we issue a
862 * standard inquiry is to get the vendor name, device name,
863 * and revision so scsi_print_inquiry() can print them.
865 * If, at some point in the future, more inquiry data is needed for
866 * some reason, this code should use a procedure similar to the
867 * probe code. i.e., issue a short inquiry, and determine from
868 * the additional length passed back from the device how much
869 * inquiry data the device supports. Once the amount the device
870 * supports is determined, issue an inquiry for that amount and no
875 scsi_inquiry(&ccb->csio,
876 /* retries */ retry_count,
878 /* tag_action */ MSG_SIMPLE_Q_TAG,
879 /* inq_buf */ (u_int8_t *)inq_buf,
880 /* inq_len */ SHORT_INQUIRY_LENGTH,
883 /* sense_len */ SSD_FULL_SIZE,
884 /* timeout */ timeout ? timeout : 5000);
886 /* Disable freezing the device queue */
887 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
889 if (arglist & CAM_ARG_ERR_RECOVER)
890 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
892 if (cam_send_ccb(device, ccb) < 0) {
893 perror("error sending SCSI inquiry");
895 if (arglist & CAM_ARG_VERBOSE) {
896 cam_error_print(device, ccb, CAM_ESF_ALL,
897 CAM_EPF_ALL, stderr);
904 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
907 if (arglist & CAM_ARG_VERBOSE) {
908 cam_error_print(device, ccb, CAM_ESF_ALL,
909 CAM_EPF_ALL, stderr);
920 fprintf(stdout, "%s%d: ", device->device_name,
921 device->dev_unit_num);
922 scsi_print_inquiry(inq_buf);
930 scsiserial(struct cam_device *device, int retry_count, int timeout)
933 struct scsi_vpd_unit_serial_number *serial_buf;
934 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
937 ccb = cam_getccb(device);
940 warnx("couldn't allocate CCB");
944 /* cam_getccb cleans up the header, caller has to zero the payload */
945 bzero(&(&ccb->ccb_h)[1],
946 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
948 serial_buf = (struct scsi_vpd_unit_serial_number *)
949 malloc(sizeof(*serial_buf));
951 if (serial_buf == NULL) {
953 warnx("can't malloc memory for serial number");
957 scsi_inquiry(&ccb->csio,
958 /*retries*/ retry_count,
960 /* tag_action */ MSG_SIMPLE_Q_TAG,
961 /* inq_buf */ (u_int8_t *)serial_buf,
962 /* inq_len */ sizeof(*serial_buf),
964 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
965 /* sense_len */ SSD_FULL_SIZE,
966 /* timeout */ timeout ? timeout : 5000);
968 /* Disable freezing the device queue */
969 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
971 if (arglist & CAM_ARG_ERR_RECOVER)
972 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
974 if (cam_send_ccb(device, ccb) < 0) {
975 warn("error getting serial number");
977 if (arglist & CAM_ARG_VERBOSE) {
978 cam_error_print(device, ccb, CAM_ESF_ALL,
979 CAM_EPF_ALL, stderr);
987 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
990 if (arglist & CAM_ARG_VERBOSE) {
991 cam_error_print(device, ccb, CAM_ESF_ALL,
992 CAM_EPF_ALL, stderr);
1003 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1004 serial_num[serial_buf->length] = '\0';
1006 if ((arglist & CAM_ARG_GET_STDINQ)
1007 || (arglist & CAM_ARG_GET_XFERRATE))
1008 fprintf(stdout, "%s%d: Serial Number ",
1009 device->device_name, device->dev_unit_num);
1011 fprintf(stdout, "%.60s\n", serial_num);
1019 camxferrate(struct cam_device *device)
1021 struct ccb_pathinq cpi;
1023 u_int32_t speed = 0;
1028 if ((retval = get_cpi(device, &cpi)) != 0)
1031 ccb = cam_getccb(device);
1034 warnx("couldn't allocate CCB");
1038 bzero(&(&ccb->ccb_h)[1],
1039 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
1041 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1042 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1044 if (((retval = cam_send_ccb(device, ccb)) < 0)
1045 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1046 const char error_string[] = "error getting transfer settings";
1051 warnx(error_string);
1053 if (arglist & CAM_ARG_VERBOSE)
1054 cam_error_print(device, ccb, CAM_ESF_ALL,
1055 CAM_EPF_ALL, stderr);
1059 goto xferrate_bailout;
1063 speed = cpi.base_transfer_speed;
1065 if (ccb->cts.transport == XPORT_SPI) {
1066 struct ccb_trans_settings_spi *spi =
1067 &ccb->cts.xport_specific.spi;
1069 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1070 freq = scsi_calc_syncsrate(spi->sync_period);
1073 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1074 speed *= (0x01 << spi->bus_width);
1076 } else if (ccb->cts.transport == XPORT_FC) {
1077 struct ccb_trans_settings_fc *fc =
1078 &ccb->cts.xport_specific.fc;
1080 if (fc->valid & CTS_FC_VALID_SPEED)
1081 speed = fc->bitrate;
1082 } else if (ccb->cts.transport == XPORT_SAS) {
1083 struct ccb_trans_settings_sas *sas =
1084 &ccb->cts.xport_specific.sas;
1086 if (sas->valid & CTS_SAS_VALID_SPEED)
1087 speed = sas->bitrate;
1088 } else if (ccb->cts.transport == XPORT_ATA) {
1089 struct ccb_trans_settings_pata *pata =
1090 &ccb->cts.xport_specific.ata;
1092 if (pata->valid & CTS_ATA_VALID_MODE)
1093 speed = ata_mode2speed(pata->mode);
1094 } else if (ccb->cts.transport == XPORT_SATA) {
1095 struct ccb_trans_settings_sata *sata =
1096 &ccb->cts.xport_specific.sata;
1098 if (sata->valid & CTS_SATA_VALID_REVISION)
1099 speed = ata_revision2speed(sata->revision);
1104 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1105 device->device_name, device->dev_unit_num,
1108 fprintf(stdout, "%s%d: %dKB/s transfers",
1109 device->device_name, device->dev_unit_num,
1113 if (ccb->cts.transport == XPORT_SPI) {
1114 struct ccb_trans_settings_spi *spi =
1115 &ccb->cts.xport_specific.spi;
1117 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1118 && (spi->sync_offset != 0))
1119 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1120 freq % 1000, spi->sync_offset);
1122 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1123 && (spi->bus_width > 0)) {
1124 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1125 && (spi->sync_offset != 0)) {
1126 fprintf(stdout, ", ");
1128 fprintf(stdout, " (");
1130 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1131 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1132 && (spi->sync_offset != 0)) {
1133 fprintf(stdout, ")");
1135 } else if (ccb->cts.transport == XPORT_ATA) {
1136 struct ccb_trans_settings_pata *pata =
1137 &ccb->cts.xport_specific.ata;
1140 if (pata->valid & CTS_ATA_VALID_MODE)
1141 printf("%s, ", ata_mode2string(pata->mode));
1142 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1143 printf("ATAPI %dbytes, ", pata->atapi);
1144 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1145 printf("PIO %dbytes", pata->bytecount);
1147 } else if (ccb->cts.transport == XPORT_SATA) {
1148 struct ccb_trans_settings_sata *sata =
1149 &ccb->cts.xport_specific.sata;
1152 if (sata->valid & CTS_SATA_VALID_REVISION)
1153 printf("SATA %d.x, ", sata->revision);
1156 if (sata->valid & CTS_SATA_VALID_MODE)
1157 printf("%s, ", ata_mode2string(sata->mode));
1158 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1159 printf("ATAPI %dbytes, ", sata->atapi);
1160 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1161 printf("PIO %dbytes", sata->bytecount);
1165 if (ccb->cts.protocol == PROTO_SCSI) {
1166 struct ccb_trans_settings_scsi *scsi =
1167 &ccb->cts.proto_specific.scsi;
1168 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1169 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1170 fprintf(stdout, ", Command Queueing Enabled");
1175 fprintf(stdout, "\n");
1185 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1187 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1188 ((u_int32_t)parm->lba_size_2 << 16);
1190 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1191 ((u_int64_t)parm->lba_size48_2 << 16) |
1192 ((u_int64_t)parm->lba_size48_3 << 32) |
1193 ((u_int64_t)parm->lba_size48_4 << 48);
1197 "Support Enabled Value\n");
1200 printf("Host Protected Area (HPA) ");
1201 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1202 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1203 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1206 printf("HPA - Security ");
1207 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1217 atacapprint(struct ata_params *parm)
1219 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1220 ((u_int32_t)parm->lba_size_2 << 16);
1222 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1223 ((u_int64_t)parm->lba_size48_2 << 16) |
1224 ((u_int64_t)parm->lba_size48_3 << 32) |
1225 ((u_int64_t)parm->lba_size48_4 << 48);
1228 printf("protocol ");
1229 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1230 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1231 if (parm->satacapabilities & ATA_SATA_GEN3)
1232 printf(" SATA 3.x\n");
1233 else if (parm->satacapabilities & ATA_SATA_GEN2)
1234 printf(" SATA 2.x\n");
1235 else if (parm->satacapabilities & ATA_SATA_GEN1)
1236 printf(" SATA 1.x\n");
1242 printf("device model %.40s\n", parm->model);
1243 printf("firmware revision %.8s\n", parm->revision);
1244 printf("serial number %.20s\n", parm->serial);
1245 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1246 printf("WWN %04x%04x%04x%04x\n",
1247 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1249 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1250 printf("media serial number %.30s\n",
1251 parm->media_serial);
1254 printf("cylinders %d\n", parm->cylinders);
1255 printf("heads %d\n", parm->heads);
1256 printf("sectors/track %d\n", parm->sectors);
1257 printf("sector size logical %u, physical %lu, offset %lu\n",
1258 ata_logical_sector_size(parm),
1259 (unsigned long)ata_physical_sector_size(parm),
1260 (unsigned long)ata_logical_sector_offset(parm));
1262 if (parm->config == ATA_PROTO_CFA ||
1263 (parm->support.command2 & ATA_SUPPORT_CFA))
1264 printf("CFA supported\n");
1266 printf("LBA%ssupported ",
1267 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1269 printf("%d sectors\n", lbasize);
1273 printf("LBA48%ssupported ",
1274 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1276 printf("%ju sectors\n", (uintmax_t)lbasize48);
1280 printf("PIO supported PIO");
1281 switch (ata_max_pmode(parm)) {
1297 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1298 printf(" w/o IORDY");
1301 printf("DMA%ssupported ",
1302 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1303 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1304 if (parm->mwdmamodes & 0xff) {
1306 if (parm->mwdmamodes & 0x04)
1308 else if (parm->mwdmamodes & 0x02)
1310 else if (parm->mwdmamodes & 0x01)
1314 if ((parm->atavalid & ATA_FLAG_88) &&
1315 (parm->udmamodes & 0xff)) {
1317 if (parm->udmamodes & 0x40)
1319 else if (parm->udmamodes & 0x20)
1321 else if (parm->udmamodes & 0x10)
1323 else if (parm->udmamodes & 0x08)
1325 else if (parm->udmamodes & 0x04)
1327 else if (parm->udmamodes & 0x02)
1329 else if (parm->udmamodes & 0x01)
1336 if (parm->media_rotation_rate == 1) {
1337 printf("media RPM non-rotating\n");
1338 } else if (parm->media_rotation_rate >= 0x0401 &&
1339 parm->media_rotation_rate <= 0xFFFE) {
1340 printf("media RPM %d\n",
1341 parm->media_rotation_rate);
1345 "Support Enabled Value Vendor\n");
1346 printf("read ahead %s %s\n",
1347 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1348 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1349 printf("write cache %s %s\n",
1350 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1351 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1352 printf("flush cache %s %s\n",
1353 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1354 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1355 printf("overlap %s\n",
1356 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1357 printf("Tagged Command Queuing (TCQ) %s %s",
1358 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1359 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1360 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1361 printf(" %d tags\n",
1362 ATA_QUEUE_LEN(parm->queue) + 1);
1365 printf("Native Command Queuing (NCQ) ");
1366 if (parm->satacapabilities != 0xffff &&
1367 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1368 printf("yes %d tags\n",
1369 ATA_QUEUE_LEN(parm->queue) + 1);
1372 printf("SMART %s %s\n",
1373 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1374 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1375 printf("microcode download %s %s\n",
1376 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1377 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1378 printf("security %s %s\n",
1379 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1380 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1381 printf("power management %s %s\n",
1382 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1383 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1384 printf("advanced power management %s %s",
1385 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1386 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1387 if (parm->support.command2 & ATA_SUPPORT_APM) {
1388 printf(" %d/0x%02X\n",
1389 parm->apm_value, parm->apm_value);
1392 printf("automatic acoustic management %s %s",
1393 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1394 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1395 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1396 printf(" %d/0x%02X %d/0x%02X\n",
1397 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1398 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1399 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1400 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1403 printf("media status notification %s %s\n",
1404 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1405 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1406 printf("power-up in Standby %s %s\n",
1407 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1408 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1409 printf("write-read-verify %s %s",
1410 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1411 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1412 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1413 printf(" %d/0x%x\n",
1414 parm->wrv_mode, parm->wrv_mode);
1417 printf("unload %s %s\n",
1418 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1419 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1420 printf("free-fall %s %s\n",
1421 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1422 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1423 printf("Data Set Management (DSM/TRIM) ");
1424 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1426 printf("DSM - max 512byte blocks ");
1427 if (parm->max_dsm_blocks == 0x00)
1428 printf("yes not specified\n");
1431 parm->max_dsm_blocks);
1433 printf("DSM - deterministic read ");
1434 if (parm->support3 & ATA_SUPPORT_DRAT) {
1435 if (parm->support3 & ATA_SUPPORT_RZAT)
1436 printf("yes zeroed\n");
1438 printf("yes any value\n");
1448 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1450 struct ata_pass_16 *ata_pass_16;
1451 struct ata_cmd ata_cmd;
1453 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1454 ata_cmd.command = ata_pass_16->command;
1455 ata_cmd.control = ata_pass_16->control;
1456 ata_cmd.features = ata_pass_16->features;
1458 if (arglist & CAM_ARG_VERBOSE) {
1459 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1460 ata_op_string(&ata_cmd),
1461 ccb->csio.ccb_h.timeout);
1464 /* Disable freezing the device queue */
1465 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1467 if (arglist & CAM_ARG_ERR_RECOVER)
1468 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1470 if (cam_send_ccb(device, ccb) < 0) {
1471 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1472 warn("error sending ATA %s via pass_16",
1473 ata_op_string(&ata_cmd));
1476 if (arglist & CAM_ARG_VERBOSE) {
1477 cam_error_print(device, ccb, CAM_ESF_ALL,
1478 CAM_EPF_ALL, stderr);
1484 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1485 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1486 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1487 warnx("ATA %s via pass_16 failed",
1488 ata_op_string(&ata_cmd));
1490 if (arglist & CAM_ARG_VERBOSE) {
1491 cam_error_print(device, ccb, CAM_ESF_ALL,
1492 CAM_EPF_ALL, stderr);
1503 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1505 if (arglist & CAM_ARG_VERBOSE) {
1506 warnx("sending ATA %s with timeout of %u msecs",
1507 ata_op_string(&(ccb->ataio.cmd)),
1508 ccb->ataio.ccb_h.timeout);
1511 /* Disable freezing the device queue */
1512 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1514 if (arglist & CAM_ARG_ERR_RECOVER)
1515 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1517 if (cam_send_ccb(device, ccb) < 0) {
1518 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1519 warn("error sending ATA %s",
1520 ata_op_string(&(ccb->ataio.cmd)));
1523 if (arglist & CAM_ARG_VERBOSE) {
1524 cam_error_print(device, ccb, CAM_ESF_ALL,
1525 CAM_EPF_ALL, stderr);
1531 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1532 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1533 warnx("ATA %s failed: %d",
1534 ata_op_string(&(ccb->ataio.cmd)), quiet);
1537 if (arglist & CAM_ARG_VERBOSE) {
1538 cam_error_print(device, ccb, CAM_ESF_ALL,
1539 CAM_EPF_ALL, stderr);
1549 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1550 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1551 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1552 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1553 u_int16_t dxfer_len, int timeout, int quiet)
1555 if (data_ptr != NULL) {
1556 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1557 AP_FLAG_TLEN_SECT_CNT;
1558 if (flags & CAM_DIR_OUT)
1559 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1561 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1563 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1566 bzero(&(&ccb->ccb_h)[1],
1567 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1569 scsi_ata_pass_16(&ccb->csio,
1583 /*sense_len*/SSD_FULL_SIZE,
1586 return scsi_cam_pass_16_send(device, ccb, quiet);
1590 ata_try_pass_16(struct cam_device *device)
1592 struct ccb_pathinq cpi;
1594 if (get_cpi(device, &cpi) != 0) {
1595 warnx("couldn't get CPI");
1599 if (cpi.protocol == PROTO_SCSI) {
1600 /* possibly compatible with pass_16 */
1604 /* likely not compatible with pass_16 */
1609 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1610 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1611 u_int8_t command, u_int8_t features, u_int32_t lba,
1612 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1613 int timeout, int quiet)
1617 switch (ata_try_pass_16(device)) {
1621 /* Try using SCSI Passthrough */
1622 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1623 0, tag_action, command, features, lba,
1624 sector_count, data_ptr, dxfer_len,
1628 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1629 sizeof(struct ccb_hdr));
1630 cam_fill_ataio(&ccb->ataio,
1639 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1640 return ata_cam_send(device, ccb, quiet);
1644 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1645 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1646 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1647 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1648 u_int16_t dxfer_len, int timeout, int force48bit)
1652 retval = ata_try_pass_16(device);
1659 /* Try using SCSI Passthrough */
1660 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1661 ata_flags, tag_action, command, features,
1662 lba, sector_count, data_ptr, dxfer_len,
1665 if (ata_flags & AP_FLAG_CHK_COND) {
1666 /* Decode ata_res from sense data */
1667 struct ata_res_pass16 *res_pass16;
1668 struct ata_res *res;
1672 /* sense_data is 4 byte aligned */
1673 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1674 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1675 ptr[i] = le16toh(ptr[i]);
1677 /* sense_data is 4 byte aligned */
1678 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1679 &ccb->csio.sense_data;
1680 res = &ccb->ataio.res;
1681 res->flags = res_pass16->flags;
1682 res->status = res_pass16->status;
1683 res->error = res_pass16->error;
1684 res->lba_low = res_pass16->lba_low;
1685 res->lba_mid = res_pass16->lba_mid;
1686 res->lba_high = res_pass16->lba_high;
1687 res->device = res_pass16->device;
1688 res->lba_low_exp = res_pass16->lba_low_exp;
1689 res->lba_mid_exp = res_pass16->lba_mid_exp;
1690 res->lba_high_exp = res_pass16->lba_high_exp;
1691 res->sector_count = res_pass16->sector_count;
1692 res->sector_count_exp = res_pass16->sector_count_exp;
1698 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1699 sizeof(struct ccb_hdr));
1700 cam_fill_ataio(&ccb->ataio,
1709 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1710 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1712 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1714 if (ata_flags & AP_FLAG_CHK_COND)
1715 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1717 return ata_cam_send(device, ccb, 0);
1721 dump_data(uint16_t *ptr, uint32_t len)
1725 for (i = 0; i < len / 2; i++) {
1727 printf(" %3d: ", i);
1728 printf("%04hx ", ptr[i]);
1737 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1738 int is48bit, u_int64_t *hpasize)
1740 struct ata_res *res;
1742 res = &ccb->ataio.res;
1743 if (res->status & ATA_STATUS_ERROR) {
1744 if (arglist & CAM_ARG_VERBOSE) {
1745 cam_error_print(device, ccb, CAM_ESF_ALL,
1746 CAM_EPF_ALL, stderr);
1747 printf("error = 0x%02x, sector_count = 0x%04x, "
1748 "device = 0x%02x, status = 0x%02x\n",
1749 res->error, res->sector_count,
1750 res->device, res->status);
1753 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1754 warnx("Max address has already been set since "
1755 "last power-on or hardware reset");
1761 if (arglist & CAM_ARG_VERBOSE) {
1762 fprintf(stdout, "%s%d: Raw native max data:\n",
1763 device->device_name, device->dev_unit_num);
1764 /* res is 4 byte aligned */
1765 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1767 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1768 "status = 0x%02x\n", res->error, res->sector_count,
1769 res->device, res->status);
1772 if (hpasize != NULL) {
1774 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1775 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1776 ((res->lba_high << 16) | (res->lba_mid << 8) |
1779 *hpasize = (((res->device & 0x0f) << 24) |
1780 (res->lba_high << 16) | (res->lba_mid << 8) |
1789 ata_read_native_max(struct cam_device *device, int retry_count,
1790 u_int32_t timeout, union ccb *ccb,
1791 struct ata_params *parm, u_int64_t *hpasize)
1797 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1798 protocol = AP_PROTO_NON_DATA;
1801 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1802 protocol |= AP_EXTEND;
1804 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1807 error = ata_do_cmd(device,
1810 /*flags*/CAM_DIR_NONE,
1811 /*protocol*/protocol,
1812 /*ata_flags*/AP_FLAG_CHK_COND,
1813 /*tag_action*/MSG_SIMPLE_Q_TAG,
1820 timeout ? timeout : 1000,
1826 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1830 atahpa_set_max(struct cam_device *device, int retry_count,
1831 u_int32_t timeout, union ccb *ccb,
1832 int is48bit, u_int64_t maxsize, int persist)
1838 protocol = AP_PROTO_NON_DATA;
1841 cmd = ATA_SET_MAX_ADDRESS48;
1842 protocol |= AP_EXTEND;
1844 cmd = ATA_SET_MAX_ADDRESS;
1847 /* lba's are zero indexed so the max lba is requested max - 1 */
1851 error = ata_do_cmd(device,
1854 /*flags*/CAM_DIR_NONE,
1855 /*protocol*/protocol,
1856 /*ata_flags*/AP_FLAG_CHK_COND,
1857 /*tag_action*/MSG_SIMPLE_Q_TAG,
1859 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1861 /*sector_count*/persist,
1864 timeout ? timeout : 1000,
1870 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1874 atahpa_password(struct cam_device *device, int retry_count,
1875 u_int32_t timeout, union ccb *ccb,
1876 int is48bit, struct ata_set_max_pwd *pwd)
1882 protocol = AP_PROTO_PIO_OUT;
1883 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1885 error = ata_do_cmd(device,
1888 /*flags*/CAM_DIR_OUT,
1889 /*protocol*/protocol,
1890 /*ata_flags*/AP_FLAG_CHK_COND,
1891 /*tag_action*/MSG_SIMPLE_Q_TAG,
1893 /*features*/ATA_HPA_FEAT_SET_PWD,
1896 /*data_ptr*/(u_int8_t*)pwd,
1897 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1898 timeout ? timeout : 1000,
1904 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1908 atahpa_lock(struct cam_device *device, int retry_count,
1909 u_int32_t timeout, union ccb *ccb, int is48bit)
1915 protocol = AP_PROTO_NON_DATA;
1916 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1918 error = ata_do_cmd(device,
1921 /*flags*/CAM_DIR_NONE,
1922 /*protocol*/protocol,
1923 /*ata_flags*/AP_FLAG_CHK_COND,
1924 /*tag_action*/MSG_SIMPLE_Q_TAG,
1926 /*features*/ATA_HPA_FEAT_LOCK,
1931 timeout ? timeout : 1000,
1937 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1941 atahpa_unlock(struct cam_device *device, int retry_count,
1942 u_int32_t timeout, union ccb *ccb,
1943 int is48bit, struct ata_set_max_pwd *pwd)
1949 protocol = AP_PROTO_PIO_OUT;
1950 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1952 error = ata_do_cmd(device,
1955 /*flags*/CAM_DIR_OUT,
1956 /*protocol*/protocol,
1957 /*ata_flags*/AP_FLAG_CHK_COND,
1958 /*tag_action*/MSG_SIMPLE_Q_TAG,
1960 /*features*/ATA_HPA_FEAT_UNLOCK,
1963 /*data_ptr*/(u_int8_t*)pwd,
1964 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1965 timeout ? timeout : 1000,
1971 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1975 atahpa_freeze_lock(struct cam_device *device, int retry_count,
1976 u_int32_t timeout, union ccb *ccb, int is48bit)
1982 protocol = AP_PROTO_NON_DATA;
1983 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1985 error = ata_do_cmd(device,
1988 /*flags*/CAM_DIR_NONE,
1989 /*protocol*/protocol,
1990 /*ata_flags*/AP_FLAG_CHK_COND,
1991 /*tag_action*/MSG_SIMPLE_Q_TAG,
1993 /*features*/ATA_HPA_FEAT_FREEZE,
1998 timeout ? timeout : 1000,
2004 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2009 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2010 union ccb *ccb, struct ata_params** ident_bufp)
2012 struct ata_params *ident_buf;
2013 struct ccb_pathinq cpi;
2014 struct ccb_getdev cgd;
2017 u_int8_t command, retry_command;
2019 if (get_cpi(device, &cpi) != 0) {
2020 warnx("couldn't get CPI");
2024 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2025 if (cpi.protocol == PROTO_ATA) {
2026 if (get_cgd(device, &cgd) != 0) {
2027 warnx("couldn't get CGD");
2031 command = (cgd.protocol == PROTO_ATA) ?
2032 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2035 /* We don't know which for sure so try both */
2036 command = ATA_ATA_IDENTIFY;
2037 retry_command = ATA_ATAPI_IDENTIFY;
2040 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2042 warnx("can't calloc memory for identify\n");
2046 error = ata_do_28bit_cmd(device,
2048 /*retries*/retry_count,
2049 /*flags*/CAM_DIR_IN,
2050 /*protocol*/AP_PROTO_PIO_IN,
2051 /*tag_action*/MSG_SIMPLE_Q_TAG,
2055 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2056 /*data_ptr*/(u_int8_t *)ptr,
2057 /*dxfer_len*/sizeof(struct ata_params),
2058 /*timeout*/timeout ? timeout : 30 * 1000,
2062 if (retry_command == 0) {
2066 error = ata_do_28bit_cmd(device,
2068 /*retries*/retry_count,
2069 /*flags*/CAM_DIR_IN,
2070 /*protocol*/AP_PROTO_PIO_IN,
2071 /*tag_action*/MSG_SIMPLE_Q_TAG,
2072 /*command*/retry_command,
2075 /*sector_count*/(u_int8_t)
2076 sizeof(struct ata_params),
2077 /*data_ptr*/(u_int8_t *)ptr,
2078 /*dxfer_len*/sizeof(struct ata_params),
2079 /*timeout*/timeout ? timeout : 30 * 1000,
2089 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2090 ptr[i] = le16toh(ptr[i]);
2095 if (arglist & CAM_ARG_VERBOSE) {
2096 fprintf(stdout, "%s%d: Raw identify data:\n",
2097 device->device_name, device->dev_unit_num);
2098 dump_data(ptr, sizeof(struct ata_params));
2101 /* check for invalid (all zero) response */
2103 warnx("Invalid identify response detected");
2108 ident_buf = (struct ata_params *)ptr;
2109 if (strncmp(ident_buf->model, "FX", 2) &&
2110 strncmp(ident_buf->model, "NEC", 3) &&
2111 strncmp(ident_buf->model, "Pioneer", 7) &&
2112 strncmp(ident_buf->model, "SHARP", 5)) {
2113 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2114 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2115 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2116 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2118 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2119 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2120 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2121 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2122 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2123 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2124 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2125 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2126 sizeof(ident_buf->media_serial));
2128 *ident_bufp = ident_buf;
2135 ataidentify(struct cam_device *device, int retry_count, int timeout)
2138 struct ata_params *ident_buf;
2141 if ((ccb = cam_getccb(device)) == NULL) {
2142 warnx("couldn't allocate CCB");
2146 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2151 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2152 if (ata_read_native_max(device, retry_count, timeout, ccb,
2153 ident_buf, &hpasize) != 0) {
2161 printf("%s%d: ", device->device_name, device->dev_unit_num);
2162 ata_print_ident(ident_buf);
2163 camxferrate(device);
2164 atacapprint(ident_buf);
2165 atahpa_print(ident_buf, hpasize, 0);
2172 #endif /* MINIMALISTIC */
2175 #ifndef MINIMALISTIC
2177 ATA_SECURITY_ACTION_PRINT,
2178 ATA_SECURITY_ACTION_FREEZE,
2179 ATA_SECURITY_ACTION_UNLOCK,
2180 ATA_SECURITY_ACTION_DISABLE,
2181 ATA_SECURITY_ACTION_ERASE,
2182 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2183 ATA_SECURITY_ACTION_SET_PASSWORD
2187 atasecurity_print_time(u_int16_t tw)
2191 printf("unspecified");
2193 printf("> 508 min");
2195 printf("%i min", 2 * tw);
2199 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2203 return 2 * 3600 * 1000; /* default: two hours */
2204 else if (timeout > 255)
2205 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2207 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2212 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2216 bzero(&cmd, sizeof(cmd));
2217 cmd.command = command;
2218 printf("Issuing %s", ata_op_string(&cmd));
2221 char pass[sizeof(pwd->password)+1];
2223 /* pwd->password may not be null terminated */
2224 pass[sizeof(pwd->password)] = '\0';
2225 strncpy(pass, pwd->password, sizeof(pwd->password));
2226 printf(" password='%s', user='%s'",
2228 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2231 if (command == ATA_SECURITY_SET_PASSWORD) {
2232 printf(", mode='%s'",
2233 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2234 "maximum" : "high");
2242 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2243 int retry_count, u_int32_t timeout, int quiet)
2247 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2249 return ata_do_28bit_cmd(device,
2252 /*flags*/CAM_DIR_NONE,
2253 /*protocol*/AP_PROTO_NON_DATA,
2254 /*tag_action*/MSG_SIMPLE_Q_TAG,
2255 /*command*/ATA_SECURITY_FREEZE_LOCK,
2266 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2267 int retry_count, u_int32_t timeout,
2268 struct ata_security_password *pwd, int quiet)
2272 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2274 return ata_do_28bit_cmd(device,
2277 /*flags*/CAM_DIR_OUT,
2278 /*protocol*/AP_PROTO_PIO_OUT,
2279 /*tag_action*/MSG_SIMPLE_Q_TAG,
2280 /*command*/ATA_SECURITY_UNLOCK,
2284 /*data_ptr*/(u_int8_t *)pwd,
2285 /*dxfer_len*/sizeof(*pwd),
2291 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2292 int retry_count, u_int32_t timeout,
2293 struct ata_security_password *pwd, int quiet)
2297 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2298 return ata_do_28bit_cmd(device,
2301 /*flags*/CAM_DIR_OUT,
2302 /*protocol*/AP_PROTO_PIO_OUT,
2303 /*tag_action*/MSG_SIMPLE_Q_TAG,
2304 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2308 /*data_ptr*/(u_int8_t *)pwd,
2309 /*dxfer_len*/sizeof(*pwd),
2316 atasecurity_erase_confirm(struct cam_device *device,
2317 struct ata_params* ident_buf)
2320 printf("\nYou are about to ERASE ALL DATA from the following"
2321 " device:\n%s%d,%s%d: ", device->device_name,
2322 device->dev_unit_num, device->given_dev_name,
2323 device->given_unit_number);
2324 ata_print_ident(ident_buf);
2328 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2330 if (fgets(str, sizeof(str), stdin) != NULL) {
2331 if (strncasecmp(str, "yes", 3) == 0) {
2333 } else if (strncasecmp(str, "no", 2) == 0) {
2336 printf("Please answer \"yes\" or "
2347 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2348 int retry_count, u_int32_t timeout,
2349 u_int32_t erase_timeout,
2350 struct ata_security_password *pwd, int quiet)
2355 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2357 error = ata_do_28bit_cmd(device,
2360 /*flags*/CAM_DIR_NONE,
2361 /*protocol*/AP_PROTO_NON_DATA,
2362 /*tag_action*/MSG_SIMPLE_Q_TAG,
2363 /*command*/ATA_SECURITY_ERASE_PREPARE,
2376 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2378 error = ata_do_28bit_cmd(device,
2381 /*flags*/CAM_DIR_OUT,
2382 /*protocol*/AP_PROTO_PIO_OUT,
2383 /*tag_action*/MSG_SIMPLE_Q_TAG,
2384 /*command*/ATA_SECURITY_ERASE_UNIT,
2388 /*data_ptr*/(u_int8_t *)pwd,
2389 /*dxfer_len*/sizeof(*pwd),
2390 /*timeout*/erase_timeout,
2393 if (error == 0 && quiet == 0)
2394 printf("\nErase Complete\n");
2400 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2401 int retry_count, u_int32_t timeout,
2402 struct ata_security_password *pwd, int quiet)
2406 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2408 return ata_do_28bit_cmd(device,
2411 /*flags*/CAM_DIR_OUT,
2412 /*protocol*/AP_PROTO_PIO_OUT,
2413 /*tag_action*/MSG_SIMPLE_Q_TAG,
2414 /*command*/ATA_SECURITY_SET_PASSWORD,
2418 /*data_ptr*/(u_int8_t *)pwd,
2419 /*dxfer_len*/sizeof(*pwd),
2425 atasecurity_print(struct ata_params *parm)
2428 printf("\nSecurity Option Value\n");
2429 if (arglist & CAM_ARG_VERBOSE) {
2430 printf("status %04x\n",
2431 parm->security_status);
2433 printf("supported %s\n",
2434 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2435 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2437 printf("enabled %s\n",
2438 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2439 printf("drive locked %s\n",
2440 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2441 printf("security config frozen %s\n",
2442 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2443 printf("count expired %s\n",
2444 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2445 printf("security level %s\n",
2446 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2447 printf("enhanced erase supported %s\n",
2448 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2449 printf("erase time ");
2450 atasecurity_print_time(parm->erase_time);
2452 printf("enhanced erase time ");
2453 atasecurity_print_time(parm->enhanced_erase_time);
2455 printf("master password rev %04x%s\n",
2456 parm->master_passwd_revision,
2457 parm->master_passwd_revision == 0x0000 ||
2458 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2462 * Validates and copies the password in optarg to the passed buffer.
2463 * If the password in optarg is the same length as the buffer then
2464 * the data will still be copied but no null termination will occur.
2467 ata_getpwd(u_int8_t *passwd, int max, char opt)
2471 len = strlen(optarg);
2473 warnx("-%c password is too long", opt);
2475 } else if (len == 0) {
2476 warnx("-%c password is missing", opt);
2478 } else if (optarg[0] == '-'){
2479 warnx("-%c password starts with '-' (generic arg?)", opt);
2481 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2482 warnx("-%c password conflicts with existing password from -%c",
2487 /* Callers pass in a buffer which does NOT need to be terminated */
2488 strncpy(passwd, optarg, max);
2495 ATA_HPA_ACTION_PRINT,
2496 ATA_HPA_ACTION_SET_MAX,
2497 ATA_HPA_ACTION_SET_PWD,
2498 ATA_HPA_ACTION_LOCK,
2499 ATA_HPA_ACTION_UNLOCK,
2500 ATA_HPA_ACTION_FREEZE_LOCK
2504 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2505 u_int64_t maxsize, int persist)
2507 printf("\nYou are about to configure HPA to limit the user accessible\n"
2508 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2509 persist ? "persistently" : "temporarily",
2510 device->device_name, device->dev_unit_num,
2511 device->given_dev_name, device->given_unit_number);
2512 ata_print_ident(ident_buf);
2516 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2518 if (NULL != fgets(str, sizeof(str), stdin)) {
2519 if (0 == strncasecmp(str, "yes", 3)) {
2521 } else if (0 == strncasecmp(str, "no", 2)) {
2524 printf("Please answer \"yes\" or "
2535 atahpa(struct cam_device *device, int retry_count, int timeout,
2536 int argc, char **argv, char *combinedopt)
2539 struct ata_params *ident_buf;
2540 struct ccb_getdev cgd;
2541 struct ata_set_max_pwd pwd;
2542 int error, confirm, quiet, c, action, actions, setpwd, persist;
2543 int security, is48bit, pwdsize;
2544 u_int64_t hpasize, maxsize;
2554 memset(&pwd, 0, sizeof(pwd));
2556 /* default action is to print hpa information */
2557 action = ATA_HPA_ACTION_PRINT;
2558 pwdsize = sizeof(pwd.password);
2560 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2563 action = ATA_HPA_ACTION_SET_MAX;
2564 maxsize = strtoumax(optarg, NULL, 0);
2569 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2571 action = ATA_HPA_ACTION_SET_PWD;
2577 action = ATA_HPA_ACTION_LOCK;
2583 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2585 action = ATA_HPA_ACTION_UNLOCK;
2591 action = ATA_HPA_ACTION_FREEZE_LOCK;
2611 warnx("too many hpa actions specified");
2615 if (get_cgd(device, &cgd) != 0) {
2616 warnx("couldn't get CGD");
2620 ccb = cam_getccb(device);
2622 warnx("couldn't allocate CCB");
2626 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2633 printf("%s%d: ", device->device_name, device->dev_unit_num);
2634 ata_print_ident(ident_buf);
2635 camxferrate(device);
2638 if (action == ATA_HPA_ACTION_PRINT) {
2639 error = ata_read_native_max(device, retry_count, timeout, ccb,
2640 ident_buf, &hpasize);
2642 atahpa_print(ident_buf, hpasize, 1);
2649 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2650 warnx("HPA is not supported by this device");
2656 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2657 warnx("HPA Security is not supported by this device");
2663 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2666 * The ATA spec requires:
2667 * 1. Read native max addr is called directly before set max addr
2668 * 2. Read native max addr is NOT called before any other set max call
2671 case ATA_HPA_ACTION_SET_MAX:
2673 atahpa_set_confirm(device, ident_buf, maxsize,
2680 error = ata_read_native_max(device, retry_count, timeout,
2681 ccb, ident_buf, &hpasize);
2683 error = atahpa_set_max(device, retry_count, timeout,
2684 ccb, is48bit, maxsize, persist);
2686 /* redo identify to get new lba values */
2687 error = ata_do_identify(device, retry_count,
2690 atahpa_print(ident_buf, hpasize, 1);
2695 case ATA_HPA_ACTION_SET_PWD:
2696 error = atahpa_password(device, retry_count, timeout,
2697 ccb, is48bit, &pwd);
2699 printf("HPA password has been set\n");
2702 case ATA_HPA_ACTION_LOCK:
2703 error = atahpa_lock(device, retry_count, timeout,
2706 printf("HPA has been locked\n");
2709 case ATA_HPA_ACTION_UNLOCK:
2710 error = atahpa_unlock(device, retry_count, timeout,
2711 ccb, is48bit, &pwd);
2713 printf("HPA has been unlocked\n");
2716 case ATA_HPA_ACTION_FREEZE_LOCK:
2717 error = atahpa_freeze_lock(device, retry_count, timeout,
2720 printf("HPA has been frozen\n");
2724 errx(1, "Option currently not supported");
2734 atasecurity(struct cam_device *device, int retry_count, int timeout,
2735 int argc, char **argv, char *combinedopt)
2738 struct ata_params *ident_buf;
2739 int error, confirm, quiet, c, action, actions, setpwd;
2740 int security_enabled, erase_timeout, pwdsize;
2741 struct ata_security_password pwd;
2749 memset(&pwd, 0, sizeof(pwd));
2751 /* default action is to print security information */
2752 action = ATA_SECURITY_ACTION_PRINT;
2754 /* user is master by default as its safer that way */
2755 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2756 pwdsize = sizeof(pwd.password);
2758 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2761 action = ATA_SECURITY_ACTION_FREEZE;
2766 if (strcasecmp(optarg, "user") == 0) {
2767 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2768 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2769 } else if (strcasecmp(optarg, "master") == 0) {
2770 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2771 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2773 warnx("-U argument '%s' is invalid (must be "
2774 "'user' or 'master')", optarg);
2780 if (strcasecmp(optarg, "high") == 0) {
2781 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2782 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2783 } else if (strcasecmp(optarg, "maximum") == 0) {
2784 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2785 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2787 warnx("-l argument '%s' is unknown (must be "
2788 "'high' or 'maximum')", optarg);
2794 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2796 action = ATA_SECURITY_ACTION_UNLOCK;
2801 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2803 action = ATA_SECURITY_ACTION_DISABLE;
2808 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2810 action = ATA_SECURITY_ACTION_ERASE;
2815 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2817 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2818 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2823 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2826 if (action == ATA_SECURITY_ACTION_PRINT)
2827 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2829 * Don't increment action as this can be combined
2830 * with other actions.
2843 erase_timeout = atoi(optarg) * 1000;
2849 warnx("too many security actions specified");
2853 if ((ccb = cam_getccb(device)) == NULL) {
2854 warnx("couldn't allocate CCB");
2858 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2865 printf("%s%d: ", device->device_name, device->dev_unit_num);
2866 ata_print_ident(ident_buf);
2867 camxferrate(device);
2870 if (action == ATA_SECURITY_ACTION_PRINT) {
2871 atasecurity_print(ident_buf);
2877 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2878 warnx("Security not supported");
2884 /* default timeout 15 seconds the same as linux hdparm */
2885 timeout = timeout ? timeout : 15 * 1000;
2887 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2889 /* first set the password if requested */
2891 /* confirm we can erase before setting the password if erasing */
2893 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2894 action == ATA_SECURITY_ACTION_ERASE) &&
2895 atasecurity_erase_confirm(device, ident_buf) == 0) {
2901 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2902 pwd.revision = ident_buf->master_passwd_revision;
2903 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2904 --pwd.revision == 0) {
2905 pwd.revision = 0xfffe;
2908 error = atasecurity_set_password(device, ccb, retry_count,
2909 timeout, &pwd, quiet);
2915 security_enabled = 1;
2919 case ATA_SECURITY_ACTION_FREEZE:
2920 error = atasecurity_freeze(device, ccb, retry_count,
2924 case ATA_SECURITY_ACTION_UNLOCK:
2925 if (security_enabled) {
2926 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2927 error = atasecurity_unlock(device, ccb,
2928 retry_count, timeout, &pwd, quiet);
2930 warnx("Can't unlock, drive is not locked");
2934 warnx("Can't unlock, security is disabled");
2939 case ATA_SECURITY_ACTION_DISABLE:
2940 if (security_enabled) {
2941 /* First unlock the drive if its locked */
2942 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2943 error = atasecurity_unlock(device, ccb,
2951 error = atasecurity_disable(device,
2959 warnx("Can't disable security (already disabled)");
2964 case ATA_SECURITY_ACTION_ERASE:
2965 if (security_enabled) {
2966 if (erase_timeout == 0) {
2967 erase_timeout = atasecurity_erase_timeout_msecs(
2968 ident_buf->erase_time);
2971 error = atasecurity_erase(device, ccb, retry_count,
2972 timeout, erase_timeout, &pwd,
2975 warnx("Can't secure erase (security is disabled)");
2980 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
2981 if (security_enabled) {
2982 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
2983 if (erase_timeout == 0) {
2985 atasecurity_erase_timeout_msecs(
2986 ident_buf->enhanced_erase_time);
2989 error = atasecurity_erase(device, ccb,
2990 retry_count, timeout,
2991 erase_timeout, &pwd,
2994 warnx("Enhanced erase is not supported");
2998 warnx("Can't secure erase (enhanced), "
2999 "(security is disabled)");
3010 #endif /* MINIMALISTIC */
3013 * Parse out a bus, or a bus, target and lun in the following
3019 * Returns the number of parsed components, or 0.
3022 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
3027 while (isspace(*tstr) && (*tstr != '\0'))
3030 tmpstr = (char *)strtok(tstr, ":");
3031 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3032 *bus = strtol(tmpstr, NULL, 0);
3033 *arglst |= CAM_ARG_BUS;
3035 tmpstr = (char *)strtok(NULL, ":");
3036 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3037 *target = strtol(tmpstr, NULL, 0);
3038 *arglst |= CAM_ARG_TARGET;
3040 tmpstr = (char *)strtok(NULL, ":");
3041 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3042 *lun = strtol(tmpstr, NULL, 0);
3043 *arglst |= CAM_ARG_LUN;
3053 dorescan_or_reset(int argc, char **argv, int rescan)
3055 static const char must[] =
3056 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3058 int bus = -1, target = -1, lun = -1;
3062 warnx(must, rescan? "rescan" : "reset");
3066 tstr = argv[optind];
3067 while (isspace(*tstr) && (*tstr != '\0'))
3069 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3070 arglist |= CAM_ARG_BUS;
3072 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3073 if (rv != 1 && rv != 3) {
3074 warnx(must, rescan? "rescan" : "reset");
3079 if ((arglist & CAM_ARG_BUS)
3080 && (arglist & CAM_ARG_TARGET)
3081 && (arglist & CAM_ARG_LUN))
3082 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3084 error = rescan_or_reset_bus(bus, rescan);
3090 rescan_or_reset_bus(int bus, int rescan)
3092 union ccb ccb, matchccb;
3098 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3099 warnx("error opening transport layer device %s", XPT_DEVICE);
3100 warn("%s", XPT_DEVICE);
3105 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3106 ccb.ccb_h.path_id = bus;
3107 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3108 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3109 ccb.crcn.flags = CAM_FLAG_NONE;
3111 /* run this at a low priority */
3112 ccb.ccb_h.pinfo.priority = 5;
3114 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3115 warn("CAMIOCOMMAND ioctl failed");
3120 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3121 fprintf(stdout, "%s of bus %d was successful\n",
3122 rescan ? "Re-scan" : "Reset", bus);
3124 fprintf(stdout, "%s of bus %d returned error %#x\n",
3125 rescan ? "Re-scan" : "Reset", bus,
3126 ccb.ccb_h.status & CAM_STATUS_MASK);
3137 * The right way to handle this is to modify the xpt so that it can
3138 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3139 * that isn't implemented, so instead we enumerate the busses and
3140 * send the rescan or reset to those busses in the case where the
3141 * given bus is -1 (wildcard). We don't send a rescan or reset
3142 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3143 * no-op, sending a rescan to the xpt bus would result in a status of
3146 bzero(&(&matchccb.ccb_h)[1],
3147 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3148 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3149 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3150 bufsize = sizeof(struct dev_match_result) * 20;
3151 matchccb.cdm.match_buf_len = bufsize;
3152 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3153 if (matchccb.cdm.matches == NULL) {
3154 warnx("can't malloc memory for matches");
3158 matchccb.cdm.num_matches = 0;
3160 matchccb.cdm.num_patterns = 1;
3161 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3163 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3164 matchccb.cdm.pattern_buf_len);
3165 if (matchccb.cdm.patterns == NULL) {
3166 warnx("can't malloc memory for patterns");
3170 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3171 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3176 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3177 warn("CAMIOCOMMAND ioctl failed");
3182 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3183 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3184 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3185 warnx("got CAM error %#x, CDM error %d\n",
3186 matchccb.ccb_h.status, matchccb.cdm.status);
3191 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3192 struct bus_match_result *bus_result;
3194 /* This shouldn't happen. */
3195 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3198 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3201 * We don't want to rescan or reset the xpt bus.
3204 if ((int)bus_result->path_id == -1)
3207 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3209 ccb.ccb_h.path_id = bus_result->path_id;
3210 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3211 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3212 ccb.crcn.flags = CAM_FLAG_NONE;
3214 /* run this at a low priority */
3215 ccb.ccb_h.pinfo.priority = 5;
3217 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3218 warn("CAMIOCOMMAND ioctl failed");
3223 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3224 fprintf(stdout, "%s of bus %d was successful\n",
3225 rescan? "Re-scan" : "Reset",
3226 bus_result->path_id);
3229 * Don't bail out just yet, maybe the other
3230 * rescan or reset commands will complete
3233 fprintf(stderr, "%s of bus %d returned error "
3234 "%#x\n", rescan? "Re-scan" : "Reset",
3235 bus_result->path_id,
3236 ccb.ccb_h.status & CAM_STATUS_MASK);
3240 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3241 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3248 if (matchccb.cdm.patterns != NULL)
3249 free(matchccb.cdm.patterns);
3250 if (matchccb.cdm.matches != NULL)
3251 free(matchccb.cdm.matches);
3257 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
3260 struct cam_device *device;
3266 warnx("invalid bus number %d", bus);
3271 warnx("invalid target number %d", target);
3276 warnx("invalid lun number %d", lun);
3282 bzero(&ccb, sizeof(union ccb));
3285 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3286 warnx("error opening transport layer device %s\n",
3288 warn("%s", XPT_DEVICE);
3292 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3293 if (device == NULL) {
3294 warnx("%s", cam_errbuf);
3299 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3300 ccb.ccb_h.path_id = bus;
3301 ccb.ccb_h.target_id = target;
3302 ccb.ccb_h.target_lun = lun;
3303 ccb.ccb_h.timeout = 5000;
3304 ccb.crcn.flags = CAM_FLAG_NONE;
3306 /* run this at a low priority */
3307 ccb.ccb_h.pinfo.priority = 5;
3310 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3311 warn("CAMIOCOMMAND ioctl failed");
3316 if (cam_send_ccb(device, &ccb) < 0) {
3317 warn("error sending XPT_RESET_DEV CCB");
3318 cam_close_device(device);
3326 cam_close_device(device);
3329 * An error code of CAM_BDR_SENT is normal for a BDR request.
3331 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3333 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3334 fprintf(stdout, "%s of %d:%d:%d was successful\n",
3335 scan? "Re-scan" : "Reset", bus, target, lun);
3338 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
3339 scan? "Re-scan" : "Reset", bus, target, lun,
3340 ccb.ccb_h.status & CAM_STATUS_MASK);
3345 #ifndef MINIMALISTIC
3347 readdefects(struct cam_device *device, int argc, char **argv,
3348 char *combinedopt, int retry_count, int timeout)
3350 union ccb *ccb = NULL;
3351 struct scsi_read_defect_data_10 *rdd_cdb;
3352 u_int8_t *defect_list = NULL;
3353 u_int32_t max_dlist_length = SRDD10_MAX_LENGTH, dlist_length = 0;
3354 u_int32_t returned_length = 0;
3355 u_int32_t num_returned = 0;
3356 u_int8_t returned_format;
3359 int lists_specified;
3362 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3368 while (isspace(*tstr) && (*tstr != '\0'))
3370 if (strcmp(tstr, "block") == 0)
3371 arglist |= CAM_ARG_FORMAT_BLOCK;
3372 else if (strcmp(tstr, "bfi") == 0)
3373 arglist |= CAM_ARG_FORMAT_BFI;
3374 else if (strcmp(tstr, "phys") == 0)
3375 arglist |= CAM_ARG_FORMAT_PHYS;
3378 warnx("invalid defect format %s", tstr);
3379 goto defect_bailout;
3384 arglist |= CAM_ARG_GLIST;
3387 arglist |= CAM_ARG_PLIST;
3394 ccb = cam_getccb(device);
3397 * Eventually we should probably support the 12 byte READ DEFECT
3398 * DATA command. It supports a longer parameter list, which may be
3399 * necessary on newer drives with lots of defects. According to
3400 * the SBC-3 spec, drives are supposed to return an illegal request
3401 * if they have more defect data than will fit in 64K.
3403 defect_list = malloc(max_dlist_length);
3404 if (defect_list == NULL) {
3405 warnx("can't malloc memory for defect list");
3407 goto defect_bailout;
3411 * We start off asking for just the header to determine how much
3412 * defect data is available. Some Hitachi drives return an error
3413 * if you ask for more data than the drive has. Once we know the
3414 * length, we retry the command with the returned length.
3416 dlist_length = sizeof(struct scsi_read_defect_data_hdr_10);
3418 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
3422 lists_specified = 0;
3425 * cam_getccb() zeros the CCB header only. So we need to zero the
3426 * payload portion of the ccb.
3428 bzero(&(&ccb->ccb_h)[1],
3429 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3431 cam_fill_csio(&ccb->csio,
3432 /*retries*/ retry_count,
3434 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
3435 CAM_PASS_ERR_RECOVER : 0),
3436 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3437 /*data_ptr*/ defect_list,
3438 /*dxfer_len*/ dlist_length,
3439 /*sense_len*/ SSD_FULL_SIZE,
3440 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
3441 /*timeout*/ timeout ? timeout : 5000);
3443 rdd_cdb->opcode = READ_DEFECT_DATA_10;
3444 if (arglist & CAM_ARG_FORMAT_BLOCK)
3445 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
3446 else if (arglist & CAM_ARG_FORMAT_BFI)
3447 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
3448 else if (arglist & CAM_ARG_FORMAT_PHYS)
3449 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
3452 warnx("no defect list format specified");
3453 goto defect_bailout;
3455 if (arglist & CAM_ARG_PLIST) {
3456 rdd_cdb->format |= SRDD10_PLIST;
3460 if (arglist & CAM_ARG_GLIST) {
3461 rdd_cdb->format |= SRDD10_GLIST;
3465 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
3467 /* Disable freezing the device queue */
3468 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3470 if (cam_send_ccb(device, ccb) < 0) {
3471 perror("error reading defect list");
3473 if (arglist & CAM_ARG_VERBOSE) {
3474 cam_error_print(device, ccb, CAM_ESF_ALL,
3475 CAM_EPF_ALL, stderr);
3479 goto defect_bailout;
3482 returned_length = scsi_2btoul(((struct
3483 scsi_read_defect_data_hdr_10 *)defect_list)->length);
3485 if (get_length != 0) {
3488 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3489 CAM_SCSI_STATUS_ERROR) {
3490 struct scsi_sense_data *sense;
3491 int error_code, sense_key, asc, ascq;
3493 sense = &ccb->csio.sense_data;
3494 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3495 ccb->csio.sense_resid, &error_code, &sense_key,
3496 &asc, &ascq, /*show_errors*/ 1);
3499 * If the drive is reporting that it just doesn't
3500 * support the defect list format, go ahead and use
3501 * the length it reported. Otherwise, the length
3502 * may not be valid, so use the maximum.
3504 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3505 && (asc == 0x1c) && (ascq == 0x00)
3506 && (returned_length > 0)) {
3507 dlist_length = returned_length +
3508 sizeof(struct scsi_read_defect_data_hdr_10);
3509 dlist_length = min(dlist_length,
3512 dlist_length = max_dlist_length;
3513 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3516 warnx("Error reading defect header");
3517 if (arglist & CAM_ARG_VERBOSE)
3518 cam_error_print(device, ccb, CAM_ESF_ALL,
3519 CAM_EPF_ALL, stderr);
3520 goto defect_bailout;
3522 dlist_length = returned_length +
3523 sizeof(struct scsi_read_defect_data_hdr_10);
3524 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3530 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
3531 defect_list)->format;
3533 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3534 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3535 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3536 struct scsi_sense_data *sense;
3537 int error_code, sense_key, asc, ascq;
3539 sense = &ccb->csio.sense_data;
3540 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3541 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3542 &ascq, /*show_errors*/ 1);
3545 * According to the SCSI spec, if the disk doesn't support
3546 * the requested format, it will generally return a sense
3547 * key of RECOVERED ERROR, and an additional sense code
3548 * of "DEFECT LIST NOT FOUND". So, we check for that, and
3549 * also check to make sure that the returned length is
3550 * greater than 0, and then print out whatever format the
3553 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3554 && (asc == 0x1c) && (ascq == 0x00)
3555 && (returned_length > 0)) {
3556 warnx("requested defect format not available");
3557 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
3558 case SRDD10_BLOCK_FORMAT:
3559 warnx("Device returned block format");
3561 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3562 warnx("Device returned bytes from index"
3565 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3566 warnx("Device returned physical sector format");
3570 warnx("Device returned unknown defect"
3571 " data format %#x", returned_format);
3572 goto defect_bailout;
3573 break; /* NOTREACHED */
3577 warnx("Error returned from read defect data command");
3578 if (arglist & CAM_ARG_VERBOSE)
3579 cam_error_print(device, ccb, CAM_ESF_ALL,
3580 CAM_EPF_ALL, stderr);
3581 goto defect_bailout;
3583 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3585 warnx("Error returned from read defect data command");
3586 if (arglist & CAM_ARG_VERBOSE)
3587 cam_error_print(device, ccb, CAM_ESF_ALL,
3588 CAM_EPF_ALL, stderr);
3589 goto defect_bailout;
3593 * XXX KDM I should probably clean up the printout format for the
3596 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
3597 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
3599 struct scsi_defect_desc_phys_sector *dlist;
3601 dlist = (struct scsi_defect_desc_phys_sector *)
3603 sizeof(struct scsi_read_defect_data_hdr_10));
3605 num_returned = returned_length /
3606 sizeof(struct scsi_defect_desc_phys_sector);
3608 fprintf(stderr, "Got %d defect", num_returned);
3610 if ((lists_specified == 0) || (num_returned == 0)) {
3611 fprintf(stderr, "s.\n");
3613 } else if (num_returned == 1)
3614 fprintf(stderr, ":\n");
3616 fprintf(stderr, "s:\n");
3618 for (i = 0; i < num_returned; i++) {
3619 fprintf(stdout, "%d:%d:%d\n",
3620 scsi_3btoul(dlist[i].cylinder),
3622 scsi_4btoul(dlist[i].sector));
3626 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
3628 struct scsi_defect_desc_bytes_from_index *dlist;
3630 dlist = (struct scsi_defect_desc_bytes_from_index *)
3632 sizeof(struct scsi_read_defect_data_hdr_10));
3634 num_returned = returned_length /
3635 sizeof(struct scsi_defect_desc_bytes_from_index);
3637 fprintf(stderr, "Got %d defect", num_returned);
3639 if ((lists_specified == 0) || (num_returned == 0)) {
3640 fprintf(stderr, "s.\n");
3642 } else if (num_returned == 1)
3643 fprintf(stderr, ":\n");
3645 fprintf(stderr, "s:\n");
3647 for (i = 0; i < num_returned; i++) {
3648 fprintf(stdout, "%d:%d:%d\n",
3649 scsi_3btoul(dlist[i].cylinder),
3651 scsi_4btoul(dlist[i].bytes_from_index));
3655 case SRDDH10_BLOCK_FORMAT:
3657 struct scsi_defect_desc_block *dlist;
3659 dlist = (struct scsi_defect_desc_block *)(defect_list +
3660 sizeof(struct scsi_read_defect_data_hdr_10));
3662 num_returned = returned_length /
3663 sizeof(struct scsi_defect_desc_block);
3665 fprintf(stderr, "Got %d defect", num_returned);
3667 if ((lists_specified == 0) || (num_returned == 0)) {
3668 fprintf(stderr, "s.\n");
3670 } else if (num_returned == 1)
3671 fprintf(stderr, ":\n");
3673 fprintf(stderr, "s:\n");
3675 for (i = 0; i < num_returned; i++)
3676 fprintf(stdout, "%u\n",
3677 scsi_4btoul(dlist[i].address));
3681 fprintf(stderr, "Unknown defect format %d\n",
3682 returned_format & SRDDH10_DLIST_FORMAT_MASK);
3688 if (defect_list != NULL)
3696 #endif /* MINIMALISTIC */
3700 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3704 ccb = cam_getccb(device);
3710 #ifndef MINIMALISTIC
3712 mode_sense(struct cam_device *device, int mode_page, int page_control,
3713 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3718 ccb = cam_getccb(device);
3721 errx(1, "mode_sense: couldn't allocate CCB");
3723 bzero(&(&ccb->ccb_h)[1],
3724 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3726 scsi_mode_sense(&ccb->csio,
3727 /* retries */ retry_count,
3729 /* tag_action */ MSG_SIMPLE_Q_TAG,
3731 /* page_code */ page_control << 6,
3732 /* page */ mode_page,
3733 /* param_buf */ data,
3734 /* param_len */ datalen,
3735 /* sense_len */ SSD_FULL_SIZE,
3736 /* timeout */ timeout ? timeout : 5000);
3738 if (arglist & CAM_ARG_ERR_RECOVER)
3739 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3741 /* Disable freezing the device queue */
3742 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3744 if (((retval = cam_send_ccb(device, ccb)) < 0)
3745 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3746 if (arglist & CAM_ARG_VERBOSE) {
3747 cam_error_print(device, ccb, CAM_ESF_ALL,
3748 CAM_EPF_ALL, stderr);
3751 cam_close_device(device);
3753 err(1, "error sending mode sense command");
3755 errx(1, "error sending mode sense command");
3762 mode_select(struct cam_device *device, int save_pages, int retry_count,
3763 int timeout, u_int8_t *data, int datalen)
3768 ccb = cam_getccb(device);
3771 errx(1, "mode_select: couldn't allocate CCB");
3773 bzero(&(&ccb->ccb_h)[1],
3774 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3776 scsi_mode_select(&ccb->csio,
3777 /* retries */ retry_count,
3779 /* tag_action */ MSG_SIMPLE_Q_TAG,
3780 /* scsi_page_fmt */ 1,
3781 /* save_pages */ save_pages,
3782 /* param_buf */ data,
3783 /* param_len */ datalen,
3784 /* sense_len */ SSD_FULL_SIZE,
3785 /* timeout */ timeout ? timeout : 5000);
3787 if (arglist & CAM_ARG_ERR_RECOVER)
3788 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3790 /* Disable freezing the device queue */
3791 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3793 if (((retval = cam_send_ccb(device, ccb)) < 0)
3794 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3795 if (arglist & CAM_ARG_VERBOSE) {
3796 cam_error_print(device, ccb, CAM_ESF_ALL,
3797 CAM_EPF_ALL, stderr);
3800 cam_close_device(device);
3803 err(1, "error sending mode select command");
3805 errx(1, "error sending mode select command");
3813 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
3814 int retry_count, int timeout)
3816 int c, mode_page = -1, page_control = 0;
3817 int binary = 0, list = 0;
3819 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3825 arglist |= CAM_ARG_DBD;
3828 arglist |= CAM_ARG_MODE_EDIT;
3834 mode_page = strtol(optarg, NULL, 0);
3836 errx(1, "invalid mode page %d", mode_page);
3839 page_control = strtol(optarg, NULL, 0);
3840 if ((page_control < 0) || (page_control > 3))
3841 errx(1, "invalid page control field %d",
3843 arglist |= CAM_ARG_PAGE_CNTL;
3850 if (mode_page == -1 && list == 0)
3851 errx(1, "you must specify a mode page!");
3854 mode_list(device, page_control, arglist & CAM_ARG_DBD,
3855 retry_count, timeout);
3857 mode_edit(device, mode_page, page_control,
3858 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
3859 retry_count, timeout);
3864 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
3865 int retry_count, int timeout)
3868 u_int32_t flags = CAM_DIR_NONE;
3869 u_int8_t *data_ptr = NULL;
3871 u_int8_t atacmd[12];
3872 struct get_hook hook;
3873 int c, data_bytes = 0;
3879 char *datastr = NULL, *tstr, *resstr = NULL;
3881 int fd_data = 0, fd_res = 0;
3884 ccb = cam_getccb(device);
3887 warnx("scsicmd: error allocating ccb");
3891 bzero(&(&ccb->ccb_h)[1],
3892 sizeof(union ccb) - sizeof(struct ccb_hdr));
3894 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3898 while (isspace(*tstr) && (*tstr != '\0'))
3900 hook.argc = argc - optind;
3901 hook.argv = argv + optind;
3903 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
3906 * Increment optind by the number of arguments the
3907 * encoding routine processed. After each call to
3908 * getopt(3), optind points to the argument that
3909 * getopt should process _next_. In this case,
3910 * that means it points to the first command string
3911 * argument, if there is one. Once we increment
3912 * this, it should point to either the next command
3913 * line argument, or it should be past the end of
3920 while (isspace(*tstr) && (*tstr != '\0'))
3922 hook.argc = argc - optind;
3923 hook.argv = argv + optind;
3925 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
3928 * Increment optind by the number of arguments the
3929 * encoding routine processed. After each call to
3930 * getopt(3), optind points to the argument that
3931 * getopt should process _next_. In this case,
3932 * that means it points to the first command string
3933 * argument, if there is one. Once we increment
3934 * this, it should point to either the next command
3935 * line argument, or it should be past the end of
3947 if (arglist & CAM_ARG_CMD_OUT) {
3948 warnx("command must either be "
3949 "read or write, not both");
3951 goto scsicmd_bailout;
3953 arglist |= CAM_ARG_CMD_IN;
3955 data_bytes = strtol(optarg, NULL, 0);
3956 if (data_bytes <= 0) {
3957 warnx("invalid number of input bytes %d",
3960 goto scsicmd_bailout;
3962 hook.argc = argc - optind;
3963 hook.argv = argv + optind;
3966 datastr = cget(&hook, NULL);
3968 * If the user supplied "-" instead of a format, he
3969 * wants the data to be written to stdout.
3971 if ((datastr != NULL)
3972 && (datastr[0] == '-'))
3975 data_ptr = (u_int8_t *)malloc(data_bytes);
3976 if (data_ptr == NULL) {
3977 warnx("can't malloc memory for data_ptr");
3979 goto scsicmd_bailout;
3983 if (arglist & CAM_ARG_CMD_IN) {
3984 warnx("command must either be "
3985 "read or write, not both");
3987 goto scsicmd_bailout;
3989 arglist |= CAM_ARG_CMD_OUT;
3990 flags = CAM_DIR_OUT;
3991 data_bytes = strtol(optarg, NULL, 0);
3992 if (data_bytes <= 0) {
3993 warnx("invalid number of output bytes %d",
3996 goto scsicmd_bailout;
3998 hook.argc = argc - optind;
3999 hook.argv = argv + optind;
4001 datastr = cget(&hook, NULL);
4002 data_ptr = (u_int8_t *)malloc(data_bytes);
4003 if (data_ptr == NULL) {
4004 warnx("can't malloc memory for data_ptr");
4006 goto scsicmd_bailout;
4008 bzero(data_ptr, data_bytes);
4010 * If the user supplied "-" instead of a format, he
4011 * wants the data to be read from stdin.
4013 if ((datastr != NULL)
4014 && (datastr[0] == '-'))
4017 buff_encode_visit(data_ptr, data_bytes, datastr,
4023 hook.argc = argc - optind;
4024 hook.argv = argv + optind;
4026 resstr = cget(&hook, NULL);
4027 if ((resstr != NULL) && (resstr[0] == '-'))
4037 * If fd_data is set, and we're writing to the device, we need to
4038 * read the data the user wants written from stdin.
4040 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4042 int amt_to_read = data_bytes;
4043 u_int8_t *buf_ptr = data_ptr;
4045 for (amt_read = 0; amt_to_read > 0;
4046 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4047 if (amt_read == -1) {
4048 warn("error reading data from stdin");
4050 goto scsicmd_bailout;
4052 amt_to_read -= amt_read;
4053 buf_ptr += amt_read;
4057 if (arglist & CAM_ARG_ERR_RECOVER)
4058 flags |= CAM_PASS_ERR_RECOVER;
4060 /* Disable freezing the device queue */
4061 flags |= CAM_DEV_QFRZDIS;
4065 * This is taken from the SCSI-3 draft spec.
4066 * (T10/1157D revision 0.3)
4067 * The top 3 bits of an opcode are the group code.
4068 * The next 5 bits are the command code.
4069 * Group 0: six byte commands
4070 * Group 1: ten byte commands
4071 * Group 2: ten byte commands
4073 * Group 4: sixteen byte commands
4074 * Group 5: twelve byte commands
4075 * Group 6: vendor specific
4076 * Group 7: vendor specific
4078 switch((cdb[0] >> 5) & 0x7) {
4089 /* computed by buff_encode_visit */
4100 * We should probably use csio_build_visit or something like that
4101 * here, but it's easier to encode arguments as you go. The
4102 * alternative would be skipping the CDB argument and then encoding
4103 * it here, since we've got the data buffer argument by now.
4105 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4107 cam_fill_csio(&ccb->csio,
4108 /*retries*/ retry_count,
4111 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4112 /*data_ptr*/ data_ptr,
4113 /*dxfer_len*/ data_bytes,
4114 /*sense_len*/ SSD_FULL_SIZE,
4115 /*cdb_len*/ cdb_len,
4116 /*timeout*/ timeout ? timeout : 5000);
4119 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4121 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4123 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4125 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4127 cam_fill_ataio(&ccb->ataio,
4128 /*retries*/ retry_count,
4132 /*data_ptr*/ data_ptr,
4133 /*dxfer_len*/ data_bytes,
4134 /*timeout*/ timeout ? timeout : 5000);
4137 if (((retval = cam_send_ccb(device, ccb)) < 0)
4138 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4139 const char warnstr[] = "error sending command";
4146 if (arglist & CAM_ARG_VERBOSE) {
4147 cam_error_print(device, ccb, CAM_ESF_ALL,
4148 CAM_EPF_ALL, stderr);
4152 goto scsicmd_bailout;
4155 if (atacmd_len && need_res) {
4157 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4159 fprintf(stdout, "\n");
4162 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4163 ccb->ataio.res.status,
4164 ccb->ataio.res.error,
4165 ccb->ataio.res.lba_low,
4166 ccb->ataio.res.lba_mid,
4167 ccb->ataio.res.lba_high,
4168 ccb->ataio.res.device,
4169 ccb->ataio.res.lba_low_exp,
4170 ccb->ataio.res.lba_mid_exp,
4171 ccb->ataio.res.lba_high_exp,
4172 ccb->ataio.res.sector_count,
4173 ccb->ataio.res.sector_count_exp);
4178 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4179 && (arglist & CAM_ARG_CMD_IN)
4180 && (data_bytes > 0)) {
4182 buff_decode_visit(data_ptr, data_bytes, datastr,
4184 fprintf(stdout, "\n");
4186 ssize_t amt_written;
4187 int amt_to_write = data_bytes;
4188 u_int8_t *buf_ptr = data_ptr;
4190 for (amt_written = 0; (amt_to_write > 0) &&
4191 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4192 amt_to_write -= amt_written;
4193 buf_ptr += amt_written;
4195 if (amt_written == -1) {
4196 warn("error writing data to stdout");
4198 goto scsicmd_bailout;
4199 } else if ((amt_written == 0)
4200 && (amt_to_write > 0)) {
4201 warnx("only wrote %u bytes out of %u",
4202 data_bytes - amt_to_write, data_bytes);
4209 if ((data_bytes > 0) && (data_ptr != NULL))
4218 camdebug(int argc, char **argv, char *combinedopt)
4221 int bus = -1, target = -1, lun = -1;
4222 char *tstr, *tmpstr = NULL;
4226 bzero(&ccb, sizeof(union ccb));
4228 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4231 arglist |= CAM_ARG_DEBUG_INFO;
4232 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4235 arglist |= CAM_ARG_DEBUG_PERIPH;
4236 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4239 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4240 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4243 arglist |= CAM_ARG_DEBUG_TRACE;
4244 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4247 arglist |= CAM_ARG_DEBUG_XPT;
4248 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4251 arglist |= CAM_ARG_DEBUG_CDB;
4252 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4255 arglist |= CAM_ARG_DEBUG_PROBE;
4256 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4263 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4264 warnx("error opening transport layer device %s", XPT_DEVICE);
4265 warn("%s", XPT_DEVICE);
4272 warnx("you must specify \"off\", \"all\" or a bus,");
4273 warnx("bus:target, or bus:target:lun");
4280 while (isspace(*tstr) && (*tstr != '\0'))
4283 if (strncmp(tstr, "off", 3) == 0) {
4284 ccb.cdbg.flags = CAM_DEBUG_NONE;
4285 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4286 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4287 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4288 } else if (strncmp(tstr, "all", 3) != 0) {
4289 tmpstr = (char *)strtok(tstr, ":");
4290 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4291 bus = strtol(tmpstr, NULL, 0);
4292 arglist |= CAM_ARG_BUS;
4293 tmpstr = (char *)strtok(NULL, ":");
4294 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4295 target = strtol(tmpstr, NULL, 0);
4296 arglist |= CAM_ARG_TARGET;
4297 tmpstr = (char *)strtok(NULL, ":");
4298 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4299 lun = strtol(tmpstr, NULL, 0);
4300 arglist |= CAM_ARG_LUN;
4305 warnx("you must specify \"all\", \"off\", or a bus,");
4306 warnx("bus:target, or bus:target:lun to debug");
4312 ccb.ccb_h.func_code = XPT_DEBUG;
4313 ccb.ccb_h.path_id = bus;
4314 ccb.ccb_h.target_id = target;
4315 ccb.ccb_h.target_lun = lun;
4317 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4318 warn("CAMIOCOMMAND ioctl failed");
4323 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4324 CAM_FUNC_NOTAVAIL) {
4325 warnx("CAM debugging not available");
4326 warnx("you need to put options CAMDEBUG in"
4327 " your kernel config file!");
4329 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4331 warnx("XPT_DEBUG CCB failed with status %#x",
4335 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4337 "Debugging turned off\n");
4340 "Debugging enabled for "
4353 tagcontrol(struct cam_device *device, int argc, char **argv,
4363 ccb = cam_getccb(device);
4366 warnx("tagcontrol: error allocating ccb");
4370 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4373 numtags = strtol(optarg, NULL, 0);
4375 warnx("tag count %d is < 0", numtags);
4377 goto tagcontrol_bailout;
4388 cam_path_string(device, pathstr, sizeof(pathstr));
4391 bzero(&(&ccb->ccb_h)[1],
4392 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4393 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4394 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4395 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4396 ccb->crs.openings = numtags;
4399 if (cam_send_ccb(device, ccb) < 0) {
4400 perror("error sending XPT_REL_SIMQ CCB");
4402 goto tagcontrol_bailout;
4405 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4406 warnx("XPT_REL_SIMQ CCB failed");
4407 cam_error_print(device, ccb, CAM_ESF_ALL,
4408 CAM_EPF_ALL, stderr);
4410 goto tagcontrol_bailout;
4415 fprintf(stdout, "%stagged openings now %d\n",
4416 pathstr, ccb->crs.openings);
4419 bzero(&(&ccb->ccb_h)[1],
4420 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4422 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4424 if (cam_send_ccb(device, ccb) < 0) {
4425 perror("error sending XPT_GDEV_STATS CCB");
4427 goto tagcontrol_bailout;
4430 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4431 warnx("XPT_GDEV_STATS CCB failed");
4432 cam_error_print(device, ccb, CAM_ESF_ALL,
4433 CAM_EPF_ALL, stderr);
4435 goto tagcontrol_bailout;
4438 if (arglist & CAM_ARG_VERBOSE) {
4439 fprintf(stdout, "%s", pathstr);
4440 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4441 fprintf(stdout, "%s", pathstr);
4442 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4443 fprintf(stdout, "%s", pathstr);
4444 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
4445 fprintf(stdout, "%s", pathstr);
4446 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
4447 fprintf(stdout, "%s", pathstr);
4448 fprintf(stdout, "held %d\n", ccb->cgds.held);
4449 fprintf(stdout, "%s", pathstr);
4450 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4451 fprintf(stdout, "%s", pathstr);
4452 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4455 fprintf(stdout, "%s", pathstr);
4456 fprintf(stdout, "device openings: ");
4458 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4459 ccb->cgds.dev_active);
4469 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4473 cam_path_string(device, pathstr, sizeof(pathstr));
4475 if (cts->transport == XPORT_SPI) {
4476 struct ccb_trans_settings_spi *spi =
4477 &cts->xport_specific.spi;
4479 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4481 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4484 if (spi->sync_offset != 0) {
4487 freq = scsi_calc_syncsrate(spi->sync_period);
4488 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4489 pathstr, freq / 1000, freq % 1000);
4493 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4494 fprintf(stdout, "%soffset: %d\n", pathstr,
4498 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4499 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4500 (0x01 << spi->bus_width) * 8);
4503 if (spi->valid & CTS_SPI_VALID_DISC) {
4504 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4505 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4506 "enabled" : "disabled");
4509 if (cts->transport == XPORT_FC) {
4510 struct ccb_trans_settings_fc *fc =
4511 &cts->xport_specific.fc;
4513 if (fc->valid & CTS_FC_VALID_WWNN)
4514 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4515 (long long) fc->wwnn);
4516 if (fc->valid & CTS_FC_VALID_WWPN)
4517 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4518 (long long) fc->wwpn);
4519 if (fc->valid & CTS_FC_VALID_PORT)
4520 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4521 if (fc->valid & CTS_FC_VALID_SPEED)
4522 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4523 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4525 if (cts->transport == XPORT_SAS) {
4526 struct ccb_trans_settings_sas *sas =
4527 &cts->xport_specific.sas;
4529 if (sas->valid & CTS_SAS_VALID_SPEED)
4530 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4531 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4533 if (cts->transport == XPORT_ATA) {
4534 struct ccb_trans_settings_pata *pata =
4535 &cts->xport_specific.ata;
4537 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4538 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4539 ata_mode2string(pata->mode));
4541 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4542 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4545 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4546 fprintf(stdout, "%sPIO transaction length: %d\n",
4547 pathstr, pata->bytecount);
4550 if (cts->transport == XPORT_SATA) {
4551 struct ccb_trans_settings_sata *sata =
4552 &cts->xport_specific.sata;
4554 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4555 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4558 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4559 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4560 ata_mode2string(sata->mode));
4562 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4563 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4566 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4567 fprintf(stdout, "%sPIO transaction length: %d\n",
4568 pathstr, sata->bytecount);
4570 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4571 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4574 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4575 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4578 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4579 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4583 if (cts->protocol == PROTO_ATA) {
4584 struct ccb_trans_settings_ata *ata=
4585 &cts->proto_specific.ata;
4587 if (ata->valid & CTS_ATA_VALID_TQ) {
4588 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4589 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4590 "enabled" : "disabled");
4593 if (cts->protocol == PROTO_SCSI) {
4594 struct ccb_trans_settings_scsi *scsi=
4595 &cts->proto_specific.scsi;
4597 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4598 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4599 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4600 "enabled" : "disabled");
4607 * Get a path inquiry CCB for the specified device.
4610 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4615 ccb = cam_getccb(device);
4617 warnx("get_cpi: couldn't allocate CCB");
4620 bzero(&(&ccb->ccb_h)[1],
4621 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4622 ccb->ccb_h.func_code = XPT_PATH_INQ;
4623 if (cam_send_ccb(device, ccb) < 0) {
4624 warn("get_cpi: error sending Path Inquiry CCB");
4625 if (arglist & CAM_ARG_VERBOSE)
4626 cam_error_print(device, ccb, CAM_ESF_ALL,
4627 CAM_EPF_ALL, stderr);
4629 goto get_cpi_bailout;
4631 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4632 if (arglist & CAM_ARG_VERBOSE)
4633 cam_error_print(device, ccb, CAM_ESF_ALL,
4634 CAM_EPF_ALL, stderr);
4636 goto get_cpi_bailout;
4638 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4646 * Get a get device CCB for the specified device.
4649 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4654 ccb = cam_getccb(device);
4656 warnx("get_cgd: couldn't allocate CCB");
4659 bzero(&(&ccb->ccb_h)[1],
4660 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4661 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4662 if (cam_send_ccb(device, ccb) < 0) {
4663 warn("get_cgd: error sending Path Inquiry CCB");
4664 if (arglist & CAM_ARG_VERBOSE)
4665 cam_error_print(device, ccb, CAM_ESF_ALL,
4666 CAM_EPF_ALL, stderr);
4668 goto get_cgd_bailout;
4670 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4671 if (arglist & CAM_ARG_VERBOSE)
4672 cam_error_print(device, ccb, CAM_ESF_ALL,
4673 CAM_EPF_ALL, stderr);
4675 goto get_cgd_bailout;
4677 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4684 /* return the type of disk (really the command type) */
4686 get_disk_type(struct cam_device *device)
4688 struct ccb_getdev cgd;
4690 (void) memset(&cgd, 0x0, sizeof(cgd));
4691 get_cgd(device, &cgd);
4692 switch(cgd.protocol) {
4705 cpi_print(struct ccb_pathinq *cpi)
4707 char adapter_str[1024];
4710 snprintf(adapter_str, sizeof(adapter_str),
4711 "%s%d:", cpi->dev_name, cpi->unit_number);
4713 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
4716 for (i = 1; i < 0xff; i = i << 1) {
4719 if ((i & cpi->hba_inquiry) == 0)
4722 fprintf(stdout, "%s supports ", adapter_str);
4726 str = "MDP message";
4729 str = "32 bit wide SCSI";
4732 str = "16 bit wide SCSI";
4735 str = "SDTR message";
4738 str = "linked CDBs";
4741 str = "tag queue messages";
4744 str = "soft reset alternative";
4747 str = "SATA Port Multiplier";
4750 str = "unknown PI bit set";
4753 fprintf(stdout, "%s\n", str);
4756 for (i = 1; i < 0xff; i = i << 1) {
4759 if ((i & cpi->hba_misc) == 0)
4762 fprintf(stdout, "%s ", adapter_str);
4766 str = "bus scans from high ID to low ID";
4769 str = "removable devices not included in scan";
4771 case PIM_NOINITIATOR:
4772 str = "initiator role not supported";
4774 case PIM_NOBUSRESET:
4775 str = "user has disabled initial BUS RESET or"
4776 " controller is in target/mixed mode";
4779 str = "do not send 6-byte commands";
4782 str = "scan bus sequentially";
4785 str = "unknown PIM bit set";
4788 fprintf(stdout, "%s\n", str);
4791 for (i = 1; i < 0xff; i = i << 1) {
4794 if ((i & cpi->target_sprt) == 0)
4797 fprintf(stdout, "%s supports ", adapter_str);
4800 str = "target mode processor mode";
4803 str = "target mode phase cog. mode";
4805 case PIT_DISCONNECT:
4806 str = "disconnects in target mode";
4809 str = "terminate I/O message in target mode";
4812 str = "group 6 commands in target mode";
4815 str = "group 7 commands in target mode";
4818 str = "unknown PIT bit set";
4822 fprintf(stdout, "%s\n", str);
4824 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
4826 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
4828 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
4830 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
4831 adapter_str, cpi->hpath_id);
4832 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
4834 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
4835 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
4836 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
4837 adapter_str, cpi->hba_vendor);
4838 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
4839 adapter_str, cpi->hba_device);
4840 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
4841 adapter_str, cpi->hba_subvendor);
4842 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
4843 adapter_str, cpi->hba_subdevice);
4844 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
4845 fprintf(stdout, "%s base transfer speed: ", adapter_str);
4846 if (cpi->base_transfer_speed > 1000)
4847 fprintf(stdout, "%d.%03dMB/sec\n",
4848 cpi->base_transfer_speed / 1000,
4849 cpi->base_transfer_speed % 1000);
4851 fprintf(stdout, "%dKB/sec\n",
4852 (cpi->base_transfer_speed % 1000) * 1000);
4853 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
4854 adapter_str, cpi->maxio);
4858 get_print_cts(struct cam_device *device, int user_settings, int quiet,
4859 struct ccb_trans_settings *cts)
4865 ccb = cam_getccb(device);
4868 warnx("get_print_cts: error allocating ccb");
4872 bzero(&(&ccb->ccb_h)[1],
4873 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4875 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
4877 if (user_settings == 0)
4878 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
4880 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
4882 if (cam_send_ccb(device, ccb) < 0) {
4883 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
4884 if (arglist & CAM_ARG_VERBOSE)
4885 cam_error_print(device, ccb, CAM_ESF_ALL,
4886 CAM_EPF_ALL, stderr);
4888 goto get_print_cts_bailout;
4891 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4892 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
4893 if (arglist & CAM_ARG_VERBOSE)
4894 cam_error_print(device, ccb, CAM_ESF_ALL,
4895 CAM_EPF_ALL, stderr);
4897 goto get_print_cts_bailout;
4901 cts_print(device, &ccb->cts);
4904 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
4906 get_print_cts_bailout:
4914 ratecontrol(struct cam_device *device, int retry_count, int timeout,
4915 int argc, char **argv, char *combinedopt)
4919 int user_settings = 0;
4921 int disc_enable = -1, tag_enable = -1;
4924 double syncrate = -1;
4927 int change_settings = 0, send_tur = 0;
4928 struct ccb_pathinq cpi;
4930 ccb = cam_getccb(device);
4932 warnx("ratecontrol: error allocating ccb");
4935 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4944 if (strncasecmp(optarg, "enable", 6) == 0)
4946 else if (strncasecmp(optarg, "disable", 7) == 0)
4949 warnx("-D argument \"%s\" is unknown", optarg);
4951 goto ratecontrol_bailout;
4953 change_settings = 1;
4956 mode = ata_string2mode(optarg);
4958 warnx("unknown mode '%s'", optarg);
4960 goto ratecontrol_bailout;
4962 change_settings = 1;
4965 offset = strtol(optarg, NULL, 0);
4967 warnx("offset value %d is < 0", offset);
4969 goto ratecontrol_bailout;
4971 change_settings = 1;
4977 syncrate = atof(optarg);
4979 warnx("sync rate %f is < 0", syncrate);
4981 goto ratecontrol_bailout;
4983 change_settings = 1;
4986 if (strncasecmp(optarg, "enable", 6) == 0)
4988 else if (strncasecmp(optarg, "disable", 7) == 0)
4991 warnx("-T argument \"%s\" is unknown", optarg);
4993 goto ratecontrol_bailout;
4995 change_settings = 1;
5001 bus_width = strtol(optarg, NULL, 0);
5002 if (bus_width < 0) {
5003 warnx("bus width %d is < 0", bus_width);
5005 goto ratecontrol_bailout;
5007 change_settings = 1;
5013 bzero(&(&ccb->ccb_h)[1],
5014 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
5016 * Grab path inquiry information, so we can determine whether
5017 * or not the initiator is capable of the things that the user
5020 ccb->ccb_h.func_code = XPT_PATH_INQ;
5021 if (cam_send_ccb(device, ccb) < 0) {
5022 perror("error sending XPT_PATH_INQ CCB");
5023 if (arglist & CAM_ARG_VERBOSE) {
5024 cam_error_print(device, ccb, CAM_ESF_ALL,
5025 CAM_EPF_ALL, stderr);
5028 goto ratecontrol_bailout;
5030 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5031 warnx("XPT_PATH_INQ CCB failed");
5032 if (arglist & CAM_ARG_VERBOSE) {
5033 cam_error_print(device, ccb, CAM_ESF_ALL,
5034 CAM_EPF_ALL, stderr);
5037 goto ratecontrol_bailout;
5039 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5040 bzero(&(&ccb->ccb_h)[1],
5041 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5043 fprintf(stdout, "%s parameters:\n",
5044 user_settings ? "User" : "Current");
5046 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5048 goto ratecontrol_bailout;
5050 if (arglist & CAM_ARG_VERBOSE)
5053 if (change_settings) {
5054 int didsettings = 0;
5055 struct ccb_trans_settings_spi *spi = NULL;
5056 struct ccb_trans_settings_pata *pata = NULL;
5057 struct ccb_trans_settings_sata *sata = NULL;
5058 struct ccb_trans_settings_ata *ata = NULL;
5059 struct ccb_trans_settings_scsi *scsi = NULL;
5061 if (ccb->cts.transport == XPORT_SPI)
5062 spi = &ccb->cts.xport_specific.spi;
5063 if (ccb->cts.transport == XPORT_ATA)
5064 pata = &ccb->cts.xport_specific.ata;
5065 if (ccb->cts.transport == XPORT_SATA)
5066 sata = &ccb->cts.xport_specific.sata;
5067 if (ccb->cts.protocol == PROTO_ATA)
5068 ata = &ccb->cts.proto_specific.ata;
5069 if (ccb->cts.protocol == PROTO_SCSI)
5070 scsi = &ccb->cts.proto_specific.scsi;
5071 ccb->cts.xport_specific.valid = 0;
5072 ccb->cts.proto_specific.valid = 0;
5073 if (spi && disc_enable != -1) {
5074 spi->valid |= CTS_SPI_VALID_DISC;
5075 if (disc_enable == 0)
5076 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5078 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5081 if (tag_enable != -1) {
5082 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5083 warnx("HBA does not support tagged queueing, "
5084 "so you cannot modify tag settings");
5086 goto ratecontrol_bailout;
5089 ata->valid |= CTS_SCSI_VALID_TQ;
5090 if (tag_enable == 0)
5091 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5093 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5096 scsi->valid |= CTS_SCSI_VALID_TQ;
5097 if (tag_enable == 0)
5098 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5100 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5104 if (spi && offset != -1) {
5105 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5106 warnx("HBA is not capable of changing offset");
5108 goto ratecontrol_bailout;
5110 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5111 spi->sync_offset = offset;
5114 if (spi && syncrate != -1) {
5115 int prelim_sync_period;
5117 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5118 warnx("HBA is not capable of changing "
5121 goto ratecontrol_bailout;
5123 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5125 * The sync rate the user gives us is in MHz.
5126 * We need to translate it into KHz for this
5131 * Next, we calculate a "preliminary" sync period
5132 * in tenths of a nanosecond.
5135 prelim_sync_period = 0;
5137 prelim_sync_period = 10000000 / syncrate;
5139 scsi_calc_syncparam(prelim_sync_period);
5142 if (sata && syncrate != -1) {
5143 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5144 warnx("HBA is not capable of changing "
5147 goto ratecontrol_bailout;
5149 if (!user_settings) {
5150 warnx("You can modify only user rate "
5151 "settings for SATA");
5153 goto ratecontrol_bailout;
5155 sata->revision = ata_speed2revision(syncrate * 100);
5156 if (sata->revision < 0) {
5157 warnx("Invalid rate %f", syncrate);
5159 goto ratecontrol_bailout;
5161 sata->valid |= CTS_SATA_VALID_REVISION;
5164 if ((pata || sata) && mode != -1) {
5165 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5166 warnx("HBA is not capable of changing "
5169 goto ratecontrol_bailout;
5171 if (!user_settings) {
5172 warnx("You can modify only user mode "
5173 "settings for ATA/SATA");
5175 goto ratecontrol_bailout;
5179 pata->valid |= CTS_ATA_VALID_MODE;
5182 sata->valid |= CTS_SATA_VALID_MODE;
5187 * The bus_width argument goes like this:
5191 * Therefore, if you shift the number of bits given on the
5192 * command line right by 4, you should get the correct
5195 if (spi && bus_width != -1) {
5197 * We might as well validate things here with a
5198 * decipherable error message, rather than what
5199 * will probably be an indecipherable error message
5200 * by the time it gets back to us.
5202 if ((bus_width == 16)
5203 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5204 warnx("HBA does not support 16 bit bus width");
5206 goto ratecontrol_bailout;
5207 } else if ((bus_width == 32)
5208 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5209 warnx("HBA does not support 32 bit bus width");
5211 goto ratecontrol_bailout;
5212 } else if ((bus_width != 8)
5213 && (bus_width != 16)
5214 && (bus_width != 32)) {
5215 warnx("Invalid bus width %d", bus_width);
5217 goto ratecontrol_bailout;
5219 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5220 spi->bus_width = bus_width >> 4;
5223 if (didsettings == 0) {
5224 goto ratecontrol_bailout;
5226 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5227 if (cam_send_ccb(device, ccb) < 0) {
5228 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5229 if (arglist & CAM_ARG_VERBOSE) {
5230 cam_error_print(device, ccb, CAM_ESF_ALL,
5231 CAM_EPF_ALL, stderr);
5234 goto ratecontrol_bailout;
5236 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5237 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5238 if (arglist & CAM_ARG_VERBOSE) {
5239 cam_error_print(device, ccb, CAM_ESF_ALL,
5240 CAM_EPF_ALL, stderr);
5243 goto ratecontrol_bailout;
5247 retval = testunitready(device, retry_count, timeout,
5248 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5250 * If the TUR didn't succeed, just bail.
5254 fprintf(stderr, "Test Unit Ready failed\n");
5255 goto ratecontrol_bailout;
5258 if ((change_settings || send_tur) && !quiet &&
5259 (ccb->cts.transport == XPORT_ATA ||
5260 ccb->cts.transport == XPORT_SATA || send_tur)) {
5261 fprintf(stdout, "New parameters:\n");
5262 retval = get_print_cts(device, user_settings, 0, NULL);
5265 ratecontrol_bailout:
5271 scsiformat(struct cam_device *device, int argc, char **argv,
5272 char *combinedopt, int retry_count, int timeout)
5276 int ycount = 0, quiet = 0;
5277 int error = 0, retval = 0;
5278 int use_timeout = 10800 * 1000;
5280 struct format_defect_list_header fh;
5281 u_int8_t *data_ptr = NULL;
5282 u_int32_t dxfer_len = 0;
5284 int num_warnings = 0;
5287 ccb = cam_getccb(device);
5290 warnx("scsiformat: error allocating ccb");
5294 bzero(&(&ccb->ccb_h)[1],
5295 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5297 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5318 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5319 "following device:\n");
5321 error = scsidoinquiry(device, argc, argv, combinedopt,
5322 retry_count, timeout);
5325 warnx("scsiformat: error sending inquiry");
5326 goto scsiformat_bailout;
5331 if (!get_confirmation()) {
5333 goto scsiformat_bailout;
5338 use_timeout = timeout;
5341 fprintf(stdout, "Current format timeout is %d seconds\n",
5342 use_timeout / 1000);
5346 * If the user hasn't disabled questions and didn't specify a
5347 * timeout on the command line, ask them if they want the current
5351 && (timeout == 0)) {
5353 int new_timeout = 0;
5355 fprintf(stdout, "Enter new timeout in seconds or press\n"
5356 "return to keep the current timeout [%d] ",
5357 use_timeout / 1000);
5359 if (fgets(str, sizeof(str), stdin) != NULL) {
5361 new_timeout = atoi(str);
5364 if (new_timeout != 0) {
5365 use_timeout = new_timeout * 1000;
5366 fprintf(stdout, "Using new timeout value %d\n",
5367 use_timeout / 1000);
5372 * Keep this outside the if block below to silence any unused
5373 * variable warnings.
5375 bzero(&fh, sizeof(fh));
5378 * If we're in immediate mode, we've got to include the format
5381 if (immediate != 0) {
5382 fh.byte2 = FU_DLH_IMMED;
5383 data_ptr = (u_int8_t *)&fh;
5384 dxfer_len = sizeof(fh);
5385 byte2 = FU_FMT_DATA;
5386 } else if (quiet == 0) {
5387 fprintf(stdout, "Formatting...");
5391 scsi_format_unit(&ccb->csio,
5392 /* retries */ retry_count,
5394 /* tag_action */ MSG_SIMPLE_Q_TAG,
5397 /* data_ptr */ data_ptr,
5398 /* dxfer_len */ dxfer_len,
5399 /* sense_len */ SSD_FULL_SIZE,
5400 /* timeout */ use_timeout);
5402 /* Disable freezing the device queue */
5403 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5405 if (arglist & CAM_ARG_ERR_RECOVER)
5406 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5408 if (((retval = cam_send_ccb(device, ccb)) < 0)
5409 || ((immediate == 0)
5410 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5411 const char errstr[] = "error sending format command";
5418 if (arglist & CAM_ARG_VERBOSE) {
5419 cam_error_print(device, ccb, CAM_ESF_ALL,
5420 CAM_EPF_ALL, stderr);
5423 goto scsiformat_bailout;
5427 * If we ran in non-immediate mode, we already checked for errors
5428 * above and printed out any necessary information. If we're in
5429 * immediate mode, we need to loop through and get status
5430 * information periodically.
5432 if (immediate == 0) {
5434 fprintf(stdout, "Format Complete\n");
5436 goto scsiformat_bailout;
5443 bzero(&(&ccb->ccb_h)[1],
5444 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5447 * There's really no need to do error recovery or
5448 * retries here, since we're just going to sit in a
5449 * loop and wait for the device to finish formatting.
5451 scsi_test_unit_ready(&ccb->csio,
5454 /* tag_action */ MSG_SIMPLE_Q_TAG,
5455 /* sense_len */ SSD_FULL_SIZE,
5456 /* timeout */ 5000);
5458 /* Disable freezing the device queue */
5459 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5461 retval = cam_send_ccb(device, ccb);
5464 * If we get an error from the ioctl, bail out. SCSI
5465 * errors are expected.
5468 warn("error sending CAMIOCOMMAND ioctl");
5469 if (arglist & CAM_ARG_VERBOSE) {
5470 cam_error_print(device, ccb, CAM_ESF_ALL,
5471 CAM_EPF_ALL, stderr);
5474 goto scsiformat_bailout;
5477 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5479 if ((status != CAM_REQ_CMP)
5480 && (status == CAM_SCSI_STATUS_ERROR)
5481 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5482 struct scsi_sense_data *sense;
5483 int error_code, sense_key, asc, ascq;
5485 sense = &ccb->csio.sense_data;
5486 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5487 ccb->csio.sense_resid, &error_code, &sense_key,
5488 &asc, &ascq, /*show_errors*/ 1);
5491 * According to the SCSI-2 and SCSI-3 specs, a
5492 * drive that is in the middle of a format should
5493 * return NOT READY with an ASC of "logical unit
5494 * not ready, format in progress". The sense key
5495 * specific bytes will then be a progress indicator.
5497 if ((sense_key == SSD_KEY_NOT_READY)
5498 && (asc == 0x04) && (ascq == 0x04)) {
5501 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5502 ccb->csio.sense_resid, sks) == 0)
5505 u_int64_t percentage;
5507 val = scsi_2btoul(&sks[1]);
5508 percentage = 10000 * val;
5511 "\rFormatting: %ju.%02u %% "
5513 (uintmax_t)(percentage /
5515 (unsigned)((percentage /
5519 } else if ((quiet == 0)
5520 && (++num_warnings <= 1)) {
5521 warnx("Unexpected SCSI Sense Key "
5522 "Specific value returned "
5524 scsi_sense_print(device, &ccb->csio,
5526 warnx("Unable to print status "
5527 "information, but format will "
5529 warnx("will exit when format is "
5534 warnx("Unexpected SCSI error during format");
5535 cam_error_print(device, ccb, CAM_ESF_ALL,
5536 CAM_EPF_ALL, stderr);
5538 goto scsiformat_bailout;
5541 } else if (status != CAM_REQ_CMP) {
5542 warnx("Unexpected CAM status %#x", status);
5543 if (arglist & CAM_ARG_VERBOSE)
5544 cam_error_print(device, ccb, CAM_ESF_ALL,
5545 CAM_EPF_ALL, stderr);
5547 goto scsiformat_bailout;
5550 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5553 fprintf(stdout, "\nFormat Complete\n");
5563 scsisanitize(struct cam_device *device, int argc, char **argv,
5564 char *combinedopt, int retry_count, int timeout)
5567 u_int8_t action = 0;
5569 int ycount = 0, quiet = 0;
5570 int error = 0, retval = 0;
5571 int use_timeout = 10800 * 1000;
5577 const char *pattern = NULL;
5578 u_int8_t *data_ptr = NULL;
5579 u_int32_t dxfer_len = 0;
5581 int num_warnings = 0;
5584 ccb = cam_getccb(device);
5587 warnx("scsisanitize: error allocating ccb");
5591 bzero(&(&ccb->ccb_h)[1],
5592 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5594 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5597 if (strcasecmp(optarg, "overwrite") == 0)
5598 action = SSZ_SERVICE_ACTION_OVERWRITE;
5599 else if (strcasecmp(optarg, "block") == 0)
5600 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
5601 else if (strcasecmp(optarg, "crypto") == 0)
5602 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
5603 else if (strcasecmp(optarg, "exitfailure") == 0)
5604 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
5606 warnx("invalid service operation \"%s\"",
5609 goto scsisanitize_bailout;
5613 passes = strtol(optarg, NULL, 0);
5614 if (passes < 1 || passes > 31) {
5615 warnx("invalid passes value %d", passes);
5617 goto scsisanitize_bailout;
5648 warnx("an action is required");
5650 goto scsisanitize_bailout;
5651 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
5652 struct scsi_sanitize_parameter_list *pl;
5656 if (pattern == NULL) {
5657 warnx("overwrite action requires -P argument");
5659 goto scsisanitize_bailout;
5661 fd = open(pattern, O_RDONLY);
5663 warn("cannot open pattern file %s", pattern);
5665 goto scsisanitize_bailout;
5667 if (fstat(fd, &sb) < 0) {
5668 warn("cannot stat pattern file %s", pattern);
5670 goto scsisanitize_bailout;
5673 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
5674 warnx("pattern file size exceeds maximum value %d",
5675 SSZPL_MAX_PATTERN_LENGTH);
5677 goto scsisanitize_bailout;
5679 dxfer_len = sizeof(*pl) + sz;
5680 data_ptr = calloc(1, dxfer_len);
5681 if (data_ptr == NULL) {
5682 warnx("cannot allocate parameter list buffer");
5684 goto scsisanitize_bailout;
5687 amt = read(fd, data_ptr + sizeof(*pl), sz);
5689 warn("cannot read pattern file");
5691 goto scsisanitize_bailout;
5692 } else if (amt != sz) {
5693 warnx("short pattern file read");
5695 goto scsisanitize_bailout;
5698 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
5704 pl->byte1 |= SSZPL_INVERT;
5705 scsi_ulto2b(sz, pl->length);
5711 else if (invert != 0)
5713 else if (pattern != NULL)
5718 warnx("%s argument only valid with overwrite "
5721 goto scsisanitize_bailout;
5726 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5727 "following device:\n");
5729 error = scsidoinquiry(device, argc, argv, combinedopt,
5730 retry_count, timeout);
5733 warnx("scsisanitize: error sending inquiry");
5734 goto scsisanitize_bailout;
5739 if (!get_confirmation()) {
5741 goto scsisanitize_bailout;
5746 use_timeout = timeout;
5749 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
5750 use_timeout / 1000);
5754 * If the user hasn't disabled questions and didn't specify a
5755 * timeout on the command line, ask them if they want the current
5759 && (timeout == 0)) {
5761 int new_timeout = 0;
5763 fprintf(stdout, "Enter new timeout in seconds or press\n"
5764 "return to keep the current timeout [%d] ",
5765 use_timeout / 1000);
5767 if (fgets(str, sizeof(str), stdin) != NULL) {
5769 new_timeout = atoi(str);
5772 if (new_timeout != 0) {
5773 use_timeout = new_timeout * 1000;
5774 fprintf(stdout, "Using new timeout value %d\n",
5775 use_timeout / 1000);
5781 byte2 |= SSZ_UNRESTRICTED_EXIT;
5785 scsi_sanitize(&ccb->csio,
5786 /* retries */ retry_count,
5788 /* tag_action */ MSG_SIMPLE_Q_TAG,
5791 /* data_ptr */ data_ptr,
5792 /* dxfer_len */ dxfer_len,
5793 /* sense_len */ SSD_FULL_SIZE,
5794 /* timeout */ use_timeout);
5796 /* Disable freezing the device queue */
5797 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5799 if (arglist & CAM_ARG_ERR_RECOVER)
5800 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5802 if (((retval = cam_send_ccb(device, ccb)) < 0)
5803 || ((immediate == 0)
5804 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5805 const char errstr[] = "error sending sanitize command";
5812 if (arglist & CAM_ARG_VERBOSE) {
5813 cam_error_print(device, ccb, CAM_ESF_ALL,
5814 CAM_EPF_ALL, stderr);
5817 goto scsisanitize_bailout;
5821 * If we ran in non-immediate mode, we already checked for errors
5822 * above and printed out any necessary information. If we're in
5823 * immediate mode, we need to loop through and get status
5824 * information periodically.
5826 if (immediate == 0) {
5828 fprintf(stdout, "Sanitize Complete\n");
5830 goto scsisanitize_bailout;
5837 bzero(&(&ccb->ccb_h)[1],
5838 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5841 * There's really no need to do error recovery or
5842 * retries here, since we're just going to sit in a
5843 * loop and wait for the device to finish sanitizing.
5845 scsi_test_unit_ready(&ccb->csio,
5848 /* tag_action */ MSG_SIMPLE_Q_TAG,
5849 /* sense_len */ SSD_FULL_SIZE,
5850 /* timeout */ 5000);
5852 /* Disable freezing the device queue */
5853 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5855 retval = cam_send_ccb(device, ccb);
5858 * If we get an error from the ioctl, bail out. SCSI
5859 * errors are expected.
5862 warn("error sending CAMIOCOMMAND ioctl");
5863 if (arglist & CAM_ARG_VERBOSE) {
5864 cam_error_print(device, ccb, CAM_ESF_ALL,
5865 CAM_EPF_ALL, stderr);
5868 goto scsisanitize_bailout;
5871 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5873 if ((status != CAM_REQ_CMP)
5874 && (status == CAM_SCSI_STATUS_ERROR)
5875 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5876 struct scsi_sense_data *sense;
5877 int error_code, sense_key, asc, ascq;
5879 sense = &ccb->csio.sense_data;
5880 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5881 ccb->csio.sense_resid, &error_code, &sense_key,
5882 &asc, &ascq, /*show_errors*/ 1);
5885 * According to the SCSI-3 spec, a drive that is in the
5886 * middle of a sanitize should return NOT READY with an
5887 * ASC of "logical unit not ready, sanitize in
5888 * progress". The sense key specific bytes will then
5889 * be a progress indicator.
5891 if ((sense_key == SSD_KEY_NOT_READY)
5892 && (asc == 0x04) && (ascq == 0x1b)) {
5895 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5896 ccb->csio.sense_resid, sks) == 0)
5899 u_int64_t percentage;
5901 val = scsi_2btoul(&sks[1]);
5902 percentage = 10000 * val;
5905 "\rSanitizing: %ju.%02u %% "
5907 (uintmax_t)(percentage /
5909 (unsigned)((percentage /
5913 } else if ((quiet == 0)
5914 && (++num_warnings <= 1)) {
5915 warnx("Unexpected SCSI Sense Key "
5916 "Specific value returned "
5917 "during sanitize:");
5918 scsi_sense_print(device, &ccb->csio,
5920 warnx("Unable to print status "
5921 "information, but sanitze will "
5923 warnx("will exit when sanitize is "
5928 warnx("Unexpected SCSI error during sanitize");
5929 cam_error_print(device, ccb, CAM_ESF_ALL,
5930 CAM_EPF_ALL, stderr);
5932 goto scsisanitize_bailout;
5935 } else if (status != CAM_REQ_CMP) {
5936 warnx("Unexpected CAM status %#x", status);
5937 if (arglist & CAM_ARG_VERBOSE)
5938 cam_error_print(device, ccb, CAM_ESF_ALL,
5939 CAM_EPF_ALL, stderr);
5941 goto scsisanitize_bailout;
5943 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5946 fprintf(stdout, "\nSanitize Complete\n");
5948 scsisanitize_bailout:
5951 if (data_ptr != NULL)
5959 scsireportluns(struct cam_device *device, int argc, char **argv,
5960 char *combinedopt, int retry_count, int timeout)
5963 int c, countonly, lunsonly;
5964 struct scsi_report_luns_data *lundata;
5966 uint8_t report_type;
5967 uint32_t list_len, i, j;
5972 report_type = RPL_REPORT_DEFAULT;
5973 ccb = cam_getccb(device);
5976 warnx("%s: error allocating ccb", __func__);
5980 bzero(&(&ccb->ccb_h)[1],
5981 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5986 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5995 if (strcasecmp(optarg, "default") == 0)
5996 report_type = RPL_REPORT_DEFAULT;
5997 else if (strcasecmp(optarg, "wellknown") == 0)
5998 report_type = RPL_REPORT_WELLKNOWN;
5999 else if (strcasecmp(optarg, "all") == 0)
6000 report_type = RPL_REPORT_ALL;
6002 warnx("%s: invalid report type \"%s\"",
6013 if ((countonly != 0)
6014 && (lunsonly != 0)) {
6015 warnx("%s: you can only specify one of -c or -l", __func__);
6020 * According to SPC-4, the allocation length must be at least 16
6021 * bytes -- enough for the header and one LUN.
6023 alloc_len = sizeof(*lundata) + 8;
6027 lundata = malloc(alloc_len);
6029 if (lundata == NULL) {
6030 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6035 scsi_report_luns(&ccb->csio,
6036 /*retries*/ retry_count,
6038 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6039 /*select_report*/ report_type,
6040 /*rpl_buf*/ lundata,
6041 /*alloc_len*/ alloc_len,
6042 /*sense_len*/ SSD_FULL_SIZE,
6043 /*timeout*/ timeout ? timeout : 5000);
6045 /* Disable freezing the device queue */
6046 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6048 if (arglist & CAM_ARG_ERR_RECOVER)
6049 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6051 if (cam_send_ccb(device, ccb) < 0) {
6052 warn("error sending REPORT LUNS command");
6054 if (arglist & CAM_ARG_VERBOSE)
6055 cam_error_print(device, ccb, CAM_ESF_ALL,
6056 CAM_EPF_ALL, stderr);
6062 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6063 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6069 list_len = scsi_4btoul(lundata->length);
6072 * If we need to list the LUNs, and our allocation
6073 * length was too short, reallocate and retry.
6075 if ((countonly == 0)
6076 && (list_len > (alloc_len - sizeof(*lundata)))) {
6077 alloc_len = list_len + sizeof(*lundata);
6083 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6084 ((list_len / 8) > 1) ? "s" : "");
6089 for (i = 0; i < (list_len / 8); i++) {
6093 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6095 fprintf(stdout, ",");
6096 switch (lundata->luns[i].lundata[j] &
6097 RPL_LUNDATA_ATYP_MASK) {
6098 case RPL_LUNDATA_ATYP_PERIPH:
6099 if ((lundata->luns[i].lundata[j] &
6100 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6101 fprintf(stdout, "%d:",
6102 lundata->luns[i].lundata[j] &
6103 RPL_LUNDATA_PERIPH_BUS_MASK);
6105 && ((lundata->luns[i].lundata[j+2] &
6106 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6109 fprintf(stdout, "%d",
6110 lundata->luns[i].lundata[j+1]);
6112 case RPL_LUNDATA_ATYP_FLAT: {
6114 tmplun[0] = lundata->luns[i].lundata[j] &
6115 RPL_LUNDATA_FLAT_LUN_MASK;
6116 tmplun[1] = lundata->luns[i].lundata[j+1];
6118 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6122 case RPL_LUNDATA_ATYP_LUN:
6123 fprintf(stdout, "%d:%d:%d",
6124 (lundata->luns[i].lundata[j+1] &
6125 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6126 lundata->luns[i].lundata[j] &
6127 RPL_LUNDATA_LUN_TARG_MASK,
6128 lundata->luns[i].lundata[j+1] &
6129 RPL_LUNDATA_LUN_LUN_MASK);
6131 case RPL_LUNDATA_ATYP_EXTLUN: {
6132 int field_len_code, eam_code;
6134 eam_code = lundata->luns[i].lundata[j] &
6135 RPL_LUNDATA_EXT_EAM_MASK;
6136 field_len_code = (lundata->luns[i].lundata[j] &
6137 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6139 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6140 && (field_len_code == 0x00)) {
6141 fprintf(stdout, "%d",
6142 lundata->luns[i].lundata[j+1]);
6143 } else if ((eam_code ==
6144 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6145 && (field_len_code == 0x03)) {
6149 * This format takes up all 8 bytes.
6150 * If we aren't starting at offset 0,
6154 fprintf(stdout, "Invalid "
6157 "specified format", j);
6161 bzero(tmp_lun, sizeof(tmp_lun));
6162 bcopy(&lundata->luns[i].lundata[j+1],
6163 &tmp_lun[1], sizeof(tmp_lun) - 1);
6164 fprintf(stdout, "%#jx",
6165 (intmax_t)scsi_8btou64(tmp_lun));
6168 fprintf(stderr, "Unknown Extended LUN"
6169 "Address method %#x, length "
6170 "code %#x", eam_code,
6177 fprintf(stderr, "Unknown LUN address method "
6178 "%#x\n", lundata->luns[i].lundata[0] &
6179 RPL_LUNDATA_ATYP_MASK);
6183 * For the flat addressing method, there are no
6184 * other levels after it.
6189 fprintf(stdout, "\n");
6202 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6203 char *combinedopt, int retry_count, int timeout)
6206 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6207 struct scsi_read_capacity_data rcap;
6208 struct scsi_read_capacity_data_long rcaplong;
6222 ccb = cam_getccb(device);
6225 warnx("%s: error allocating ccb", __func__);
6229 bzero(&(&ccb->ccb_h)[1],
6230 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6232 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6259 if ((blocksizeonly != 0)
6260 && (numblocks != 0)) {
6261 warnx("%s: you can only specify one of -b or -N", __func__);
6266 if ((blocksizeonly != 0)
6267 && (sizeonly != 0)) {
6268 warnx("%s: you can only specify one of -b or -s", __func__);
6275 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6281 && (blocksizeonly != 0)) {
6282 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6287 scsi_read_capacity(&ccb->csio,
6288 /*retries*/ retry_count,
6290 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6293 /*timeout*/ timeout ? timeout : 5000);
6295 /* Disable freezing the device queue */
6296 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6298 if (arglist & CAM_ARG_ERR_RECOVER)
6299 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6301 if (cam_send_ccb(device, ccb) < 0) {
6302 warn("error sending READ CAPACITY command");
6304 if (arglist & CAM_ARG_VERBOSE)
6305 cam_error_print(device, ccb, CAM_ESF_ALL,
6306 CAM_EPF_ALL, stderr);
6312 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6313 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6318 maxsector = scsi_4btoul(rcap.addr);
6319 block_len = scsi_4btoul(rcap.length);
6322 * A last block of 2^32-1 means that the true capacity is over 2TB,
6323 * and we need to issue the long READ CAPACITY to get the real
6324 * capacity. Otherwise, we're all set.
6326 if (maxsector != 0xffffffff)
6329 scsi_read_capacity_16(&ccb->csio,
6330 /*retries*/ retry_count,
6332 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6336 /*rcap_buf*/ (uint8_t *)&rcaplong,
6337 /*rcap_buf_len*/ sizeof(rcaplong),
6338 /*sense_len*/ SSD_FULL_SIZE,
6339 /*timeout*/ timeout ? timeout : 5000);
6341 /* Disable freezing the device queue */
6342 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6344 if (arglist & CAM_ARG_ERR_RECOVER)
6345 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6347 if (cam_send_ccb(device, ccb) < 0) {
6348 warn("error sending READ CAPACITY (16) command");
6350 if (arglist & CAM_ARG_VERBOSE)
6351 cam_error_print(device, ccb, CAM_ESF_ALL,
6352 CAM_EPF_ALL, stderr);
6358 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6359 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6364 maxsector = scsi_8btou64(rcaplong.addr);
6365 block_len = scsi_4btoul(rcaplong.length);
6368 if (blocksizeonly == 0) {
6370 * Humanize implies !quiet, and also implies numblocks.
6372 if (humanize != 0) {
6377 tmpbytes = (maxsector + 1) * block_len;
6378 ret = humanize_number(tmpstr, sizeof(tmpstr),
6379 tmpbytes, "", HN_AUTOSCALE,
6382 HN_DIVISOR_1000 : 0));
6384 warnx("%s: humanize_number failed!", __func__);
6388 fprintf(stdout, "Device Size: %s%s", tmpstr,
6389 (sizeonly == 0) ? ", " : "\n");
6390 } else if (numblocks != 0) {
6391 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6392 "Blocks: " : "", (uintmax_t)maxsector + 1,
6393 (sizeonly == 0) ? ", " : "\n");
6395 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6396 "Last Block: " : "", (uintmax_t)maxsector,
6397 (sizeonly == 0) ? ", " : "\n");
6401 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6402 "Block Length: " : "", block_len, (quiet == 0) ?
6411 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6412 int retry_count, int timeout)
6416 uint8_t *smp_request = NULL, *smp_response = NULL;
6417 int request_size = 0, response_size = 0;
6418 int fd_request = 0, fd_response = 0;
6419 char *datastr = NULL;
6420 struct get_hook hook;
6425 * Note that at the moment we don't support sending SMP CCBs to
6426 * devices that aren't probed by CAM.
6428 ccb = cam_getccb(device);
6430 warnx("%s: error allocating CCB", __func__);
6434 bzero(&(&ccb->ccb_h)[1],
6435 sizeof(union ccb) - sizeof(struct ccb_hdr));
6437 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6440 arglist |= CAM_ARG_CMD_IN;
6441 response_size = strtol(optarg, NULL, 0);
6442 if (response_size <= 0) {
6443 warnx("invalid number of response bytes %d",
6446 goto smpcmd_bailout;
6448 hook.argc = argc - optind;
6449 hook.argv = argv + optind;
6452 datastr = cget(&hook, NULL);
6454 * If the user supplied "-" instead of a format, he
6455 * wants the data to be written to stdout.
6457 if ((datastr != NULL)
6458 && (datastr[0] == '-'))
6461 smp_response = (u_int8_t *)malloc(response_size);
6462 if (smp_response == NULL) {
6463 warn("can't malloc memory for SMP response");
6465 goto smpcmd_bailout;
6469 arglist |= CAM_ARG_CMD_OUT;
6470 request_size = strtol(optarg, NULL, 0);
6471 if (request_size <= 0) {
6472 warnx("invalid number of request bytes %d",
6475 goto smpcmd_bailout;
6477 hook.argc = argc - optind;
6478 hook.argv = argv + optind;
6480 datastr = cget(&hook, NULL);
6481 smp_request = (u_int8_t *)malloc(request_size);
6482 if (smp_request == NULL) {
6483 warn("can't malloc memory for SMP request");
6485 goto smpcmd_bailout;
6487 bzero(smp_request, request_size);
6489 * If the user supplied "-" instead of a format, he
6490 * wants the data to be read from stdin.
6492 if ((datastr != NULL)
6493 && (datastr[0] == '-'))
6496 buff_encode_visit(smp_request, request_size,
6507 * If fd_data is set, and we're writing to the device, we need to
6508 * read the data the user wants written from stdin.
6510 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6512 int amt_to_read = request_size;
6513 u_int8_t *buf_ptr = smp_request;
6515 for (amt_read = 0; amt_to_read > 0;
6516 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6517 if (amt_read == -1) {
6518 warn("error reading data from stdin");
6520 goto smpcmd_bailout;
6522 amt_to_read -= amt_read;
6523 buf_ptr += amt_read;
6527 if (((arglist & CAM_ARG_CMD_IN) == 0)
6528 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6529 warnx("%s: need both the request (-r) and response (-R) "
6530 "arguments", __func__);
6532 goto smpcmd_bailout;
6535 flags |= CAM_DEV_QFRZDIS;
6537 cam_fill_smpio(&ccb->smpio,
6538 /*retries*/ retry_count,
6541 /*smp_request*/ smp_request,
6542 /*smp_request_len*/ request_size,
6543 /*smp_response*/ smp_response,
6544 /*smp_response_len*/ response_size,
6545 /*timeout*/ timeout ? timeout : 5000);
6547 ccb->smpio.flags = SMP_FLAG_NONE;
6549 if (((retval = cam_send_ccb(device, ccb)) < 0)
6550 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6551 const char warnstr[] = "error sending command";
6558 if (arglist & CAM_ARG_VERBOSE) {
6559 cam_error_print(device, ccb, CAM_ESF_ALL,
6560 CAM_EPF_ALL, stderr);
6564 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6565 && (response_size > 0)) {
6566 if (fd_response == 0) {
6567 buff_decode_visit(smp_response, response_size,
6568 datastr, arg_put, NULL);
6569 fprintf(stdout, "\n");
6571 ssize_t amt_written;
6572 int amt_to_write = response_size;
6573 u_int8_t *buf_ptr = smp_response;
6575 for (amt_written = 0; (amt_to_write > 0) &&
6576 (amt_written = write(STDOUT_FILENO, buf_ptr,
6577 amt_to_write)) > 0;){
6578 amt_to_write -= amt_written;
6579 buf_ptr += amt_written;
6581 if (amt_written == -1) {
6582 warn("error writing data to stdout");
6584 goto smpcmd_bailout;
6585 } else if ((amt_written == 0)
6586 && (amt_to_write > 0)) {
6587 warnx("only wrote %u bytes out of %u",
6588 response_size - amt_to_write,
6597 if (smp_request != NULL)
6600 if (smp_response != NULL)
6607 smpreportgeneral(struct cam_device *device, int argc, char **argv,
6608 char *combinedopt, int retry_count, int timeout)
6611 struct smp_report_general_request *request = NULL;
6612 struct smp_report_general_response *response = NULL;
6613 struct sbuf *sb = NULL;
6615 int c, long_response = 0;
6619 * Note that at the moment we don't support sending SMP CCBs to
6620 * devices that aren't probed by CAM.
6622 ccb = cam_getccb(device);
6624 warnx("%s: error allocating CCB", __func__);
6628 bzero(&(&ccb->ccb_h)[1],
6629 sizeof(union ccb) - sizeof(struct ccb_hdr));
6631 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6640 request = malloc(sizeof(*request));
6641 if (request == NULL) {
6642 warn("%s: unable to allocate %zd bytes", __func__,
6648 response = malloc(sizeof(*response));
6649 if (response == NULL) {
6650 warn("%s: unable to allocate %zd bytes", __func__,
6657 smp_report_general(&ccb->smpio,
6661 /*request_len*/ sizeof(*request),
6662 (uint8_t *)response,
6663 /*response_len*/ sizeof(*response),
6664 /*long_response*/ long_response,
6667 if (((retval = cam_send_ccb(device, ccb)) < 0)
6668 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6669 const char warnstr[] = "error sending command";
6676 if (arglist & CAM_ARG_VERBOSE) {
6677 cam_error_print(device, ccb, CAM_ESF_ALL,
6678 CAM_EPF_ALL, stderr);
6685 * If the device supports the long response bit, try again and see
6686 * if we can get all of the data.
6688 if ((response->long_response & SMP_RG_LONG_RESPONSE)
6689 && (long_response == 0)) {
6690 ccb->ccb_h.status = CAM_REQ_INPROG;
6691 bzero(&(&ccb->ccb_h)[1],
6692 sizeof(union ccb) - sizeof(struct ccb_hdr));
6698 * XXX KDM detect and decode SMP errors here.
6700 sb = sbuf_new_auto();
6702 warnx("%s: error allocating sbuf", __func__);
6706 smp_report_general_sbuf(response, sizeof(*response), sb);
6708 if (sbuf_finish(sb) != 0) {
6709 warnx("%s: sbuf_finish", __func__);
6713 printf("%s", sbuf_data(sb));
6719 if (request != NULL)
6722 if (response != NULL)
6731 static struct camcontrol_opts phy_ops[] = {
6732 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
6733 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
6734 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
6735 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
6736 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
6737 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
6738 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
6739 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
6740 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
6745 smpphycontrol(struct cam_device *device, int argc, char **argv,
6746 char *combinedopt, int retry_count, int timeout)
6749 struct smp_phy_control_request *request = NULL;
6750 struct smp_phy_control_response *response = NULL;
6751 int long_response = 0;
6754 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
6756 uint64_t attached_dev_name = 0;
6757 int dev_name_set = 0;
6758 uint32_t min_plr = 0, max_plr = 0;
6759 uint32_t pp_timeout_val = 0;
6760 int slumber_partial = 0;
6761 int set_pp_timeout_val = 0;
6765 * Note that at the moment we don't support sending SMP CCBs to
6766 * devices that aren't probed by CAM.
6768 ccb = cam_getccb(device);
6770 warnx("%s: error allocating CCB", __func__);
6774 bzero(&(&ccb->ccb_h)[1],
6775 sizeof(union ccb) - sizeof(struct ccb_hdr));
6777 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6785 if (strcasecmp(optarg, "enable") == 0)
6787 else if (strcasecmp(optarg, "disable") == 0)
6790 warnx("%s: Invalid argument %s", __func__,
6797 slumber_partial |= enable <<
6798 SMP_PC_SAS_SLUMBER_SHIFT;
6801 slumber_partial |= enable <<
6802 SMP_PC_SAS_PARTIAL_SHIFT;
6805 slumber_partial |= enable <<
6806 SMP_PC_SATA_SLUMBER_SHIFT;
6809 slumber_partial |= enable <<
6810 SMP_PC_SATA_PARTIAL_SHIFT;
6813 warnx("%s: programmer error", __func__);
6816 break; /*NOTREACHED*/
6821 attached_dev_name = (uintmax_t)strtoumax(optarg,
6830 * We don't do extensive checking here, so this
6831 * will continue to work when new speeds come out.
6833 min_plr = strtoul(optarg, NULL, 0);
6835 || (min_plr > 0xf)) {
6836 warnx("%s: invalid link rate %x",
6844 * We don't do extensive checking here, so this
6845 * will continue to work when new speeds come out.
6847 max_plr = strtoul(optarg, NULL, 0);
6849 || (max_plr > 0xf)) {
6850 warnx("%s: invalid link rate %x",
6857 camcontrol_optret optreturn;
6858 cam_argmask argnums;
6861 if (phy_op_set != 0) {
6862 warnx("%s: only one phy operation argument "
6863 "(-o) allowed", __func__);
6871 * Allow the user to specify the phy operation
6872 * numerically, as well as with a name. This will
6873 * future-proof it a bit, so options that are added
6874 * in future specs can be used.
6876 if (isdigit(optarg[0])) {
6877 phy_operation = strtoul(optarg, NULL, 0);
6878 if ((phy_operation == 0)
6879 || (phy_operation > 0xff)) {
6880 warnx("%s: invalid phy operation %#x",
6881 __func__, phy_operation);
6887 optreturn = getoption(phy_ops, optarg, &phy_operation,
6890 if (optreturn == CC_OR_AMBIGUOUS) {
6891 warnx("%s: ambiguous option %s", __func__,
6896 } else if (optreturn == CC_OR_NOT_FOUND) {
6897 warnx("%s: option %s not found", __func__,
6909 pp_timeout_val = strtoul(optarg, NULL, 0);
6910 if (pp_timeout_val > 15) {
6911 warnx("%s: invalid partial pathway timeout "
6912 "value %u, need a value less than 16",
6913 __func__, pp_timeout_val);
6917 set_pp_timeout_val = 1;
6925 warnx("%s: a PHY (-p phy) argument is required",__func__);
6930 if (((dev_name_set != 0)
6931 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
6932 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
6933 && (dev_name_set == 0))) {
6934 warnx("%s: -d name and -o setdevname arguments both "
6935 "required to set device name", __func__);
6940 request = malloc(sizeof(*request));
6941 if (request == NULL) {
6942 warn("%s: unable to allocate %zd bytes", __func__,
6948 response = malloc(sizeof(*response));
6949 if (response == NULL) {
6950 warn("%s: unable to allocate %zd bytes", __func__,
6956 smp_phy_control(&ccb->smpio,
6961 (uint8_t *)response,
6964 /*expected_exp_change_count*/ 0,
6967 (set_pp_timeout_val != 0) ? 1 : 0,
6975 if (((retval = cam_send_ccb(device, ccb)) < 0)
6976 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6977 const char warnstr[] = "error sending command";
6984 if (arglist & CAM_ARG_VERBOSE) {
6986 * Use CAM_EPF_NORMAL so we only get one line of
6987 * SMP command decoding.
6989 cam_error_print(device, ccb, CAM_ESF_ALL,
6990 CAM_EPF_NORMAL, stderr);
6996 /* XXX KDM print out something here for success? */
7001 if (request != NULL)
7004 if (response != NULL)
7011 smpmaninfo(struct cam_device *device, int argc, char **argv,
7012 char *combinedopt, int retry_count, int timeout)
7015 struct smp_report_manuf_info_request request;
7016 struct smp_report_manuf_info_response response;
7017 struct sbuf *sb = NULL;
7018 int long_response = 0;
7023 * Note that at the moment we don't support sending SMP CCBs to
7024 * devices that aren't probed by CAM.
7026 ccb = cam_getccb(device);
7028 warnx("%s: error allocating CCB", __func__);
7032 bzero(&(&ccb->ccb_h)[1],
7033 sizeof(union ccb) - sizeof(struct ccb_hdr));
7035 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7044 bzero(&request, sizeof(request));
7045 bzero(&response, sizeof(response));
7047 smp_report_manuf_info(&ccb->smpio,
7052 (uint8_t *)&response,
7057 if (((retval = cam_send_ccb(device, ccb)) < 0)
7058 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7059 const char warnstr[] = "error sending command";
7066 if (arglist & CAM_ARG_VERBOSE) {
7067 cam_error_print(device, ccb, CAM_ESF_ALL,
7068 CAM_EPF_ALL, stderr);
7074 sb = sbuf_new_auto();
7076 warnx("%s: error allocating sbuf", __func__);
7080 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7082 if (sbuf_finish(sb) != 0) {
7083 warnx("%s: sbuf_finish", __func__);
7087 printf("%s", sbuf_data(sb));
7101 getdevid(struct cam_devitem *item)
7104 union ccb *ccb = NULL;
7106 struct cam_device *dev;
7108 dev = cam_open_btl(item->dev_match.path_id,
7109 item->dev_match.target_id,
7110 item->dev_match.target_lun, O_RDWR, NULL);
7113 warnx("%s", cam_errbuf);
7118 item->device_id_len = 0;
7120 ccb = cam_getccb(dev);
7122 warnx("%s: error allocating CCB", __func__);
7127 bzero(&(&ccb->ccb_h)[1],
7128 sizeof(union ccb) - sizeof(struct ccb_hdr));
7131 * On the first try, we just probe for the size of the data, and
7132 * then allocate that much memory and try again.
7135 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7136 ccb->ccb_h.flags = CAM_DIR_IN;
7137 ccb->cdai.flags = 0;
7138 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7139 ccb->cdai.bufsiz = item->device_id_len;
7140 if (item->device_id_len != 0)
7141 ccb->cdai.buf = (uint8_t *)item->device_id;
7143 if (cam_send_ccb(dev, ccb) < 0) {
7144 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7149 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7150 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7155 if (item->device_id_len == 0) {
7157 * This is our first time through. Allocate the buffer,
7158 * and then go back to get the data.
7160 if (ccb->cdai.provsiz == 0) {
7161 warnx("%s: invalid .provsiz field returned with "
7162 "XPT_GDEV_ADVINFO CCB", __func__);
7166 item->device_id_len = ccb->cdai.provsiz;
7167 item->device_id = malloc(item->device_id_len);
7168 if (item->device_id == NULL) {
7169 warn("%s: unable to allocate %d bytes", __func__,
7170 item->device_id_len);
7174 ccb->ccb_h.status = CAM_REQ_INPROG;
7180 cam_close_device(dev);
7189 * XXX KDM merge this code with getdevtree()?
7192 buildbusdevlist(struct cam_devlist *devlist)
7195 int bufsize, fd = -1;
7196 struct dev_match_pattern *patterns;
7197 struct cam_devitem *item = NULL;
7198 int skip_device = 0;
7201 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7202 warn("couldn't open %s", XPT_DEVICE);
7206 bzero(&ccb, sizeof(union ccb));
7208 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7209 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7210 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7212 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7213 bufsize = sizeof(struct dev_match_result) * 100;
7214 ccb.cdm.match_buf_len = bufsize;
7215 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7216 if (ccb.cdm.matches == NULL) {
7217 warnx("can't malloc memory for matches");
7221 ccb.cdm.num_matches = 0;
7222 ccb.cdm.num_patterns = 2;
7223 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7224 ccb.cdm.num_patterns;
7226 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7227 if (patterns == NULL) {
7228 warnx("can't malloc memory for patterns");
7233 ccb.cdm.patterns = patterns;
7234 bzero(patterns, ccb.cdm.pattern_buf_len);
7236 patterns[0].type = DEV_MATCH_DEVICE;
7237 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7238 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7239 patterns[1].type = DEV_MATCH_PERIPH;
7240 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7241 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7244 * We do the ioctl multiple times if necessary, in case there are
7245 * more than 100 nodes in the EDT.
7250 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7251 warn("error sending CAMIOCOMMAND ioctl");
7256 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7257 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7258 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7259 warnx("got CAM error %#x, CDM error %d\n",
7260 ccb.ccb_h.status, ccb.cdm.status);
7265 for (i = 0; i < ccb.cdm.num_matches; i++) {
7266 switch (ccb.cdm.matches[i].type) {
7267 case DEV_MATCH_DEVICE: {
7268 struct device_match_result *dev_result;
7271 &ccb.cdm.matches[i].result.device_result;
7273 if (dev_result->flags &
7274 DEV_RESULT_UNCONFIGURED) {
7280 item = malloc(sizeof(*item));
7282 warn("%s: unable to allocate %zd bytes",
7283 __func__, sizeof(*item));
7287 bzero(item, sizeof(*item));
7288 bcopy(dev_result, &item->dev_match,
7289 sizeof(*dev_result));
7290 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7293 if (getdevid(item) != 0) {
7299 case DEV_MATCH_PERIPH: {
7300 struct periph_match_result *periph_result;
7303 &ccb.cdm.matches[i].result.periph_result;
7305 if (skip_device != 0)
7307 item->num_periphs++;
7308 item->periph_matches = realloc(
7309 item->periph_matches,
7311 sizeof(struct periph_match_result));
7312 if (item->periph_matches == NULL) {
7313 warn("%s: error allocating periph "
7318 bcopy(periph_result, &item->periph_matches[
7319 item->num_periphs - 1],
7320 sizeof(*periph_result));
7324 fprintf(stderr, "%s: unexpected match "
7325 "type %d\n", __func__,
7326 ccb.cdm.matches[i].type);
7329 break; /*NOTREACHED*/
7332 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7333 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7341 free(ccb.cdm.matches);
7344 freebusdevlist(devlist);
7350 freebusdevlist(struct cam_devlist *devlist)
7352 struct cam_devitem *item, *item2;
7354 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7355 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7357 free(item->device_id);
7358 free(item->periph_matches);
7363 static struct cam_devitem *
7364 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7366 struct cam_devitem *item;
7368 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7369 struct scsi_vpd_id_descriptor *idd;
7372 * XXX KDM look for LUN IDs as well?
7374 idd = scsi_get_devid(item->device_id,
7375 item->device_id_len,
7376 scsi_devid_is_sas_target);
7380 if (scsi_8btou64(idd->identifier) == sasaddr)
7388 smpphylist(struct cam_device *device, int argc, char **argv,
7389 char *combinedopt, int retry_count, int timeout)
7391 struct smp_report_general_request *rgrequest = NULL;
7392 struct smp_report_general_response *rgresponse = NULL;
7393 struct smp_discover_request *disrequest = NULL;
7394 struct smp_discover_response *disresponse = NULL;
7395 struct cam_devlist devlist;
7397 int long_response = 0;
7404 * Note that at the moment we don't support sending SMP CCBs to
7405 * devices that aren't probed by CAM.
7407 ccb = cam_getccb(device);
7409 warnx("%s: error allocating CCB", __func__);
7413 bzero(&(&ccb->ccb_h)[1],
7414 sizeof(union ccb) - sizeof(struct ccb_hdr));
7415 STAILQ_INIT(&devlist.dev_queue);
7417 rgrequest = malloc(sizeof(*rgrequest));
7418 if (rgrequest == NULL) {
7419 warn("%s: unable to allocate %zd bytes", __func__,
7420 sizeof(*rgrequest));
7425 rgresponse = malloc(sizeof(*rgresponse));
7426 if (rgresponse == NULL) {
7427 warn("%s: unable to allocate %zd bytes", __func__,
7428 sizeof(*rgresponse));
7433 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7446 smp_report_general(&ccb->smpio,
7450 /*request_len*/ sizeof(*rgrequest),
7451 (uint8_t *)rgresponse,
7452 /*response_len*/ sizeof(*rgresponse),
7453 /*long_response*/ long_response,
7456 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7458 if (((retval = cam_send_ccb(device, ccb)) < 0)
7459 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7460 const char warnstr[] = "error sending command";
7467 if (arglist & CAM_ARG_VERBOSE) {
7468 cam_error_print(device, ccb, CAM_ESF_ALL,
7469 CAM_EPF_ALL, stderr);
7475 num_phys = rgresponse->num_phys;
7477 if (num_phys == 0) {
7479 fprintf(stdout, "%s: No Phys reported\n", __func__);
7484 devlist.path_id = device->path_id;
7486 retval = buildbusdevlist(&devlist);
7491 fprintf(stdout, "%d PHYs:\n", num_phys);
7492 fprintf(stdout, "PHY Attached SAS Address\n");
7495 disrequest = malloc(sizeof(*disrequest));
7496 if (disrequest == NULL) {
7497 warn("%s: unable to allocate %zd bytes", __func__,
7498 sizeof(*disrequest));
7503 disresponse = malloc(sizeof(*disresponse));
7504 if (disresponse == NULL) {
7505 warn("%s: unable to allocate %zd bytes", __func__,
7506 sizeof(*disresponse));
7511 for (i = 0; i < num_phys; i++) {
7512 struct cam_devitem *item;
7513 struct device_match_result *dev_match;
7514 char vendor[16], product[48], revision[16];
7518 bzero(&(&ccb->ccb_h)[1],
7519 sizeof(union ccb) - sizeof(struct ccb_hdr));
7521 ccb->ccb_h.status = CAM_REQ_INPROG;
7522 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7524 smp_discover(&ccb->smpio,
7528 sizeof(*disrequest),
7529 (uint8_t *)disresponse,
7530 sizeof(*disresponse),
7532 /*ignore_zone_group*/ 0,
7536 if (((retval = cam_send_ccb(device, ccb)) < 0)
7537 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7538 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7539 const char warnstr[] = "error sending command";
7546 if (arglist & CAM_ARG_VERBOSE) {
7547 cam_error_print(device, ccb, CAM_ESF_ALL,
7548 CAM_EPF_ALL, stderr);
7554 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7556 fprintf(stdout, "%3d <vacant>\n", i);
7560 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7563 item = findsasdevice(&devlist,
7564 scsi_8btou64(disresponse->attached_sas_address));
7568 || (item != NULL)) {
7569 fprintf(stdout, "%3d 0x%016jx", i,
7570 (uintmax_t)scsi_8btou64(
7571 disresponse->attached_sas_address));
7573 fprintf(stdout, "\n");
7576 } else if (quiet != 0)
7579 dev_match = &item->dev_match;
7581 if (dev_match->protocol == PROTO_SCSI) {
7582 cam_strvis(vendor, dev_match->inq_data.vendor,
7583 sizeof(dev_match->inq_data.vendor),
7585 cam_strvis(product, dev_match->inq_data.product,
7586 sizeof(dev_match->inq_data.product),
7588 cam_strvis(revision, dev_match->inq_data.revision,
7589 sizeof(dev_match->inq_data.revision),
7591 sprintf(tmpstr, "<%s %s %s>", vendor, product,
7593 } else if ((dev_match->protocol == PROTO_ATA)
7594 || (dev_match->protocol == PROTO_SATAPM)) {
7595 cam_strvis(product, dev_match->ident_data.model,
7596 sizeof(dev_match->ident_data.model),
7598 cam_strvis(revision, dev_match->ident_data.revision,
7599 sizeof(dev_match->ident_data.revision),
7601 sprintf(tmpstr, "<%s %s>", product, revision);
7603 sprintf(tmpstr, "<>");
7605 fprintf(stdout, " %-33s ", tmpstr);
7608 * If we have 0 periphs, that's a bug...
7610 if (item->num_periphs == 0) {
7611 fprintf(stdout, "\n");
7615 fprintf(stdout, "(");
7616 for (j = 0; j < item->num_periphs; j++) {
7618 fprintf(stdout, ",");
7620 fprintf(stdout, "%s%d",
7621 item->periph_matches[j].periph_name,
7622 item->periph_matches[j].unit_number);
7625 fprintf(stdout, ")\n");
7639 freebusdevlist(&devlist);
7645 atapm(struct cam_device *device, int argc, char **argv,
7646 char *combinedopt, int retry_count, int timeout)
7654 ccb = cam_getccb(device);
7657 warnx("%s: error allocating ccb", __func__);
7661 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7670 if (strcmp(argv[1], "idle") == 0) {
7672 cmd = ATA_IDLE_IMMEDIATE;
7675 } else if (strcmp(argv[1], "standby") == 0) {
7677 cmd = ATA_STANDBY_IMMEDIATE;
7679 cmd = ATA_STANDBY_CMD;
7687 else if (t <= (240 * 5))
7689 else if (t <= (252 * 5))
7690 /* special encoding for 21 minutes */
7692 else if (t <= (11 * 30 * 60))
7693 sc = (t - 1) / (30 * 60) + 241;
7697 cam_fill_ataio(&ccb->ataio,
7700 /*flags*/CAM_DIR_NONE,
7704 timeout ? timeout : 30 * 1000);
7705 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
7707 /* Disable freezing the device queue */
7708 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7710 if (arglist & CAM_ARG_ERR_RECOVER)
7711 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7713 if (cam_send_ccb(device, ccb) < 0) {
7714 warn("error sending command");
7716 if (arglist & CAM_ARG_VERBOSE)
7717 cam_error_print(device, ccb, CAM_ESF_ALL,
7718 CAM_EPF_ALL, stderr);
7724 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7725 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7734 #endif /* MINIMALISTIC */
7737 usage(int printlong)
7740 fprintf(printlong ? stdout : stderr,
7741 "usage: camcontrol <command> [device id][generic args][command args]\n"
7742 " camcontrol devlist [-v]\n"
7743 #ifndef MINIMALISTIC
7744 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
7745 " camcontrol tur [dev_id][generic args]\n"
7746 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
7747 " camcontrol identify [dev_id][generic args] [-v]\n"
7748 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
7749 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
7751 " camcontrol start [dev_id][generic args]\n"
7752 " camcontrol stop [dev_id][generic args]\n"
7753 " camcontrol load [dev_id][generic args]\n"
7754 " camcontrol eject [dev_id][generic args]\n"
7755 #endif /* MINIMALISTIC */
7756 " camcontrol rescan <all | bus[:target:lun]>\n"
7757 " camcontrol reset <all | bus[:target:lun]>\n"
7758 #ifndef MINIMALISTIC
7759 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
7760 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
7761 " [-P pagectl][-e | -b][-d]\n"
7762 " camcontrol cmd [dev_id][generic args]\n"
7763 " <-a cmd [args] | -c cmd [args]>\n"
7764 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
7765 " camcontrol smpcmd [dev_id][generic args]\n"
7766 " <-r len fmt [args]> <-R len fmt [args]>\n"
7767 " camcontrol smprg [dev_id][generic args][-l]\n"
7768 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
7769 " [-o operation][-d name][-m rate][-M rate]\n"
7770 " [-T pp_timeout][-a enable|disable]\n"
7771 " [-A enable|disable][-s enable|disable]\n"
7772 " [-S enable|disable]\n"
7773 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
7774 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
7775 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
7776 " <all|bus[:target[:lun]]|off>\n"
7777 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
7778 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
7779 " [-D <enable|disable>][-M mode][-O offset]\n"
7780 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
7781 " [-U][-W bus_width]\n"
7782 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
7783 " camcontrol sanitize [dev_id][generic args]\n"
7784 " [-a overwrite|block|crypto|exitfailure]\n"
7785 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
7787 " camcontrol idle [dev_id][generic args][-t time]\n"
7788 " camcontrol standby [dev_id][generic args][-t time]\n"
7789 " camcontrol sleep [dev_id][generic args]\n"
7790 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
7791 " camcontrol security [dev_id][generic args]\n"
7792 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
7793 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
7794 " [-U <user|master>] [-y]\n"
7795 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
7796 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
7797 #endif /* MINIMALISTIC */
7798 " camcontrol help\n");
7801 #ifndef MINIMALISTIC
7803 "Specify one of the following options:\n"
7804 "devlist list all CAM devices\n"
7805 "periphlist list all CAM peripheral drivers attached to a device\n"
7806 "tur send a test unit ready to the named device\n"
7807 "inquiry send a SCSI inquiry command to the named device\n"
7808 "identify send a ATA identify command to the named device\n"
7809 "reportluns send a SCSI report luns command to the device\n"
7810 "readcap send a SCSI read capacity command to the device\n"
7811 "start send a Start Unit command to the device\n"
7812 "stop send a Stop Unit command to the device\n"
7813 "load send a Start Unit command to the device with the load bit set\n"
7814 "eject send a Stop Unit command to the device with the eject bit set\n"
7815 "rescan rescan all busses, the given bus, or bus:target:lun\n"
7816 "reset reset all busses, the given bus, or bus:target:lun\n"
7817 "defects read the defect list of the specified device\n"
7818 "modepage display or edit (-e) the given mode page\n"
7819 "cmd send the given SCSI command, may need -i or -o as well\n"
7820 "smpcmd send the given SMP command, requires -o and -i\n"
7821 "smprg send the SMP Report General command\n"
7822 "smppc send the SMP PHY Control command, requires -p\n"
7823 "smpphylist display phys attached to a SAS expander\n"
7824 "smpmaninfo send the SMP Report Manufacturer Info command\n"
7825 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
7826 "tags report or set the number of transaction slots for a device\n"
7827 "negotiate report or set device negotiation parameters\n"
7828 "format send the SCSI FORMAT UNIT command to the named device\n"
7829 "sanitize send the SCSI SANITIZE command to the named device\n"
7830 "idle send the ATA IDLE command to the named device\n"
7831 "standby send the ATA STANDBY command to the named device\n"
7832 "sleep send the ATA SLEEP command to the named device\n"
7833 "fwdownload program firmware of the named device with the given image"
7834 "security report or send ATA security commands to the named device\n"
7835 "help this message\n"
7836 "Device Identifiers:\n"
7837 "bus:target specify the bus and target, lun defaults to 0\n"
7838 "bus:target:lun specify the bus, target and lun\n"
7839 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
7840 "Generic arguments:\n"
7841 "-v be verbose, print out sense information\n"
7842 "-t timeout command timeout in seconds, overrides default timeout\n"
7843 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
7844 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
7845 "-E have the kernel attempt to perform SCSI error recovery\n"
7846 "-C count specify the SCSI command retry count (needs -E to work)\n"
7847 "modepage arguments:\n"
7848 "-l list all available mode pages\n"
7849 "-m page specify the mode page to view or edit\n"
7850 "-e edit the specified mode page\n"
7851 "-b force view to binary mode\n"
7852 "-d disable block descriptors for mode sense\n"
7853 "-P pgctl page control field 0-3\n"
7854 "defects arguments:\n"
7855 "-f format specify defect list format (block, bfi or phys)\n"
7856 "-G get the grown defect list\n"
7857 "-P get the permanent defect list\n"
7858 "inquiry arguments:\n"
7859 "-D get the standard inquiry data\n"
7860 "-S get the serial number\n"
7861 "-R get the transfer rate, etc.\n"
7862 "reportluns arguments:\n"
7863 "-c only report a count of available LUNs\n"
7864 "-l only print out luns, and not a count\n"
7865 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
7866 "readcap arguments\n"
7867 "-b only report the blocksize\n"
7868 "-h human readable device size, base 2\n"
7869 "-H human readable device size, base 10\n"
7870 "-N print the number of blocks instead of last block\n"
7871 "-q quiet, print numbers only\n"
7872 "-s only report the last block/device size\n"
7874 "-c cdb [args] specify the SCSI CDB\n"
7875 "-i len fmt specify input data and input data format\n"
7876 "-o len fmt [args] specify output data and output data fmt\n"
7877 "smpcmd arguments:\n"
7878 "-r len fmt [args] specify the SMP command to be sent\n"
7879 "-R len fmt [args] specify SMP response format\n"
7880 "smprg arguments:\n"
7881 "-l specify the long response format\n"
7882 "smppc arguments:\n"
7883 "-p phy specify the PHY to operate on\n"
7884 "-l specify the long request/response format\n"
7885 "-o operation specify the phy control operation\n"
7886 "-d name set the attached device name\n"
7887 "-m rate set the minimum physical link rate\n"
7888 "-M rate set the maximum physical link rate\n"
7889 "-T pp_timeout set the partial pathway timeout value\n"
7890 "-a enable|disable enable or disable SATA slumber\n"
7891 "-A enable|disable enable or disable SATA partial phy power\n"
7892 "-s enable|disable enable or disable SAS slumber\n"
7893 "-S enable|disable enable or disable SAS partial phy power\n"
7894 "smpphylist arguments:\n"
7895 "-l specify the long response format\n"
7896 "-q only print phys with attached devices\n"
7897 "smpmaninfo arguments:\n"
7898 "-l specify the long response format\n"
7899 "debug arguments:\n"
7900 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
7901 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
7902 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
7903 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
7905 "-N tags specify the number of tags to use for this device\n"
7906 "-q be quiet, don't report the number of tags\n"
7907 "-v report a number of tag-related parameters\n"
7908 "negotiate arguments:\n"
7909 "-a send a test unit ready after negotiation\n"
7910 "-c report/set current negotiation settings\n"
7911 "-D <arg> \"enable\" or \"disable\" disconnection\n"
7912 "-M mode set ATA mode\n"
7913 "-O offset set command delay offset\n"
7914 "-q be quiet, don't report anything\n"
7915 "-R syncrate synchronization rate in MHz\n"
7916 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
7917 "-U report/set user negotiation settings\n"
7918 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
7919 "-v also print a Path Inquiry CCB for the controller\n"
7920 "format arguments:\n"
7921 "-q be quiet, don't print status messages\n"
7922 "-r run in report only mode\n"
7923 "-w don't send immediate format command\n"
7924 "-y don't ask any questions\n"
7925 "sanitize arguments:\n"
7926 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
7927 "-c passes overwrite passes to perform (1 to 31)\n"
7928 "-I invert overwrite pattern after each pass\n"
7929 "-P pattern path to overwrite pattern file\n"
7930 "-q be quiet, don't print status messages\n"
7931 "-r run in report only mode\n"
7932 "-U run operation in unrestricted completion exit mode\n"
7933 "-w don't send immediate sanitize command\n"
7934 "-y don't ask any questions\n"
7935 "idle/standby arguments:\n"
7936 "-t <arg> number of seconds before respective state.\n"
7937 "fwdownload arguments:\n"
7938 "-f fw_image path to firmware image file\n"
7939 "-y don't ask any questions\n"
7940 "-s run in simulation mode\n"
7941 "-v print info for every firmware segment sent to device\n"
7942 "security arguments:\n"
7943 "-d pwd disable security using the given password for the selected\n"
7945 "-e pwd erase the device using the given pwd for the selected user\n"
7946 "-f freeze the security configuration of the specified device\n"
7947 "-h pwd enhanced erase the device using the given pwd for the\n"
7949 "-k pwd unlock the device using the given pwd for the selected\n"
7951 "-l <high|maximum> specifies which security level to set: high or maximum\n"
7952 "-q be quiet, do not print any status messages\n"
7953 "-s pwd password the device (enable security) using the given\n"
7954 " pwd for the selected user\n"
7955 "-T timeout overrides the timeout (seconds) used for erase operation\n"
7956 "-U <user|master> specifies which user to set: user or master\n"
7957 "-y don't ask any questions\n"
7959 "-f freeze the HPA configuration of the device\n"
7960 "-l lock the HPA configuration of the device\n"
7961 "-P make the HPA max sectors persist\n"
7962 "-p pwd Set the HPA configuration password required for unlock\n"
7964 "-q be quiet, do not print any status messages\n"
7965 "-s sectors configures the maximum user accessible sectors of the\n"
7967 "-U pwd unlock the HPA configuration of the device\n"
7968 "-y don't ask any questions\n"
7970 #endif /* MINIMALISTIC */
7974 main(int argc, char **argv)
7977 char *device = NULL;
7979 struct cam_device *cam_dev = NULL;
7980 int timeout = 0, retry_count = 1;
7981 camcontrol_optret optreturn;
7983 const char *mainopt = "C:En:t:u:v";
7984 const char *subopt = NULL;
7985 char combinedopt[256];
7986 int error = 0, optstart = 2;
7988 #ifndef MINIMALISTIC
7989 int bus, target, lun;
7990 #endif /* MINIMALISTIC */
7992 cmdlist = CAM_CMD_NONE;
7993 arglist = CAM_ARG_NONE;
8001 * Get the base option.
8003 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
8005 if (optreturn == CC_OR_AMBIGUOUS) {
8006 warnx("ambiguous option %s", argv[1]);
8009 } else if (optreturn == CC_OR_NOT_FOUND) {
8010 warnx("option %s not found", argv[1]);
8016 * Ahh, getopt(3) is a pain.
8018 * This is a gross hack. There really aren't many other good
8019 * options (excuse the pun) for parsing options in a situation like
8020 * this. getopt is kinda braindead, so you end up having to run
8021 * through the options twice, and give each invocation of getopt
8022 * the option string for the other invocation.
8024 * You would think that you could just have two groups of options.
8025 * The first group would get parsed by the first invocation of
8026 * getopt, and the second group would get parsed by the second
8027 * invocation of getopt. It doesn't quite work out that way. When
8028 * the first invocation of getopt finishes, it leaves optind pointing
8029 * to the argument _after_ the first argument in the second group.
8030 * So when the second invocation of getopt comes around, it doesn't
8031 * recognize the first argument it gets and then bails out.
8033 * A nice alternative would be to have a flag for getopt that says
8034 * "just keep parsing arguments even when you encounter an unknown
8035 * argument", but there isn't one. So there's no real clean way to
8036 * easily parse two sets of arguments without having one invocation
8037 * of getopt know about the other.
8039 * Without this hack, the first invocation of getopt would work as
8040 * long as the generic arguments are first, but the second invocation
8041 * (in the subfunction) would fail in one of two ways. In the case
8042 * where you don't set optreset, it would fail because optind may be
8043 * pointing to the argument after the one it should be pointing at.
8044 * In the case where you do set optreset, and reset optind, it would
8045 * fail because getopt would run into the first set of options, which
8046 * it doesn't understand.
8048 * All of this would "sort of" work if you could somehow figure out
8049 * whether optind had been incremented one option too far. The
8050 * mechanics of that, however, are more daunting than just giving
8051 * both invocations all of the expect options for either invocation.
8053 * Needless to say, I wouldn't mind if someone invented a better
8054 * (non-GPL!) command line parsing interface than getopt. I
8055 * wouldn't mind if someone added more knobs to getopt to make it
8056 * work better. Who knows, I may talk myself into doing it someday,
8057 * if the standards weenies let me. As it is, it just leads to
8058 * hackery like this and causes people to avoid it in some cases.
8060 * KDM, September 8th, 1998
8063 sprintf(combinedopt, "%s%s", mainopt, subopt);
8065 sprintf(combinedopt, "%s", mainopt);
8068 * For these options we do not parse optional device arguments and
8069 * we do not open a passthrough device.
8071 if ((cmdlist == CAM_CMD_RESCAN)
8072 || (cmdlist == CAM_CMD_RESET)
8073 || (cmdlist == CAM_CMD_DEVTREE)
8074 || (cmdlist == CAM_CMD_USAGE)
8075 || (cmdlist == CAM_CMD_DEBUG))
8078 #ifndef MINIMALISTIC
8080 && (argc > 2 && argv[2][0] != '-')) {
8084 if (isdigit(argv[2][0])) {
8085 /* device specified as bus:target[:lun] */
8086 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
8088 errx(1, "numeric device specification must "
8089 "be either bus:target, or "
8091 /* default to 0 if lun was not specified */
8092 if ((arglist & CAM_ARG_LUN) == 0) {
8094 arglist |= CAM_ARG_LUN;
8098 if (cam_get_device(argv[2], name, sizeof name, &unit)
8100 errx(1, "%s", cam_errbuf);
8101 device = strdup(name);
8102 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
8106 #endif /* MINIMALISTIC */
8108 * Start getopt processing at argv[2/3], since we've already
8109 * accepted argv[1..2] as the command name, and as a possible
8115 * Now we run through the argument list looking for generic
8116 * options, and ignoring options that possibly belong to
8119 while ((c = getopt(argc, argv, combinedopt))!= -1){
8122 retry_count = strtol(optarg, NULL, 0);
8123 if (retry_count < 0)
8124 errx(1, "retry count %d is < 0",
8126 arglist |= CAM_ARG_RETRIES;
8129 arglist |= CAM_ARG_ERR_RECOVER;
8132 arglist |= CAM_ARG_DEVICE;
8134 while (isspace(*tstr) && (*tstr != '\0'))
8136 device = (char *)strdup(tstr);
8139 timeout = strtol(optarg, NULL, 0);
8141 errx(1, "invalid timeout %d", timeout);
8142 /* Convert the timeout from seconds to ms */
8144 arglist |= CAM_ARG_TIMEOUT;
8147 arglist |= CAM_ARG_UNIT;
8148 unit = strtol(optarg, NULL, 0);
8151 arglist |= CAM_ARG_VERBOSE;
8158 #ifndef MINIMALISTIC
8160 * For most commands we'll want to open the passthrough device
8161 * associated with the specified device. In the case of the rescan
8162 * commands, we don't use a passthrough device at all, just the
8163 * transport layer device.
8166 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
8167 && (((arglist & CAM_ARG_DEVICE) == 0)
8168 || ((arglist & CAM_ARG_UNIT) == 0))) {
8169 errx(1, "subcommand \"%s\" requires a valid device "
8170 "identifier", argv[1]);
8173 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
8174 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
8175 cam_open_spec_device(device,unit,O_RDWR,NULL)))
8177 errx(1,"%s", cam_errbuf);
8179 #endif /* MINIMALISTIC */
8182 * Reset optind to 2, and reset getopt, so these routines can parse
8183 * the arguments again.
8189 #ifndef MINIMALISTIC
8190 case CAM_CMD_DEVLIST:
8191 error = getdevlist(cam_dev);
8194 error = atahpa(cam_dev, retry_count, timeout,
8195 argc, argv, combinedopt);
8197 #endif /* MINIMALISTIC */
8198 case CAM_CMD_DEVTREE:
8199 error = getdevtree(argc, argv, combinedopt);
8201 #ifndef MINIMALISTIC
8203 error = testunitready(cam_dev, retry_count, timeout, 0);
8205 case CAM_CMD_INQUIRY:
8206 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
8207 retry_count, timeout);
8209 case CAM_CMD_IDENTIFY:
8210 error = ataidentify(cam_dev, retry_count, timeout);
8212 case CAM_CMD_STARTSTOP:
8213 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
8214 arglist & CAM_ARG_EJECT, retry_count,
8217 #endif /* MINIMALISTIC */
8218 case CAM_CMD_RESCAN:
8219 error = dorescan_or_reset(argc, argv, 1);
8222 error = dorescan_or_reset(argc, argv, 0);
8224 #ifndef MINIMALISTIC
8225 case CAM_CMD_READ_DEFECTS:
8226 error = readdefects(cam_dev, argc, argv, combinedopt,
8227 retry_count, timeout);
8229 case CAM_CMD_MODE_PAGE:
8230 modepage(cam_dev, argc, argv, combinedopt,
8231 retry_count, timeout);
8233 case CAM_CMD_SCSI_CMD:
8234 error = scsicmd(cam_dev, argc, argv, combinedopt,
8235 retry_count, timeout);
8237 case CAM_CMD_SMP_CMD:
8238 error = smpcmd(cam_dev, argc, argv, combinedopt,
8239 retry_count, timeout);
8241 case CAM_CMD_SMP_RG:
8242 error = smpreportgeneral(cam_dev, argc, argv,
8243 combinedopt, retry_count,
8246 case CAM_CMD_SMP_PC:
8247 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
8248 retry_count, timeout);
8250 case CAM_CMD_SMP_PHYLIST:
8251 error = smpphylist(cam_dev, argc, argv, combinedopt,
8252 retry_count, timeout);
8254 case CAM_CMD_SMP_MANINFO:
8255 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
8256 retry_count, timeout);
8259 error = camdebug(argc, argv, combinedopt);
8262 error = tagcontrol(cam_dev, argc, argv, combinedopt);
8265 error = ratecontrol(cam_dev, retry_count, timeout,
8266 argc, argv, combinedopt);
8268 case CAM_CMD_FORMAT:
8269 error = scsiformat(cam_dev, argc, argv,
8270 combinedopt, retry_count, timeout);
8272 case CAM_CMD_REPORTLUNS:
8273 error = scsireportluns(cam_dev, argc, argv,
8274 combinedopt, retry_count,
8277 case CAM_CMD_READCAP:
8278 error = scsireadcapacity(cam_dev, argc, argv,
8279 combinedopt, retry_count,
8283 case CAM_CMD_STANDBY:
8285 error = atapm(cam_dev, argc, argv,
8286 combinedopt, retry_count, timeout);
8288 case CAM_CMD_SECURITY:
8289 error = atasecurity(cam_dev, retry_count, timeout,
8290 argc, argv, combinedopt);
8292 case CAM_CMD_DOWNLOAD_FW:
8293 error = fwdownload(cam_dev, argc, argv, combinedopt,
8294 arglist & CAM_ARG_VERBOSE, retry_count, timeout,
8295 get_disk_type(cam_dev));
8297 case CAM_CMD_SANITIZE:
8298 error = scsisanitize(cam_dev, argc, argv,
8299 combinedopt, retry_count, timeout);
8301 #endif /* MINIMALISTIC */
8311 if (cam_dev != NULL)
8312 cam_close_device(cam_dev);