2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
55 #include <cam/cam_debug.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/scsi/scsi_all.h>
58 #include <cam/scsi/scsi_da.h>
59 #include <cam/scsi/scsi_pass.h>
60 #include <cam/scsi/scsi_message.h>
61 #include <cam/scsi/smp_all.h>
62 #include <cam/ata/ata_all.h>
64 #include "camcontrol.h"
67 CAM_CMD_NONE = 0x00000000,
68 CAM_CMD_DEVLIST = 0x00000001,
69 CAM_CMD_TUR = 0x00000002,
70 CAM_CMD_INQUIRY = 0x00000003,
71 CAM_CMD_STARTSTOP = 0x00000004,
72 CAM_CMD_RESCAN = 0x00000005,
73 CAM_CMD_READ_DEFECTS = 0x00000006,
74 CAM_CMD_MODE_PAGE = 0x00000007,
75 CAM_CMD_SCSI_CMD = 0x00000008,
76 CAM_CMD_DEVTREE = 0x00000009,
77 CAM_CMD_USAGE = 0x0000000a,
78 CAM_CMD_DEBUG = 0x0000000b,
79 CAM_CMD_RESET = 0x0000000c,
80 CAM_CMD_FORMAT = 0x0000000d,
81 CAM_CMD_TAG = 0x0000000e,
82 CAM_CMD_RATE = 0x0000000f,
83 CAM_CMD_DETACH = 0x00000010,
84 CAM_CMD_REPORTLUNS = 0x00000011,
85 CAM_CMD_READCAP = 0x00000012,
86 CAM_CMD_IDENTIFY = 0x00000013,
87 CAM_CMD_IDLE = 0x00000014,
88 CAM_CMD_STANDBY = 0x00000015,
89 CAM_CMD_SLEEP = 0x00000016,
90 CAM_CMD_SMP_CMD = 0x00000017,
91 CAM_CMD_SMP_RG = 0x00000018,
92 CAM_CMD_SMP_PC = 0x00000019,
93 CAM_CMD_SMP_PHYLIST = 0x0000001a,
94 CAM_CMD_SMP_MANINFO = 0x0000001b,
95 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
96 CAM_CMD_SECURITY = 0x0000001d,
97 CAM_CMD_HPA = 0x0000001e,
98 CAM_CMD_SANITIZE = 0x0000001f,
102 CAM_ARG_NONE = 0x00000000,
103 CAM_ARG_VERBOSE = 0x00000001,
104 CAM_ARG_DEVICE = 0x00000002,
105 CAM_ARG_BUS = 0x00000004,
106 CAM_ARG_TARGET = 0x00000008,
107 CAM_ARG_LUN = 0x00000010,
108 CAM_ARG_EJECT = 0x00000020,
109 CAM_ARG_UNIT = 0x00000040,
110 CAM_ARG_FORMAT_BLOCK = 0x00000080,
111 CAM_ARG_FORMAT_BFI = 0x00000100,
112 CAM_ARG_FORMAT_PHYS = 0x00000200,
113 CAM_ARG_PLIST = 0x00000400,
114 CAM_ARG_GLIST = 0x00000800,
115 CAM_ARG_GET_SERIAL = 0x00001000,
116 CAM_ARG_GET_STDINQ = 0x00002000,
117 CAM_ARG_GET_XFERRATE = 0x00004000,
118 CAM_ARG_INQ_MASK = 0x00007000,
119 CAM_ARG_MODE_EDIT = 0x00008000,
120 CAM_ARG_PAGE_CNTL = 0x00010000,
121 CAM_ARG_TIMEOUT = 0x00020000,
122 CAM_ARG_CMD_IN = 0x00040000,
123 CAM_ARG_CMD_OUT = 0x00080000,
124 CAM_ARG_DBD = 0x00100000,
125 CAM_ARG_ERR_RECOVER = 0x00200000,
126 CAM_ARG_RETRIES = 0x00400000,
127 CAM_ARG_START_UNIT = 0x00800000,
128 CAM_ARG_DEBUG_INFO = 0x01000000,
129 CAM_ARG_DEBUG_TRACE = 0x02000000,
130 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
131 CAM_ARG_DEBUG_CDB = 0x08000000,
132 CAM_ARG_DEBUG_XPT = 0x10000000,
133 CAM_ARG_DEBUG_PERIPH = 0x20000000,
134 CAM_ARG_DEBUG_PROBE = 0x40000000,
137 struct camcontrol_opts {
145 struct ata_res_pass16 {
146 u_int16_t reserved[5];
149 u_int8_t sector_count_exp;
150 u_int8_t sector_count;
151 u_int8_t lba_low_exp;
153 u_int8_t lba_mid_exp;
155 u_int8_t lba_high_exp;
161 struct ata_set_max_pwd
164 u_int8_t password[32];
165 u_int16_t reserved2[239];
168 static const char scsicmd_opts[] = "a:c:dfi:o:r";
169 static const char readdefect_opts[] = "f:GP";
170 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
171 static const char smprg_opts[] = "l";
172 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
173 static const char smpphylist_opts[] = "lq";
177 static struct camcontrol_opts option_table[] = {
179 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
180 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
181 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
182 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
183 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
184 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
185 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
186 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
187 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
188 #endif /* MINIMALISTIC */
189 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
190 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
192 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
193 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
194 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
195 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
196 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
197 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
198 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
199 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
200 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
201 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
202 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
203 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
204 #endif /* MINIMALISTIC */
205 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL},
207 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
208 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
209 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
210 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
211 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
212 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
213 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
214 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
215 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
216 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
217 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
218 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:ys"},
219 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
220 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
221 #endif /* MINIMALISTIC */
222 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
223 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
224 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
235 struct device_match_result dev_match;
237 struct periph_match_result *periph_matches;
238 struct scsi_vpd_device_id *device_id;
240 STAILQ_ENTRY(cam_devitem) links;
244 STAILQ_HEAD(, cam_devitem) dev_queue;
248 static cam_cmdmask cmdlist;
249 static cam_argmask arglist;
251 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
252 uint32_t *cmdnum, cam_argmask *argnum,
253 const char **subopt);
255 static int getdevlist(struct cam_device *device);
256 #endif /* MINIMALISTIC */
257 static int getdevtree(void);
259 static int testunitready(struct cam_device *device, int retry_count,
260 int timeout, int quiet);
261 static int scsistart(struct cam_device *device, int startstop, int loadeject,
262 int retry_count, int timeout);
263 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
264 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
265 static int camxferrate(struct cam_device *device);
266 #endif /* MINIMALISTIC */
267 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
268 lun_id_t *lun, cam_argmask *arglst);
269 static int dorescan_or_reset(int argc, char **argv, int rescan);
270 static int rescan_or_reset_bus(path_id_t bus, int rescan);
271 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
272 lun_id_t lun, int scan);
274 static int readdefects(struct cam_device *device, int argc, char **argv,
275 char *combinedopt, int retry_count, int timeout);
276 static void modepage(struct cam_device *device, int argc, char **argv,
277 char *combinedopt, int retry_count, int timeout);
278 static int scsicmd(struct cam_device *device, int argc, char **argv,
279 char *combinedopt, int retry_count, int timeout);
280 static int smpcmd(struct cam_device *device, int argc, char **argv,
281 char *combinedopt, int retry_count, int timeout);
282 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
283 char *combinedopt, int retry_count, int timeout);
284 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
285 char *combinedopt, int retry_count, int timeout);
286 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
287 char *combinedopt, int retry_count, int timeout);
288 static int getdevid(struct cam_devitem *item);
289 static int buildbusdevlist(struct cam_devlist *devlist);
290 static void freebusdevlist(struct cam_devlist *devlist);
291 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
293 static int smpphylist(struct cam_device *device, int argc, char **argv,
294 char *combinedopt, int retry_count, int timeout);
295 static int tagcontrol(struct cam_device *device, int argc, char **argv,
297 static void cts_print(struct cam_device *device,
298 struct ccb_trans_settings *cts);
299 static void cpi_print(struct ccb_pathinq *cpi);
300 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
301 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
302 static int get_print_cts(struct cam_device *device, int user_settings,
303 int quiet, struct ccb_trans_settings *cts);
304 static int ratecontrol(struct cam_device *device, int retry_count,
305 int timeout, int argc, char **argv, char *combinedopt);
306 static int scsiformat(struct cam_device *device, int argc, char **argv,
307 char *combinedopt, int retry_count, int timeout);
308 static int scsisanitize(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int retry_count, int timeout);
310 static int scsireportluns(struct cam_device *device, int argc, char **argv,
311 char *combinedopt, int retry_count, int timeout);
312 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
313 char *combinedopt, int retry_count, int timeout);
314 static int atapm(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int retry_count, int timeout);
316 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
317 int argc, char **argv, char *combinedopt);
318 static int atahpa(struct cam_device *device, int retry_count, int timeout,
319 int argc, char **argv, char *combinedopt);
321 #endif /* MINIMALISTIC */
323 #define min(a,b) (((a)<(b))?(a):(b))
326 #define max(a,b) (((a)>(b))?(a):(b))
330 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
331 cam_argmask *argnum, const char **subopt)
333 struct camcontrol_opts *opts;
336 for (opts = table; (opts != NULL) && (opts->optname != NULL);
338 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
339 *cmdnum = opts->cmdnum;
340 *argnum = opts->argnum;
341 *subopt = opts->subopt;
342 if (++num_matches > 1)
343 return(CC_OR_AMBIGUOUS);
350 return(CC_OR_NOT_FOUND);
355 getdevlist(struct cam_device *device)
361 ccb = cam_getccb(device);
363 ccb->ccb_h.func_code = XPT_GDEVLIST;
364 ccb->ccb_h.flags = CAM_DIR_NONE;
365 ccb->ccb_h.retry_count = 1;
367 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
368 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
369 if (cam_send_ccb(device, ccb) < 0) {
370 perror("error getting device list");
377 switch (ccb->cgdl.status) {
378 case CAM_GDEVLIST_MORE_DEVS:
379 strcpy(status, "MORE");
381 case CAM_GDEVLIST_LAST_DEVICE:
382 strcpy(status, "LAST");
384 case CAM_GDEVLIST_LIST_CHANGED:
385 strcpy(status, "CHANGED");
387 case CAM_GDEVLIST_ERROR:
388 strcpy(status, "ERROR");
393 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
394 ccb->cgdl.periph_name,
395 ccb->cgdl.unit_number,
396 ccb->cgdl.generation,
401 * If the list has changed, we need to start over from the
404 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
412 #endif /* MINIMALISTIC */
424 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
425 warn("couldn't open %s", XPT_DEVICE);
429 bzero(&ccb, sizeof(union ccb));
431 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
432 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
433 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
435 ccb.ccb_h.func_code = XPT_DEV_MATCH;
436 bufsize = sizeof(struct dev_match_result) * 100;
437 ccb.cdm.match_buf_len = bufsize;
438 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
439 if (ccb.cdm.matches == NULL) {
440 warnx("can't malloc memory for matches");
444 ccb.cdm.num_matches = 0;
447 * We fetch all nodes, since we display most of them in the default
448 * case, and all in the verbose case.
450 ccb.cdm.num_patterns = 0;
451 ccb.cdm.pattern_buf_len = 0;
454 * We do the ioctl multiple times if necessary, in case there are
455 * more than 100 nodes in the EDT.
458 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
459 warn("error sending CAMIOCOMMAND ioctl");
464 if ((ccb.ccb_h.status != CAM_REQ_CMP)
465 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
466 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
467 warnx("got CAM error %#x, CDM error %d\n",
468 ccb.ccb_h.status, ccb.cdm.status);
473 for (i = 0; i < ccb.cdm.num_matches; i++) {
474 switch (ccb.cdm.matches[i].type) {
475 case DEV_MATCH_BUS: {
476 struct bus_match_result *bus_result;
479 * Only print the bus information if the
480 * user turns on the verbose flag.
482 if ((arglist & CAM_ARG_VERBOSE) == 0)
486 &ccb.cdm.matches[i].result.bus_result;
489 fprintf(stdout, ")\n");
493 fprintf(stdout, "scbus%d on %s%d bus %d:\n",
495 bus_result->dev_name,
496 bus_result->unit_number,
500 case DEV_MATCH_DEVICE: {
501 struct device_match_result *dev_result;
502 char vendor[16], product[48], revision[16];
503 char fw[5], tmpstr[256];
506 &ccb.cdm.matches[i].result.device_result;
508 if ((dev_result->flags
509 & DEV_RESULT_UNCONFIGURED)
510 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
516 if (dev_result->protocol == PROTO_SCSI) {
517 cam_strvis(vendor, dev_result->inq_data.vendor,
518 sizeof(dev_result->inq_data.vendor),
521 dev_result->inq_data.product,
522 sizeof(dev_result->inq_data.product),
525 dev_result->inq_data.revision,
526 sizeof(dev_result->inq_data.revision),
528 sprintf(tmpstr, "<%s %s %s>", vendor, product,
530 } else if (dev_result->protocol == PROTO_ATA ||
531 dev_result->protocol == PROTO_SATAPM) {
533 dev_result->ident_data.model,
534 sizeof(dev_result->ident_data.model),
537 dev_result->ident_data.revision,
538 sizeof(dev_result->ident_data.revision),
540 sprintf(tmpstr, "<%s %s>", product,
542 } else if (dev_result->protocol == PROTO_SEMB) {
543 struct sep_identify_data *sid;
545 sid = (struct sep_identify_data *)
546 &dev_result->ident_data;
547 cam_strvis(vendor, sid->vendor_id,
548 sizeof(sid->vendor_id),
550 cam_strvis(product, sid->product_id,
551 sizeof(sid->product_id),
553 cam_strvis(revision, sid->product_rev,
554 sizeof(sid->product_rev),
556 cam_strvis(fw, sid->firmware_rev,
557 sizeof(sid->firmware_rev),
559 sprintf(tmpstr, "<%s %s %s %s>",
560 vendor, product, revision, fw);
562 sprintf(tmpstr, "<>");
565 fprintf(stdout, ")\n");
569 fprintf(stdout, "%-33s at scbus%d "
570 "target %d lun %d (",
573 dev_result->target_id,
574 dev_result->target_lun);
580 case DEV_MATCH_PERIPH: {
581 struct periph_match_result *periph_result;
584 &ccb.cdm.matches[i].result.periph_result;
586 if (skip_device != 0)
590 fprintf(stdout, ",");
592 fprintf(stdout, "%s%d",
593 periph_result->periph_name,
594 periph_result->unit_number);
600 fprintf(stdout, "unknown match type\n");
605 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
606 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
609 fprintf(stdout, ")\n");
618 testunitready(struct cam_device *device, int retry_count, int timeout,
624 ccb = cam_getccb(device);
626 scsi_test_unit_ready(&ccb->csio,
627 /* retries */ retry_count,
629 /* tag_action */ MSG_SIMPLE_Q_TAG,
630 /* sense_len */ SSD_FULL_SIZE,
631 /* timeout */ timeout ? timeout : 5000);
633 /* Disable freezing the device queue */
634 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
636 if (arglist & CAM_ARG_ERR_RECOVER)
637 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
639 if (cam_send_ccb(device, ccb) < 0) {
641 perror("error sending test unit ready");
643 if (arglist & CAM_ARG_VERBOSE) {
644 cam_error_print(device, ccb, CAM_ESF_ALL,
645 CAM_EPF_ALL, stderr);
652 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
654 fprintf(stdout, "Unit is ready\n");
657 fprintf(stdout, "Unit is not ready\n");
660 if (arglist & CAM_ARG_VERBOSE) {
661 cam_error_print(device, ccb, CAM_ESF_ALL,
662 CAM_EPF_ALL, stderr);
672 scsistart(struct cam_device *device, int startstop, int loadeject,
673 int retry_count, int timeout)
678 ccb = cam_getccb(device);
681 * If we're stopping, send an ordered tag so the drive in question
682 * will finish any previously queued writes before stopping. If
683 * the device isn't capable of tagged queueing, or if tagged
684 * queueing is turned off, the tag action is a no-op.
686 scsi_start_stop(&ccb->csio,
687 /* retries */ retry_count,
689 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
691 /* start/stop */ startstop,
692 /* load_eject */ loadeject,
694 /* sense_len */ SSD_FULL_SIZE,
695 /* timeout */ timeout ? timeout : 120000);
697 /* Disable freezing the device queue */
698 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
700 if (arglist & CAM_ARG_ERR_RECOVER)
701 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
703 if (cam_send_ccb(device, ccb) < 0) {
704 perror("error sending start unit");
706 if (arglist & CAM_ARG_VERBOSE) {
707 cam_error_print(device, ccb, CAM_ESF_ALL,
708 CAM_EPF_ALL, stderr);
715 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
717 fprintf(stdout, "Unit started successfully");
719 fprintf(stdout,", Media loaded\n");
721 fprintf(stdout,"\n");
723 fprintf(stdout, "Unit stopped successfully");
725 fprintf(stdout, ", Media ejected\n");
727 fprintf(stdout, "\n");
733 "Error received from start unit command\n");
736 "Error received from stop unit command\n");
738 if (arglist & CAM_ARG_VERBOSE) {
739 cam_error_print(device, ccb, CAM_ESF_ALL,
740 CAM_EPF_ALL, stderr);
750 scsidoinquiry(struct cam_device *device, int argc, char **argv,
751 char *combinedopt, int retry_count, int timeout)
756 while ((c = getopt(argc, argv, combinedopt)) != -1) {
759 arglist |= CAM_ARG_GET_STDINQ;
762 arglist |= CAM_ARG_GET_XFERRATE;
765 arglist |= CAM_ARG_GET_SERIAL;
773 * If the user didn't specify any inquiry options, he wants all of
776 if ((arglist & CAM_ARG_INQ_MASK) == 0)
777 arglist |= CAM_ARG_INQ_MASK;
779 if (arglist & CAM_ARG_GET_STDINQ)
780 error = scsiinquiry(device, retry_count, timeout);
785 if (arglist & CAM_ARG_GET_SERIAL)
786 scsiserial(device, retry_count, timeout);
791 if (arglist & CAM_ARG_GET_XFERRATE)
792 error = camxferrate(device);
798 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
801 struct scsi_inquiry_data *inq_buf;
804 ccb = cam_getccb(device);
807 warnx("couldn't allocate CCB");
811 /* cam_getccb cleans up the header, caller has to zero the payload */
812 bzero(&(&ccb->ccb_h)[1],
813 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
815 inq_buf = (struct scsi_inquiry_data *)malloc(
816 sizeof(struct scsi_inquiry_data));
818 if (inq_buf == NULL) {
820 warnx("can't malloc memory for inquiry\n");
823 bzero(inq_buf, sizeof(*inq_buf));
826 * Note that although the size of the inquiry buffer is the full
827 * 256 bytes specified in the SCSI spec, we only tell the device
828 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
829 * two reasons for this:
831 * - The SCSI spec says that when a length field is only 1 byte,
832 * a value of 0 will be interpreted as 256. Therefore
833 * scsi_inquiry() will convert an inq_len (which is passed in as
834 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
835 * to 0. Evidently, very few devices meet the spec in that
836 * regard. Some devices, like many Seagate disks, take the 0 as
837 * 0, and don't return any data. One Pioneer DVD-R drive
838 * returns more data than the command asked for.
840 * So, since there are numerous devices that just don't work
841 * right with the full inquiry size, we don't send the full size.
843 * - The second reason not to use the full inquiry data length is
844 * that we don't need it here. The only reason we issue a
845 * standard inquiry is to get the vendor name, device name,
846 * and revision so scsi_print_inquiry() can print them.
848 * If, at some point in the future, more inquiry data is needed for
849 * some reason, this code should use a procedure similar to the
850 * probe code. i.e., issue a short inquiry, and determine from
851 * the additional length passed back from the device how much
852 * inquiry data the device supports. Once the amount the device
853 * supports is determined, issue an inquiry for that amount and no
858 scsi_inquiry(&ccb->csio,
859 /* retries */ retry_count,
861 /* tag_action */ MSG_SIMPLE_Q_TAG,
862 /* inq_buf */ (u_int8_t *)inq_buf,
863 /* inq_len */ SHORT_INQUIRY_LENGTH,
866 /* sense_len */ SSD_FULL_SIZE,
867 /* timeout */ timeout ? timeout : 5000);
869 /* Disable freezing the device queue */
870 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
872 if (arglist & CAM_ARG_ERR_RECOVER)
873 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
875 if (cam_send_ccb(device, ccb) < 0) {
876 perror("error sending SCSI inquiry");
878 if (arglist & CAM_ARG_VERBOSE) {
879 cam_error_print(device, ccb, CAM_ESF_ALL,
880 CAM_EPF_ALL, stderr);
887 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
890 if (arglist & CAM_ARG_VERBOSE) {
891 cam_error_print(device, ccb, CAM_ESF_ALL,
892 CAM_EPF_ALL, stderr);
903 fprintf(stdout, "%s%d: ", device->device_name,
904 device->dev_unit_num);
905 scsi_print_inquiry(inq_buf);
913 scsiserial(struct cam_device *device, int retry_count, int timeout)
916 struct scsi_vpd_unit_serial_number *serial_buf;
917 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
920 ccb = cam_getccb(device);
923 warnx("couldn't allocate CCB");
927 /* cam_getccb cleans up the header, caller has to zero the payload */
928 bzero(&(&ccb->ccb_h)[1],
929 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
931 serial_buf = (struct scsi_vpd_unit_serial_number *)
932 malloc(sizeof(*serial_buf));
934 if (serial_buf == NULL) {
936 warnx("can't malloc memory for serial number");
940 scsi_inquiry(&ccb->csio,
941 /*retries*/ retry_count,
943 /* tag_action */ MSG_SIMPLE_Q_TAG,
944 /* inq_buf */ (u_int8_t *)serial_buf,
945 /* inq_len */ sizeof(*serial_buf),
947 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
948 /* sense_len */ SSD_FULL_SIZE,
949 /* timeout */ timeout ? timeout : 5000);
951 /* Disable freezing the device queue */
952 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
954 if (arglist & CAM_ARG_ERR_RECOVER)
955 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
957 if (cam_send_ccb(device, ccb) < 0) {
958 warn("error getting serial number");
960 if (arglist & CAM_ARG_VERBOSE) {
961 cam_error_print(device, ccb, CAM_ESF_ALL,
962 CAM_EPF_ALL, stderr);
970 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
973 if (arglist & CAM_ARG_VERBOSE) {
974 cam_error_print(device, ccb, CAM_ESF_ALL,
975 CAM_EPF_ALL, stderr);
986 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
987 serial_num[serial_buf->length] = '\0';
989 if ((arglist & CAM_ARG_GET_STDINQ)
990 || (arglist & CAM_ARG_GET_XFERRATE))
991 fprintf(stdout, "%s%d: Serial Number ",
992 device->device_name, device->dev_unit_num);
994 fprintf(stdout, "%.60s\n", serial_num);
1002 camxferrate(struct cam_device *device)
1004 struct ccb_pathinq cpi;
1006 u_int32_t speed = 0;
1011 if ((retval = get_cpi(device, &cpi)) != 0)
1014 ccb = cam_getccb(device);
1017 warnx("couldn't allocate CCB");
1021 bzero(&(&ccb->ccb_h)[1],
1022 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
1024 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1025 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1027 if (((retval = cam_send_ccb(device, ccb)) < 0)
1028 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1029 const char error_string[] = "error getting transfer settings";
1034 warnx(error_string);
1036 if (arglist & CAM_ARG_VERBOSE)
1037 cam_error_print(device, ccb, CAM_ESF_ALL,
1038 CAM_EPF_ALL, stderr);
1042 goto xferrate_bailout;
1046 speed = cpi.base_transfer_speed;
1048 if (ccb->cts.transport == XPORT_SPI) {
1049 struct ccb_trans_settings_spi *spi =
1050 &ccb->cts.xport_specific.spi;
1052 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1053 freq = scsi_calc_syncsrate(spi->sync_period);
1056 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1057 speed *= (0x01 << spi->bus_width);
1059 } else if (ccb->cts.transport == XPORT_FC) {
1060 struct ccb_trans_settings_fc *fc =
1061 &ccb->cts.xport_specific.fc;
1063 if (fc->valid & CTS_FC_VALID_SPEED)
1064 speed = fc->bitrate;
1065 } else if (ccb->cts.transport == XPORT_SAS) {
1066 struct ccb_trans_settings_sas *sas =
1067 &ccb->cts.xport_specific.sas;
1069 if (sas->valid & CTS_SAS_VALID_SPEED)
1070 speed = sas->bitrate;
1071 } else if (ccb->cts.transport == XPORT_ATA) {
1072 struct ccb_trans_settings_pata *pata =
1073 &ccb->cts.xport_specific.ata;
1075 if (pata->valid & CTS_ATA_VALID_MODE)
1076 speed = ata_mode2speed(pata->mode);
1077 } else if (ccb->cts.transport == XPORT_SATA) {
1078 struct ccb_trans_settings_sata *sata =
1079 &ccb->cts.xport_specific.sata;
1081 if (sata->valid & CTS_SATA_VALID_REVISION)
1082 speed = ata_revision2speed(sata->revision);
1087 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1088 device->device_name, device->dev_unit_num,
1091 fprintf(stdout, "%s%d: %dKB/s transfers",
1092 device->device_name, device->dev_unit_num,
1096 if (ccb->cts.transport == XPORT_SPI) {
1097 struct ccb_trans_settings_spi *spi =
1098 &ccb->cts.xport_specific.spi;
1100 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1101 && (spi->sync_offset != 0))
1102 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1103 freq % 1000, spi->sync_offset);
1105 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1106 && (spi->bus_width > 0)) {
1107 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1108 && (spi->sync_offset != 0)) {
1109 fprintf(stdout, ", ");
1111 fprintf(stdout, " (");
1113 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1114 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1115 && (spi->sync_offset != 0)) {
1116 fprintf(stdout, ")");
1118 } else if (ccb->cts.transport == XPORT_ATA) {
1119 struct ccb_trans_settings_pata *pata =
1120 &ccb->cts.xport_specific.ata;
1123 if (pata->valid & CTS_ATA_VALID_MODE)
1124 printf("%s, ", ata_mode2string(pata->mode));
1125 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1126 printf("ATAPI %dbytes, ", pata->atapi);
1127 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1128 printf("PIO %dbytes", pata->bytecount);
1130 } else if (ccb->cts.transport == XPORT_SATA) {
1131 struct ccb_trans_settings_sata *sata =
1132 &ccb->cts.xport_specific.sata;
1135 if (sata->valid & CTS_SATA_VALID_REVISION)
1136 printf("SATA %d.x, ", sata->revision);
1139 if (sata->valid & CTS_SATA_VALID_MODE)
1140 printf("%s, ", ata_mode2string(sata->mode));
1141 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1142 printf("ATAPI %dbytes, ", sata->atapi);
1143 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1144 printf("PIO %dbytes", sata->bytecount);
1148 if (ccb->cts.protocol == PROTO_SCSI) {
1149 struct ccb_trans_settings_scsi *scsi =
1150 &ccb->cts.proto_specific.scsi;
1151 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1152 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1153 fprintf(stdout, ", Command Queueing Enabled");
1158 fprintf(stdout, "\n");
1168 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1170 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1171 ((u_int32_t)parm->lba_size_2 << 16);
1173 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1174 ((u_int64_t)parm->lba_size48_2 << 16) |
1175 ((u_int64_t)parm->lba_size48_3 << 32) |
1176 ((u_int64_t)parm->lba_size48_4 << 48);
1180 "Support Enabled Value\n");
1183 printf("Host Protected Area (HPA) ");
1184 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1185 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1186 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1189 printf("HPA - Security ");
1190 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1200 atasata(struct ata_params *parm)
1204 if (parm->satacapabilities != 0xffff &&
1205 parm->satacapabilities != 0x0000)
1212 atacapprint(struct ata_params *parm)
1214 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1215 ((u_int32_t)parm->lba_size_2 << 16);
1217 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1218 ((u_int64_t)parm->lba_size48_2 << 16) |
1219 ((u_int64_t)parm->lba_size48_3 << 32) |
1220 ((u_int64_t)parm->lba_size48_4 << 48);
1223 printf("protocol ");
1224 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1225 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1226 if (parm->satacapabilities & ATA_SATA_GEN3)
1227 printf(" SATA 3.x\n");
1228 else if (parm->satacapabilities & ATA_SATA_GEN2)
1229 printf(" SATA 2.x\n");
1230 else if (parm->satacapabilities & ATA_SATA_GEN1)
1231 printf(" SATA 1.x\n");
1237 printf("device model %.40s\n", parm->model);
1238 printf("firmware revision %.8s\n", parm->revision);
1239 printf("serial number %.20s\n", parm->serial);
1240 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1241 printf("WWN %04x%04x%04x%04x\n",
1242 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1244 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1245 printf("media serial number %.30s\n",
1246 parm->media_serial);
1249 printf("cylinders %d\n", parm->cylinders);
1250 printf("heads %d\n", parm->heads);
1251 printf("sectors/track %d\n", parm->sectors);
1252 printf("sector size logical %u, physical %lu, offset %lu\n",
1253 ata_logical_sector_size(parm),
1254 (unsigned long)ata_physical_sector_size(parm),
1255 (unsigned long)ata_logical_sector_offset(parm));
1257 if (parm->config == ATA_PROTO_CFA ||
1258 (parm->support.command2 & ATA_SUPPORT_CFA))
1259 printf("CFA supported\n");
1261 printf("LBA%ssupported ",
1262 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1264 printf("%d sectors\n", lbasize);
1268 printf("LBA48%ssupported ",
1269 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1271 printf("%ju sectors\n", (uintmax_t)lbasize48);
1275 printf("PIO supported PIO");
1276 switch (ata_max_pmode(parm)) {
1292 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1293 printf(" w/o IORDY");
1296 printf("DMA%ssupported ",
1297 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1298 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1299 if (parm->mwdmamodes & 0xff) {
1301 if (parm->mwdmamodes & 0x04)
1303 else if (parm->mwdmamodes & 0x02)
1305 else if (parm->mwdmamodes & 0x01)
1309 if ((parm->atavalid & ATA_FLAG_88) &&
1310 (parm->udmamodes & 0xff)) {
1312 if (parm->udmamodes & 0x40)
1314 else if (parm->udmamodes & 0x20)
1316 else if (parm->udmamodes & 0x10)
1318 else if (parm->udmamodes & 0x08)
1320 else if (parm->udmamodes & 0x04)
1322 else if (parm->udmamodes & 0x02)
1324 else if (parm->udmamodes & 0x01)
1331 if (parm->media_rotation_rate == 1) {
1332 printf("media RPM non-rotating\n");
1333 } else if (parm->media_rotation_rate >= 0x0401 &&
1334 parm->media_rotation_rate <= 0xFFFE) {
1335 printf("media RPM %d\n",
1336 parm->media_rotation_rate);
1340 "Support Enabled Value Vendor\n");
1341 printf("read ahead %s %s\n",
1342 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1343 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1344 printf("write cache %s %s\n",
1345 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1346 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1347 printf("flush cache %s %s\n",
1348 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1349 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1350 printf("overlap %s\n",
1351 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1352 printf("Tagged Command Queuing (TCQ) %s %s",
1353 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1354 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1355 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1356 printf(" %d tags\n",
1357 ATA_QUEUE_LEN(parm->queue) + 1);
1360 printf("Native Command Queuing (NCQ) ");
1361 if (parm->satacapabilities != 0xffff &&
1362 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1363 printf("yes %d tags\n",
1364 ATA_QUEUE_LEN(parm->queue) + 1);
1368 printf("NCQ Queue Management %s\n", atasata(parm) &&
1369 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1371 printf("NCQ Streaming %s\n", atasata(parm) &&
1372 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1374 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1375 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1378 printf("SMART %s %s\n",
1379 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1380 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1381 printf("microcode download %s %s\n",
1382 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1383 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1384 printf("security %s %s\n",
1385 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1386 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1387 printf("power management %s %s\n",
1388 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1389 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1390 printf("advanced power management %s %s",
1391 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1392 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1393 if (parm->support.command2 & ATA_SUPPORT_APM) {
1394 printf(" %d/0x%02X\n",
1395 parm->apm_value, parm->apm_value);
1398 printf("automatic acoustic management %s %s",
1399 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1400 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1401 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1402 printf(" %d/0x%02X %d/0x%02X\n",
1403 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1404 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1405 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1406 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1409 printf("media status notification %s %s\n",
1410 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1411 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1412 printf("power-up in Standby %s %s\n",
1413 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1414 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1415 printf("write-read-verify %s %s",
1416 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1417 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1418 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1419 printf(" %d/0x%x\n",
1420 parm->wrv_mode, parm->wrv_mode);
1423 printf("unload %s %s\n",
1424 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1425 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1426 printf("general purpose logging %s %s\n",
1427 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1428 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1429 printf("free-fall %s %s\n",
1430 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1431 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1432 printf("Data Set Management (DSM/TRIM) ");
1433 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1435 printf("DSM - max 512byte blocks ");
1436 if (parm->max_dsm_blocks == 0x00)
1437 printf("yes not specified\n");
1440 parm->max_dsm_blocks);
1442 printf("DSM - deterministic read ");
1443 if (parm->support3 & ATA_SUPPORT_DRAT) {
1444 if (parm->support3 & ATA_SUPPORT_RZAT)
1445 printf("yes zeroed\n");
1447 printf("yes any value\n");
1457 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1459 struct ata_pass_16 *ata_pass_16;
1460 struct ata_cmd ata_cmd;
1462 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1463 ata_cmd.command = ata_pass_16->command;
1464 ata_cmd.control = ata_pass_16->control;
1465 ata_cmd.features = ata_pass_16->features;
1467 if (arglist & CAM_ARG_VERBOSE) {
1468 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1469 ata_op_string(&ata_cmd),
1470 ccb->csio.ccb_h.timeout);
1473 /* Disable freezing the device queue */
1474 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1476 if (arglist & CAM_ARG_ERR_RECOVER)
1477 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1479 if (cam_send_ccb(device, ccb) < 0) {
1480 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1481 warn("error sending ATA %s via pass_16",
1482 ata_op_string(&ata_cmd));
1485 if (arglist & CAM_ARG_VERBOSE) {
1486 cam_error_print(device, ccb, CAM_ESF_ALL,
1487 CAM_EPF_ALL, stderr);
1493 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1494 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1495 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1496 warnx("ATA %s via pass_16 failed",
1497 ata_op_string(&ata_cmd));
1499 if (arglist & CAM_ARG_VERBOSE) {
1500 cam_error_print(device, ccb, CAM_ESF_ALL,
1501 CAM_EPF_ALL, stderr);
1512 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1514 if (arglist & CAM_ARG_VERBOSE) {
1515 warnx("sending ATA %s with timeout of %u msecs",
1516 ata_op_string(&(ccb->ataio.cmd)),
1517 ccb->ataio.ccb_h.timeout);
1520 /* Disable freezing the device queue */
1521 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1523 if (arglist & CAM_ARG_ERR_RECOVER)
1524 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1526 if (cam_send_ccb(device, ccb) < 0) {
1527 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1528 warn("error sending ATA %s",
1529 ata_op_string(&(ccb->ataio.cmd)));
1532 if (arglist & CAM_ARG_VERBOSE) {
1533 cam_error_print(device, ccb, CAM_ESF_ALL,
1534 CAM_EPF_ALL, stderr);
1540 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1541 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1542 warnx("ATA %s failed: %d",
1543 ata_op_string(&(ccb->ataio.cmd)), quiet);
1546 if (arglist & CAM_ARG_VERBOSE) {
1547 cam_error_print(device, ccb, CAM_ESF_ALL,
1548 CAM_EPF_ALL, stderr);
1558 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1559 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1560 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1561 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1562 u_int16_t dxfer_len, int timeout, int quiet)
1564 if (data_ptr != NULL) {
1565 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1566 AP_FLAG_TLEN_SECT_CNT;
1567 if (flags & CAM_DIR_OUT)
1568 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1570 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1572 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1575 bzero(&(&ccb->ccb_h)[1],
1576 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1578 scsi_ata_pass_16(&ccb->csio,
1592 /*sense_len*/SSD_FULL_SIZE,
1595 return scsi_cam_pass_16_send(device, ccb, quiet);
1599 ata_try_pass_16(struct cam_device *device)
1601 struct ccb_pathinq cpi;
1603 if (get_cpi(device, &cpi) != 0) {
1604 warnx("couldn't get CPI");
1608 if (cpi.protocol == PROTO_SCSI) {
1609 /* possibly compatible with pass_16 */
1613 /* likely not compatible with pass_16 */
1618 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1619 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1620 u_int8_t command, u_int8_t features, u_int32_t lba,
1621 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1622 int timeout, int quiet)
1626 switch (ata_try_pass_16(device)) {
1630 /* Try using SCSI Passthrough */
1631 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1632 0, tag_action, command, features, lba,
1633 sector_count, data_ptr, dxfer_len,
1637 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1638 sizeof(struct ccb_hdr));
1639 cam_fill_ataio(&ccb->ataio,
1648 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1649 return ata_cam_send(device, ccb, quiet);
1653 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1654 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1655 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1656 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1657 u_int16_t dxfer_len, int timeout, int force48bit)
1661 retval = ata_try_pass_16(device);
1668 /* Try using SCSI Passthrough */
1669 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1670 ata_flags, tag_action, command, features,
1671 lba, sector_count, data_ptr, dxfer_len,
1674 if (ata_flags & AP_FLAG_CHK_COND) {
1675 /* Decode ata_res from sense data */
1676 struct ata_res_pass16 *res_pass16;
1677 struct ata_res *res;
1681 /* sense_data is 4 byte aligned */
1682 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1683 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1684 ptr[i] = le16toh(ptr[i]);
1686 /* sense_data is 4 byte aligned */
1687 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1688 &ccb->csio.sense_data;
1689 res = &ccb->ataio.res;
1690 res->flags = res_pass16->flags;
1691 res->status = res_pass16->status;
1692 res->error = res_pass16->error;
1693 res->lba_low = res_pass16->lba_low;
1694 res->lba_mid = res_pass16->lba_mid;
1695 res->lba_high = res_pass16->lba_high;
1696 res->device = res_pass16->device;
1697 res->lba_low_exp = res_pass16->lba_low_exp;
1698 res->lba_mid_exp = res_pass16->lba_mid_exp;
1699 res->lba_high_exp = res_pass16->lba_high_exp;
1700 res->sector_count = res_pass16->sector_count;
1701 res->sector_count_exp = res_pass16->sector_count_exp;
1707 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1708 sizeof(struct ccb_hdr));
1709 cam_fill_ataio(&ccb->ataio,
1718 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1719 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1721 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1723 if (ata_flags & AP_FLAG_CHK_COND)
1724 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1726 return ata_cam_send(device, ccb, 0);
1730 dump_data(uint16_t *ptr, uint32_t len)
1734 for (i = 0; i < len / 2; i++) {
1736 printf(" %3d: ", i);
1737 printf("%04hx ", ptr[i]);
1746 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1747 int is48bit, u_int64_t *hpasize)
1749 struct ata_res *res;
1751 res = &ccb->ataio.res;
1752 if (res->status & ATA_STATUS_ERROR) {
1753 if (arglist & CAM_ARG_VERBOSE) {
1754 cam_error_print(device, ccb, CAM_ESF_ALL,
1755 CAM_EPF_ALL, stderr);
1756 printf("error = 0x%02x, sector_count = 0x%04x, "
1757 "device = 0x%02x, status = 0x%02x\n",
1758 res->error, res->sector_count,
1759 res->device, res->status);
1762 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1763 warnx("Max address has already been set since "
1764 "last power-on or hardware reset");
1770 if (arglist & CAM_ARG_VERBOSE) {
1771 fprintf(stdout, "%s%d: Raw native max data:\n",
1772 device->device_name, device->dev_unit_num);
1773 /* res is 4 byte aligned */
1774 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1776 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1777 "status = 0x%02x\n", res->error, res->sector_count,
1778 res->device, res->status);
1781 if (hpasize != NULL) {
1783 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1784 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1785 ((res->lba_high << 16) | (res->lba_mid << 8) |
1788 *hpasize = (((res->device & 0x0f) << 24) |
1789 (res->lba_high << 16) | (res->lba_mid << 8) |
1798 ata_read_native_max(struct cam_device *device, int retry_count,
1799 u_int32_t timeout, union ccb *ccb,
1800 struct ata_params *parm, u_int64_t *hpasize)
1806 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1807 protocol = AP_PROTO_NON_DATA;
1810 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1811 protocol |= AP_EXTEND;
1813 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1816 error = ata_do_cmd(device,
1819 /*flags*/CAM_DIR_NONE,
1820 /*protocol*/protocol,
1821 /*ata_flags*/AP_FLAG_CHK_COND,
1822 /*tag_action*/MSG_SIMPLE_Q_TAG,
1829 timeout ? timeout : 1000,
1835 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1839 atahpa_set_max(struct cam_device *device, int retry_count,
1840 u_int32_t timeout, union ccb *ccb,
1841 int is48bit, u_int64_t maxsize, int persist)
1847 protocol = AP_PROTO_NON_DATA;
1850 cmd = ATA_SET_MAX_ADDRESS48;
1851 protocol |= AP_EXTEND;
1853 cmd = ATA_SET_MAX_ADDRESS;
1856 /* lba's are zero indexed so the max lba is requested max - 1 */
1860 error = ata_do_cmd(device,
1863 /*flags*/CAM_DIR_NONE,
1864 /*protocol*/protocol,
1865 /*ata_flags*/AP_FLAG_CHK_COND,
1866 /*tag_action*/MSG_SIMPLE_Q_TAG,
1868 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1870 /*sector_count*/persist,
1873 timeout ? timeout : 1000,
1879 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1883 atahpa_password(struct cam_device *device, int retry_count,
1884 u_int32_t timeout, union ccb *ccb,
1885 int is48bit, struct ata_set_max_pwd *pwd)
1891 protocol = AP_PROTO_PIO_OUT;
1892 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1894 error = ata_do_cmd(device,
1897 /*flags*/CAM_DIR_OUT,
1898 /*protocol*/protocol,
1899 /*ata_flags*/AP_FLAG_CHK_COND,
1900 /*tag_action*/MSG_SIMPLE_Q_TAG,
1902 /*features*/ATA_HPA_FEAT_SET_PWD,
1905 /*data_ptr*/(u_int8_t*)pwd,
1906 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1907 timeout ? timeout : 1000,
1913 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1917 atahpa_lock(struct cam_device *device, int retry_count,
1918 u_int32_t timeout, union ccb *ccb, int is48bit)
1924 protocol = AP_PROTO_NON_DATA;
1925 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1927 error = ata_do_cmd(device,
1930 /*flags*/CAM_DIR_NONE,
1931 /*protocol*/protocol,
1932 /*ata_flags*/AP_FLAG_CHK_COND,
1933 /*tag_action*/MSG_SIMPLE_Q_TAG,
1935 /*features*/ATA_HPA_FEAT_LOCK,
1940 timeout ? timeout : 1000,
1946 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1950 atahpa_unlock(struct cam_device *device, int retry_count,
1951 u_int32_t timeout, union ccb *ccb,
1952 int is48bit, struct ata_set_max_pwd *pwd)
1958 protocol = AP_PROTO_PIO_OUT;
1959 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1961 error = ata_do_cmd(device,
1964 /*flags*/CAM_DIR_OUT,
1965 /*protocol*/protocol,
1966 /*ata_flags*/AP_FLAG_CHK_COND,
1967 /*tag_action*/MSG_SIMPLE_Q_TAG,
1969 /*features*/ATA_HPA_FEAT_UNLOCK,
1972 /*data_ptr*/(u_int8_t*)pwd,
1973 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1974 timeout ? timeout : 1000,
1980 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1984 atahpa_freeze_lock(struct cam_device *device, int retry_count,
1985 u_int32_t timeout, union ccb *ccb, int is48bit)
1991 protocol = AP_PROTO_NON_DATA;
1992 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1994 error = ata_do_cmd(device,
1997 /*flags*/CAM_DIR_NONE,
1998 /*protocol*/protocol,
1999 /*ata_flags*/AP_FLAG_CHK_COND,
2000 /*tag_action*/MSG_SIMPLE_Q_TAG,
2002 /*features*/ATA_HPA_FEAT_FREEZE,
2007 timeout ? timeout : 1000,
2013 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2018 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2019 union ccb *ccb, struct ata_params** ident_bufp)
2021 struct ata_params *ident_buf;
2022 struct ccb_pathinq cpi;
2023 struct ccb_getdev cgd;
2026 u_int8_t command, retry_command;
2028 if (get_cpi(device, &cpi) != 0) {
2029 warnx("couldn't get CPI");
2033 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2034 if (cpi.protocol == PROTO_ATA) {
2035 if (get_cgd(device, &cgd) != 0) {
2036 warnx("couldn't get CGD");
2040 command = (cgd.protocol == PROTO_ATA) ?
2041 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2044 /* We don't know which for sure so try both */
2045 command = ATA_ATA_IDENTIFY;
2046 retry_command = ATA_ATAPI_IDENTIFY;
2049 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2051 warnx("can't calloc memory for identify\n");
2055 error = ata_do_28bit_cmd(device,
2057 /*retries*/retry_count,
2058 /*flags*/CAM_DIR_IN,
2059 /*protocol*/AP_PROTO_PIO_IN,
2060 /*tag_action*/MSG_SIMPLE_Q_TAG,
2064 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2065 /*data_ptr*/(u_int8_t *)ptr,
2066 /*dxfer_len*/sizeof(struct ata_params),
2067 /*timeout*/timeout ? timeout : 30 * 1000,
2071 if (retry_command == 0) {
2075 error = ata_do_28bit_cmd(device,
2077 /*retries*/retry_count,
2078 /*flags*/CAM_DIR_IN,
2079 /*protocol*/AP_PROTO_PIO_IN,
2080 /*tag_action*/MSG_SIMPLE_Q_TAG,
2081 /*command*/retry_command,
2084 /*sector_count*/(u_int8_t)
2085 sizeof(struct ata_params),
2086 /*data_ptr*/(u_int8_t *)ptr,
2087 /*dxfer_len*/sizeof(struct ata_params),
2088 /*timeout*/timeout ? timeout : 30 * 1000,
2098 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2099 ptr[i] = le16toh(ptr[i]);
2104 if (arglist & CAM_ARG_VERBOSE) {
2105 fprintf(stdout, "%s%d: Raw identify data:\n",
2106 device->device_name, device->dev_unit_num);
2107 dump_data(ptr, sizeof(struct ata_params));
2110 /* check for invalid (all zero) response */
2112 warnx("Invalid identify response detected");
2117 ident_buf = (struct ata_params *)ptr;
2118 if (strncmp(ident_buf->model, "FX", 2) &&
2119 strncmp(ident_buf->model, "NEC", 3) &&
2120 strncmp(ident_buf->model, "Pioneer", 7) &&
2121 strncmp(ident_buf->model, "SHARP", 5)) {
2122 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2123 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2124 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2125 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2127 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2128 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2129 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2130 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2131 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2132 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2133 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2134 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2135 sizeof(ident_buf->media_serial));
2137 *ident_bufp = ident_buf;
2144 ataidentify(struct cam_device *device, int retry_count, int timeout)
2147 struct ata_params *ident_buf;
2150 if ((ccb = cam_getccb(device)) == NULL) {
2151 warnx("couldn't allocate CCB");
2155 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2160 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2161 if (ata_read_native_max(device, retry_count, timeout, ccb,
2162 ident_buf, &hpasize) != 0) {
2170 printf("%s%d: ", device->device_name, device->dev_unit_num);
2171 ata_print_ident(ident_buf);
2172 camxferrate(device);
2173 atacapprint(ident_buf);
2174 atahpa_print(ident_buf, hpasize, 0);
2181 #endif /* MINIMALISTIC */
2184 #ifndef MINIMALISTIC
2186 ATA_SECURITY_ACTION_PRINT,
2187 ATA_SECURITY_ACTION_FREEZE,
2188 ATA_SECURITY_ACTION_UNLOCK,
2189 ATA_SECURITY_ACTION_DISABLE,
2190 ATA_SECURITY_ACTION_ERASE,
2191 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2192 ATA_SECURITY_ACTION_SET_PASSWORD
2193 } atasecurity_action;
2196 atasecurity_print_time(u_int16_t tw)
2200 printf("unspecified");
2202 printf("> 508 min");
2204 printf("%i min", 2 * tw);
2208 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2212 return 2 * 3600 * 1000; /* default: two hours */
2213 else if (timeout > 255)
2214 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2216 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2221 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2225 bzero(&cmd, sizeof(cmd));
2226 cmd.command = command;
2227 printf("Issuing %s", ata_op_string(&cmd));
2230 char pass[sizeof(pwd->password)+1];
2232 /* pwd->password may not be null terminated */
2233 pass[sizeof(pwd->password)] = '\0';
2234 strncpy(pass, pwd->password, sizeof(pwd->password));
2235 printf(" password='%s', user='%s'",
2237 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2240 if (command == ATA_SECURITY_SET_PASSWORD) {
2241 printf(", mode='%s'",
2242 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2243 "maximum" : "high");
2251 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2252 int retry_count, u_int32_t timeout, int quiet)
2256 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2258 return ata_do_28bit_cmd(device,
2261 /*flags*/CAM_DIR_NONE,
2262 /*protocol*/AP_PROTO_NON_DATA,
2263 /*tag_action*/MSG_SIMPLE_Q_TAG,
2264 /*command*/ATA_SECURITY_FREEZE_LOCK,
2275 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2276 int retry_count, u_int32_t timeout,
2277 struct ata_security_password *pwd, int quiet)
2281 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2283 return ata_do_28bit_cmd(device,
2286 /*flags*/CAM_DIR_OUT,
2287 /*protocol*/AP_PROTO_PIO_OUT,
2288 /*tag_action*/MSG_SIMPLE_Q_TAG,
2289 /*command*/ATA_SECURITY_UNLOCK,
2293 /*data_ptr*/(u_int8_t *)pwd,
2294 /*dxfer_len*/sizeof(*pwd),
2300 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2301 int retry_count, u_int32_t timeout,
2302 struct ata_security_password *pwd, int quiet)
2306 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2307 return ata_do_28bit_cmd(device,
2310 /*flags*/CAM_DIR_OUT,
2311 /*protocol*/AP_PROTO_PIO_OUT,
2312 /*tag_action*/MSG_SIMPLE_Q_TAG,
2313 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2317 /*data_ptr*/(u_int8_t *)pwd,
2318 /*dxfer_len*/sizeof(*pwd),
2325 atasecurity_erase_confirm(struct cam_device *device,
2326 struct ata_params* ident_buf)
2329 printf("\nYou are about to ERASE ALL DATA from the following"
2330 " device:\n%s%d,%s%d: ", device->device_name,
2331 device->dev_unit_num, device->given_dev_name,
2332 device->given_unit_number);
2333 ata_print_ident(ident_buf);
2337 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2339 if (fgets(str, sizeof(str), stdin) != NULL) {
2340 if (strncasecmp(str, "yes", 3) == 0) {
2342 } else if (strncasecmp(str, "no", 2) == 0) {
2345 printf("Please answer \"yes\" or "
2356 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2357 int retry_count, u_int32_t timeout,
2358 u_int32_t erase_timeout,
2359 struct ata_security_password *pwd, int quiet)
2364 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2366 error = ata_do_28bit_cmd(device,
2369 /*flags*/CAM_DIR_NONE,
2370 /*protocol*/AP_PROTO_NON_DATA,
2371 /*tag_action*/MSG_SIMPLE_Q_TAG,
2372 /*command*/ATA_SECURITY_ERASE_PREPARE,
2385 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2387 error = ata_do_28bit_cmd(device,
2390 /*flags*/CAM_DIR_OUT,
2391 /*protocol*/AP_PROTO_PIO_OUT,
2392 /*tag_action*/MSG_SIMPLE_Q_TAG,
2393 /*command*/ATA_SECURITY_ERASE_UNIT,
2397 /*data_ptr*/(u_int8_t *)pwd,
2398 /*dxfer_len*/sizeof(*pwd),
2399 /*timeout*/erase_timeout,
2402 if (error == 0 && quiet == 0)
2403 printf("\nErase Complete\n");
2409 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2410 int retry_count, u_int32_t timeout,
2411 struct ata_security_password *pwd, int quiet)
2415 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2417 return ata_do_28bit_cmd(device,
2420 /*flags*/CAM_DIR_OUT,
2421 /*protocol*/AP_PROTO_PIO_OUT,
2422 /*tag_action*/MSG_SIMPLE_Q_TAG,
2423 /*command*/ATA_SECURITY_SET_PASSWORD,
2427 /*data_ptr*/(u_int8_t *)pwd,
2428 /*dxfer_len*/sizeof(*pwd),
2434 atasecurity_print(struct ata_params *parm)
2437 printf("\nSecurity Option Value\n");
2438 if (arglist & CAM_ARG_VERBOSE) {
2439 printf("status %04x\n",
2440 parm->security_status);
2442 printf("supported %s\n",
2443 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2444 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2446 printf("enabled %s\n",
2447 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2448 printf("drive locked %s\n",
2449 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2450 printf("security config frozen %s\n",
2451 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2452 printf("count expired %s\n",
2453 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2454 printf("security level %s\n",
2455 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2456 printf("enhanced erase supported %s\n",
2457 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2458 printf("erase time ");
2459 atasecurity_print_time(parm->erase_time);
2461 printf("enhanced erase time ");
2462 atasecurity_print_time(parm->enhanced_erase_time);
2464 printf("master password rev %04x%s\n",
2465 parm->master_passwd_revision,
2466 parm->master_passwd_revision == 0x0000 ||
2467 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2471 * Validates and copies the password in optarg to the passed buffer.
2472 * If the password in optarg is the same length as the buffer then
2473 * the data will still be copied but no null termination will occur.
2476 ata_getpwd(u_int8_t *passwd, int max, char opt)
2480 len = strlen(optarg);
2482 warnx("-%c password is too long", opt);
2484 } else if (len == 0) {
2485 warnx("-%c password is missing", opt);
2487 } else if (optarg[0] == '-'){
2488 warnx("-%c password starts with '-' (generic arg?)", opt);
2490 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2491 warnx("-%c password conflicts with existing password from -%c",
2496 /* Callers pass in a buffer which does NOT need to be terminated */
2497 strncpy(passwd, optarg, max);
2504 ATA_HPA_ACTION_PRINT,
2505 ATA_HPA_ACTION_SET_MAX,
2506 ATA_HPA_ACTION_SET_PWD,
2507 ATA_HPA_ACTION_LOCK,
2508 ATA_HPA_ACTION_UNLOCK,
2509 ATA_HPA_ACTION_FREEZE_LOCK
2513 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2514 u_int64_t maxsize, int persist)
2516 printf("\nYou are about to configure HPA to limit the user accessible\n"
2517 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2518 persist ? "persistently" : "temporarily",
2519 device->device_name, device->dev_unit_num,
2520 device->given_dev_name, device->given_unit_number);
2521 ata_print_ident(ident_buf);
2525 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2527 if (NULL != fgets(str, sizeof(str), stdin)) {
2528 if (0 == strncasecmp(str, "yes", 3)) {
2530 } else if (0 == strncasecmp(str, "no", 2)) {
2533 printf("Please answer \"yes\" or "
2544 atahpa(struct cam_device *device, int retry_count, int timeout,
2545 int argc, char **argv, char *combinedopt)
2548 struct ata_params *ident_buf;
2549 struct ccb_getdev cgd;
2550 struct ata_set_max_pwd pwd;
2551 int error, confirm, quiet, c, action, actions, setpwd, persist;
2552 int security, is48bit, pwdsize;
2553 u_int64_t hpasize, maxsize;
2563 memset(&pwd, 0, sizeof(pwd));
2565 /* default action is to print hpa information */
2566 action = ATA_HPA_ACTION_PRINT;
2567 pwdsize = sizeof(pwd.password);
2569 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2572 action = ATA_HPA_ACTION_SET_MAX;
2573 maxsize = strtoumax(optarg, NULL, 0);
2578 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2580 action = ATA_HPA_ACTION_SET_PWD;
2586 action = ATA_HPA_ACTION_LOCK;
2592 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2594 action = ATA_HPA_ACTION_UNLOCK;
2600 action = ATA_HPA_ACTION_FREEZE_LOCK;
2620 warnx("too many hpa actions specified");
2624 if (get_cgd(device, &cgd) != 0) {
2625 warnx("couldn't get CGD");
2629 ccb = cam_getccb(device);
2631 warnx("couldn't allocate CCB");
2635 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2642 printf("%s%d: ", device->device_name, device->dev_unit_num);
2643 ata_print_ident(ident_buf);
2644 camxferrate(device);
2647 if (action == ATA_HPA_ACTION_PRINT) {
2648 error = ata_read_native_max(device, retry_count, timeout, ccb,
2649 ident_buf, &hpasize);
2651 atahpa_print(ident_buf, hpasize, 1);
2658 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2659 warnx("HPA is not supported by this device");
2665 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2666 warnx("HPA Security is not supported by this device");
2672 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2675 * The ATA spec requires:
2676 * 1. Read native max addr is called directly before set max addr
2677 * 2. Read native max addr is NOT called before any other set max call
2680 case ATA_HPA_ACTION_SET_MAX:
2682 atahpa_set_confirm(device, ident_buf, maxsize,
2689 error = ata_read_native_max(device, retry_count, timeout,
2690 ccb, ident_buf, &hpasize);
2692 error = atahpa_set_max(device, retry_count, timeout,
2693 ccb, is48bit, maxsize, persist);
2695 /* redo identify to get new lba values */
2696 error = ata_do_identify(device, retry_count,
2699 atahpa_print(ident_buf, hpasize, 1);
2704 case ATA_HPA_ACTION_SET_PWD:
2705 error = atahpa_password(device, retry_count, timeout,
2706 ccb, is48bit, &pwd);
2708 printf("HPA password has been set\n");
2711 case ATA_HPA_ACTION_LOCK:
2712 error = atahpa_lock(device, retry_count, timeout,
2715 printf("HPA has been locked\n");
2718 case ATA_HPA_ACTION_UNLOCK:
2719 error = atahpa_unlock(device, retry_count, timeout,
2720 ccb, is48bit, &pwd);
2722 printf("HPA has been unlocked\n");
2725 case ATA_HPA_ACTION_FREEZE_LOCK:
2726 error = atahpa_freeze_lock(device, retry_count, timeout,
2729 printf("HPA has been frozen\n");
2733 errx(1, "Option currently not supported");
2743 atasecurity(struct cam_device *device, int retry_count, int timeout,
2744 int argc, char **argv, char *combinedopt)
2747 struct ata_params *ident_buf;
2748 int error, confirm, quiet, c, action, actions, setpwd;
2749 int security_enabled, erase_timeout, pwdsize;
2750 struct ata_security_password pwd;
2758 memset(&pwd, 0, sizeof(pwd));
2760 /* default action is to print security information */
2761 action = ATA_SECURITY_ACTION_PRINT;
2763 /* user is master by default as its safer that way */
2764 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2765 pwdsize = sizeof(pwd.password);
2767 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2770 action = ATA_SECURITY_ACTION_FREEZE;
2775 if (strcasecmp(optarg, "user") == 0) {
2776 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2777 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2778 } else if (strcasecmp(optarg, "master") == 0) {
2779 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2780 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2782 warnx("-U argument '%s' is invalid (must be "
2783 "'user' or 'master')", optarg);
2789 if (strcasecmp(optarg, "high") == 0) {
2790 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2791 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2792 } else if (strcasecmp(optarg, "maximum") == 0) {
2793 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2794 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2796 warnx("-l argument '%s' is unknown (must be "
2797 "'high' or 'maximum')", optarg);
2803 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2805 action = ATA_SECURITY_ACTION_UNLOCK;
2810 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2812 action = ATA_SECURITY_ACTION_DISABLE;
2817 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2819 action = ATA_SECURITY_ACTION_ERASE;
2824 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2826 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2827 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2832 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2835 if (action == ATA_SECURITY_ACTION_PRINT)
2836 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2838 * Don't increment action as this can be combined
2839 * with other actions.
2852 erase_timeout = atoi(optarg) * 1000;
2858 warnx("too many security actions specified");
2862 if ((ccb = cam_getccb(device)) == NULL) {
2863 warnx("couldn't allocate CCB");
2867 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2874 printf("%s%d: ", device->device_name, device->dev_unit_num);
2875 ata_print_ident(ident_buf);
2876 camxferrate(device);
2879 if (action == ATA_SECURITY_ACTION_PRINT) {
2880 atasecurity_print(ident_buf);
2886 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2887 warnx("Security not supported");
2893 /* default timeout 15 seconds the same as linux hdparm */
2894 timeout = timeout ? timeout : 15 * 1000;
2896 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2898 /* first set the password if requested */
2900 /* confirm we can erase before setting the password if erasing */
2902 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2903 action == ATA_SECURITY_ACTION_ERASE) &&
2904 atasecurity_erase_confirm(device, ident_buf) == 0) {
2910 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2911 pwd.revision = ident_buf->master_passwd_revision;
2912 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2913 --pwd.revision == 0) {
2914 pwd.revision = 0xfffe;
2917 error = atasecurity_set_password(device, ccb, retry_count,
2918 timeout, &pwd, quiet);
2924 security_enabled = 1;
2928 case ATA_SECURITY_ACTION_FREEZE:
2929 error = atasecurity_freeze(device, ccb, retry_count,
2933 case ATA_SECURITY_ACTION_UNLOCK:
2934 if (security_enabled) {
2935 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2936 error = atasecurity_unlock(device, ccb,
2937 retry_count, timeout, &pwd, quiet);
2939 warnx("Can't unlock, drive is not locked");
2943 warnx("Can't unlock, security is disabled");
2948 case ATA_SECURITY_ACTION_DISABLE:
2949 if (security_enabled) {
2950 /* First unlock the drive if its locked */
2951 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2952 error = atasecurity_unlock(device, ccb,
2960 error = atasecurity_disable(device,
2968 warnx("Can't disable security (already disabled)");
2973 case ATA_SECURITY_ACTION_ERASE:
2974 if (security_enabled) {
2975 if (erase_timeout == 0) {
2976 erase_timeout = atasecurity_erase_timeout_msecs(
2977 ident_buf->erase_time);
2980 error = atasecurity_erase(device, ccb, retry_count,
2981 timeout, erase_timeout, &pwd,
2984 warnx("Can't secure erase (security is disabled)");
2989 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
2990 if (security_enabled) {
2991 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
2992 if (erase_timeout == 0) {
2994 atasecurity_erase_timeout_msecs(
2995 ident_buf->enhanced_erase_time);
2998 error = atasecurity_erase(device, ccb,
2999 retry_count, timeout,
3000 erase_timeout, &pwd,
3003 warnx("Enhanced erase is not supported");
3007 warnx("Can't secure erase (enhanced), "
3008 "(security is disabled)");
3019 #endif /* MINIMALISTIC */
3022 * Parse out a bus, or a bus, target and lun in the following
3028 * Returns the number of parsed components, or 0.
3031 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3032 cam_argmask *arglst)
3037 while (isspace(*tstr) && (*tstr != '\0'))
3040 tmpstr = (char *)strtok(tstr, ":");
3041 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3042 *bus = strtol(tmpstr, NULL, 0);
3043 *arglst |= CAM_ARG_BUS;
3045 tmpstr = (char *)strtok(NULL, ":");
3046 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3047 *target = strtol(tmpstr, NULL, 0);
3048 *arglst |= CAM_ARG_TARGET;
3050 tmpstr = (char *)strtok(NULL, ":");
3051 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3052 *lun = strtol(tmpstr, NULL, 0);
3053 *arglst |= CAM_ARG_LUN;
3063 dorescan_or_reset(int argc, char **argv, int rescan)
3065 static const char must[] =
3066 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3068 path_id_t bus = CAM_BUS_WILDCARD;
3069 target_id_t target = CAM_TARGET_WILDCARD;
3070 lun_id_t lun = CAM_LUN_WILDCARD;
3074 warnx(must, rescan? "rescan" : "reset");
3078 tstr = argv[optind];
3079 while (isspace(*tstr) && (*tstr != '\0'))
3081 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3082 arglist |= CAM_ARG_BUS;
3084 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3085 if (rv != 1 && rv != 3) {
3086 warnx(must, rescan? "rescan" : "reset");
3091 if ((arglist & CAM_ARG_BUS)
3092 && (arglist & CAM_ARG_TARGET)
3093 && (arglist & CAM_ARG_LUN))
3094 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3096 error = rescan_or_reset_bus(bus, rescan);
3102 rescan_or_reset_bus(path_id_t bus, int rescan)
3104 union ccb ccb, matchccb;
3110 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3111 warnx("error opening transport layer device %s", XPT_DEVICE);
3112 warn("%s", XPT_DEVICE);
3116 if (bus != CAM_BUS_WILDCARD) {
3117 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3118 ccb.ccb_h.path_id = bus;
3119 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3120 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3121 ccb.crcn.flags = CAM_FLAG_NONE;
3123 /* run this at a low priority */
3124 ccb.ccb_h.pinfo.priority = 5;
3126 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3127 warn("CAMIOCOMMAND ioctl failed");
3132 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3133 fprintf(stdout, "%s of bus %d was successful\n",
3134 rescan ? "Re-scan" : "Reset", bus);
3136 fprintf(stdout, "%s of bus %d returned error %#x\n",
3137 rescan ? "Re-scan" : "Reset", bus,
3138 ccb.ccb_h.status & CAM_STATUS_MASK);
3149 * The right way to handle this is to modify the xpt so that it can
3150 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3151 * that isn't implemented, so instead we enumerate the busses and
3152 * send the rescan or reset to those busses in the case where the
3153 * given bus is -1 (wildcard). We don't send a rescan or reset
3154 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3155 * no-op, sending a rescan to the xpt bus would result in a status of
3158 bzero(&(&matchccb.ccb_h)[1],
3159 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3160 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3161 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3162 bufsize = sizeof(struct dev_match_result) * 20;
3163 matchccb.cdm.match_buf_len = bufsize;
3164 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3165 if (matchccb.cdm.matches == NULL) {
3166 warnx("can't malloc memory for matches");
3170 matchccb.cdm.num_matches = 0;
3172 matchccb.cdm.num_patterns = 1;
3173 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3175 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3176 matchccb.cdm.pattern_buf_len);
3177 if (matchccb.cdm.patterns == NULL) {
3178 warnx("can't malloc memory for patterns");
3182 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3183 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3188 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3189 warn("CAMIOCOMMAND ioctl failed");
3194 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3195 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3196 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3197 warnx("got CAM error %#x, CDM error %d\n",
3198 matchccb.ccb_h.status, matchccb.cdm.status);
3203 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3204 struct bus_match_result *bus_result;
3206 /* This shouldn't happen. */
3207 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3210 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3213 * We don't want to rescan or reset the xpt bus.
3216 if (bus_result->path_id == CAM_XPT_PATH_ID)
3219 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3221 ccb.ccb_h.path_id = bus_result->path_id;
3222 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3223 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3224 ccb.crcn.flags = CAM_FLAG_NONE;
3226 /* run this at a low priority */
3227 ccb.ccb_h.pinfo.priority = 5;
3229 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3230 warn("CAMIOCOMMAND ioctl failed");
3235 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3236 fprintf(stdout, "%s of bus %d was successful\n",
3237 rescan? "Re-scan" : "Reset",
3238 bus_result->path_id);
3241 * Don't bail out just yet, maybe the other
3242 * rescan or reset commands will complete
3245 fprintf(stderr, "%s of bus %d returned error "
3246 "%#x\n", rescan? "Re-scan" : "Reset",
3247 bus_result->path_id,
3248 ccb.ccb_h.status & CAM_STATUS_MASK);
3252 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3253 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3260 if (matchccb.cdm.patterns != NULL)
3261 free(matchccb.cdm.patterns);
3262 if (matchccb.cdm.matches != NULL)
3263 free(matchccb.cdm.matches);
3269 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3272 struct cam_device *device;
3277 if (bus == CAM_BUS_WILDCARD) {
3278 warnx("invalid bus number %d", bus);
3282 if (target == CAM_TARGET_WILDCARD) {
3283 warnx("invalid target number %d", target);
3287 if (lun == CAM_LUN_WILDCARD) {
3288 warnx("invalid lun number %jx", (uintmax_t)lun);
3294 bzero(&ccb, sizeof(union ccb));
3297 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3298 warnx("error opening transport layer device %s\n",
3300 warn("%s", XPT_DEVICE);
3304 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3305 if (device == NULL) {
3306 warnx("%s", cam_errbuf);
3311 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3312 ccb.ccb_h.path_id = bus;
3313 ccb.ccb_h.target_id = target;
3314 ccb.ccb_h.target_lun = lun;
3315 ccb.ccb_h.timeout = 5000;
3316 ccb.crcn.flags = CAM_FLAG_NONE;
3318 /* run this at a low priority */
3319 ccb.ccb_h.pinfo.priority = 5;
3322 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3323 warn("CAMIOCOMMAND ioctl failed");
3328 if (cam_send_ccb(device, &ccb) < 0) {
3329 warn("error sending XPT_RESET_DEV CCB");
3330 cam_close_device(device);
3338 cam_close_device(device);
3341 * An error code of CAM_BDR_SENT is normal for a BDR request.
3343 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3345 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3346 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3347 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3350 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3351 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3352 ccb.ccb_h.status & CAM_STATUS_MASK);
3357 #ifndef MINIMALISTIC
3359 readdefects(struct cam_device *device, int argc, char **argv,
3360 char *combinedopt, int retry_count, int timeout)
3362 union ccb *ccb = NULL;
3363 struct scsi_read_defect_data_10 *rdd_cdb;
3364 u_int8_t *defect_list = NULL;
3365 u_int32_t max_dlist_length = SRDD10_MAX_LENGTH, dlist_length = 0;
3366 u_int32_t returned_length = 0;
3367 u_int32_t num_returned = 0;
3368 u_int8_t returned_format;
3371 int lists_specified;
3374 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3380 while (isspace(*tstr) && (*tstr != '\0'))
3382 if (strcmp(tstr, "block") == 0)
3383 arglist |= CAM_ARG_FORMAT_BLOCK;
3384 else if (strcmp(tstr, "bfi") == 0)
3385 arglist |= CAM_ARG_FORMAT_BFI;
3386 else if (strcmp(tstr, "phys") == 0)
3387 arglist |= CAM_ARG_FORMAT_PHYS;
3390 warnx("invalid defect format %s", tstr);
3391 goto defect_bailout;
3396 arglist |= CAM_ARG_GLIST;
3399 arglist |= CAM_ARG_PLIST;
3406 ccb = cam_getccb(device);
3409 * Eventually we should probably support the 12 byte READ DEFECT
3410 * DATA command. It supports a longer parameter list, which may be
3411 * necessary on newer drives with lots of defects. According to
3412 * the SBC-3 spec, drives are supposed to return an illegal request
3413 * if they have more defect data than will fit in 64K.
3415 defect_list = malloc(max_dlist_length);
3416 if (defect_list == NULL) {
3417 warnx("can't malloc memory for defect list");
3419 goto defect_bailout;
3423 * We start off asking for just the header to determine how much
3424 * defect data is available. Some Hitachi drives return an error
3425 * if you ask for more data than the drive has. Once we know the
3426 * length, we retry the command with the returned length.
3428 dlist_length = sizeof(struct scsi_read_defect_data_hdr_10);
3430 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
3434 lists_specified = 0;
3437 * cam_getccb() zeros the CCB header only. So we need to zero the
3438 * payload portion of the ccb.
3440 bzero(&(&ccb->ccb_h)[1],
3441 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3443 cam_fill_csio(&ccb->csio,
3444 /*retries*/ retry_count,
3446 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
3447 CAM_PASS_ERR_RECOVER : 0),
3448 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3449 /*data_ptr*/ defect_list,
3450 /*dxfer_len*/ dlist_length,
3451 /*sense_len*/ SSD_FULL_SIZE,
3452 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
3453 /*timeout*/ timeout ? timeout : 5000);
3455 rdd_cdb->opcode = READ_DEFECT_DATA_10;
3456 if (arglist & CAM_ARG_FORMAT_BLOCK)
3457 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
3458 else if (arglist & CAM_ARG_FORMAT_BFI)
3459 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
3460 else if (arglist & CAM_ARG_FORMAT_PHYS)
3461 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
3464 warnx("no defect list format specified");
3465 goto defect_bailout;
3467 if (arglist & CAM_ARG_PLIST) {
3468 rdd_cdb->format |= SRDD10_PLIST;
3472 if (arglist & CAM_ARG_GLIST) {
3473 rdd_cdb->format |= SRDD10_GLIST;
3477 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
3479 /* Disable freezing the device queue */
3480 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3482 if (cam_send_ccb(device, ccb) < 0) {
3483 perror("error reading defect list");
3485 if (arglist & CAM_ARG_VERBOSE) {
3486 cam_error_print(device, ccb, CAM_ESF_ALL,
3487 CAM_EPF_ALL, stderr);
3491 goto defect_bailout;
3494 returned_length = scsi_2btoul(((struct
3495 scsi_read_defect_data_hdr_10 *)defect_list)->length);
3497 if (get_length != 0) {
3500 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3501 CAM_SCSI_STATUS_ERROR) {
3502 struct scsi_sense_data *sense;
3503 int error_code, sense_key, asc, ascq;
3505 sense = &ccb->csio.sense_data;
3506 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3507 ccb->csio.sense_resid, &error_code, &sense_key,
3508 &asc, &ascq, /*show_errors*/ 1);
3511 * If the drive is reporting that it just doesn't
3512 * support the defect list format, go ahead and use
3513 * the length it reported. Otherwise, the length
3514 * may not be valid, so use the maximum.
3516 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3517 && (asc == 0x1c) && (ascq == 0x00)
3518 && (returned_length > 0)) {
3519 dlist_length = returned_length +
3520 sizeof(struct scsi_read_defect_data_hdr_10);
3521 dlist_length = min(dlist_length,
3524 dlist_length = max_dlist_length;
3525 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3528 warnx("Error reading defect header");
3529 if (arglist & CAM_ARG_VERBOSE)
3530 cam_error_print(device, ccb, CAM_ESF_ALL,
3531 CAM_EPF_ALL, stderr);
3532 goto defect_bailout;
3534 dlist_length = returned_length +
3535 sizeof(struct scsi_read_defect_data_hdr_10);
3536 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3542 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
3543 defect_list)->format;
3545 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3546 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3547 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3548 struct scsi_sense_data *sense;
3549 int error_code, sense_key, asc, ascq;
3551 sense = &ccb->csio.sense_data;
3552 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3553 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3554 &ascq, /*show_errors*/ 1);
3557 * According to the SCSI spec, if the disk doesn't support
3558 * the requested format, it will generally return a sense
3559 * key of RECOVERED ERROR, and an additional sense code
3560 * of "DEFECT LIST NOT FOUND". So, we check for that, and
3561 * also check to make sure that the returned length is
3562 * greater than 0, and then print out whatever format the
3565 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3566 && (asc == 0x1c) && (ascq == 0x00)
3567 && (returned_length > 0)) {
3568 warnx("requested defect format not available");
3569 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
3570 case SRDD10_BLOCK_FORMAT:
3571 warnx("Device returned block format");
3573 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3574 warnx("Device returned bytes from index"
3577 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3578 warnx("Device returned physical sector format");
3582 warnx("Device returned unknown defect"
3583 " data format %#x", returned_format);
3584 goto defect_bailout;
3585 break; /* NOTREACHED */
3589 warnx("Error returned from read defect data command");
3590 if (arglist & CAM_ARG_VERBOSE)
3591 cam_error_print(device, ccb, CAM_ESF_ALL,
3592 CAM_EPF_ALL, stderr);
3593 goto defect_bailout;
3595 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3597 warnx("Error returned from read defect data command");
3598 if (arglist & CAM_ARG_VERBOSE)
3599 cam_error_print(device, ccb, CAM_ESF_ALL,
3600 CAM_EPF_ALL, stderr);
3601 goto defect_bailout;
3605 * XXX KDM I should probably clean up the printout format for the
3608 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
3609 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
3611 struct scsi_defect_desc_phys_sector *dlist;
3613 dlist = (struct scsi_defect_desc_phys_sector *)
3615 sizeof(struct scsi_read_defect_data_hdr_10));
3617 num_returned = returned_length /
3618 sizeof(struct scsi_defect_desc_phys_sector);
3620 fprintf(stderr, "Got %d defect", num_returned);
3622 if ((lists_specified == 0) || (num_returned == 0)) {
3623 fprintf(stderr, "s.\n");
3625 } else if (num_returned == 1)
3626 fprintf(stderr, ":\n");
3628 fprintf(stderr, "s:\n");
3630 for (i = 0; i < num_returned; i++) {
3631 fprintf(stdout, "%d:%d:%d\n",
3632 scsi_3btoul(dlist[i].cylinder),
3634 scsi_4btoul(dlist[i].sector));
3638 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
3640 struct scsi_defect_desc_bytes_from_index *dlist;
3642 dlist = (struct scsi_defect_desc_bytes_from_index *)
3644 sizeof(struct scsi_read_defect_data_hdr_10));
3646 num_returned = returned_length /
3647 sizeof(struct scsi_defect_desc_bytes_from_index);
3649 fprintf(stderr, "Got %d defect", num_returned);
3651 if ((lists_specified == 0) || (num_returned == 0)) {
3652 fprintf(stderr, "s.\n");
3654 } else if (num_returned == 1)
3655 fprintf(stderr, ":\n");
3657 fprintf(stderr, "s:\n");
3659 for (i = 0; i < num_returned; i++) {
3660 fprintf(stdout, "%d:%d:%d\n",
3661 scsi_3btoul(dlist[i].cylinder),
3663 scsi_4btoul(dlist[i].bytes_from_index));
3667 case SRDDH10_BLOCK_FORMAT:
3669 struct scsi_defect_desc_block *dlist;
3671 dlist = (struct scsi_defect_desc_block *)(defect_list +
3672 sizeof(struct scsi_read_defect_data_hdr_10));
3674 num_returned = returned_length /
3675 sizeof(struct scsi_defect_desc_block);
3677 fprintf(stderr, "Got %d defect", num_returned);
3679 if ((lists_specified == 0) || (num_returned == 0)) {
3680 fprintf(stderr, "s.\n");
3682 } else if (num_returned == 1)
3683 fprintf(stderr, ":\n");
3685 fprintf(stderr, "s:\n");
3687 for (i = 0; i < num_returned; i++)
3688 fprintf(stdout, "%u\n",
3689 scsi_4btoul(dlist[i].address));
3693 fprintf(stderr, "Unknown defect format %d\n",
3694 returned_format & SRDDH10_DLIST_FORMAT_MASK);
3700 if (defect_list != NULL)
3708 #endif /* MINIMALISTIC */
3712 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3716 ccb = cam_getccb(device);
3722 #ifndef MINIMALISTIC
3724 mode_sense(struct cam_device *device, int mode_page, int page_control,
3725 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3730 ccb = cam_getccb(device);
3733 errx(1, "mode_sense: couldn't allocate CCB");
3735 bzero(&(&ccb->ccb_h)[1],
3736 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3738 scsi_mode_sense(&ccb->csio,
3739 /* retries */ retry_count,
3741 /* tag_action */ MSG_SIMPLE_Q_TAG,
3743 /* page_code */ page_control << 6,
3744 /* page */ mode_page,
3745 /* param_buf */ data,
3746 /* param_len */ datalen,
3747 /* sense_len */ SSD_FULL_SIZE,
3748 /* timeout */ timeout ? timeout : 5000);
3750 if (arglist & CAM_ARG_ERR_RECOVER)
3751 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3753 /* Disable freezing the device queue */
3754 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3756 if (((retval = cam_send_ccb(device, ccb)) < 0)
3757 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3758 if (arglist & CAM_ARG_VERBOSE) {
3759 cam_error_print(device, ccb, CAM_ESF_ALL,
3760 CAM_EPF_ALL, stderr);
3763 cam_close_device(device);
3765 err(1, "error sending mode sense command");
3767 errx(1, "error sending mode sense command");
3774 mode_select(struct cam_device *device, int save_pages, int retry_count,
3775 int timeout, u_int8_t *data, int datalen)
3780 ccb = cam_getccb(device);
3783 errx(1, "mode_select: couldn't allocate CCB");
3785 bzero(&(&ccb->ccb_h)[1],
3786 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3788 scsi_mode_select(&ccb->csio,
3789 /* retries */ retry_count,
3791 /* tag_action */ MSG_SIMPLE_Q_TAG,
3792 /* scsi_page_fmt */ 1,
3793 /* save_pages */ save_pages,
3794 /* param_buf */ data,
3795 /* param_len */ datalen,
3796 /* sense_len */ SSD_FULL_SIZE,
3797 /* timeout */ timeout ? timeout : 5000);
3799 if (arglist & CAM_ARG_ERR_RECOVER)
3800 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3802 /* Disable freezing the device queue */
3803 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3805 if (((retval = cam_send_ccb(device, ccb)) < 0)
3806 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3807 if (arglist & CAM_ARG_VERBOSE) {
3808 cam_error_print(device, ccb, CAM_ESF_ALL,
3809 CAM_EPF_ALL, stderr);
3812 cam_close_device(device);
3815 err(1, "error sending mode select command");
3817 errx(1, "error sending mode select command");
3825 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
3826 int retry_count, int timeout)
3828 int c, mode_page = -1, page_control = 0;
3829 int binary = 0, list = 0;
3831 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3837 arglist |= CAM_ARG_DBD;
3840 arglist |= CAM_ARG_MODE_EDIT;
3846 mode_page = strtol(optarg, NULL, 0);
3848 errx(1, "invalid mode page %d", mode_page);
3851 page_control = strtol(optarg, NULL, 0);
3852 if ((page_control < 0) || (page_control > 3))
3853 errx(1, "invalid page control field %d",
3855 arglist |= CAM_ARG_PAGE_CNTL;
3862 if (mode_page == -1 && list == 0)
3863 errx(1, "you must specify a mode page!");
3866 mode_list(device, page_control, arglist & CAM_ARG_DBD,
3867 retry_count, timeout);
3869 mode_edit(device, mode_page, page_control,
3870 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
3871 retry_count, timeout);
3876 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
3877 int retry_count, int timeout)
3880 u_int32_t flags = CAM_DIR_NONE;
3881 u_int8_t *data_ptr = NULL;
3883 u_int8_t atacmd[12];
3884 struct get_hook hook;
3885 int c, data_bytes = 0;
3891 char *datastr = NULL, *tstr, *resstr = NULL;
3893 int fd_data = 0, fd_res = 0;
3896 ccb = cam_getccb(device);
3899 warnx("scsicmd: error allocating ccb");
3903 bzero(&(&ccb->ccb_h)[1],
3904 sizeof(union ccb) - sizeof(struct ccb_hdr));
3906 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3910 while (isspace(*tstr) && (*tstr != '\0'))
3912 hook.argc = argc - optind;
3913 hook.argv = argv + optind;
3915 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
3918 * Increment optind by the number of arguments the
3919 * encoding routine processed. After each call to
3920 * getopt(3), optind points to the argument that
3921 * getopt should process _next_. In this case,
3922 * that means it points to the first command string
3923 * argument, if there is one. Once we increment
3924 * this, it should point to either the next command
3925 * line argument, or it should be past the end of
3932 while (isspace(*tstr) && (*tstr != '\0'))
3934 hook.argc = argc - optind;
3935 hook.argv = argv + optind;
3937 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
3940 * Increment optind by the number of arguments the
3941 * encoding routine processed. After each call to
3942 * getopt(3), optind points to the argument that
3943 * getopt should process _next_. In this case,
3944 * that means it points to the first command string
3945 * argument, if there is one. Once we increment
3946 * this, it should point to either the next command
3947 * line argument, or it should be past the end of
3959 if (arglist & CAM_ARG_CMD_OUT) {
3960 warnx("command must either be "
3961 "read or write, not both");
3963 goto scsicmd_bailout;
3965 arglist |= CAM_ARG_CMD_IN;
3967 data_bytes = strtol(optarg, NULL, 0);
3968 if (data_bytes <= 0) {
3969 warnx("invalid number of input bytes %d",
3972 goto scsicmd_bailout;
3974 hook.argc = argc - optind;
3975 hook.argv = argv + optind;
3978 datastr = cget(&hook, NULL);
3980 * If the user supplied "-" instead of a format, he
3981 * wants the data to be written to stdout.
3983 if ((datastr != NULL)
3984 && (datastr[0] == '-'))
3987 data_ptr = (u_int8_t *)malloc(data_bytes);
3988 if (data_ptr == NULL) {
3989 warnx("can't malloc memory for data_ptr");
3991 goto scsicmd_bailout;
3995 if (arglist & CAM_ARG_CMD_IN) {
3996 warnx("command must either be "
3997 "read or write, not both");
3999 goto scsicmd_bailout;
4001 arglist |= CAM_ARG_CMD_OUT;
4002 flags = CAM_DIR_OUT;
4003 data_bytes = strtol(optarg, NULL, 0);
4004 if (data_bytes <= 0) {
4005 warnx("invalid number of output bytes %d",
4008 goto scsicmd_bailout;
4010 hook.argc = argc - optind;
4011 hook.argv = argv + optind;
4013 datastr = cget(&hook, NULL);
4014 data_ptr = (u_int8_t *)malloc(data_bytes);
4015 if (data_ptr == NULL) {
4016 warnx("can't malloc memory for data_ptr");
4018 goto scsicmd_bailout;
4020 bzero(data_ptr, data_bytes);
4022 * If the user supplied "-" instead of a format, he
4023 * wants the data to be read from stdin.
4025 if ((datastr != NULL)
4026 && (datastr[0] == '-'))
4029 buff_encode_visit(data_ptr, data_bytes, datastr,
4035 hook.argc = argc - optind;
4036 hook.argv = argv + optind;
4038 resstr = cget(&hook, NULL);
4039 if ((resstr != NULL) && (resstr[0] == '-'))
4049 * If fd_data is set, and we're writing to the device, we need to
4050 * read the data the user wants written from stdin.
4052 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4054 int amt_to_read = data_bytes;
4055 u_int8_t *buf_ptr = data_ptr;
4057 for (amt_read = 0; amt_to_read > 0;
4058 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4059 if (amt_read == -1) {
4060 warn("error reading data from stdin");
4062 goto scsicmd_bailout;
4064 amt_to_read -= amt_read;
4065 buf_ptr += amt_read;
4069 if (arglist & CAM_ARG_ERR_RECOVER)
4070 flags |= CAM_PASS_ERR_RECOVER;
4072 /* Disable freezing the device queue */
4073 flags |= CAM_DEV_QFRZDIS;
4077 * This is taken from the SCSI-3 draft spec.
4078 * (T10/1157D revision 0.3)
4079 * The top 3 bits of an opcode are the group code.
4080 * The next 5 bits are the command code.
4081 * Group 0: six byte commands
4082 * Group 1: ten byte commands
4083 * Group 2: ten byte commands
4085 * Group 4: sixteen byte commands
4086 * Group 5: twelve byte commands
4087 * Group 6: vendor specific
4088 * Group 7: vendor specific
4090 switch((cdb[0] >> 5) & 0x7) {
4101 /* computed by buff_encode_visit */
4112 * We should probably use csio_build_visit or something like that
4113 * here, but it's easier to encode arguments as you go. The
4114 * alternative would be skipping the CDB argument and then encoding
4115 * it here, since we've got the data buffer argument by now.
4117 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4119 cam_fill_csio(&ccb->csio,
4120 /*retries*/ retry_count,
4123 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4124 /*data_ptr*/ data_ptr,
4125 /*dxfer_len*/ data_bytes,
4126 /*sense_len*/ SSD_FULL_SIZE,
4127 /*cdb_len*/ cdb_len,
4128 /*timeout*/ timeout ? timeout : 5000);
4131 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4133 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4135 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4137 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4139 cam_fill_ataio(&ccb->ataio,
4140 /*retries*/ retry_count,
4144 /*data_ptr*/ data_ptr,
4145 /*dxfer_len*/ data_bytes,
4146 /*timeout*/ timeout ? timeout : 5000);
4149 if (((retval = cam_send_ccb(device, ccb)) < 0)
4150 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4151 const char warnstr[] = "error sending command";
4158 if (arglist & CAM_ARG_VERBOSE) {
4159 cam_error_print(device, ccb, CAM_ESF_ALL,
4160 CAM_EPF_ALL, stderr);
4164 goto scsicmd_bailout;
4167 if (atacmd_len && need_res) {
4169 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4171 fprintf(stdout, "\n");
4174 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4175 ccb->ataio.res.status,
4176 ccb->ataio.res.error,
4177 ccb->ataio.res.lba_low,
4178 ccb->ataio.res.lba_mid,
4179 ccb->ataio.res.lba_high,
4180 ccb->ataio.res.device,
4181 ccb->ataio.res.lba_low_exp,
4182 ccb->ataio.res.lba_mid_exp,
4183 ccb->ataio.res.lba_high_exp,
4184 ccb->ataio.res.sector_count,
4185 ccb->ataio.res.sector_count_exp);
4190 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4191 && (arglist & CAM_ARG_CMD_IN)
4192 && (data_bytes > 0)) {
4194 buff_decode_visit(data_ptr, data_bytes, datastr,
4196 fprintf(stdout, "\n");
4198 ssize_t amt_written;
4199 int amt_to_write = data_bytes;
4200 u_int8_t *buf_ptr = data_ptr;
4202 for (amt_written = 0; (amt_to_write > 0) &&
4203 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4204 amt_to_write -= amt_written;
4205 buf_ptr += amt_written;
4207 if (amt_written == -1) {
4208 warn("error writing data to stdout");
4210 goto scsicmd_bailout;
4211 } else if ((amt_written == 0)
4212 && (amt_to_write > 0)) {
4213 warnx("only wrote %u bytes out of %u",
4214 data_bytes - amt_to_write, data_bytes);
4221 if ((data_bytes > 0) && (data_ptr != NULL))
4230 camdebug(int argc, char **argv, char *combinedopt)
4233 path_id_t bus = CAM_BUS_WILDCARD;
4234 target_id_t target = CAM_TARGET_WILDCARD;
4235 lun_id_t lun = CAM_LUN_WILDCARD;
4236 char *tstr, *tmpstr = NULL;
4240 bzero(&ccb, sizeof(union ccb));
4242 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4245 arglist |= CAM_ARG_DEBUG_INFO;
4246 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4249 arglist |= CAM_ARG_DEBUG_PERIPH;
4250 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4253 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4254 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4257 arglist |= CAM_ARG_DEBUG_TRACE;
4258 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4261 arglist |= CAM_ARG_DEBUG_XPT;
4262 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4265 arglist |= CAM_ARG_DEBUG_CDB;
4266 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4269 arglist |= CAM_ARG_DEBUG_PROBE;
4270 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4277 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4278 warnx("error opening transport layer device %s", XPT_DEVICE);
4279 warn("%s", XPT_DEVICE);
4286 warnx("you must specify \"off\", \"all\" or a bus,");
4287 warnx("bus:target, or bus:target:lun");
4294 while (isspace(*tstr) && (*tstr != '\0'))
4297 if (strncmp(tstr, "off", 3) == 0) {
4298 ccb.cdbg.flags = CAM_DEBUG_NONE;
4299 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4300 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4301 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4302 } else if (strncmp(tstr, "all", 3) != 0) {
4303 tmpstr = (char *)strtok(tstr, ":");
4304 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4305 bus = strtol(tmpstr, NULL, 0);
4306 arglist |= CAM_ARG_BUS;
4307 tmpstr = (char *)strtok(NULL, ":");
4308 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4309 target = strtol(tmpstr, NULL, 0);
4310 arglist |= CAM_ARG_TARGET;
4311 tmpstr = (char *)strtok(NULL, ":");
4312 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4313 lun = strtol(tmpstr, NULL, 0);
4314 arglist |= CAM_ARG_LUN;
4319 warnx("you must specify \"all\", \"off\", or a bus,");
4320 warnx("bus:target, or bus:target:lun to debug");
4326 ccb.ccb_h.func_code = XPT_DEBUG;
4327 ccb.ccb_h.path_id = bus;
4328 ccb.ccb_h.target_id = target;
4329 ccb.ccb_h.target_lun = lun;
4331 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4332 warn("CAMIOCOMMAND ioctl failed");
4337 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4338 CAM_FUNC_NOTAVAIL) {
4339 warnx("CAM debugging not available");
4340 warnx("you need to put options CAMDEBUG in"
4341 " your kernel config file!");
4343 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4345 warnx("XPT_DEBUG CCB failed with status %#x",
4349 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4351 "Debugging turned off\n");
4354 "Debugging enabled for "
4356 bus, target, (uintmax_t)lun);
4367 tagcontrol(struct cam_device *device, int argc, char **argv,
4377 ccb = cam_getccb(device);
4380 warnx("tagcontrol: error allocating ccb");
4384 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4387 numtags = strtol(optarg, NULL, 0);
4389 warnx("tag count %d is < 0", numtags);
4391 goto tagcontrol_bailout;
4402 cam_path_string(device, pathstr, sizeof(pathstr));
4405 bzero(&(&ccb->ccb_h)[1],
4406 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4407 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4408 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4409 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4410 ccb->crs.openings = numtags;
4413 if (cam_send_ccb(device, ccb) < 0) {
4414 perror("error sending XPT_REL_SIMQ CCB");
4416 goto tagcontrol_bailout;
4419 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4420 warnx("XPT_REL_SIMQ CCB failed");
4421 cam_error_print(device, ccb, CAM_ESF_ALL,
4422 CAM_EPF_ALL, stderr);
4424 goto tagcontrol_bailout;
4429 fprintf(stdout, "%stagged openings now %d\n",
4430 pathstr, ccb->crs.openings);
4433 bzero(&(&ccb->ccb_h)[1],
4434 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4436 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4438 if (cam_send_ccb(device, ccb) < 0) {
4439 perror("error sending XPT_GDEV_STATS CCB");
4441 goto tagcontrol_bailout;
4444 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4445 warnx("XPT_GDEV_STATS CCB failed");
4446 cam_error_print(device, ccb, CAM_ESF_ALL,
4447 CAM_EPF_ALL, stderr);
4449 goto tagcontrol_bailout;
4452 if (arglist & CAM_ARG_VERBOSE) {
4453 fprintf(stdout, "%s", pathstr);
4454 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4455 fprintf(stdout, "%s", pathstr);
4456 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4457 fprintf(stdout, "%s", pathstr);
4458 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
4459 fprintf(stdout, "%s", pathstr);
4460 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
4461 fprintf(stdout, "%s", pathstr);
4462 fprintf(stdout, "held %d\n", ccb->cgds.held);
4463 fprintf(stdout, "%s", pathstr);
4464 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4465 fprintf(stdout, "%s", pathstr);
4466 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4469 fprintf(stdout, "%s", pathstr);
4470 fprintf(stdout, "device openings: ");
4472 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4473 ccb->cgds.dev_active);
4483 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4487 cam_path_string(device, pathstr, sizeof(pathstr));
4489 if (cts->transport == XPORT_SPI) {
4490 struct ccb_trans_settings_spi *spi =
4491 &cts->xport_specific.spi;
4493 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4495 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4498 if (spi->sync_offset != 0) {
4501 freq = scsi_calc_syncsrate(spi->sync_period);
4502 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4503 pathstr, freq / 1000, freq % 1000);
4507 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4508 fprintf(stdout, "%soffset: %d\n", pathstr,
4512 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4513 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4514 (0x01 << spi->bus_width) * 8);
4517 if (spi->valid & CTS_SPI_VALID_DISC) {
4518 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4519 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4520 "enabled" : "disabled");
4523 if (cts->transport == XPORT_FC) {
4524 struct ccb_trans_settings_fc *fc =
4525 &cts->xport_specific.fc;
4527 if (fc->valid & CTS_FC_VALID_WWNN)
4528 fprintf(stdout, "%sWWNN: 0x%llx", pathstr,
4529 (long long) fc->wwnn);
4530 if (fc->valid & CTS_FC_VALID_WWPN)
4531 fprintf(stdout, "%sWWPN: 0x%llx", pathstr,
4532 (long long) fc->wwpn);
4533 if (fc->valid & CTS_FC_VALID_PORT)
4534 fprintf(stdout, "%sPortID: 0x%x", pathstr, fc->port);
4535 if (fc->valid & CTS_FC_VALID_SPEED)
4536 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4537 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4539 if (cts->transport == XPORT_SAS) {
4540 struct ccb_trans_settings_sas *sas =
4541 &cts->xport_specific.sas;
4543 if (sas->valid & CTS_SAS_VALID_SPEED)
4544 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4545 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4547 if (cts->transport == XPORT_ATA) {
4548 struct ccb_trans_settings_pata *pata =
4549 &cts->xport_specific.ata;
4551 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4552 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4553 ata_mode2string(pata->mode));
4555 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4556 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4559 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4560 fprintf(stdout, "%sPIO transaction length: %d\n",
4561 pathstr, pata->bytecount);
4564 if (cts->transport == XPORT_SATA) {
4565 struct ccb_trans_settings_sata *sata =
4566 &cts->xport_specific.sata;
4568 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4569 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4572 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4573 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4574 ata_mode2string(sata->mode));
4576 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4577 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4580 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4581 fprintf(stdout, "%sPIO transaction length: %d\n",
4582 pathstr, sata->bytecount);
4584 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4585 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4588 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4589 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4592 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4593 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4597 if (cts->protocol == PROTO_ATA) {
4598 struct ccb_trans_settings_ata *ata=
4599 &cts->proto_specific.ata;
4601 if (ata->valid & CTS_ATA_VALID_TQ) {
4602 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4603 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4604 "enabled" : "disabled");
4607 if (cts->protocol == PROTO_SCSI) {
4608 struct ccb_trans_settings_scsi *scsi=
4609 &cts->proto_specific.scsi;
4611 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4612 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4613 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4614 "enabled" : "disabled");
4621 * Get a path inquiry CCB for the specified device.
4624 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4629 ccb = cam_getccb(device);
4631 warnx("get_cpi: couldn't allocate CCB");
4634 bzero(&(&ccb->ccb_h)[1],
4635 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4636 ccb->ccb_h.func_code = XPT_PATH_INQ;
4637 if (cam_send_ccb(device, ccb) < 0) {
4638 warn("get_cpi: error sending Path Inquiry CCB");
4639 if (arglist & CAM_ARG_VERBOSE)
4640 cam_error_print(device, ccb, CAM_ESF_ALL,
4641 CAM_EPF_ALL, stderr);
4643 goto get_cpi_bailout;
4645 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4646 if (arglist & CAM_ARG_VERBOSE)
4647 cam_error_print(device, ccb, CAM_ESF_ALL,
4648 CAM_EPF_ALL, stderr);
4650 goto get_cpi_bailout;
4652 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4660 * Get a get device CCB for the specified device.
4663 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4668 ccb = cam_getccb(device);
4670 warnx("get_cgd: couldn't allocate CCB");
4673 bzero(&(&ccb->ccb_h)[1],
4674 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4675 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4676 if (cam_send_ccb(device, ccb) < 0) {
4677 warn("get_cgd: error sending Path Inquiry CCB");
4678 if (arglist & CAM_ARG_VERBOSE)
4679 cam_error_print(device, ccb, CAM_ESF_ALL,
4680 CAM_EPF_ALL, stderr);
4682 goto get_cgd_bailout;
4684 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4685 if (arglist & CAM_ARG_VERBOSE)
4686 cam_error_print(device, ccb, CAM_ESF_ALL,
4687 CAM_EPF_ALL, stderr);
4689 goto get_cgd_bailout;
4691 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4698 /* return the type of disk (really the command type) */
4700 get_disk_type(struct cam_device *device)
4702 struct ccb_getdev cgd;
4704 (void) memset(&cgd, 0x0, sizeof(cgd));
4705 get_cgd(device, &cgd);
4706 switch(cgd.protocol) {
4719 cpi_print(struct ccb_pathinq *cpi)
4721 char adapter_str[1024];
4724 snprintf(adapter_str, sizeof(adapter_str),
4725 "%s%d:", cpi->dev_name, cpi->unit_number);
4727 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
4730 for (i = 1; i < 0xff; i = i << 1) {
4733 if ((i & cpi->hba_inquiry) == 0)
4736 fprintf(stdout, "%s supports ", adapter_str);
4740 str = "MDP message";
4743 str = "32 bit wide SCSI";
4746 str = "16 bit wide SCSI";
4749 str = "SDTR message";
4752 str = "linked CDBs";
4755 str = "tag queue messages";
4758 str = "soft reset alternative";
4761 str = "SATA Port Multiplier";
4764 str = "unknown PI bit set";
4767 fprintf(stdout, "%s\n", str);
4770 for (i = 1; i < 0xff; i = i << 1) {
4773 if ((i & cpi->hba_misc) == 0)
4776 fprintf(stdout, "%s ", adapter_str);
4780 str = "bus scans from high ID to low ID";
4783 str = "removable devices not included in scan";
4785 case PIM_NOINITIATOR:
4786 str = "initiator role not supported";
4788 case PIM_NOBUSRESET:
4789 str = "user has disabled initial BUS RESET or"
4790 " controller is in target/mixed mode";
4793 str = "do not send 6-byte commands";
4796 str = "scan bus sequentially";
4799 str = "unknown PIM bit set";
4802 fprintf(stdout, "%s\n", str);
4805 for (i = 1; i < 0xff; i = i << 1) {
4808 if ((i & cpi->target_sprt) == 0)
4811 fprintf(stdout, "%s supports ", adapter_str);
4814 str = "target mode processor mode";
4817 str = "target mode phase cog. mode";
4819 case PIT_DISCONNECT:
4820 str = "disconnects in target mode";
4823 str = "terminate I/O message in target mode";
4826 str = "group 6 commands in target mode";
4829 str = "group 7 commands in target mode";
4832 str = "unknown PIT bit set";
4836 fprintf(stdout, "%s\n", str);
4838 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
4840 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
4842 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
4844 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
4845 adapter_str, cpi->hpath_id);
4846 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
4848 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
4849 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
4850 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
4851 adapter_str, cpi->hba_vendor);
4852 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
4853 adapter_str, cpi->hba_device);
4854 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
4855 adapter_str, cpi->hba_subvendor);
4856 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
4857 adapter_str, cpi->hba_subdevice);
4858 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
4859 fprintf(stdout, "%s base transfer speed: ", adapter_str);
4860 if (cpi->base_transfer_speed > 1000)
4861 fprintf(stdout, "%d.%03dMB/sec\n",
4862 cpi->base_transfer_speed / 1000,
4863 cpi->base_transfer_speed % 1000);
4865 fprintf(stdout, "%dKB/sec\n",
4866 (cpi->base_transfer_speed % 1000) * 1000);
4867 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
4868 adapter_str, cpi->maxio);
4872 get_print_cts(struct cam_device *device, int user_settings, int quiet,
4873 struct ccb_trans_settings *cts)
4879 ccb = cam_getccb(device);
4882 warnx("get_print_cts: error allocating ccb");
4886 bzero(&(&ccb->ccb_h)[1],
4887 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4889 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
4891 if (user_settings == 0)
4892 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
4894 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
4896 if (cam_send_ccb(device, ccb) < 0) {
4897 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
4898 if (arglist & CAM_ARG_VERBOSE)
4899 cam_error_print(device, ccb, CAM_ESF_ALL,
4900 CAM_EPF_ALL, stderr);
4902 goto get_print_cts_bailout;
4905 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4906 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
4907 if (arglist & CAM_ARG_VERBOSE)
4908 cam_error_print(device, ccb, CAM_ESF_ALL,
4909 CAM_EPF_ALL, stderr);
4911 goto get_print_cts_bailout;
4915 cts_print(device, &ccb->cts);
4918 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
4920 get_print_cts_bailout:
4928 ratecontrol(struct cam_device *device, int retry_count, int timeout,
4929 int argc, char **argv, char *combinedopt)
4933 int user_settings = 0;
4935 int disc_enable = -1, tag_enable = -1;
4938 double syncrate = -1;
4941 int change_settings = 0, send_tur = 0;
4942 struct ccb_pathinq cpi;
4944 ccb = cam_getccb(device);
4946 warnx("ratecontrol: error allocating ccb");
4949 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4958 if (strncasecmp(optarg, "enable", 6) == 0)
4960 else if (strncasecmp(optarg, "disable", 7) == 0)
4963 warnx("-D argument \"%s\" is unknown", optarg);
4965 goto ratecontrol_bailout;
4967 change_settings = 1;
4970 mode = ata_string2mode(optarg);
4972 warnx("unknown mode '%s'", optarg);
4974 goto ratecontrol_bailout;
4976 change_settings = 1;
4979 offset = strtol(optarg, NULL, 0);
4981 warnx("offset value %d is < 0", offset);
4983 goto ratecontrol_bailout;
4985 change_settings = 1;
4991 syncrate = atof(optarg);
4993 warnx("sync rate %f is < 0", syncrate);
4995 goto ratecontrol_bailout;
4997 change_settings = 1;
5000 if (strncasecmp(optarg, "enable", 6) == 0)
5002 else if (strncasecmp(optarg, "disable", 7) == 0)
5005 warnx("-T argument \"%s\" is unknown", optarg);
5007 goto ratecontrol_bailout;
5009 change_settings = 1;
5015 bus_width = strtol(optarg, NULL, 0);
5016 if (bus_width < 0) {
5017 warnx("bus width %d is < 0", bus_width);
5019 goto ratecontrol_bailout;
5021 change_settings = 1;
5027 bzero(&(&ccb->ccb_h)[1],
5028 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
5030 * Grab path inquiry information, so we can determine whether
5031 * or not the initiator is capable of the things that the user
5034 ccb->ccb_h.func_code = XPT_PATH_INQ;
5035 if (cam_send_ccb(device, ccb) < 0) {
5036 perror("error sending XPT_PATH_INQ CCB");
5037 if (arglist & CAM_ARG_VERBOSE) {
5038 cam_error_print(device, ccb, CAM_ESF_ALL,
5039 CAM_EPF_ALL, stderr);
5042 goto ratecontrol_bailout;
5044 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5045 warnx("XPT_PATH_INQ CCB failed");
5046 if (arglist & CAM_ARG_VERBOSE) {
5047 cam_error_print(device, ccb, CAM_ESF_ALL,
5048 CAM_EPF_ALL, stderr);
5051 goto ratecontrol_bailout;
5053 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5054 bzero(&(&ccb->ccb_h)[1],
5055 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5057 fprintf(stdout, "%s parameters:\n",
5058 user_settings ? "User" : "Current");
5060 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5062 goto ratecontrol_bailout;
5064 if (arglist & CAM_ARG_VERBOSE)
5067 if (change_settings) {
5068 int didsettings = 0;
5069 struct ccb_trans_settings_spi *spi = NULL;
5070 struct ccb_trans_settings_pata *pata = NULL;
5071 struct ccb_trans_settings_sata *sata = NULL;
5072 struct ccb_trans_settings_ata *ata = NULL;
5073 struct ccb_trans_settings_scsi *scsi = NULL;
5075 if (ccb->cts.transport == XPORT_SPI)
5076 spi = &ccb->cts.xport_specific.spi;
5077 if (ccb->cts.transport == XPORT_ATA)
5078 pata = &ccb->cts.xport_specific.ata;
5079 if (ccb->cts.transport == XPORT_SATA)
5080 sata = &ccb->cts.xport_specific.sata;
5081 if (ccb->cts.protocol == PROTO_ATA)
5082 ata = &ccb->cts.proto_specific.ata;
5083 if (ccb->cts.protocol == PROTO_SCSI)
5084 scsi = &ccb->cts.proto_specific.scsi;
5085 ccb->cts.xport_specific.valid = 0;
5086 ccb->cts.proto_specific.valid = 0;
5087 if (spi && disc_enable != -1) {
5088 spi->valid |= CTS_SPI_VALID_DISC;
5089 if (disc_enable == 0)
5090 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5092 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5095 if (tag_enable != -1) {
5096 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5097 warnx("HBA does not support tagged queueing, "
5098 "so you cannot modify tag settings");
5100 goto ratecontrol_bailout;
5103 ata->valid |= CTS_SCSI_VALID_TQ;
5104 if (tag_enable == 0)
5105 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5107 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5110 scsi->valid |= CTS_SCSI_VALID_TQ;
5111 if (tag_enable == 0)
5112 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5114 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5118 if (spi && offset != -1) {
5119 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5120 warnx("HBA is not capable of changing offset");
5122 goto ratecontrol_bailout;
5124 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5125 spi->sync_offset = offset;
5128 if (spi && syncrate != -1) {
5129 int prelim_sync_period;
5131 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5132 warnx("HBA is not capable of changing "
5135 goto ratecontrol_bailout;
5137 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5139 * The sync rate the user gives us is in MHz.
5140 * We need to translate it into KHz for this
5145 * Next, we calculate a "preliminary" sync period
5146 * in tenths of a nanosecond.
5149 prelim_sync_period = 0;
5151 prelim_sync_period = 10000000 / syncrate;
5153 scsi_calc_syncparam(prelim_sync_period);
5156 if (sata && syncrate != -1) {
5157 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5158 warnx("HBA is not capable of changing "
5161 goto ratecontrol_bailout;
5163 if (!user_settings) {
5164 warnx("You can modify only user rate "
5165 "settings for SATA");
5167 goto ratecontrol_bailout;
5169 sata->revision = ata_speed2revision(syncrate * 100);
5170 if (sata->revision < 0) {
5171 warnx("Invalid rate %f", syncrate);
5173 goto ratecontrol_bailout;
5175 sata->valid |= CTS_SATA_VALID_REVISION;
5178 if ((pata || sata) && mode != -1) {
5179 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5180 warnx("HBA is not capable of changing "
5183 goto ratecontrol_bailout;
5185 if (!user_settings) {
5186 warnx("You can modify only user mode "
5187 "settings for ATA/SATA");
5189 goto ratecontrol_bailout;
5193 pata->valid |= CTS_ATA_VALID_MODE;
5196 sata->valid |= CTS_SATA_VALID_MODE;
5201 * The bus_width argument goes like this:
5205 * Therefore, if you shift the number of bits given on the
5206 * command line right by 4, you should get the correct
5209 if (spi && bus_width != -1) {
5211 * We might as well validate things here with a
5212 * decipherable error message, rather than what
5213 * will probably be an indecipherable error message
5214 * by the time it gets back to us.
5216 if ((bus_width == 16)
5217 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5218 warnx("HBA does not support 16 bit bus width");
5220 goto ratecontrol_bailout;
5221 } else if ((bus_width == 32)
5222 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5223 warnx("HBA does not support 32 bit bus width");
5225 goto ratecontrol_bailout;
5226 } else if ((bus_width != 8)
5227 && (bus_width != 16)
5228 && (bus_width != 32)) {
5229 warnx("Invalid bus width %d", bus_width);
5231 goto ratecontrol_bailout;
5233 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5234 spi->bus_width = bus_width >> 4;
5237 if (didsettings == 0) {
5238 goto ratecontrol_bailout;
5240 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5241 if (cam_send_ccb(device, ccb) < 0) {
5242 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5243 if (arglist & CAM_ARG_VERBOSE) {
5244 cam_error_print(device, ccb, CAM_ESF_ALL,
5245 CAM_EPF_ALL, stderr);
5248 goto ratecontrol_bailout;
5250 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5251 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5252 if (arglist & CAM_ARG_VERBOSE) {
5253 cam_error_print(device, ccb, CAM_ESF_ALL,
5254 CAM_EPF_ALL, stderr);
5257 goto ratecontrol_bailout;
5261 retval = testunitready(device, retry_count, timeout,
5262 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5264 * If the TUR didn't succeed, just bail.
5268 fprintf(stderr, "Test Unit Ready failed\n");
5269 goto ratecontrol_bailout;
5272 if ((change_settings || send_tur) && !quiet &&
5273 (ccb->cts.transport == XPORT_ATA ||
5274 ccb->cts.transport == XPORT_SATA || send_tur)) {
5275 fprintf(stdout, "New parameters:\n");
5276 retval = get_print_cts(device, user_settings, 0, NULL);
5279 ratecontrol_bailout:
5285 scsiformat(struct cam_device *device, int argc, char **argv,
5286 char *combinedopt, int retry_count, int timeout)
5290 int ycount = 0, quiet = 0;
5291 int error = 0, retval = 0;
5292 int use_timeout = 10800 * 1000;
5294 struct format_defect_list_header fh;
5295 u_int8_t *data_ptr = NULL;
5296 u_int32_t dxfer_len = 0;
5298 int num_warnings = 0;
5301 ccb = cam_getccb(device);
5304 warnx("scsiformat: error allocating ccb");
5308 bzero(&(&ccb->ccb_h)[1],
5309 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5311 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5332 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5333 "following device:\n");
5335 error = scsidoinquiry(device, argc, argv, combinedopt,
5336 retry_count, timeout);
5339 warnx("scsiformat: error sending inquiry");
5340 goto scsiformat_bailout;
5345 if (!get_confirmation()) {
5347 goto scsiformat_bailout;
5352 use_timeout = timeout;
5355 fprintf(stdout, "Current format timeout is %d seconds\n",
5356 use_timeout / 1000);
5360 * If the user hasn't disabled questions and didn't specify a
5361 * timeout on the command line, ask them if they want the current
5365 && (timeout == 0)) {
5367 int new_timeout = 0;
5369 fprintf(stdout, "Enter new timeout in seconds or press\n"
5370 "return to keep the current timeout [%d] ",
5371 use_timeout / 1000);
5373 if (fgets(str, sizeof(str), stdin) != NULL) {
5375 new_timeout = atoi(str);
5378 if (new_timeout != 0) {
5379 use_timeout = new_timeout * 1000;
5380 fprintf(stdout, "Using new timeout value %d\n",
5381 use_timeout / 1000);
5386 * Keep this outside the if block below to silence any unused
5387 * variable warnings.
5389 bzero(&fh, sizeof(fh));
5392 * If we're in immediate mode, we've got to include the format
5395 if (immediate != 0) {
5396 fh.byte2 = FU_DLH_IMMED;
5397 data_ptr = (u_int8_t *)&fh;
5398 dxfer_len = sizeof(fh);
5399 byte2 = FU_FMT_DATA;
5400 } else if (quiet == 0) {
5401 fprintf(stdout, "Formatting...");
5405 scsi_format_unit(&ccb->csio,
5406 /* retries */ retry_count,
5408 /* tag_action */ MSG_SIMPLE_Q_TAG,
5411 /* data_ptr */ data_ptr,
5412 /* dxfer_len */ dxfer_len,
5413 /* sense_len */ SSD_FULL_SIZE,
5414 /* timeout */ use_timeout);
5416 /* Disable freezing the device queue */
5417 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5419 if (arglist & CAM_ARG_ERR_RECOVER)
5420 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5422 if (((retval = cam_send_ccb(device, ccb)) < 0)
5423 || ((immediate == 0)
5424 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5425 const char errstr[] = "error sending format command";
5432 if (arglist & CAM_ARG_VERBOSE) {
5433 cam_error_print(device, ccb, CAM_ESF_ALL,
5434 CAM_EPF_ALL, stderr);
5437 goto scsiformat_bailout;
5441 * If we ran in non-immediate mode, we already checked for errors
5442 * above and printed out any necessary information. If we're in
5443 * immediate mode, we need to loop through and get status
5444 * information periodically.
5446 if (immediate == 0) {
5448 fprintf(stdout, "Format Complete\n");
5450 goto scsiformat_bailout;
5457 bzero(&(&ccb->ccb_h)[1],
5458 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5461 * There's really no need to do error recovery or
5462 * retries here, since we're just going to sit in a
5463 * loop and wait for the device to finish formatting.
5465 scsi_test_unit_ready(&ccb->csio,
5468 /* tag_action */ MSG_SIMPLE_Q_TAG,
5469 /* sense_len */ SSD_FULL_SIZE,
5470 /* timeout */ 5000);
5472 /* Disable freezing the device queue */
5473 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5475 retval = cam_send_ccb(device, ccb);
5478 * If we get an error from the ioctl, bail out. SCSI
5479 * errors are expected.
5482 warn("error sending CAMIOCOMMAND ioctl");
5483 if (arglist & CAM_ARG_VERBOSE) {
5484 cam_error_print(device, ccb, CAM_ESF_ALL,
5485 CAM_EPF_ALL, stderr);
5488 goto scsiformat_bailout;
5491 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5493 if ((status != CAM_REQ_CMP)
5494 && (status == CAM_SCSI_STATUS_ERROR)
5495 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5496 struct scsi_sense_data *sense;
5497 int error_code, sense_key, asc, ascq;
5499 sense = &ccb->csio.sense_data;
5500 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5501 ccb->csio.sense_resid, &error_code, &sense_key,
5502 &asc, &ascq, /*show_errors*/ 1);
5505 * According to the SCSI-2 and SCSI-3 specs, a
5506 * drive that is in the middle of a format should
5507 * return NOT READY with an ASC of "logical unit
5508 * not ready, format in progress". The sense key
5509 * specific bytes will then be a progress indicator.
5511 if ((sense_key == SSD_KEY_NOT_READY)
5512 && (asc == 0x04) && (ascq == 0x04)) {
5515 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5516 ccb->csio.sense_resid, sks) == 0)
5519 u_int64_t percentage;
5521 val = scsi_2btoul(&sks[1]);
5522 percentage = 10000 * val;
5525 "\rFormatting: %ju.%02u %% "
5527 (uintmax_t)(percentage /
5529 (unsigned)((percentage /
5533 } else if ((quiet == 0)
5534 && (++num_warnings <= 1)) {
5535 warnx("Unexpected SCSI Sense Key "
5536 "Specific value returned "
5538 scsi_sense_print(device, &ccb->csio,
5540 warnx("Unable to print status "
5541 "information, but format will "
5543 warnx("will exit when format is "
5548 warnx("Unexpected SCSI error during format");
5549 cam_error_print(device, ccb, CAM_ESF_ALL,
5550 CAM_EPF_ALL, stderr);
5552 goto scsiformat_bailout;
5555 } else if (status != CAM_REQ_CMP) {
5556 warnx("Unexpected CAM status %#x", status);
5557 if (arglist & CAM_ARG_VERBOSE)
5558 cam_error_print(device, ccb, CAM_ESF_ALL,
5559 CAM_EPF_ALL, stderr);
5561 goto scsiformat_bailout;
5564 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5567 fprintf(stdout, "\nFormat Complete\n");
5577 scsisanitize(struct cam_device *device, int argc, char **argv,
5578 char *combinedopt, int retry_count, int timeout)
5581 u_int8_t action = 0;
5583 int ycount = 0, quiet = 0;
5584 int error = 0, retval = 0;
5585 int use_timeout = 10800 * 1000;
5591 const char *pattern = NULL;
5592 u_int8_t *data_ptr = NULL;
5593 u_int32_t dxfer_len = 0;
5595 int num_warnings = 0;
5598 ccb = cam_getccb(device);
5601 warnx("scsisanitize: error allocating ccb");
5605 bzero(&(&ccb->ccb_h)[1],
5606 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5608 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5611 if (strcasecmp(optarg, "overwrite") == 0)
5612 action = SSZ_SERVICE_ACTION_OVERWRITE;
5613 else if (strcasecmp(optarg, "block") == 0)
5614 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
5615 else if (strcasecmp(optarg, "crypto") == 0)
5616 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
5617 else if (strcasecmp(optarg, "exitfailure") == 0)
5618 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
5620 warnx("invalid service operation \"%s\"",
5623 goto scsisanitize_bailout;
5627 passes = strtol(optarg, NULL, 0);
5628 if (passes < 1 || passes > 31) {
5629 warnx("invalid passes value %d", passes);
5631 goto scsisanitize_bailout;
5662 warnx("an action is required");
5664 goto scsisanitize_bailout;
5665 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
5666 struct scsi_sanitize_parameter_list *pl;
5670 if (pattern == NULL) {
5671 warnx("overwrite action requires -P argument");
5673 goto scsisanitize_bailout;
5675 fd = open(pattern, O_RDONLY);
5677 warn("cannot open pattern file %s", pattern);
5679 goto scsisanitize_bailout;
5681 if (fstat(fd, &sb) < 0) {
5682 warn("cannot stat pattern file %s", pattern);
5684 goto scsisanitize_bailout;
5687 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
5688 warnx("pattern file size exceeds maximum value %d",
5689 SSZPL_MAX_PATTERN_LENGTH);
5691 goto scsisanitize_bailout;
5693 dxfer_len = sizeof(*pl) + sz;
5694 data_ptr = calloc(1, dxfer_len);
5695 if (data_ptr == NULL) {
5696 warnx("cannot allocate parameter list buffer");
5698 goto scsisanitize_bailout;
5701 amt = read(fd, data_ptr + sizeof(*pl), sz);
5703 warn("cannot read pattern file");
5705 goto scsisanitize_bailout;
5706 } else if (amt != sz) {
5707 warnx("short pattern file read");
5709 goto scsisanitize_bailout;
5712 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
5718 pl->byte1 |= SSZPL_INVERT;
5719 scsi_ulto2b(sz, pl->length);
5725 else if (invert != 0)
5727 else if (pattern != NULL)
5732 warnx("%s argument only valid with overwrite "
5735 goto scsisanitize_bailout;
5740 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5741 "following device:\n");
5743 error = scsidoinquiry(device, argc, argv, combinedopt,
5744 retry_count, timeout);
5747 warnx("scsisanitize: error sending inquiry");
5748 goto scsisanitize_bailout;
5753 if (!get_confirmation()) {
5755 goto scsisanitize_bailout;
5760 use_timeout = timeout;
5763 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
5764 use_timeout / 1000);
5768 * If the user hasn't disabled questions and didn't specify a
5769 * timeout on the command line, ask them if they want the current
5773 && (timeout == 0)) {
5775 int new_timeout = 0;
5777 fprintf(stdout, "Enter new timeout in seconds or press\n"
5778 "return to keep the current timeout [%d] ",
5779 use_timeout / 1000);
5781 if (fgets(str, sizeof(str), stdin) != NULL) {
5783 new_timeout = atoi(str);
5786 if (new_timeout != 0) {
5787 use_timeout = new_timeout * 1000;
5788 fprintf(stdout, "Using new timeout value %d\n",
5789 use_timeout / 1000);
5795 byte2 |= SSZ_UNRESTRICTED_EXIT;
5799 scsi_sanitize(&ccb->csio,
5800 /* retries */ retry_count,
5802 /* tag_action */ MSG_SIMPLE_Q_TAG,
5805 /* data_ptr */ data_ptr,
5806 /* dxfer_len */ dxfer_len,
5807 /* sense_len */ SSD_FULL_SIZE,
5808 /* timeout */ use_timeout);
5810 /* Disable freezing the device queue */
5811 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5813 if (arglist & CAM_ARG_ERR_RECOVER)
5814 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5816 if (((retval = cam_send_ccb(device, ccb)) < 0)
5817 || ((immediate == 0)
5818 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5819 const char errstr[] = "error sending sanitize command";
5826 if (arglist & CAM_ARG_VERBOSE) {
5827 cam_error_print(device, ccb, CAM_ESF_ALL,
5828 CAM_EPF_ALL, stderr);
5831 goto scsisanitize_bailout;
5835 * If we ran in non-immediate mode, we already checked for errors
5836 * above and printed out any necessary information. If we're in
5837 * immediate mode, we need to loop through and get status
5838 * information periodically.
5840 if (immediate == 0) {
5842 fprintf(stdout, "Sanitize Complete\n");
5844 goto scsisanitize_bailout;
5851 bzero(&(&ccb->ccb_h)[1],
5852 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5855 * There's really no need to do error recovery or
5856 * retries here, since we're just going to sit in a
5857 * loop and wait for the device to finish sanitizing.
5859 scsi_test_unit_ready(&ccb->csio,
5862 /* tag_action */ MSG_SIMPLE_Q_TAG,
5863 /* sense_len */ SSD_FULL_SIZE,
5864 /* timeout */ 5000);
5866 /* Disable freezing the device queue */
5867 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5869 retval = cam_send_ccb(device, ccb);
5872 * If we get an error from the ioctl, bail out. SCSI
5873 * errors are expected.
5876 warn("error sending CAMIOCOMMAND ioctl");
5877 if (arglist & CAM_ARG_VERBOSE) {
5878 cam_error_print(device, ccb, CAM_ESF_ALL,
5879 CAM_EPF_ALL, stderr);
5882 goto scsisanitize_bailout;
5885 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5887 if ((status != CAM_REQ_CMP)
5888 && (status == CAM_SCSI_STATUS_ERROR)
5889 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5890 struct scsi_sense_data *sense;
5891 int error_code, sense_key, asc, ascq;
5893 sense = &ccb->csio.sense_data;
5894 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5895 ccb->csio.sense_resid, &error_code, &sense_key,
5896 &asc, &ascq, /*show_errors*/ 1);
5899 * According to the SCSI-3 spec, a drive that is in the
5900 * middle of a sanitize should return NOT READY with an
5901 * ASC of "logical unit not ready, sanitize in
5902 * progress". The sense key specific bytes will then
5903 * be a progress indicator.
5905 if ((sense_key == SSD_KEY_NOT_READY)
5906 && (asc == 0x04) && (ascq == 0x1b)) {
5909 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5910 ccb->csio.sense_resid, sks) == 0)
5913 u_int64_t percentage;
5915 val = scsi_2btoul(&sks[1]);
5916 percentage = 10000 * val;
5919 "\rSanitizing: %ju.%02u %% "
5921 (uintmax_t)(percentage /
5923 (unsigned)((percentage /
5927 } else if ((quiet == 0)
5928 && (++num_warnings <= 1)) {
5929 warnx("Unexpected SCSI Sense Key "
5930 "Specific value returned "
5931 "during sanitize:");
5932 scsi_sense_print(device, &ccb->csio,
5934 warnx("Unable to print status "
5935 "information, but sanitze will "
5937 warnx("will exit when sanitize is "
5942 warnx("Unexpected SCSI error during sanitize");
5943 cam_error_print(device, ccb, CAM_ESF_ALL,
5944 CAM_EPF_ALL, stderr);
5946 goto scsisanitize_bailout;
5949 } else if (status != CAM_REQ_CMP) {
5950 warnx("Unexpected CAM status %#x", status);
5951 if (arglist & CAM_ARG_VERBOSE)
5952 cam_error_print(device, ccb, CAM_ESF_ALL,
5953 CAM_EPF_ALL, stderr);
5955 goto scsisanitize_bailout;
5957 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5960 fprintf(stdout, "\nSanitize Complete\n");
5962 scsisanitize_bailout:
5965 if (data_ptr != NULL)
5973 scsireportluns(struct cam_device *device, int argc, char **argv,
5974 char *combinedopt, int retry_count, int timeout)
5977 int c, countonly, lunsonly;
5978 struct scsi_report_luns_data *lundata;
5980 uint8_t report_type;
5981 uint32_t list_len, i, j;
5986 report_type = RPL_REPORT_DEFAULT;
5987 ccb = cam_getccb(device);
5990 warnx("%s: error allocating ccb", __func__);
5994 bzero(&(&ccb->ccb_h)[1],
5995 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6000 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6009 if (strcasecmp(optarg, "default") == 0)
6010 report_type = RPL_REPORT_DEFAULT;
6011 else if (strcasecmp(optarg, "wellknown") == 0)
6012 report_type = RPL_REPORT_WELLKNOWN;
6013 else if (strcasecmp(optarg, "all") == 0)
6014 report_type = RPL_REPORT_ALL;
6016 warnx("%s: invalid report type \"%s\"",
6027 if ((countonly != 0)
6028 && (lunsonly != 0)) {
6029 warnx("%s: you can only specify one of -c or -l", __func__);
6034 * According to SPC-4, the allocation length must be at least 16
6035 * bytes -- enough for the header and one LUN.
6037 alloc_len = sizeof(*lundata) + 8;
6041 lundata = malloc(alloc_len);
6043 if (lundata == NULL) {
6044 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6049 scsi_report_luns(&ccb->csio,
6050 /*retries*/ retry_count,
6052 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6053 /*select_report*/ report_type,
6054 /*rpl_buf*/ lundata,
6055 /*alloc_len*/ alloc_len,
6056 /*sense_len*/ SSD_FULL_SIZE,
6057 /*timeout*/ timeout ? timeout : 5000);
6059 /* Disable freezing the device queue */
6060 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6062 if (arglist & CAM_ARG_ERR_RECOVER)
6063 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6065 if (cam_send_ccb(device, ccb) < 0) {
6066 warn("error sending REPORT LUNS command");
6068 if (arglist & CAM_ARG_VERBOSE)
6069 cam_error_print(device, ccb, CAM_ESF_ALL,
6070 CAM_EPF_ALL, stderr);
6076 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6077 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6083 list_len = scsi_4btoul(lundata->length);
6086 * If we need to list the LUNs, and our allocation
6087 * length was too short, reallocate and retry.
6089 if ((countonly == 0)
6090 && (list_len > (alloc_len - sizeof(*lundata)))) {
6091 alloc_len = list_len + sizeof(*lundata);
6097 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6098 ((list_len / 8) > 1) ? "s" : "");
6103 for (i = 0; i < (list_len / 8); i++) {
6107 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6109 fprintf(stdout, ",");
6110 switch (lundata->luns[i].lundata[j] &
6111 RPL_LUNDATA_ATYP_MASK) {
6112 case RPL_LUNDATA_ATYP_PERIPH:
6113 if ((lundata->luns[i].lundata[j] &
6114 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6115 fprintf(stdout, "%d:",
6116 lundata->luns[i].lundata[j] &
6117 RPL_LUNDATA_PERIPH_BUS_MASK);
6119 && ((lundata->luns[i].lundata[j+2] &
6120 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6123 fprintf(stdout, "%d",
6124 lundata->luns[i].lundata[j+1]);
6126 case RPL_LUNDATA_ATYP_FLAT: {
6128 tmplun[0] = lundata->luns[i].lundata[j] &
6129 RPL_LUNDATA_FLAT_LUN_MASK;
6130 tmplun[1] = lundata->luns[i].lundata[j+1];
6132 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6136 case RPL_LUNDATA_ATYP_LUN:
6137 fprintf(stdout, "%d:%d:%d",
6138 (lundata->luns[i].lundata[j+1] &
6139 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6140 lundata->luns[i].lundata[j] &
6141 RPL_LUNDATA_LUN_TARG_MASK,
6142 lundata->luns[i].lundata[j+1] &
6143 RPL_LUNDATA_LUN_LUN_MASK);
6145 case RPL_LUNDATA_ATYP_EXTLUN: {
6146 int field_len_code, eam_code;
6148 eam_code = lundata->luns[i].lundata[j] &
6149 RPL_LUNDATA_EXT_EAM_MASK;
6150 field_len_code = (lundata->luns[i].lundata[j] &
6151 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6153 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6154 && (field_len_code == 0x00)) {
6155 fprintf(stdout, "%d",
6156 lundata->luns[i].lundata[j+1]);
6157 } else if ((eam_code ==
6158 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6159 && (field_len_code == 0x03)) {
6163 * This format takes up all 8 bytes.
6164 * If we aren't starting at offset 0,
6168 fprintf(stdout, "Invalid "
6171 "specified format", j);
6175 bzero(tmp_lun, sizeof(tmp_lun));
6176 bcopy(&lundata->luns[i].lundata[j+1],
6177 &tmp_lun[1], sizeof(tmp_lun) - 1);
6178 fprintf(stdout, "%#jx",
6179 (intmax_t)scsi_8btou64(tmp_lun));
6182 fprintf(stderr, "Unknown Extended LUN"
6183 "Address method %#x, length "
6184 "code %#x", eam_code,
6191 fprintf(stderr, "Unknown LUN address method "
6192 "%#x\n", lundata->luns[i].lundata[0] &
6193 RPL_LUNDATA_ATYP_MASK);
6197 * For the flat addressing method, there are no
6198 * other levels after it.
6203 fprintf(stdout, "\n");
6216 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6217 char *combinedopt, int retry_count, int timeout)
6220 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6221 struct scsi_read_capacity_data rcap;
6222 struct scsi_read_capacity_data_long rcaplong;
6236 ccb = cam_getccb(device);
6239 warnx("%s: error allocating ccb", __func__);
6243 bzero(&(&ccb->ccb_h)[1],
6244 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6246 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6273 if ((blocksizeonly != 0)
6274 && (numblocks != 0)) {
6275 warnx("%s: you can only specify one of -b or -N", __func__);
6280 if ((blocksizeonly != 0)
6281 && (sizeonly != 0)) {
6282 warnx("%s: you can only specify one of -b or -s", __func__);
6289 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6295 && (blocksizeonly != 0)) {
6296 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6301 scsi_read_capacity(&ccb->csio,
6302 /*retries*/ retry_count,
6304 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6307 /*timeout*/ timeout ? timeout : 5000);
6309 /* Disable freezing the device queue */
6310 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6312 if (arglist & CAM_ARG_ERR_RECOVER)
6313 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6315 if (cam_send_ccb(device, ccb) < 0) {
6316 warn("error sending READ CAPACITY command");
6318 if (arglist & CAM_ARG_VERBOSE)
6319 cam_error_print(device, ccb, CAM_ESF_ALL,
6320 CAM_EPF_ALL, stderr);
6326 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6327 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6332 maxsector = scsi_4btoul(rcap.addr);
6333 block_len = scsi_4btoul(rcap.length);
6336 * A last block of 2^32-1 means that the true capacity is over 2TB,
6337 * and we need to issue the long READ CAPACITY to get the real
6338 * capacity. Otherwise, we're all set.
6340 if (maxsector != 0xffffffff)
6343 scsi_read_capacity_16(&ccb->csio,
6344 /*retries*/ retry_count,
6346 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6351 /*sense_len*/ SSD_FULL_SIZE,
6352 /*timeout*/ timeout ? timeout : 5000);
6354 /* Disable freezing the device queue */
6355 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6357 if (arglist & CAM_ARG_ERR_RECOVER)
6358 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6360 if (cam_send_ccb(device, ccb) < 0) {
6361 warn("error sending READ CAPACITY (16) command");
6363 if (arglist & CAM_ARG_VERBOSE)
6364 cam_error_print(device, ccb, CAM_ESF_ALL,
6365 CAM_EPF_ALL, stderr);
6371 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6372 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6377 maxsector = scsi_8btou64(rcaplong.addr);
6378 block_len = scsi_4btoul(rcaplong.length);
6381 if (blocksizeonly == 0) {
6383 * Humanize implies !quiet, and also implies numblocks.
6385 if (humanize != 0) {
6390 tmpbytes = (maxsector + 1) * block_len;
6391 ret = humanize_number(tmpstr, sizeof(tmpstr),
6392 tmpbytes, "", HN_AUTOSCALE,
6395 HN_DIVISOR_1000 : 0));
6397 warnx("%s: humanize_number failed!", __func__);
6401 fprintf(stdout, "Device Size: %s%s", tmpstr,
6402 (sizeonly == 0) ? ", " : "\n");
6403 } else if (numblocks != 0) {
6404 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6405 "Blocks: " : "", (uintmax_t)maxsector + 1,
6406 (sizeonly == 0) ? ", " : "\n");
6408 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6409 "Last Block: " : "", (uintmax_t)maxsector,
6410 (sizeonly == 0) ? ", " : "\n");
6414 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6415 "Block Length: " : "", block_len, (quiet == 0) ?
6424 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6425 int retry_count, int timeout)
6429 uint8_t *smp_request = NULL, *smp_response = NULL;
6430 int request_size = 0, response_size = 0;
6431 int fd_request = 0, fd_response = 0;
6432 char *datastr = NULL;
6433 struct get_hook hook;
6438 * Note that at the moment we don't support sending SMP CCBs to
6439 * devices that aren't probed by CAM.
6441 ccb = cam_getccb(device);
6443 warnx("%s: error allocating CCB", __func__);
6447 bzero(&(&ccb->ccb_h)[1],
6448 sizeof(union ccb) - sizeof(struct ccb_hdr));
6450 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6453 arglist |= CAM_ARG_CMD_IN;
6454 response_size = strtol(optarg, NULL, 0);
6455 if (response_size <= 0) {
6456 warnx("invalid number of response bytes %d",
6459 goto smpcmd_bailout;
6461 hook.argc = argc - optind;
6462 hook.argv = argv + optind;
6465 datastr = cget(&hook, NULL);
6467 * If the user supplied "-" instead of a format, he
6468 * wants the data to be written to stdout.
6470 if ((datastr != NULL)
6471 && (datastr[0] == '-'))
6474 smp_response = (u_int8_t *)malloc(response_size);
6475 if (smp_response == NULL) {
6476 warn("can't malloc memory for SMP response");
6478 goto smpcmd_bailout;
6482 arglist |= CAM_ARG_CMD_OUT;
6483 request_size = strtol(optarg, NULL, 0);
6484 if (request_size <= 0) {
6485 warnx("invalid number of request bytes %d",
6488 goto smpcmd_bailout;
6490 hook.argc = argc - optind;
6491 hook.argv = argv + optind;
6493 datastr = cget(&hook, NULL);
6494 smp_request = (u_int8_t *)malloc(request_size);
6495 if (smp_request == NULL) {
6496 warn("can't malloc memory for SMP request");
6498 goto smpcmd_bailout;
6500 bzero(smp_request, request_size);
6502 * If the user supplied "-" instead of a format, he
6503 * wants the data to be read from stdin.
6505 if ((datastr != NULL)
6506 && (datastr[0] == '-'))
6509 buff_encode_visit(smp_request, request_size,
6520 * If fd_data is set, and we're writing to the device, we need to
6521 * read the data the user wants written from stdin.
6523 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6525 int amt_to_read = request_size;
6526 u_int8_t *buf_ptr = smp_request;
6528 for (amt_read = 0; amt_to_read > 0;
6529 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6530 if (amt_read == -1) {
6531 warn("error reading data from stdin");
6533 goto smpcmd_bailout;
6535 amt_to_read -= amt_read;
6536 buf_ptr += amt_read;
6540 if (((arglist & CAM_ARG_CMD_IN) == 0)
6541 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6542 warnx("%s: need both the request (-r) and response (-R) "
6543 "arguments", __func__);
6545 goto smpcmd_bailout;
6548 flags |= CAM_DEV_QFRZDIS;
6550 cam_fill_smpio(&ccb->smpio,
6551 /*retries*/ retry_count,
6554 /*smp_request*/ smp_request,
6555 /*smp_request_len*/ request_size,
6556 /*smp_response*/ smp_response,
6557 /*smp_response_len*/ response_size,
6558 /*timeout*/ timeout ? timeout : 5000);
6560 ccb->smpio.flags = SMP_FLAG_NONE;
6562 if (((retval = cam_send_ccb(device, ccb)) < 0)
6563 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6564 const char warnstr[] = "error sending command";
6571 if (arglist & CAM_ARG_VERBOSE) {
6572 cam_error_print(device, ccb, CAM_ESF_ALL,
6573 CAM_EPF_ALL, stderr);
6577 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6578 && (response_size > 0)) {
6579 if (fd_response == 0) {
6580 buff_decode_visit(smp_response, response_size,
6581 datastr, arg_put, NULL);
6582 fprintf(stdout, "\n");
6584 ssize_t amt_written;
6585 int amt_to_write = response_size;
6586 u_int8_t *buf_ptr = smp_response;
6588 for (amt_written = 0; (amt_to_write > 0) &&
6589 (amt_written = write(STDOUT_FILENO, buf_ptr,
6590 amt_to_write)) > 0;){
6591 amt_to_write -= amt_written;
6592 buf_ptr += amt_written;
6594 if (amt_written == -1) {
6595 warn("error writing data to stdout");
6597 goto smpcmd_bailout;
6598 } else if ((amt_written == 0)
6599 && (amt_to_write > 0)) {
6600 warnx("only wrote %u bytes out of %u",
6601 response_size - amt_to_write,
6610 if (smp_request != NULL)
6613 if (smp_response != NULL)
6620 smpreportgeneral(struct cam_device *device, int argc, char **argv,
6621 char *combinedopt, int retry_count, int timeout)
6624 struct smp_report_general_request *request = NULL;
6625 struct smp_report_general_response *response = NULL;
6626 struct sbuf *sb = NULL;
6628 int c, long_response = 0;
6632 * Note that at the moment we don't support sending SMP CCBs to
6633 * devices that aren't probed by CAM.
6635 ccb = cam_getccb(device);
6637 warnx("%s: error allocating CCB", __func__);
6641 bzero(&(&ccb->ccb_h)[1],
6642 sizeof(union ccb) - sizeof(struct ccb_hdr));
6644 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6653 request = malloc(sizeof(*request));
6654 if (request == NULL) {
6655 warn("%s: unable to allocate %zd bytes", __func__,
6661 response = malloc(sizeof(*response));
6662 if (response == NULL) {
6663 warn("%s: unable to allocate %zd bytes", __func__,
6670 smp_report_general(&ccb->smpio,
6674 /*request_len*/ sizeof(*request),
6675 (uint8_t *)response,
6676 /*response_len*/ sizeof(*response),
6677 /*long_response*/ long_response,
6680 if (((retval = cam_send_ccb(device, ccb)) < 0)
6681 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6682 const char warnstr[] = "error sending command";
6689 if (arglist & CAM_ARG_VERBOSE) {
6690 cam_error_print(device, ccb, CAM_ESF_ALL,
6691 CAM_EPF_ALL, stderr);
6698 * If the device supports the long response bit, try again and see
6699 * if we can get all of the data.
6701 if ((response->long_response & SMP_RG_LONG_RESPONSE)
6702 && (long_response == 0)) {
6703 ccb->ccb_h.status = CAM_REQ_INPROG;
6704 bzero(&(&ccb->ccb_h)[1],
6705 sizeof(union ccb) - sizeof(struct ccb_hdr));
6711 * XXX KDM detect and decode SMP errors here.
6713 sb = sbuf_new_auto();
6715 warnx("%s: error allocating sbuf", __func__);
6719 smp_report_general_sbuf(response, sizeof(*response), sb);
6721 if (sbuf_finish(sb) != 0) {
6722 warnx("%s: sbuf_finish", __func__);
6726 printf("%s", sbuf_data(sb));
6732 if (request != NULL)
6735 if (response != NULL)
6744 static struct camcontrol_opts phy_ops[] = {
6745 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
6746 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
6747 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
6748 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
6749 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
6750 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
6751 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
6752 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
6753 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
6758 smpphycontrol(struct cam_device *device, int argc, char **argv,
6759 char *combinedopt, int retry_count, int timeout)
6762 struct smp_phy_control_request *request = NULL;
6763 struct smp_phy_control_response *response = NULL;
6764 int long_response = 0;
6767 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
6769 uint64_t attached_dev_name = 0;
6770 int dev_name_set = 0;
6771 uint32_t min_plr = 0, max_plr = 0;
6772 uint32_t pp_timeout_val = 0;
6773 int slumber_partial = 0;
6774 int set_pp_timeout_val = 0;
6778 * Note that at the moment we don't support sending SMP CCBs to
6779 * devices that aren't probed by CAM.
6781 ccb = cam_getccb(device);
6783 warnx("%s: error allocating CCB", __func__);
6787 bzero(&(&ccb->ccb_h)[1],
6788 sizeof(union ccb) - sizeof(struct ccb_hdr));
6790 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6798 if (strcasecmp(optarg, "enable") == 0)
6800 else if (strcasecmp(optarg, "disable") == 0)
6803 warnx("%s: Invalid argument %s", __func__,
6810 slumber_partial |= enable <<
6811 SMP_PC_SAS_SLUMBER_SHIFT;
6814 slumber_partial |= enable <<
6815 SMP_PC_SAS_PARTIAL_SHIFT;
6818 slumber_partial |= enable <<
6819 SMP_PC_SATA_SLUMBER_SHIFT;
6822 slumber_partial |= enable <<
6823 SMP_PC_SATA_PARTIAL_SHIFT;
6826 warnx("%s: programmer error", __func__);
6829 break; /*NOTREACHED*/
6834 attached_dev_name = (uintmax_t)strtoumax(optarg,
6843 * We don't do extensive checking here, so this
6844 * will continue to work when new speeds come out.
6846 min_plr = strtoul(optarg, NULL, 0);
6848 || (min_plr > 0xf)) {
6849 warnx("%s: invalid link rate %x",
6857 * We don't do extensive checking here, so this
6858 * will continue to work when new speeds come out.
6860 max_plr = strtoul(optarg, NULL, 0);
6862 || (max_plr > 0xf)) {
6863 warnx("%s: invalid link rate %x",
6870 camcontrol_optret optreturn;
6871 cam_argmask argnums;
6874 if (phy_op_set != 0) {
6875 warnx("%s: only one phy operation argument "
6876 "(-o) allowed", __func__);
6884 * Allow the user to specify the phy operation
6885 * numerically, as well as with a name. This will
6886 * future-proof it a bit, so options that are added
6887 * in future specs can be used.
6889 if (isdigit(optarg[0])) {
6890 phy_operation = strtoul(optarg, NULL, 0);
6891 if ((phy_operation == 0)
6892 || (phy_operation > 0xff)) {
6893 warnx("%s: invalid phy operation %#x",
6894 __func__, phy_operation);
6900 optreturn = getoption(phy_ops, optarg, &phy_operation,
6903 if (optreturn == CC_OR_AMBIGUOUS) {
6904 warnx("%s: ambiguous option %s", __func__,
6909 } else if (optreturn == CC_OR_NOT_FOUND) {
6910 warnx("%s: option %s not found", __func__,
6922 pp_timeout_val = strtoul(optarg, NULL, 0);
6923 if (pp_timeout_val > 15) {
6924 warnx("%s: invalid partial pathway timeout "
6925 "value %u, need a value less than 16",
6926 __func__, pp_timeout_val);
6930 set_pp_timeout_val = 1;
6938 warnx("%s: a PHY (-p phy) argument is required",__func__);
6943 if (((dev_name_set != 0)
6944 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
6945 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
6946 && (dev_name_set == 0))) {
6947 warnx("%s: -d name and -o setdevname arguments both "
6948 "required to set device name", __func__);
6953 request = malloc(sizeof(*request));
6954 if (request == NULL) {
6955 warn("%s: unable to allocate %zd bytes", __func__,
6961 response = malloc(sizeof(*response));
6962 if (response == NULL) {
6963 warn("%s: unable to allocate %zd bytes", __func__,
6969 smp_phy_control(&ccb->smpio,
6974 (uint8_t *)response,
6977 /*expected_exp_change_count*/ 0,
6980 (set_pp_timeout_val != 0) ? 1 : 0,
6988 if (((retval = cam_send_ccb(device, ccb)) < 0)
6989 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6990 const char warnstr[] = "error sending command";
6997 if (arglist & CAM_ARG_VERBOSE) {
6999 * Use CAM_EPF_NORMAL so we only get one line of
7000 * SMP command decoding.
7002 cam_error_print(device, ccb, CAM_ESF_ALL,
7003 CAM_EPF_NORMAL, stderr);
7009 /* XXX KDM print out something here for success? */
7014 if (request != NULL)
7017 if (response != NULL)
7024 smpmaninfo(struct cam_device *device, int argc, char **argv,
7025 char *combinedopt, int retry_count, int timeout)
7028 struct smp_report_manuf_info_request request;
7029 struct smp_report_manuf_info_response response;
7030 struct sbuf *sb = NULL;
7031 int long_response = 0;
7036 * Note that at the moment we don't support sending SMP CCBs to
7037 * devices that aren't probed by CAM.
7039 ccb = cam_getccb(device);
7041 warnx("%s: error allocating CCB", __func__);
7045 bzero(&(&ccb->ccb_h)[1],
7046 sizeof(union ccb) - sizeof(struct ccb_hdr));
7048 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7057 bzero(&request, sizeof(request));
7058 bzero(&response, sizeof(response));
7060 smp_report_manuf_info(&ccb->smpio,
7065 (uint8_t *)&response,
7070 if (((retval = cam_send_ccb(device, ccb)) < 0)
7071 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7072 const char warnstr[] = "error sending command";
7079 if (arglist & CAM_ARG_VERBOSE) {
7080 cam_error_print(device, ccb, CAM_ESF_ALL,
7081 CAM_EPF_ALL, stderr);
7087 sb = sbuf_new_auto();
7089 warnx("%s: error allocating sbuf", __func__);
7093 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7095 if (sbuf_finish(sb) != 0) {
7096 warnx("%s: sbuf_finish", __func__);
7100 printf("%s", sbuf_data(sb));
7114 getdevid(struct cam_devitem *item)
7117 union ccb *ccb = NULL;
7119 struct cam_device *dev;
7121 dev = cam_open_btl(item->dev_match.path_id,
7122 item->dev_match.target_id,
7123 item->dev_match.target_lun, O_RDWR, NULL);
7126 warnx("%s", cam_errbuf);
7131 item->device_id_len = 0;
7133 ccb = cam_getccb(dev);
7135 warnx("%s: error allocating CCB", __func__);
7140 bzero(&(&ccb->ccb_h)[1],
7141 sizeof(union ccb) - sizeof(struct ccb_hdr));
7144 * On the first try, we just probe for the size of the data, and
7145 * then allocate that much memory and try again.
7148 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7149 ccb->ccb_h.flags = CAM_DIR_IN;
7150 ccb->cdai.flags = 0;
7151 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7152 ccb->cdai.bufsiz = item->device_id_len;
7153 if (item->device_id_len != 0)
7154 ccb->cdai.buf = (uint8_t *)item->device_id;
7156 if (cam_send_ccb(dev, ccb) < 0) {
7157 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7162 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7163 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7168 if (item->device_id_len == 0) {
7170 * This is our first time through. Allocate the buffer,
7171 * and then go back to get the data.
7173 if (ccb->cdai.provsiz == 0) {
7174 warnx("%s: invalid .provsiz field returned with "
7175 "XPT_GDEV_ADVINFO CCB", __func__);
7179 item->device_id_len = ccb->cdai.provsiz;
7180 item->device_id = malloc(item->device_id_len);
7181 if (item->device_id == NULL) {
7182 warn("%s: unable to allocate %d bytes", __func__,
7183 item->device_id_len);
7187 ccb->ccb_h.status = CAM_REQ_INPROG;
7193 cam_close_device(dev);
7202 * XXX KDM merge this code with getdevtree()?
7205 buildbusdevlist(struct cam_devlist *devlist)
7208 int bufsize, fd = -1;
7209 struct dev_match_pattern *patterns;
7210 struct cam_devitem *item = NULL;
7211 int skip_device = 0;
7214 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7215 warn("couldn't open %s", XPT_DEVICE);
7219 bzero(&ccb, sizeof(union ccb));
7221 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7222 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7223 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7225 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7226 bufsize = sizeof(struct dev_match_result) * 100;
7227 ccb.cdm.match_buf_len = bufsize;
7228 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7229 if (ccb.cdm.matches == NULL) {
7230 warnx("can't malloc memory for matches");
7234 ccb.cdm.num_matches = 0;
7235 ccb.cdm.num_patterns = 2;
7236 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7237 ccb.cdm.num_patterns;
7239 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7240 if (patterns == NULL) {
7241 warnx("can't malloc memory for patterns");
7246 ccb.cdm.patterns = patterns;
7247 bzero(patterns, ccb.cdm.pattern_buf_len);
7249 patterns[0].type = DEV_MATCH_DEVICE;
7250 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7251 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7252 patterns[1].type = DEV_MATCH_PERIPH;
7253 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7254 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7257 * We do the ioctl multiple times if necessary, in case there are
7258 * more than 100 nodes in the EDT.
7263 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7264 warn("error sending CAMIOCOMMAND ioctl");
7269 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7270 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7271 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7272 warnx("got CAM error %#x, CDM error %d\n",
7273 ccb.ccb_h.status, ccb.cdm.status);
7278 for (i = 0; i < ccb.cdm.num_matches; i++) {
7279 switch (ccb.cdm.matches[i].type) {
7280 case DEV_MATCH_DEVICE: {
7281 struct device_match_result *dev_result;
7284 &ccb.cdm.matches[i].result.device_result;
7286 if (dev_result->flags &
7287 DEV_RESULT_UNCONFIGURED) {
7293 item = malloc(sizeof(*item));
7295 warn("%s: unable to allocate %zd bytes",
7296 __func__, sizeof(*item));
7300 bzero(item, sizeof(*item));
7301 bcopy(dev_result, &item->dev_match,
7302 sizeof(*dev_result));
7303 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7306 if (getdevid(item) != 0) {
7312 case DEV_MATCH_PERIPH: {
7313 struct periph_match_result *periph_result;
7316 &ccb.cdm.matches[i].result.periph_result;
7318 if (skip_device != 0)
7320 item->num_periphs++;
7321 item->periph_matches = realloc(
7322 item->periph_matches,
7324 sizeof(struct periph_match_result));
7325 if (item->periph_matches == NULL) {
7326 warn("%s: error allocating periph "
7331 bcopy(periph_result, &item->periph_matches[
7332 item->num_periphs - 1],
7333 sizeof(*periph_result));
7337 fprintf(stderr, "%s: unexpected match "
7338 "type %d\n", __func__,
7339 ccb.cdm.matches[i].type);
7342 break; /*NOTREACHED*/
7345 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7346 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7354 free(ccb.cdm.matches);
7357 freebusdevlist(devlist);
7363 freebusdevlist(struct cam_devlist *devlist)
7365 struct cam_devitem *item, *item2;
7367 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7368 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7370 free(item->device_id);
7371 free(item->periph_matches);
7376 static struct cam_devitem *
7377 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7379 struct cam_devitem *item;
7381 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7382 struct scsi_vpd_id_descriptor *idd;
7385 * XXX KDM look for LUN IDs as well?
7387 idd = scsi_get_devid(item->device_id,
7388 item->device_id_len,
7389 scsi_devid_is_sas_target);
7393 if (scsi_8btou64(idd->identifier) == sasaddr)
7401 smpphylist(struct cam_device *device, int argc, char **argv,
7402 char *combinedopt, int retry_count, int timeout)
7404 struct smp_report_general_request *rgrequest = NULL;
7405 struct smp_report_general_response *rgresponse = NULL;
7406 struct smp_discover_request *disrequest = NULL;
7407 struct smp_discover_response *disresponse = NULL;
7408 struct cam_devlist devlist;
7410 int long_response = 0;
7417 * Note that at the moment we don't support sending SMP CCBs to
7418 * devices that aren't probed by CAM.
7420 ccb = cam_getccb(device);
7422 warnx("%s: error allocating CCB", __func__);
7426 bzero(&(&ccb->ccb_h)[1],
7427 sizeof(union ccb) - sizeof(struct ccb_hdr));
7428 STAILQ_INIT(&devlist.dev_queue);
7430 rgrequest = malloc(sizeof(*rgrequest));
7431 if (rgrequest == NULL) {
7432 warn("%s: unable to allocate %zd bytes", __func__,
7433 sizeof(*rgrequest));
7438 rgresponse = malloc(sizeof(*rgresponse));
7439 if (rgresponse == NULL) {
7440 warn("%s: unable to allocate %zd bytes", __func__,
7441 sizeof(*rgresponse));
7446 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7459 smp_report_general(&ccb->smpio,
7463 /*request_len*/ sizeof(*rgrequest),
7464 (uint8_t *)rgresponse,
7465 /*response_len*/ sizeof(*rgresponse),
7466 /*long_response*/ long_response,
7469 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7471 if (((retval = cam_send_ccb(device, ccb)) < 0)
7472 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7473 const char warnstr[] = "error sending command";
7480 if (arglist & CAM_ARG_VERBOSE) {
7481 cam_error_print(device, ccb, CAM_ESF_ALL,
7482 CAM_EPF_ALL, stderr);
7488 num_phys = rgresponse->num_phys;
7490 if (num_phys == 0) {
7492 fprintf(stdout, "%s: No Phys reported\n", __func__);
7497 devlist.path_id = device->path_id;
7499 retval = buildbusdevlist(&devlist);
7504 fprintf(stdout, "%d PHYs:\n", num_phys);
7505 fprintf(stdout, "PHY Attached SAS Address\n");
7508 disrequest = malloc(sizeof(*disrequest));
7509 if (disrequest == NULL) {
7510 warn("%s: unable to allocate %zd bytes", __func__,
7511 sizeof(*disrequest));
7516 disresponse = malloc(sizeof(*disresponse));
7517 if (disresponse == NULL) {
7518 warn("%s: unable to allocate %zd bytes", __func__,
7519 sizeof(*disresponse));
7524 for (i = 0; i < num_phys; i++) {
7525 struct cam_devitem *item;
7526 struct device_match_result *dev_match;
7527 char vendor[16], product[48], revision[16];
7531 bzero(&(&ccb->ccb_h)[1],
7532 sizeof(union ccb) - sizeof(struct ccb_hdr));
7534 ccb->ccb_h.status = CAM_REQ_INPROG;
7535 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7537 smp_discover(&ccb->smpio,
7541 sizeof(*disrequest),
7542 (uint8_t *)disresponse,
7543 sizeof(*disresponse),
7545 /*ignore_zone_group*/ 0,
7549 if (((retval = cam_send_ccb(device, ccb)) < 0)
7550 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7551 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7552 const char warnstr[] = "error sending command";
7559 if (arglist & CAM_ARG_VERBOSE) {
7560 cam_error_print(device, ccb, CAM_ESF_ALL,
7561 CAM_EPF_ALL, stderr);
7567 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7569 fprintf(stdout, "%3d <vacant>\n", i);
7573 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7576 item = findsasdevice(&devlist,
7577 scsi_8btou64(disresponse->attached_sas_address));
7581 || (item != NULL)) {
7582 fprintf(stdout, "%3d 0x%016jx", i,
7583 (uintmax_t)scsi_8btou64(
7584 disresponse->attached_sas_address));
7586 fprintf(stdout, "\n");
7589 } else if (quiet != 0)
7592 dev_match = &item->dev_match;
7594 if (dev_match->protocol == PROTO_SCSI) {
7595 cam_strvis(vendor, dev_match->inq_data.vendor,
7596 sizeof(dev_match->inq_data.vendor),
7598 cam_strvis(product, dev_match->inq_data.product,
7599 sizeof(dev_match->inq_data.product),
7601 cam_strvis(revision, dev_match->inq_data.revision,
7602 sizeof(dev_match->inq_data.revision),
7604 sprintf(tmpstr, "<%s %s %s>", vendor, product,
7606 } else if ((dev_match->protocol == PROTO_ATA)
7607 || (dev_match->protocol == PROTO_SATAPM)) {
7608 cam_strvis(product, dev_match->ident_data.model,
7609 sizeof(dev_match->ident_data.model),
7611 cam_strvis(revision, dev_match->ident_data.revision,
7612 sizeof(dev_match->ident_data.revision),
7614 sprintf(tmpstr, "<%s %s>", product, revision);
7616 sprintf(tmpstr, "<>");
7618 fprintf(stdout, " %-33s ", tmpstr);
7621 * If we have 0 periphs, that's a bug...
7623 if (item->num_periphs == 0) {
7624 fprintf(stdout, "\n");
7628 fprintf(stdout, "(");
7629 for (j = 0; j < item->num_periphs; j++) {
7631 fprintf(stdout, ",");
7633 fprintf(stdout, "%s%d",
7634 item->periph_matches[j].periph_name,
7635 item->periph_matches[j].unit_number);
7638 fprintf(stdout, ")\n");
7652 freebusdevlist(&devlist);
7658 atapm(struct cam_device *device, int argc, char **argv,
7659 char *combinedopt, int retry_count, int timeout)
7667 ccb = cam_getccb(device);
7670 warnx("%s: error allocating ccb", __func__);
7674 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7683 if (strcmp(argv[1], "idle") == 0) {
7685 cmd = ATA_IDLE_IMMEDIATE;
7688 } else if (strcmp(argv[1], "standby") == 0) {
7690 cmd = ATA_STANDBY_IMMEDIATE;
7692 cmd = ATA_STANDBY_CMD;
7700 else if (t <= (240 * 5))
7702 else if (t <= (252 * 5))
7703 /* special encoding for 21 minutes */
7705 else if (t <= (11 * 30 * 60))
7706 sc = (t - 1) / (30 * 60) + 241;
7710 retval = ata_do_28bit_cmd(device,
7712 /*retries*/retry_count,
7713 /*flags*/CAM_DIR_NONE,
7714 /*protocol*/AP_PROTO_NON_DATA,
7715 /*tag_action*/MSG_SIMPLE_Q_TAG,
7722 /*timeout*/timeout ? timeout : 30 * 1000,
7729 #endif /* MINIMALISTIC */
7732 usage(int printlong)
7735 fprintf(printlong ? stdout : stderr,
7736 "usage: camcontrol <command> [device id][generic args][command args]\n"
7737 " camcontrol devlist [-v]\n"
7738 #ifndef MINIMALISTIC
7739 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
7740 " camcontrol tur [dev_id][generic args]\n"
7741 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
7742 " camcontrol identify [dev_id][generic args] [-v]\n"
7743 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
7744 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
7746 " camcontrol start [dev_id][generic args]\n"
7747 " camcontrol stop [dev_id][generic args]\n"
7748 " camcontrol load [dev_id][generic args]\n"
7749 " camcontrol eject [dev_id][generic args]\n"
7750 #endif /* MINIMALISTIC */
7751 " camcontrol rescan <all | bus[:target:lun]>\n"
7752 " camcontrol reset <all | bus[:target:lun]>\n"
7753 #ifndef MINIMALISTIC
7754 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
7755 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
7756 " [-P pagectl][-e | -b][-d]\n"
7757 " camcontrol cmd [dev_id][generic args]\n"
7758 " <-a cmd [args] | -c cmd [args]>\n"
7759 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
7760 " camcontrol smpcmd [dev_id][generic args]\n"
7761 " <-r len fmt [args]> <-R len fmt [args]>\n"
7762 " camcontrol smprg [dev_id][generic args][-l]\n"
7763 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
7764 " [-o operation][-d name][-m rate][-M rate]\n"
7765 " [-T pp_timeout][-a enable|disable]\n"
7766 " [-A enable|disable][-s enable|disable]\n"
7767 " [-S enable|disable]\n"
7768 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
7769 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
7770 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
7771 " <all|bus[:target[:lun]]|off>\n"
7772 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
7773 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
7774 " [-D <enable|disable>][-M mode][-O offset]\n"
7775 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
7776 " [-U][-W bus_width]\n"
7777 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
7778 " camcontrol sanitize [dev_id][generic args]\n"
7779 " [-a overwrite|block|crypto|exitfailure]\n"
7780 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
7782 " camcontrol idle [dev_id][generic args][-t time]\n"
7783 " camcontrol standby [dev_id][generic args][-t time]\n"
7784 " camcontrol sleep [dev_id][generic args]\n"
7785 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
7786 " camcontrol security [dev_id][generic args]\n"
7787 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
7788 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
7789 " [-U <user|master>] [-y]\n"
7790 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
7791 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
7792 #endif /* MINIMALISTIC */
7793 " camcontrol help\n");
7796 #ifndef MINIMALISTIC
7798 "Specify one of the following options:\n"
7799 "devlist list all CAM devices\n"
7800 "periphlist list all CAM peripheral drivers attached to a device\n"
7801 "tur send a test unit ready to the named device\n"
7802 "inquiry send a SCSI inquiry command to the named device\n"
7803 "identify send a ATA identify command to the named device\n"
7804 "reportluns send a SCSI report luns command to the device\n"
7805 "readcap send a SCSI read capacity command to the device\n"
7806 "start send a Start Unit command to the device\n"
7807 "stop send a Stop Unit command to the device\n"
7808 "load send a Start Unit command to the device with the load bit set\n"
7809 "eject send a Stop Unit command to the device with the eject bit set\n"
7810 "rescan rescan all busses, the given bus, or bus:target:lun\n"
7811 "reset reset all busses, the given bus, or bus:target:lun\n"
7812 "defects read the defect list of the specified device\n"
7813 "modepage display or edit (-e) the given mode page\n"
7814 "cmd send the given SCSI command, may need -i or -o as well\n"
7815 "smpcmd send the given SMP command, requires -o and -i\n"
7816 "smprg send the SMP Report General command\n"
7817 "smppc send the SMP PHY Control command, requires -p\n"
7818 "smpphylist display phys attached to a SAS expander\n"
7819 "smpmaninfo send the SMP Report Manufacturer Info command\n"
7820 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
7821 "tags report or set the number of transaction slots for a device\n"
7822 "negotiate report or set device negotiation parameters\n"
7823 "format send the SCSI FORMAT UNIT command to the named device\n"
7824 "sanitize send the SCSI SANITIZE command to the named device\n"
7825 "idle send the ATA IDLE command to the named device\n"
7826 "standby send the ATA STANDBY command to the named device\n"
7827 "sleep send the ATA SLEEP command to the named device\n"
7828 "fwdownload program firmware of the named device with the given image"
7829 "security report or send ATA security commands to the named device\n"
7830 "help this message\n"
7831 "Device Identifiers:\n"
7832 "bus:target specify the bus and target, lun defaults to 0\n"
7833 "bus:target:lun specify the bus, target and lun\n"
7834 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
7835 "Generic arguments:\n"
7836 "-v be verbose, print out sense information\n"
7837 "-t timeout command timeout in seconds, overrides default timeout\n"
7838 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
7839 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
7840 "-E have the kernel attempt to perform SCSI error recovery\n"
7841 "-C count specify the SCSI command retry count (needs -E to work)\n"
7842 "modepage arguments:\n"
7843 "-l list all available mode pages\n"
7844 "-m page specify the mode page to view or edit\n"
7845 "-e edit the specified mode page\n"
7846 "-b force view to binary mode\n"
7847 "-d disable block descriptors for mode sense\n"
7848 "-P pgctl page control field 0-3\n"
7849 "defects arguments:\n"
7850 "-f format specify defect list format (block, bfi or phys)\n"
7851 "-G get the grown defect list\n"
7852 "-P get the permanent defect list\n"
7853 "inquiry arguments:\n"
7854 "-D get the standard inquiry data\n"
7855 "-S get the serial number\n"
7856 "-R get the transfer rate, etc.\n"
7857 "reportluns arguments:\n"
7858 "-c only report a count of available LUNs\n"
7859 "-l only print out luns, and not a count\n"
7860 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
7861 "readcap arguments\n"
7862 "-b only report the blocksize\n"
7863 "-h human readable device size, base 2\n"
7864 "-H human readable device size, base 10\n"
7865 "-N print the number of blocks instead of last block\n"
7866 "-q quiet, print numbers only\n"
7867 "-s only report the last block/device size\n"
7869 "-c cdb [args] specify the SCSI CDB\n"
7870 "-i len fmt specify input data and input data format\n"
7871 "-o len fmt [args] specify output data and output data fmt\n"
7872 "smpcmd arguments:\n"
7873 "-r len fmt [args] specify the SMP command to be sent\n"
7874 "-R len fmt [args] specify SMP response format\n"
7875 "smprg arguments:\n"
7876 "-l specify the long response format\n"
7877 "smppc arguments:\n"
7878 "-p phy specify the PHY to operate on\n"
7879 "-l specify the long request/response format\n"
7880 "-o operation specify the phy control operation\n"
7881 "-d name set the attached device name\n"
7882 "-m rate set the minimum physical link rate\n"
7883 "-M rate set the maximum physical link rate\n"
7884 "-T pp_timeout set the partial pathway timeout value\n"
7885 "-a enable|disable enable or disable SATA slumber\n"
7886 "-A enable|disable enable or disable SATA partial phy power\n"
7887 "-s enable|disable enable or disable SAS slumber\n"
7888 "-S enable|disable enable or disable SAS partial phy power\n"
7889 "smpphylist arguments:\n"
7890 "-l specify the long response format\n"
7891 "-q only print phys with attached devices\n"
7892 "smpmaninfo arguments:\n"
7893 "-l specify the long response format\n"
7894 "debug arguments:\n"
7895 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
7896 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
7897 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
7898 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
7900 "-N tags specify the number of tags to use for this device\n"
7901 "-q be quiet, don't report the number of tags\n"
7902 "-v report a number of tag-related parameters\n"
7903 "negotiate arguments:\n"
7904 "-a send a test unit ready after negotiation\n"
7905 "-c report/set current negotiation settings\n"
7906 "-D <arg> \"enable\" or \"disable\" disconnection\n"
7907 "-M mode set ATA mode\n"
7908 "-O offset set command delay offset\n"
7909 "-q be quiet, don't report anything\n"
7910 "-R syncrate synchronization rate in MHz\n"
7911 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
7912 "-U report/set user negotiation settings\n"
7913 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
7914 "-v also print a Path Inquiry CCB for the controller\n"
7915 "format arguments:\n"
7916 "-q be quiet, don't print status messages\n"
7917 "-r run in report only mode\n"
7918 "-w don't send immediate format command\n"
7919 "-y don't ask any questions\n"
7920 "sanitize arguments:\n"
7921 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
7922 "-c passes overwrite passes to perform (1 to 31)\n"
7923 "-I invert overwrite pattern after each pass\n"
7924 "-P pattern path to overwrite pattern file\n"
7925 "-q be quiet, don't print status messages\n"
7926 "-r run in report only mode\n"
7927 "-U run operation in unrestricted completion exit mode\n"
7928 "-w don't send immediate sanitize command\n"
7929 "-y don't ask any questions\n"
7930 "idle/standby arguments:\n"
7931 "-t <arg> number of seconds before respective state.\n"
7932 "fwdownload arguments:\n"
7933 "-f fw_image path to firmware image file\n"
7934 "-y don't ask any questions\n"
7935 "-s run in simulation mode\n"
7936 "-v print info for every firmware segment sent to device\n"
7937 "security arguments:\n"
7938 "-d pwd disable security using the given password for the selected\n"
7940 "-e pwd erase the device using the given pwd for the selected user\n"
7941 "-f freeze the security configuration of the specified device\n"
7942 "-h pwd enhanced erase the device using the given pwd for the\n"
7944 "-k pwd unlock the device using the given pwd for the selected\n"
7946 "-l <high|maximum> specifies which security level to set: high or maximum\n"
7947 "-q be quiet, do not print any status messages\n"
7948 "-s pwd password the device (enable security) using the given\n"
7949 " pwd for the selected user\n"
7950 "-T timeout overrides the timeout (seconds) used for erase operation\n"
7951 "-U <user|master> specifies which user to set: user or master\n"
7952 "-y don't ask any questions\n"
7954 "-f freeze the HPA configuration of the device\n"
7955 "-l lock the HPA configuration of the device\n"
7956 "-P make the HPA max sectors persist\n"
7957 "-p pwd Set the HPA configuration password required for unlock\n"
7959 "-q be quiet, do not print any status messages\n"
7960 "-s sectors configures the maximum user accessible sectors of the\n"
7962 "-U pwd unlock the HPA configuration of the device\n"
7963 "-y don't ask any questions\n"
7965 #endif /* MINIMALISTIC */
7969 main(int argc, char **argv)
7972 char *device = NULL;
7974 struct cam_device *cam_dev = NULL;
7975 int timeout = 0, retry_count = 1;
7976 camcontrol_optret optreturn;
7978 const char *mainopt = "C:En:t:u:v";
7979 const char *subopt = NULL;
7980 char combinedopt[256];
7981 int error = 0, optstart = 2;
7983 #ifndef MINIMALISTIC
7987 #endif /* MINIMALISTIC */
7989 cmdlist = CAM_CMD_NONE;
7990 arglist = CAM_ARG_NONE;
7998 * Get the base option.
8000 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
8002 if (optreturn == CC_OR_AMBIGUOUS) {
8003 warnx("ambiguous option %s", argv[1]);
8006 } else if (optreturn == CC_OR_NOT_FOUND) {
8007 warnx("option %s not found", argv[1]);
8013 * Ahh, getopt(3) is a pain.
8015 * This is a gross hack. There really aren't many other good
8016 * options (excuse the pun) for parsing options in a situation like
8017 * this. getopt is kinda braindead, so you end up having to run
8018 * through the options twice, and give each invocation of getopt
8019 * the option string for the other invocation.
8021 * You would think that you could just have two groups of options.
8022 * The first group would get parsed by the first invocation of
8023 * getopt, and the second group would get parsed by the second
8024 * invocation of getopt. It doesn't quite work out that way. When
8025 * the first invocation of getopt finishes, it leaves optind pointing
8026 * to the argument _after_ the first argument in the second group.
8027 * So when the second invocation of getopt comes around, it doesn't
8028 * recognize the first argument it gets and then bails out.
8030 * A nice alternative would be to have a flag for getopt that says
8031 * "just keep parsing arguments even when you encounter an unknown
8032 * argument", but there isn't one. So there's no real clean way to
8033 * easily parse two sets of arguments without having one invocation
8034 * of getopt know about the other.
8036 * Without this hack, the first invocation of getopt would work as
8037 * long as the generic arguments are first, but the second invocation
8038 * (in the subfunction) would fail in one of two ways. In the case
8039 * where you don't set optreset, it would fail because optind may be
8040 * pointing to the argument after the one it should be pointing at.
8041 * In the case where you do set optreset, and reset optind, it would
8042 * fail because getopt would run into the first set of options, which
8043 * it doesn't understand.
8045 * All of this would "sort of" work if you could somehow figure out
8046 * whether optind had been incremented one option too far. The
8047 * mechanics of that, however, are more daunting than just giving
8048 * both invocations all of the expect options for either invocation.
8050 * Needless to say, I wouldn't mind if someone invented a better
8051 * (non-GPL!) command line parsing interface than getopt. I
8052 * wouldn't mind if someone added more knobs to getopt to make it
8053 * work better. Who knows, I may talk myself into doing it someday,
8054 * if the standards weenies let me. As it is, it just leads to
8055 * hackery like this and causes people to avoid it in some cases.
8057 * KDM, September 8th, 1998
8060 sprintf(combinedopt, "%s%s", mainopt, subopt);
8062 sprintf(combinedopt, "%s", mainopt);
8065 * For these options we do not parse optional device arguments and
8066 * we do not open a passthrough device.
8068 if ((cmdlist == CAM_CMD_RESCAN)
8069 || (cmdlist == CAM_CMD_RESET)
8070 || (cmdlist == CAM_CMD_DEVTREE)
8071 || (cmdlist == CAM_CMD_USAGE)
8072 || (cmdlist == CAM_CMD_DEBUG))
8075 #ifndef MINIMALISTIC
8077 && (argc > 2 && argv[2][0] != '-')) {
8081 if (isdigit(argv[2][0])) {
8082 /* device specified as bus:target[:lun] */
8083 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
8085 errx(1, "numeric device specification must "
8086 "be either bus:target, or "
8088 /* default to 0 if lun was not specified */
8089 if ((arglist & CAM_ARG_LUN) == 0) {
8091 arglist |= CAM_ARG_LUN;
8095 if (cam_get_device(argv[2], name, sizeof name, &unit)
8097 errx(1, "%s", cam_errbuf);
8098 device = strdup(name);
8099 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
8103 #endif /* MINIMALISTIC */
8105 * Start getopt processing at argv[2/3], since we've already
8106 * accepted argv[1..2] as the command name, and as a possible
8112 * Now we run through the argument list looking for generic
8113 * options, and ignoring options that possibly belong to
8116 while ((c = getopt(argc, argv, combinedopt))!= -1){
8119 retry_count = strtol(optarg, NULL, 0);
8120 if (retry_count < 0)
8121 errx(1, "retry count %d is < 0",
8123 arglist |= CAM_ARG_RETRIES;
8126 arglist |= CAM_ARG_ERR_RECOVER;
8129 arglist |= CAM_ARG_DEVICE;
8131 while (isspace(*tstr) && (*tstr != '\0'))
8133 device = (char *)strdup(tstr);
8136 timeout = strtol(optarg, NULL, 0);
8138 errx(1, "invalid timeout %d", timeout);
8139 /* Convert the timeout from seconds to ms */
8141 arglist |= CAM_ARG_TIMEOUT;
8144 arglist |= CAM_ARG_UNIT;
8145 unit = strtol(optarg, NULL, 0);
8148 arglist |= CAM_ARG_VERBOSE;
8155 #ifndef MINIMALISTIC
8157 * For most commands we'll want to open the passthrough device
8158 * associated with the specified device. In the case of the rescan
8159 * commands, we don't use a passthrough device at all, just the
8160 * transport layer device.
8163 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
8164 && (((arglist & CAM_ARG_DEVICE) == 0)
8165 || ((arglist & CAM_ARG_UNIT) == 0))) {
8166 errx(1, "subcommand \"%s\" requires a valid device "
8167 "identifier", argv[1]);
8170 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
8171 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
8172 cam_open_spec_device(device,unit,O_RDWR,NULL)))
8174 errx(1,"%s", cam_errbuf);
8176 #endif /* MINIMALISTIC */
8179 * Reset optind to 2, and reset getopt, so these routines can parse
8180 * the arguments again.
8186 #ifndef MINIMALISTIC
8187 case CAM_CMD_DEVLIST:
8188 error = getdevlist(cam_dev);
8191 error = atahpa(cam_dev, retry_count, timeout,
8192 argc, argv, combinedopt);
8194 #endif /* MINIMALISTIC */
8195 case CAM_CMD_DEVTREE:
8196 error = getdevtree();
8198 #ifndef MINIMALISTIC
8200 error = testunitready(cam_dev, retry_count, timeout, 0);
8202 case CAM_CMD_INQUIRY:
8203 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
8204 retry_count, timeout);
8206 case CAM_CMD_IDENTIFY:
8207 error = ataidentify(cam_dev, retry_count, timeout);
8209 case CAM_CMD_STARTSTOP:
8210 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
8211 arglist & CAM_ARG_EJECT, retry_count,
8214 #endif /* MINIMALISTIC */
8215 case CAM_CMD_RESCAN:
8216 error = dorescan_or_reset(argc, argv, 1);
8219 error = dorescan_or_reset(argc, argv, 0);
8221 #ifndef MINIMALISTIC
8222 case CAM_CMD_READ_DEFECTS:
8223 error = readdefects(cam_dev, argc, argv, combinedopt,
8224 retry_count, timeout);
8226 case CAM_CMD_MODE_PAGE:
8227 modepage(cam_dev, argc, argv, combinedopt,
8228 retry_count, timeout);
8230 case CAM_CMD_SCSI_CMD:
8231 error = scsicmd(cam_dev, argc, argv, combinedopt,
8232 retry_count, timeout);
8234 case CAM_CMD_SMP_CMD:
8235 error = smpcmd(cam_dev, argc, argv, combinedopt,
8236 retry_count, timeout);
8238 case CAM_CMD_SMP_RG:
8239 error = smpreportgeneral(cam_dev, argc, argv,
8240 combinedopt, retry_count,
8243 case CAM_CMD_SMP_PC:
8244 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
8245 retry_count, timeout);
8247 case CAM_CMD_SMP_PHYLIST:
8248 error = smpphylist(cam_dev, argc, argv, combinedopt,
8249 retry_count, timeout);
8251 case CAM_CMD_SMP_MANINFO:
8252 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
8253 retry_count, timeout);
8256 error = camdebug(argc, argv, combinedopt);
8259 error = tagcontrol(cam_dev, argc, argv, combinedopt);
8262 error = ratecontrol(cam_dev, retry_count, timeout,
8263 argc, argv, combinedopt);
8265 case CAM_CMD_FORMAT:
8266 error = scsiformat(cam_dev, argc, argv,
8267 combinedopt, retry_count, timeout);
8269 case CAM_CMD_REPORTLUNS:
8270 error = scsireportluns(cam_dev, argc, argv,
8271 combinedopt, retry_count,
8274 case CAM_CMD_READCAP:
8275 error = scsireadcapacity(cam_dev, argc, argv,
8276 combinedopt, retry_count,
8280 case CAM_CMD_STANDBY:
8282 error = atapm(cam_dev, argc, argv,
8283 combinedopt, retry_count, timeout);
8285 case CAM_CMD_SECURITY:
8286 error = atasecurity(cam_dev, retry_count, timeout,
8287 argc, argv, combinedopt);
8289 case CAM_CMD_DOWNLOAD_FW:
8290 error = fwdownload(cam_dev, argc, argv, combinedopt,
8291 arglist & CAM_ARG_VERBOSE, retry_count, timeout,
8292 get_disk_type(cam_dev));
8294 case CAM_CMD_SANITIZE:
8295 error = scsisanitize(cam_dev, argc, argv,
8296 combinedopt, retry_count, timeout);
8298 #endif /* MINIMALISTIC */
8308 if (cam_dev != NULL)
8309 cam_close_device(cam_dev);