2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
55 #include <cam/cam_debug.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/scsi/scsi_all.h>
58 #include <cam/scsi/scsi_da.h>
59 #include <cam/scsi/scsi_pass.h>
60 #include <cam/scsi/scsi_message.h>
61 #include <cam/scsi/smp_all.h>
62 #include <cam/ata/ata_all.h>
64 #include "camcontrol.h"
67 CAM_CMD_NONE = 0x00000000,
68 CAM_CMD_DEVLIST = 0x00000001,
69 CAM_CMD_TUR = 0x00000002,
70 CAM_CMD_INQUIRY = 0x00000003,
71 CAM_CMD_STARTSTOP = 0x00000004,
72 CAM_CMD_RESCAN = 0x00000005,
73 CAM_CMD_READ_DEFECTS = 0x00000006,
74 CAM_CMD_MODE_PAGE = 0x00000007,
75 CAM_CMD_SCSI_CMD = 0x00000008,
76 CAM_CMD_DEVTREE = 0x00000009,
77 CAM_CMD_USAGE = 0x0000000a,
78 CAM_CMD_DEBUG = 0x0000000b,
79 CAM_CMD_RESET = 0x0000000c,
80 CAM_CMD_FORMAT = 0x0000000d,
81 CAM_CMD_TAG = 0x0000000e,
82 CAM_CMD_RATE = 0x0000000f,
83 CAM_CMD_DETACH = 0x00000010,
84 CAM_CMD_REPORTLUNS = 0x00000011,
85 CAM_CMD_READCAP = 0x00000012,
86 CAM_CMD_IDENTIFY = 0x00000013,
87 CAM_CMD_IDLE = 0x00000014,
88 CAM_CMD_STANDBY = 0x00000015,
89 CAM_CMD_SLEEP = 0x00000016,
90 CAM_CMD_SMP_CMD = 0x00000017,
91 CAM_CMD_SMP_RG = 0x00000018,
92 CAM_CMD_SMP_PC = 0x00000019,
93 CAM_CMD_SMP_PHYLIST = 0x0000001a,
94 CAM_CMD_SMP_MANINFO = 0x0000001b,
95 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
96 CAM_CMD_SECURITY = 0x0000001d,
97 CAM_CMD_HPA = 0x0000001e,
98 CAM_CMD_SANITIZE = 0x0000001f,
102 CAM_ARG_NONE = 0x00000000,
103 CAM_ARG_VERBOSE = 0x00000001,
104 CAM_ARG_DEVICE = 0x00000002,
105 CAM_ARG_BUS = 0x00000004,
106 CAM_ARG_TARGET = 0x00000008,
107 CAM_ARG_LUN = 0x00000010,
108 CAM_ARG_EJECT = 0x00000020,
109 CAM_ARG_UNIT = 0x00000040,
110 CAM_ARG_FORMAT_BLOCK = 0x00000080,
111 CAM_ARG_FORMAT_BFI = 0x00000100,
112 CAM_ARG_FORMAT_PHYS = 0x00000200,
113 CAM_ARG_PLIST = 0x00000400,
114 CAM_ARG_GLIST = 0x00000800,
115 CAM_ARG_GET_SERIAL = 0x00001000,
116 CAM_ARG_GET_STDINQ = 0x00002000,
117 CAM_ARG_GET_XFERRATE = 0x00004000,
118 CAM_ARG_INQ_MASK = 0x00007000,
119 CAM_ARG_MODE_EDIT = 0x00008000,
120 CAM_ARG_PAGE_CNTL = 0x00010000,
121 CAM_ARG_TIMEOUT = 0x00020000,
122 CAM_ARG_CMD_IN = 0x00040000,
123 CAM_ARG_CMD_OUT = 0x00080000,
124 CAM_ARG_DBD = 0x00100000,
125 CAM_ARG_ERR_RECOVER = 0x00200000,
126 CAM_ARG_RETRIES = 0x00400000,
127 CAM_ARG_START_UNIT = 0x00800000,
128 CAM_ARG_DEBUG_INFO = 0x01000000,
129 CAM_ARG_DEBUG_TRACE = 0x02000000,
130 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
131 CAM_ARG_DEBUG_CDB = 0x08000000,
132 CAM_ARG_DEBUG_XPT = 0x10000000,
133 CAM_ARG_DEBUG_PERIPH = 0x20000000,
134 CAM_ARG_DEBUG_PROBE = 0x40000000,
137 struct camcontrol_opts {
145 struct ata_res_pass16 {
146 u_int16_t reserved[5];
149 u_int8_t sector_count_exp;
150 u_int8_t sector_count;
151 u_int8_t lba_low_exp;
153 u_int8_t lba_mid_exp;
155 u_int8_t lba_high_exp;
161 struct ata_set_max_pwd
164 u_int8_t password[32];
165 u_int16_t reserved2[239];
168 static const char scsicmd_opts[] = "a:c:dfi:o:r";
169 static const char readdefect_opts[] = "f:GP";
170 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
171 static const char smprg_opts[] = "l";
172 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
173 static const char smpphylist_opts[] = "lq";
177 static struct camcontrol_opts option_table[] = {
179 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
180 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
181 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
182 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
183 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
184 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
185 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
186 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
187 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
188 #endif /* MINIMALISTIC */
189 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
190 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
192 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
193 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
194 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
195 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
196 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
197 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
198 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
199 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
200 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
201 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
202 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
203 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
204 #endif /* MINIMALISTIC */
205 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
207 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
208 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
209 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
210 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
211 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
212 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
213 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
214 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
215 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
216 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
217 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
218 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:ys"},
219 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
220 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
221 #endif /* MINIMALISTIC */
222 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
223 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
224 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
235 struct device_match_result dev_match;
237 struct periph_match_result *periph_matches;
238 struct scsi_vpd_device_id *device_id;
240 STAILQ_ENTRY(cam_devitem) links;
244 STAILQ_HEAD(, cam_devitem) dev_queue;
248 static cam_cmdmask cmdlist;
249 static cam_argmask arglist;
251 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
252 uint32_t *cmdnum, cam_argmask *argnum,
253 const char **subopt);
255 static int getdevlist(struct cam_device *device);
256 #endif /* MINIMALISTIC */
257 static int getdevtree(int argc, char **argv, char *combinedopt);
259 static int testunitready(struct cam_device *device, int retry_count,
260 int timeout, int quiet);
261 static int scsistart(struct cam_device *device, int startstop, int loadeject,
262 int retry_count, int timeout);
263 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
264 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
265 static int camxferrate(struct cam_device *device);
266 #endif /* MINIMALISTIC */
267 static int parse_btl(char *tstr, 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 */
415 getdevtree(int argc, char **argv, char *combinedopt)
426 while ((c = getopt(argc, argv, combinedopt)) != -1) {
429 if ((arglist & CAM_ARG_VERBOSE) == 0)
437 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
438 warn("couldn't open %s", XPT_DEVICE);
442 bzero(&ccb, sizeof(union ccb));
444 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
445 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
446 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
448 ccb.ccb_h.func_code = XPT_DEV_MATCH;
449 bufsize = sizeof(struct dev_match_result) * 100;
450 ccb.cdm.match_buf_len = bufsize;
451 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
452 if (ccb.cdm.matches == NULL) {
453 warnx("can't malloc memory for matches");
457 ccb.cdm.num_matches = 0;
460 * We fetch all nodes, since we display most of them in the default
461 * case, and all in the verbose case.
463 ccb.cdm.num_patterns = 0;
464 ccb.cdm.pattern_buf_len = 0;
467 * We do the ioctl multiple times if necessary, in case there are
468 * more than 100 nodes in the EDT.
471 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
472 warn("error sending CAMIOCOMMAND ioctl");
477 if ((ccb.ccb_h.status != CAM_REQ_CMP)
478 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
479 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
480 warnx("got CAM error %#x, CDM error %d\n",
481 ccb.ccb_h.status, ccb.cdm.status);
486 for (i = 0; i < ccb.cdm.num_matches; i++) {
487 switch (ccb.cdm.matches[i].type) {
488 case DEV_MATCH_BUS: {
489 struct bus_match_result *bus_result;
492 * Only print the bus information if the
493 * user turns on the verbose flag.
495 if ((busonly == 0) &&
496 (arglist & CAM_ARG_VERBOSE) == 0)
500 &ccb.cdm.matches[i].result.bus_result;
503 fprintf(stdout, ")\n");
507 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
509 bus_result->dev_name,
510 bus_result->unit_number,
512 (busonly ? "" : ":"));
515 case DEV_MATCH_DEVICE: {
516 struct device_match_result *dev_result;
517 char vendor[16], product[48], revision[16];
518 char fw[5], tmpstr[256];
524 &ccb.cdm.matches[i].result.device_result;
526 if ((dev_result->flags
527 & DEV_RESULT_UNCONFIGURED)
528 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
534 if (dev_result->protocol == PROTO_SCSI) {
535 cam_strvis(vendor, dev_result->inq_data.vendor,
536 sizeof(dev_result->inq_data.vendor),
539 dev_result->inq_data.product,
540 sizeof(dev_result->inq_data.product),
543 dev_result->inq_data.revision,
544 sizeof(dev_result->inq_data.revision),
546 sprintf(tmpstr, "<%s %s %s>", vendor, product,
548 } else if (dev_result->protocol == PROTO_ATA ||
549 dev_result->protocol == PROTO_SATAPM) {
551 dev_result->ident_data.model,
552 sizeof(dev_result->ident_data.model),
555 dev_result->ident_data.revision,
556 sizeof(dev_result->ident_data.revision),
558 sprintf(tmpstr, "<%s %s>", product,
560 } else if (dev_result->protocol == PROTO_SEMB) {
561 struct sep_identify_data *sid;
563 sid = (struct sep_identify_data *)
564 &dev_result->ident_data;
565 cam_strvis(vendor, sid->vendor_id,
566 sizeof(sid->vendor_id),
568 cam_strvis(product, sid->product_id,
569 sizeof(sid->product_id),
571 cam_strvis(revision, sid->product_rev,
572 sizeof(sid->product_rev),
574 cam_strvis(fw, sid->firmware_rev,
575 sizeof(sid->firmware_rev),
577 sprintf(tmpstr, "<%s %s %s %s>",
578 vendor, product, revision, fw);
580 sprintf(tmpstr, "<>");
583 fprintf(stdout, ")\n");
587 fprintf(stdout, "%-33s at scbus%d "
588 "target %d lun %jx (",
591 dev_result->target_id,
592 (uintmax_t)dev_result->target_lun);
598 case DEV_MATCH_PERIPH: {
599 struct periph_match_result *periph_result;
602 &ccb.cdm.matches[i].result.periph_result;
604 if (busonly || skip_device != 0)
608 fprintf(stdout, ",");
610 fprintf(stdout, "%s%d",
611 periph_result->periph_name,
612 periph_result->unit_number);
618 fprintf(stdout, "unknown match type\n");
623 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
624 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
627 fprintf(stdout, ")\n");
636 testunitready(struct cam_device *device, int retry_count, int timeout,
642 ccb = cam_getccb(device);
644 scsi_test_unit_ready(&ccb->csio,
645 /* retries */ retry_count,
647 /* tag_action */ MSG_SIMPLE_Q_TAG,
648 /* sense_len */ SSD_FULL_SIZE,
649 /* timeout */ timeout ? timeout : 5000);
651 /* Disable freezing the device queue */
652 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
654 if (arglist & CAM_ARG_ERR_RECOVER)
655 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
657 if (cam_send_ccb(device, ccb) < 0) {
659 perror("error sending test unit ready");
661 if (arglist & CAM_ARG_VERBOSE) {
662 cam_error_print(device, ccb, CAM_ESF_ALL,
663 CAM_EPF_ALL, stderr);
670 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
672 fprintf(stdout, "Unit is ready\n");
675 fprintf(stdout, "Unit is not ready\n");
678 if (arglist & CAM_ARG_VERBOSE) {
679 cam_error_print(device, ccb, CAM_ESF_ALL,
680 CAM_EPF_ALL, stderr);
690 scsistart(struct cam_device *device, int startstop, int loadeject,
691 int retry_count, int timeout)
696 ccb = cam_getccb(device);
699 * If we're stopping, send an ordered tag so the drive in question
700 * will finish any previously queued writes before stopping. If
701 * the device isn't capable of tagged queueing, or if tagged
702 * queueing is turned off, the tag action is a no-op.
704 scsi_start_stop(&ccb->csio,
705 /* retries */ retry_count,
707 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
709 /* start/stop */ startstop,
710 /* load_eject */ loadeject,
712 /* sense_len */ SSD_FULL_SIZE,
713 /* timeout */ timeout ? timeout : 120000);
715 /* Disable freezing the device queue */
716 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
718 if (arglist & CAM_ARG_ERR_RECOVER)
719 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
721 if (cam_send_ccb(device, ccb) < 0) {
722 perror("error sending start unit");
724 if (arglist & CAM_ARG_VERBOSE) {
725 cam_error_print(device, ccb, CAM_ESF_ALL,
726 CAM_EPF_ALL, stderr);
733 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
735 fprintf(stdout, "Unit started successfully");
737 fprintf(stdout,", Media loaded\n");
739 fprintf(stdout,"\n");
741 fprintf(stdout, "Unit stopped successfully");
743 fprintf(stdout, ", Media ejected\n");
745 fprintf(stdout, "\n");
751 "Error received from start unit command\n");
754 "Error received from stop unit command\n");
756 if (arglist & CAM_ARG_VERBOSE) {
757 cam_error_print(device, ccb, CAM_ESF_ALL,
758 CAM_EPF_ALL, stderr);
768 scsidoinquiry(struct cam_device *device, int argc, char **argv,
769 char *combinedopt, int retry_count, int timeout)
774 while ((c = getopt(argc, argv, combinedopt)) != -1) {
777 arglist |= CAM_ARG_GET_STDINQ;
780 arglist |= CAM_ARG_GET_XFERRATE;
783 arglist |= CAM_ARG_GET_SERIAL;
791 * If the user didn't specify any inquiry options, he wants all of
794 if ((arglist & CAM_ARG_INQ_MASK) == 0)
795 arglist |= CAM_ARG_INQ_MASK;
797 if (arglist & CAM_ARG_GET_STDINQ)
798 error = scsiinquiry(device, retry_count, timeout);
803 if (arglist & CAM_ARG_GET_SERIAL)
804 scsiserial(device, retry_count, timeout);
809 if (arglist & CAM_ARG_GET_XFERRATE)
810 error = camxferrate(device);
816 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
819 struct scsi_inquiry_data *inq_buf;
822 ccb = cam_getccb(device);
825 warnx("couldn't allocate CCB");
829 /* cam_getccb cleans up the header, caller has to zero the payload */
830 bzero(&(&ccb->ccb_h)[1],
831 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
833 inq_buf = (struct scsi_inquiry_data *)malloc(
834 sizeof(struct scsi_inquiry_data));
836 if (inq_buf == NULL) {
838 warnx("can't malloc memory for inquiry\n");
841 bzero(inq_buf, sizeof(*inq_buf));
844 * Note that although the size of the inquiry buffer is the full
845 * 256 bytes specified in the SCSI spec, we only tell the device
846 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
847 * two reasons for this:
849 * - The SCSI spec says that when a length field is only 1 byte,
850 * a value of 0 will be interpreted as 256. Therefore
851 * scsi_inquiry() will convert an inq_len (which is passed in as
852 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
853 * to 0. Evidently, very few devices meet the spec in that
854 * regard. Some devices, like many Seagate disks, take the 0 as
855 * 0, and don't return any data. One Pioneer DVD-R drive
856 * returns more data than the command asked for.
858 * So, since there are numerous devices that just don't work
859 * right with the full inquiry size, we don't send the full size.
861 * - The second reason not to use the full inquiry data length is
862 * that we don't need it here. The only reason we issue a
863 * standard inquiry is to get the vendor name, device name,
864 * and revision so scsi_print_inquiry() can print them.
866 * If, at some point in the future, more inquiry data is needed for
867 * some reason, this code should use a procedure similar to the
868 * probe code. i.e., issue a short inquiry, and determine from
869 * the additional length passed back from the device how much
870 * inquiry data the device supports. Once the amount the device
871 * supports is determined, issue an inquiry for that amount and no
876 scsi_inquiry(&ccb->csio,
877 /* retries */ retry_count,
879 /* tag_action */ MSG_SIMPLE_Q_TAG,
880 /* inq_buf */ (u_int8_t *)inq_buf,
881 /* inq_len */ SHORT_INQUIRY_LENGTH,
884 /* sense_len */ SSD_FULL_SIZE,
885 /* timeout */ timeout ? timeout : 5000);
887 /* Disable freezing the device queue */
888 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
890 if (arglist & CAM_ARG_ERR_RECOVER)
891 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
893 if (cam_send_ccb(device, ccb) < 0) {
894 perror("error sending SCSI inquiry");
896 if (arglist & CAM_ARG_VERBOSE) {
897 cam_error_print(device, ccb, CAM_ESF_ALL,
898 CAM_EPF_ALL, stderr);
905 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
908 if (arglist & CAM_ARG_VERBOSE) {
909 cam_error_print(device, ccb, CAM_ESF_ALL,
910 CAM_EPF_ALL, stderr);
921 fprintf(stdout, "%s%d: ", device->device_name,
922 device->dev_unit_num);
923 scsi_print_inquiry(inq_buf);
931 scsiserial(struct cam_device *device, int retry_count, int timeout)
934 struct scsi_vpd_unit_serial_number *serial_buf;
935 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
938 ccb = cam_getccb(device);
941 warnx("couldn't allocate CCB");
945 /* cam_getccb cleans up the header, caller has to zero the payload */
946 bzero(&(&ccb->ccb_h)[1],
947 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
949 serial_buf = (struct scsi_vpd_unit_serial_number *)
950 malloc(sizeof(*serial_buf));
952 if (serial_buf == NULL) {
954 warnx("can't malloc memory for serial number");
958 scsi_inquiry(&ccb->csio,
959 /*retries*/ retry_count,
961 /* tag_action */ MSG_SIMPLE_Q_TAG,
962 /* inq_buf */ (u_int8_t *)serial_buf,
963 /* inq_len */ sizeof(*serial_buf),
965 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
966 /* sense_len */ SSD_FULL_SIZE,
967 /* timeout */ timeout ? timeout : 5000);
969 /* Disable freezing the device queue */
970 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
972 if (arglist & CAM_ARG_ERR_RECOVER)
973 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
975 if (cam_send_ccb(device, ccb) < 0) {
976 warn("error getting serial number");
978 if (arglist & CAM_ARG_VERBOSE) {
979 cam_error_print(device, ccb, CAM_ESF_ALL,
980 CAM_EPF_ALL, stderr);
988 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
991 if (arglist & CAM_ARG_VERBOSE) {
992 cam_error_print(device, ccb, CAM_ESF_ALL,
993 CAM_EPF_ALL, stderr);
1004 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1005 serial_num[serial_buf->length] = '\0';
1007 if ((arglist & CAM_ARG_GET_STDINQ)
1008 || (arglist & CAM_ARG_GET_XFERRATE))
1009 fprintf(stdout, "%s%d: Serial Number ",
1010 device->device_name, device->dev_unit_num);
1012 fprintf(stdout, "%.60s\n", serial_num);
1020 camxferrate(struct cam_device *device)
1022 struct ccb_pathinq cpi;
1024 u_int32_t speed = 0;
1029 if ((retval = get_cpi(device, &cpi)) != 0)
1032 ccb = cam_getccb(device);
1035 warnx("couldn't allocate CCB");
1039 bzero(&(&ccb->ccb_h)[1],
1040 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
1042 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1043 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1045 if (((retval = cam_send_ccb(device, ccb)) < 0)
1046 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1047 const char error_string[] = "error getting transfer settings";
1052 warnx(error_string);
1054 if (arglist & CAM_ARG_VERBOSE)
1055 cam_error_print(device, ccb, CAM_ESF_ALL,
1056 CAM_EPF_ALL, stderr);
1060 goto xferrate_bailout;
1064 speed = cpi.base_transfer_speed;
1066 if (ccb->cts.transport == XPORT_SPI) {
1067 struct ccb_trans_settings_spi *spi =
1068 &ccb->cts.xport_specific.spi;
1070 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1071 freq = scsi_calc_syncsrate(spi->sync_period);
1074 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1075 speed *= (0x01 << spi->bus_width);
1077 } else if (ccb->cts.transport == XPORT_FC) {
1078 struct ccb_trans_settings_fc *fc =
1079 &ccb->cts.xport_specific.fc;
1081 if (fc->valid & CTS_FC_VALID_SPEED)
1082 speed = fc->bitrate;
1083 } else if (ccb->cts.transport == XPORT_SAS) {
1084 struct ccb_trans_settings_sas *sas =
1085 &ccb->cts.xport_specific.sas;
1087 if (sas->valid & CTS_SAS_VALID_SPEED)
1088 speed = sas->bitrate;
1089 } else if (ccb->cts.transport == XPORT_ATA) {
1090 struct ccb_trans_settings_pata *pata =
1091 &ccb->cts.xport_specific.ata;
1093 if (pata->valid & CTS_ATA_VALID_MODE)
1094 speed = ata_mode2speed(pata->mode);
1095 } else if (ccb->cts.transport == XPORT_SATA) {
1096 struct ccb_trans_settings_sata *sata =
1097 &ccb->cts.xport_specific.sata;
1099 if (sata->valid & CTS_SATA_VALID_REVISION)
1100 speed = ata_revision2speed(sata->revision);
1105 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1106 device->device_name, device->dev_unit_num,
1109 fprintf(stdout, "%s%d: %dKB/s transfers",
1110 device->device_name, device->dev_unit_num,
1114 if (ccb->cts.transport == XPORT_SPI) {
1115 struct ccb_trans_settings_spi *spi =
1116 &ccb->cts.xport_specific.spi;
1118 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1119 && (spi->sync_offset != 0))
1120 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1121 freq % 1000, spi->sync_offset);
1123 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1124 && (spi->bus_width > 0)) {
1125 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1126 && (spi->sync_offset != 0)) {
1127 fprintf(stdout, ", ");
1129 fprintf(stdout, " (");
1131 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1132 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1133 && (spi->sync_offset != 0)) {
1134 fprintf(stdout, ")");
1136 } else if (ccb->cts.transport == XPORT_ATA) {
1137 struct ccb_trans_settings_pata *pata =
1138 &ccb->cts.xport_specific.ata;
1141 if (pata->valid & CTS_ATA_VALID_MODE)
1142 printf("%s, ", ata_mode2string(pata->mode));
1143 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1144 printf("ATAPI %dbytes, ", pata->atapi);
1145 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1146 printf("PIO %dbytes", pata->bytecount);
1148 } else if (ccb->cts.transport == XPORT_SATA) {
1149 struct ccb_trans_settings_sata *sata =
1150 &ccb->cts.xport_specific.sata;
1153 if (sata->valid & CTS_SATA_VALID_REVISION)
1154 printf("SATA %d.x, ", sata->revision);
1157 if (sata->valid & CTS_SATA_VALID_MODE)
1158 printf("%s, ", ata_mode2string(sata->mode));
1159 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1160 printf("ATAPI %dbytes, ", sata->atapi);
1161 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1162 printf("PIO %dbytes", sata->bytecount);
1166 if (ccb->cts.protocol == PROTO_SCSI) {
1167 struct ccb_trans_settings_scsi *scsi =
1168 &ccb->cts.proto_specific.scsi;
1169 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1170 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1171 fprintf(stdout, ", Command Queueing Enabled");
1176 fprintf(stdout, "\n");
1186 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1188 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1189 ((u_int32_t)parm->lba_size_2 << 16);
1191 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1192 ((u_int64_t)parm->lba_size48_2 << 16) |
1193 ((u_int64_t)parm->lba_size48_3 << 32) |
1194 ((u_int64_t)parm->lba_size48_4 << 48);
1198 "Support Enabled Value\n");
1201 printf("Host Protected Area (HPA) ");
1202 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1203 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1204 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1207 printf("HPA - Security ");
1208 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1218 atasata(struct ata_params *parm)
1222 if (parm->satacapabilities != 0xffff &&
1223 parm->satacapabilities != 0x0000)
1230 atacapprint(struct ata_params *parm)
1232 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1233 ((u_int32_t)parm->lba_size_2 << 16);
1235 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1236 ((u_int64_t)parm->lba_size48_2 << 16) |
1237 ((u_int64_t)parm->lba_size48_3 << 32) |
1238 ((u_int64_t)parm->lba_size48_4 << 48);
1241 printf("protocol ");
1242 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1243 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1244 if (parm->satacapabilities & ATA_SATA_GEN3)
1245 printf(" SATA 3.x\n");
1246 else if (parm->satacapabilities & ATA_SATA_GEN2)
1247 printf(" SATA 2.x\n");
1248 else if (parm->satacapabilities & ATA_SATA_GEN1)
1249 printf(" SATA 1.x\n");
1255 printf("device model %.40s\n", parm->model);
1256 printf("firmware revision %.8s\n", parm->revision);
1257 printf("serial number %.20s\n", parm->serial);
1258 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1259 printf("WWN %04x%04x%04x%04x\n",
1260 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1262 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1263 printf("media serial number %.30s\n",
1264 parm->media_serial);
1267 printf("cylinders %d\n", parm->cylinders);
1268 printf("heads %d\n", parm->heads);
1269 printf("sectors/track %d\n", parm->sectors);
1270 printf("sector size logical %u, physical %lu, offset %lu\n",
1271 ata_logical_sector_size(parm),
1272 (unsigned long)ata_physical_sector_size(parm),
1273 (unsigned long)ata_logical_sector_offset(parm));
1275 if (parm->config == ATA_PROTO_CFA ||
1276 (parm->support.command2 & ATA_SUPPORT_CFA))
1277 printf("CFA supported\n");
1279 printf("LBA%ssupported ",
1280 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1282 printf("%d sectors\n", lbasize);
1286 printf("LBA48%ssupported ",
1287 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1289 printf("%ju sectors\n", (uintmax_t)lbasize48);
1293 printf("PIO supported PIO");
1294 switch (ata_max_pmode(parm)) {
1310 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1311 printf(" w/o IORDY");
1314 printf("DMA%ssupported ",
1315 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1316 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1317 if (parm->mwdmamodes & 0xff) {
1319 if (parm->mwdmamodes & 0x04)
1321 else if (parm->mwdmamodes & 0x02)
1323 else if (parm->mwdmamodes & 0x01)
1327 if ((parm->atavalid & ATA_FLAG_88) &&
1328 (parm->udmamodes & 0xff)) {
1330 if (parm->udmamodes & 0x40)
1332 else if (parm->udmamodes & 0x20)
1334 else if (parm->udmamodes & 0x10)
1336 else if (parm->udmamodes & 0x08)
1338 else if (parm->udmamodes & 0x04)
1340 else if (parm->udmamodes & 0x02)
1342 else if (parm->udmamodes & 0x01)
1349 if (parm->media_rotation_rate == 1) {
1350 printf("media RPM non-rotating\n");
1351 } else if (parm->media_rotation_rate >= 0x0401 &&
1352 parm->media_rotation_rate <= 0xFFFE) {
1353 printf("media RPM %d\n",
1354 parm->media_rotation_rate);
1358 "Support Enabled Value Vendor\n");
1359 printf("read ahead %s %s\n",
1360 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1361 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1362 printf("write cache %s %s\n",
1363 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1364 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1365 printf("flush cache %s %s\n",
1366 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1367 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1368 printf("overlap %s\n",
1369 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1370 printf("Tagged Command Queuing (TCQ) %s %s",
1371 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1372 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1373 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1374 printf(" %d tags\n",
1375 ATA_QUEUE_LEN(parm->queue) + 1);
1378 printf("Native Command Queuing (NCQ) ");
1379 if (parm->satacapabilities != 0xffff &&
1380 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1381 printf("yes %d tags\n",
1382 ATA_QUEUE_LEN(parm->queue) + 1);
1386 printf("NCQ Queue Management %s\n", atasata(parm) &&
1387 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1389 printf("NCQ Streaming %s\n", atasata(parm) &&
1390 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1392 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1393 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1396 printf("SMART %s %s\n",
1397 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1398 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1399 printf("microcode download %s %s\n",
1400 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1401 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1402 printf("security %s %s\n",
1403 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1404 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1405 printf("power management %s %s\n",
1406 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1407 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1408 printf("advanced power management %s %s",
1409 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1410 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1411 if (parm->support.command2 & ATA_SUPPORT_APM) {
1412 printf(" %d/0x%02X\n",
1413 parm->apm_value, parm->apm_value);
1416 printf("automatic acoustic management %s %s",
1417 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1418 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1419 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1420 printf(" %d/0x%02X %d/0x%02X\n",
1421 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1422 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1423 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1424 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1427 printf("media status notification %s %s\n",
1428 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1429 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1430 printf("power-up in Standby %s %s\n",
1431 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1432 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1433 printf("write-read-verify %s %s",
1434 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1435 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1436 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1437 printf(" %d/0x%x\n",
1438 parm->wrv_mode, parm->wrv_mode);
1441 printf("unload %s %s\n",
1442 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1443 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1444 printf("general purpose logging %s %s\n",
1445 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1446 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1447 printf("free-fall %s %s\n",
1448 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1449 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1450 printf("Data Set Management (DSM/TRIM) ");
1451 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1453 printf("DSM - max 512byte blocks ");
1454 if (parm->max_dsm_blocks == 0x00)
1455 printf("yes not specified\n");
1458 parm->max_dsm_blocks);
1460 printf("DSM - deterministic read ");
1461 if (parm->support3 & ATA_SUPPORT_DRAT) {
1462 if (parm->support3 & ATA_SUPPORT_RZAT)
1463 printf("yes zeroed\n");
1465 printf("yes any value\n");
1475 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1477 struct ata_pass_16 *ata_pass_16;
1478 struct ata_cmd ata_cmd;
1480 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1481 ata_cmd.command = ata_pass_16->command;
1482 ata_cmd.control = ata_pass_16->control;
1483 ata_cmd.features = ata_pass_16->features;
1485 if (arglist & CAM_ARG_VERBOSE) {
1486 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1487 ata_op_string(&ata_cmd),
1488 ccb->csio.ccb_h.timeout);
1491 /* Disable freezing the device queue */
1492 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1494 if (arglist & CAM_ARG_ERR_RECOVER)
1495 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1497 if (cam_send_ccb(device, ccb) < 0) {
1498 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1499 warn("error sending ATA %s via pass_16",
1500 ata_op_string(&ata_cmd));
1503 if (arglist & CAM_ARG_VERBOSE) {
1504 cam_error_print(device, ccb, CAM_ESF_ALL,
1505 CAM_EPF_ALL, stderr);
1511 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1512 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1513 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1514 warnx("ATA %s via pass_16 failed",
1515 ata_op_string(&ata_cmd));
1517 if (arglist & CAM_ARG_VERBOSE) {
1518 cam_error_print(device, ccb, CAM_ESF_ALL,
1519 CAM_EPF_ALL, stderr);
1530 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1532 if (arglist & CAM_ARG_VERBOSE) {
1533 warnx("sending ATA %s with timeout of %u msecs",
1534 ata_op_string(&(ccb->ataio.cmd)),
1535 ccb->ataio.ccb_h.timeout);
1538 /* Disable freezing the device queue */
1539 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1541 if (arglist & CAM_ARG_ERR_RECOVER)
1542 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1544 if (cam_send_ccb(device, ccb) < 0) {
1545 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1546 warn("error sending ATA %s",
1547 ata_op_string(&(ccb->ataio.cmd)));
1550 if (arglist & CAM_ARG_VERBOSE) {
1551 cam_error_print(device, ccb, CAM_ESF_ALL,
1552 CAM_EPF_ALL, stderr);
1558 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1559 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1560 warnx("ATA %s failed: %d",
1561 ata_op_string(&(ccb->ataio.cmd)), quiet);
1564 if (arglist & CAM_ARG_VERBOSE) {
1565 cam_error_print(device, ccb, CAM_ESF_ALL,
1566 CAM_EPF_ALL, stderr);
1576 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1577 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1578 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1579 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1580 u_int16_t dxfer_len, int timeout, int quiet)
1582 if (data_ptr != NULL) {
1583 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1584 AP_FLAG_TLEN_SECT_CNT;
1585 if (flags & CAM_DIR_OUT)
1586 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1588 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1590 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1593 bzero(&(&ccb->ccb_h)[1],
1594 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1596 scsi_ata_pass_16(&ccb->csio,
1610 /*sense_len*/SSD_FULL_SIZE,
1613 return scsi_cam_pass_16_send(device, ccb, quiet);
1617 ata_try_pass_16(struct cam_device *device)
1619 struct ccb_pathinq cpi;
1621 if (get_cpi(device, &cpi) != 0) {
1622 warnx("couldn't get CPI");
1626 if (cpi.protocol == PROTO_SCSI) {
1627 /* possibly compatible with pass_16 */
1631 /* likely not compatible with pass_16 */
1636 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1637 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1638 u_int8_t command, u_int8_t features, u_int32_t lba,
1639 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1640 int timeout, int quiet)
1644 switch (ata_try_pass_16(device)) {
1648 /* Try using SCSI Passthrough */
1649 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1650 0, tag_action, command, features, lba,
1651 sector_count, data_ptr, dxfer_len,
1655 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1656 sizeof(struct ccb_hdr));
1657 cam_fill_ataio(&ccb->ataio,
1666 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1667 return ata_cam_send(device, ccb, quiet);
1671 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1672 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1673 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1674 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1675 u_int16_t dxfer_len, int timeout, int force48bit)
1679 retval = ata_try_pass_16(device);
1686 /* Try using SCSI Passthrough */
1687 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1688 ata_flags, tag_action, command, features,
1689 lba, sector_count, data_ptr, dxfer_len,
1692 if (ata_flags & AP_FLAG_CHK_COND) {
1693 /* Decode ata_res from sense data */
1694 struct ata_res_pass16 *res_pass16;
1695 struct ata_res *res;
1699 /* sense_data is 4 byte aligned */
1700 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1701 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1702 ptr[i] = le16toh(ptr[i]);
1704 /* sense_data is 4 byte aligned */
1705 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1706 &ccb->csio.sense_data;
1707 res = &ccb->ataio.res;
1708 res->flags = res_pass16->flags;
1709 res->status = res_pass16->status;
1710 res->error = res_pass16->error;
1711 res->lba_low = res_pass16->lba_low;
1712 res->lba_mid = res_pass16->lba_mid;
1713 res->lba_high = res_pass16->lba_high;
1714 res->device = res_pass16->device;
1715 res->lba_low_exp = res_pass16->lba_low_exp;
1716 res->lba_mid_exp = res_pass16->lba_mid_exp;
1717 res->lba_high_exp = res_pass16->lba_high_exp;
1718 res->sector_count = res_pass16->sector_count;
1719 res->sector_count_exp = res_pass16->sector_count_exp;
1725 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1726 sizeof(struct ccb_hdr));
1727 cam_fill_ataio(&ccb->ataio,
1736 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1737 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1739 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1741 if (ata_flags & AP_FLAG_CHK_COND)
1742 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1744 return ata_cam_send(device, ccb, 0);
1748 dump_data(uint16_t *ptr, uint32_t len)
1752 for (i = 0; i < len / 2; i++) {
1754 printf(" %3d: ", i);
1755 printf("%04hx ", ptr[i]);
1764 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1765 int is48bit, u_int64_t *hpasize)
1767 struct ata_res *res;
1769 res = &ccb->ataio.res;
1770 if (res->status & ATA_STATUS_ERROR) {
1771 if (arglist & CAM_ARG_VERBOSE) {
1772 cam_error_print(device, ccb, CAM_ESF_ALL,
1773 CAM_EPF_ALL, stderr);
1774 printf("error = 0x%02x, sector_count = 0x%04x, "
1775 "device = 0x%02x, status = 0x%02x\n",
1776 res->error, res->sector_count,
1777 res->device, res->status);
1780 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1781 warnx("Max address has already been set since "
1782 "last power-on or hardware reset");
1788 if (arglist & CAM_ARG_VERBOSE) {
1789 fprintf(stdout, "%s%d: Raw native max data:\n",
1790 device->device_name, device->dev_unit_num);
1791 /* res is 4 byte aligned */
1792 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1794 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1795 "status = 0x%02x\n", res->error, res->sector_count,
1796 res->device, res->status);
1799 if (hpasize != NULL) {
1801 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1802 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1803 ((res->lba_high << 16) | (res->lba_mid << 8) |
1806 *hpasize = (((res->device & 0x0f) << 24) |
1807 (res->lba_high << 16) | (res->lba_mid << 8) |
1816 ata_read_native_max(struct cam_device *device, int retry_count,
1817 u_int32_t timeout, union ccb *ccb,
1818 struct ata_params *parm, u_int64_t *hpasize)
1824 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1825 protocol = AP_PROTO_NON_DATA;
1828 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1829 protocol |= AP_EXTEND;
1831 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1834 error = ata_do_cmd(device,
1837 /*flags*/CAM_DIR_NONE,
1838 /*protocol*/protocol,
1839 /*ata_flags*/AP_FLAG_CHK_COND,
1840 /*tag_action*/MSG_SIMPLE_Q_TAG,
1847 timeout ? timeout : 1000,
1853 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1857 atahpa_set_max(struct cam_device *device, int retry_count,
1858 u_int32_t timeout, union ccb *ccb,
1859 int is48bit, u_int64_t maxsize, int persist)
1865 protocol = AP_PROTO_NON_DATA;
1868 cmd = ATA_SET_MAX_ADDRESS48;
1869 protocol |= AP_EXTEND;
1871 cmd = ATA_SET_MAX_ADDRESS;
1874 /* lba's are zero indexed so the max lba is requested max - 1 */
1878 error = ata_do_cmd(device,
1881 /*flags*/CAM_DIR_NONE,
1882 /*protocol*/protocol,
1883 /*ata_flags*/AP_FLAG_CHK_COND,
1884 /*tag_action*/MSG_SIMPLE_Q_TAG,
1886 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1888 /*sector_count*/persist,
1891 timeout ? timeout : 1000,
1897 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1901 atahpa_password(struct cam_device *device, int retry_count,
1902 u_int32_t timeout, union ccb *ccb,
1903 int is48bit, struct ata_set_max_pwd *pwd)
1909 protocol = AP_PROTO_PIO_OUT;
1910 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1912 error = ata_do_cmd(device,
1915 /*flags*/CAM_DIR_OUT,
1916 /*protocol*/protocol,
1917 /*ata_flags*/AP_FLAG_CHK_COND,
1918 /*tag_action*/MSG_SIMPLE_Q_TAG,
1920 /*features*/ATA_HPA_FEAT_SET_PWD,
1923 /*data_ptr*/(u_int8_t*)pwd,
1924 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1925 timeout ? timeout : 1000,
1931 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1935 atahpa_lock(struct cam_device *device, int retry_count,
1936 u_int32_t timeout, union ccb *ccb, int is48bit)
1942 protocol = AP_PROTO_NON_DATA;
1943 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1945 error = ata_do_cmd(device,
1948 /*flags*/CAM_DIR_NONE,
1949 /*protocol*/protocol,
1950 /*ata_flags*/AP_FLAG_CHK_COND,
1951 /*tag_action*/MSG_SIMPLE_Q_TAG,
1953 /*features*/ATA_HPA_FEAT_LOCK,
1958 timeout ? timeout : 1000,
1964 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1968 atahpa_unlock(struct cam_device *device, int retry_count,
1969 u_int32_t timeout, union ccb *ccb,
1970 int is48bit, struct ata_set_max_pwd *pwd)
1976 protocol = AP_PROTO_PIO_OUT;
1977 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1979 error = ata_do_cmd(device,
1982 /*flags*/CAM_DIR_OUT,
1983 /*protocol*/protocol,
1984 /*ata_flags*/AP_FLAG_CHK_COND,
1985 /*tag_action*/MSG_SIMPLE_Q_TAG,
1987 /*features*/ATA_HPA_FEAT_UNLOCK,
1990 /*data_ptr*/(u_int8_t*)pwd,
1991 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1992 timeout ? timeout : 1000,
1998 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2002 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2003 u_int32_t timeout, union ccb *ccb, int is48bit)
2009 protocol = AP_PROTO_NON_DATA;
2010 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2012 error = ata_do_cmd(device,
2015 /*flags*/CAM_DIR_NONE,
2016 /*protocol*/protocol,
2017 /*ata_flags*/AP_FLAG_CHK_COND,
2018 /*tag_action*/MSG_SIMPLE_Q_TAG,
2020 /*features*/ATA_HPA_FEAT_FREEZE,
2025 timeout ? timeout : 1000,
2031 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2036 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2037 union ccb *ccb, struct ata_params** ident_bufp)
2039 struct ata_params *ident_buf;
2040 struct ccb_pathinq cpi;
2041 struct ccb_getdev cgd;
2044 u_int8_t command, retry_command;
2046 if (get_cpi(device, &cpi) != 0) {
2047 warnx("couldn't get CPI");
2051 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2052 if (cpi.protocol == PROTO_ATA) {
2053 if (get_cgd(device, &cgd) != 0) {
2054 warnx("couldn't get CGD");
2058 command = (cgd.protocol == PROTO_ATA) ?
2059 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2062 /* We don't know which for sure so try both */
2063 command = ATA_ATA_IDENTIFY;
2064 retry_command = ATA_ATAPI_IDENTIFY;
2067 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2069 warnx("can't calloc memory for identify\n");
2073 error = ata_do_28bit_cmd(device,
2075 /*retries*/retry_count,
2076 /*flags*/CAM_DIR_IN,
2077 /*protocol*/AP_PROTO_PIO_IN,
2078 /*tag_action*/MSG_SIMPLE_Q_TAG,
2082 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2083 /*data_ptr*/(u_int8_t *)ptr,
2084 /*dxfer_len*/sizeof(struct ata_params),
2085 /*timeout*/timeout ? timeout : 30 * 1000,
2089 if (retry_command == 0) {
2093 error = ata_do_28bit_cmd(device,
2095 /*retries*/retry_count,
2096 /*flags*/CAM_DIR_IN,
2097 /*protocol*/AP_PROTO_PIO_IN,
2098 /*tag_action*/MSG_SIMPLE_Q_TAG,
2099 /*command*/retry_command,
2102 /*sector_count*/(u_int8_t)
2103 sizeof(struct ata_params),
2104 /*data_ptr*/(u_int8_t *)ptr,
2105 /*dxfer_len*/sizeof(struct ata_params),
2106 /*timeout*/timeout ? timeout : 30 * 1000,
2116 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2117 ptr[i] = le16toh(ptr[i]);
2122 if (arglist & CAM_ARG_VERBOSE) {
2123 fprintf(stdout, "%s%d: Raw identify data:\n",
2124 device->device_name, device->dev_unit_num);
2125 dump_data(ptr, sizeof(struct ata_params));
2128 /* check for invalid (all zero) response */
2130 warnx("Invalid identify response detected");
2135 ident_buf = (struct ata_params *)ptr;
2136 if (strncmp(ident_buf->model, "FX", 2) &&
2137 strncmp(ident_buf->model, "NEC", 3) &&
2138 strncmp(ident_buf->model, "Pioneer", 7) &&
2139 strncmp(ident_buf->model, "SHARP", 5)) {
2140 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2141 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2142 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2143 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2145 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2146 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2147 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2148 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2149 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2150 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2151 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2152 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2153 sizeof(ident_buf->media_serial));
2155 *ident_bufp = ident_buf;
2162 ataidentify(struct cam_device *device, int retry_count, int timeout)
2165 struct ata_params *ident_buf;
2168 if ((ccb = cam_getccb(device)) == NULL) {
2169 warnx("couldn't allocate CCB");
2173 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2178 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2179 if (ata_read_native_max(device, retry_count, timeout, ccb,
2180 ident_buf, &hpasize) != 0) {
2188 printf("%s%d: ", device->device_name, device->dev_unit_num);
2189 ata_print_ident(ident_buf);
2190 camxferrate(device);
2191 atacapprint(ident_buf);
2192 atahpa_print(ident_buf, hpasize, 0);
2199 #endif /* MINIMALISTIC */
2202 #ifndef MINIMALISTIC
2204 ATA_SECURITY_ACTION_PRINT,
2205 ATA_SECURITY_ACTION_FREEZE,
2206 ATA_SECURITY_ACTION_UNLOCK,
2207 ATA_SECURITY_ACTION_DISABLE,
2208 ATA_SECURITY_ACTION_ERASE,
2209 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2210 ATA_SECURITY_ACTION_SET_PASSWORD
2214 atasecurity_print_time(u_int16_t tw)
2218 printf("unspecified");
2220 printf("> 508 min");
2222 printf("%i min", 2 * tw);
2226 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2230 return 2 * 3600 * 1000; /* default: two hours */
2231 else if (timeout > 255)
2232 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2234 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2239 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2243 bzero(&cmd, sizeof(cmd));
2244 cmd.command = command;
2245 printf("Issuing %s", ata_op_string(&cmd));
2248 char pass[sizeof(pwd->password)+1];
2250 /* pwd->password may not be null terminated */
2251 pass[sizeof(pwd->password)] = '\0';
2252 strncpy(pass, pwd->password, sizeof(pwd->password));
2253 printf(" password='%s', user='%s'",
2255 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2258 if (command == ATA_SECURITY_SET_PASSWORD) {
2259 printf(", mode='%s'",
2260 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2261 "maximum" : "high");
2269 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2270 int retry_count, u_int32_t timeout, int quiet)
2274 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2276 return ata_do_28bit_cmd(device,
2279 /*flags*/CAM_DIR_NONE,
2280 /*protocol*/AP_PROTO_NON_DATA,
2281 /*tag_action*/MSG_SIMPLE_Q_TAG,
2282 /*command*/ATA_SECURITY_FREEZE_LOCK,
2293 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2294 int retry_count, u_int32_t timeout,
2295 struct ata_security_password *pwd, int quiet)
2299 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2301 return ata_do_28bit_cmd(device,
2304 /*flags*/CAM_DIR_OUT,
2305 /*protocol*/AP_PROTO_PIO_OUT,
2306 /*tag_action*/MSG_SIMPLE_Q_TAG,
2307 /*command*/ATA_SECURITY_UNLOCK,
2311 /*data_ptr*/(u_int8_t *)pwd,
2312 /*dxfer_len*/sizeof(*pwd),
2318 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2319 int retry_count, u_int32_t timeout,
2320 struct ata_security_password *pwd, int quiet)
2324 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2325 return ata_do_28bit_cmd(device,
2328 /*flags*/CAM_DIR_OUT,
2329 /*protocol*/AP_PROTO_PIO_OUT,
2330 /*tag_action*/MSG_SIMPLE_Q_TAG,
2331 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2335 /*data_ptr*/(u_int8_t *)pwd,
2336 /*dxfer_len*/sizeof(*pwd),
2343 atasecurity_erase_confirm(struct cam_device *device,
2344 struct ata_params* ident_buf)
2347 printf("\nYou are about to ERASE ALL DATA from the following"
2348 " device:\n%s%d,%s%d: ", device->device_name,
2349 device->dev_unit_num, device->given_dev_name,
2350 device->given_unit_number);
2351 ata_print_ident(ident_buf);
2355 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2357 if (fgets(str, sizeof(str), stdin) != NULL) {
2358 if (strncasecmp(str, "yes", 3) == 0) {
2360 } else if (strncasecmp(str, "no", 2) == 0) {
2363 printf("Please answer \"yes\" or "
2374 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2375 int retry_count, u_int32_t timeout,
2376 u_int32_t erase_timeout,
2377 struct ata_security_password *pwd, int quiet)
2382 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2384 error = ata_do_28bit_cmd(device,
2387 /*flags*/CAM_DIR_NONE,
2388 /*protocol*/AP_PROTO_NON_DATA,
2389 /*tag_action*/MSG_SIMPLE_Q_TAG,
2390 /*command*/ATA_SECURITY_ERASE_PREPARE,
2403 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2405 error = ata_do_28bit_cmd(device,
2408 /*flags*/CAM_DIR_OUT,
2409 /*protocol*/AP_PROTO_PIO_OUT,
2410 /*tag_action*/MSG_SIMPLE_Q_TAG,
2411 /*command*/ATA_SECURITY_ERASE_UNIT,
2415 /*data_ptr*/(u_int8_t *)pwd,
2416 /*dxfer_len*/sizeof(*pwd),
2417 /*timeout*/erase_timeout,
2420 if (error == 0 && quiet == 0)
2421 printf("\nErase Complete\n");
2427 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2428 int retry_count, u_int32_t timeout,
2429 struct ata_security_password *pwd, int quiet)
2433 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2435 return ata_do_28bit_cmd(device,
2438 /*flags*/CAM_DIR_OUT,
2439 /*protocol*/AP_PROTO_PIO_OUT,
2440 /*tag_action*/MSG_SIMPLE_Q_TAG,
2441 /*command*/ATA_SECURITY_SET_PASSWORD,
2445 /*data_ptr*/(u_int8_t *)pwd,
2446 /*dxfer_len*/sizeof(*pwd),
2452 atasecurity_print(struct ata_params *parm)
2455 printf("\nSecurity Option Value\n");
2456 if (arglist & CAM_ARG_VERBOSE) {
2457 printf("status %04x\n",
2458 parm->security_status);
2460 printf("supported %s\n",
2461 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2462 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2464 printf("enabled %s\n",
2465 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2466 printf("drive locked %s\n",
2467 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2468 printf("security config frozen %s\n",
2469 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2470 printf("count expired %s\n",
2471 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2472 printf("security level %s\n",
2473 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2474 printf("enhanced erase supported %s\n",
2475 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2476 printf("erase time ");
2477 atasecurity_print_time(parm->erase_time);
2479 printf("enhanced erase time ");
2480 atasecurity_print_time(parm->enhanced_erase_time);
2482 printf("master password rev %04x%s\n",
2483 parm->master_passwd_revision,
2484 parm->master_passwd_revision == 0x0000 ||
2485 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2489 * Validates and copies the password in optarg to the passed buffer.
2490 * If the password in optarg is the same length as the buffer then
2491 * the data will still be copied but no null termination will occur.
2494 ata_getpwd(u_int8_t *passwd, int max, char opt)
2498 len = strlen(optarg);
2500 warnx("-%c password is too long", opt);
2502 } else if (len == 0) {
2503 warnx("-%c password is missing", opt);
2505 } else if (optarg[0] == '-'){
2506 warnx("-%c password starts with '-' (generic arg?)", opt);
2508 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2509 warnx("-%c password conflicts with existing password from -%c",
2514 /* Callers pass in a buffer which does NOT need to be terminated */
2515 strncpy(passwd, optarg, max);
2522 ATA_HPA_ACTION_PRINT,
2523 ATA_HPA_ACTION_SET_MAX,
2524 ATA_HPA_ACTION_SET_PWD,
2525 ATA_HPA_ACTION_LOCK,
2526 ATA_HPA_ACTION_UNLOCK,
2527 ATA_HPA_ACTION_FREEZE_LOCK
2531 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2532 u_int64_t maxsize, int persist)
2534 printf("\nYou are about to configure HPA to limit the user accessible\n"
2535 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2536 persist ? "persistently" : "temporarily",
2537 device->device_name, device->dev_unit_num,
2538 device->given_dev_name, device->given_unit_number);
2539 ata_print_ident(ident_buf);
2543 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2545 if (NULL != fgets(str, sizeof(str), stdin)) {
2546 if (0 == strncasecmp(str, "yes", 3)) {
2548 } else if (0 == strncasecmp(str, "no", 2)) {
2551 printf("Please answer \"yes\" or "
2562 atahpa(struct cam_device *device, int retry_count, int timeout,
2563 int argc, char **argv, char *combinedopt)
2566 struct ata_params *ident_buf;
2567 struct ccb_getdev cgd;
2568 struct ata_set_max_pwd pwd;
2569 int error, confirm, quiet, c, action, actions, setpwd, persist;
2570 int security, is48bit, pwdsize;
2571 u_int64_t hpasize, maxsize;
2581 memset(&pwd, 0, sizeof(pwd));
2583 /* default action is to print hpa information */
2584 action = ATA_HPA_ACTION_PRINT;
2585 pwdsize = sizeof(pwd.password);
2587 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2590 action = ATA_HPA_ACTION_SET_MAX;
2591 maxsize = strtoumax(optarg, NULL, 0);
2596 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2598 action = ATA_HPA_ACTION_SET_PWD;
2604 action = ATA_HPA_ACTION_LOCK;
2610 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2612 action = ATA_HPA_ACTION_UNLOCK;
2618 action = ATA_HPA_ACTION_FREEZE_LOCK;
2638 warnx("too many hpa actions specified");
2642 if (get_cgd(device, &cgd) != 0) {
2643 warnx("couldn't get CGD");
2647 ccb = cam_getccb(device);
2649 warnx("couldn't allocate CCB");
2653 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2660 printf("%s%d: ", device->device_name, device->dev_unit_num);
2661 ata_print_ident(ident_buf);
2662 camxferrate(device);
2665 if (action == ATA_HPA_ACTION_PRINT) {
2666 error = ata_read_native_max(device, retry_count, timeout, ccb,
2667 ident_buf, &hpasize);
2669 atahpa_print(ident_buf, hpasize, 1);
2676 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2677 warnx("HPA is not supported by this device");
2683 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2684 warnx("HPA Security is not supported by this device");
2690 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2693 * The ATA spec requires:
2694 * 1. Read native max addr is called directly before set max addr
2695 * 2. Read native max addr is NOT called before any other set max call
2698 case ATA_HPA_ACTION_SET_MAX:
2700 atahpa_set_confirm(device, ident_buf, maxsize,
2707 error = ata_read_native_max(device, retry_count, timeout,
2708 ccb, ident_buf, &hpasize);
2710 error = atahpa_set_max(device, retry_count, timeout,
2711 ccb, is48bit, maxsize, persist);
2713 /* redo identify to get new lba values */
2714 error = ata_do_identify(device, retry_count,
2717 atahpa_print(ident_buf, hpasize, 1);
2722 case ATA_HPA_ACTION_SET_PWD:
2723 error = atahpa_password(device, retry_count, timeout,
2724 ccb, is48bit, &pwd);
2726 printf("HPA password has been set\n");
2729 case ATA_HPA_ACTION_LOCK:
2730 error = atahpa_lock(device, retry_count, timeout,
2733 printf("HPA has been locked\n");
2736 case ATA_HPA_ACTION_UNLOCK:
2737 error = atahpa_unlock(device, retry_count, timeout,
2738 ccb, is48bit, &pwd);
2740 printf("HPA has been unlocked\n");
2743 case ATA_HPA_ACTION_FREEZE_LOCK:
2744 error = atahpa_freeze_lock(device, retry_count, timeout,
2747 printf("HPA has been frozen\n");
2751 errx(1, "Option currently not supported");
2761 atasecurity(struct cam_device *device, int retry_count, int timeout,
2762 int argc, char **argv, char *combinedopt)
2765 struct ata_params *ident_buf;
2766 int error, confirm, quiet, c, action, actions, setpwd;
2767 int security_enabled, erase_timeout, pwdsize;
2768 struct ata_security_password pwd;
2776 memset(&pwd, 0, sizeof(pwd));
2778 /* default action is to print security information */
2779 action = ATA_SECURITY_ACTION_PRINT;
2781 /* user is master by default as its safer that way */
2782 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2783 pwdsize = sizeof(pwd.password);
2785 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2788 action = ATA_SECURITY_ACTION_FREEZE;
2793 if (strcasecmp(optarg, "user") == 0) {
2794 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2795 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2796 } else if (strcasecmp(optarg, "master") == 0) {
2797 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2798 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2800 warnx("-U argument '%s' is invalid (must be "
2801 "'user' or 'master')", optarg);
2807 if (strcasecmp(optarg, "high") == 0) {
2808 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2809 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2810 } else if (strcasecmp(optarg, "maximum") == 0) {
2811 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2812 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2814 warnx("-l argument '%s' is unknown (must be "
2815 "'high' or 'maximum')", optarg);
2821 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2823 action = ATA_SECURITY_ACTION_UNLOCK;
2828 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2830 action = ATA_SECURITY_ACTION_DISABLE;
2835 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2837 action = ATA_SECURITY_ACTION_ERASE;
2842 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2844 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2845 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2850 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2853 if (action == ATA_SECURITY_ACTION_PRINT)
2854 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2856 * Don't increment action as this can be combined
2857 * with other actions.
2870 erase_timeout = atoi(optarg) * 1000;
2876 warnx("too many security actions specified");
2880 if ((ccb = cam_getccb(device)) == NULL) {
2881 warnx("couldn't allocate CCB");
2885 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2892 printf("%s%d: ", device->device_name, device->dev_unit_num);
2893 ata_print_ident(ident_buf);
2894 camxferrate(device);
2897 if (action == ATA_SECURITY_ACTION_PRINT) {
2898 atasecurity_print(ident_buf);
2904 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2905 warnx("Security not supported");
2911 /* default timeout 15 seconds the same as linux hdparm */
2912 timeout = timeout ? timeout : 15 * 1000;
2914 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2916 /* first set the password if requested */
2918 /* confirm we can erase before setting the password if erasing */
2920 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2921 action == ATA_SECURITY_ACTION_ERASE) &&
2922 atasecurity_erase_confirm(device, ident_buf) == 0) {
2928 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2929 pwd.revision = ident_buf->master_passwd_revision;
2930 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2931 --pwd.revision == 0) {
2932 pwd.revision = 0xfffe;
2935 error = atasecurity_set_password(device, ccb, retry_count,
2936 timeout, &pwd, quiet);
2942 security_enabled = 1;
2946 case ATA_SECURITY_ACTION_FREEZE:
2947 error = atasecurity_freeze(device, ccb, retry_count,
2951 case ATA_SECURITY_ACTION_UNLOCK:
2952 if (security_enabled) {
2953 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2954 error = atasecurity_unlock(device, ccb,
2955 retry_count, timeout, &pwd, quiet);
2957 warnx("Can't unlock, drive is not locked");
2961 warnx("Can't unlock, security is disabled");
2966 case ATA_SECURITY_ACTION_DISABLE:
2967 if (security_enabled) {
2968 /* First unlock the drive if its locked */
2969 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2970 error = atasecurity_unlock(device, ccb,
2978 error = atasecurity_disable(device,
2986 warnx("Can't disable security (already disabled)");
2991 case ATA_SECURITY_ACTION_ERASE:
2992 if (security_enabled) {
2993 if (erase_timeout == 0) {
2994 erase_timeout = atasecurity_erase_timeout_msecs(
2995 ident_buf->erase_time);
2998 error = atasecurity_erase(device, ccb, retry_count,
2999 timeout, erase_timeout, &pwd,
3002 warnx("Can't secure erase (security is disabled)");
3007 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3008 if (security_enabled) {
3009 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3010 if (erase_timeout == 0) {
3012 atasecurity_erase_timeout_msecs(
3013 ident_buf->enhanced_erase_time);
3016 error = atasecurity_erase(device, ccb,
3017 retry_count, timeout,
3018 erase_timeout, &pwd,
3021 warnx("Enhanced erase is not supported");
3025 warnx("Can't secure erase (enhanced), "
3026 "(security is disabled)");
3037 #endif /* MINIMALISTIC */
3040 * Parse out a bus, or a bus, target and lun in the following
3046 * Returns the number of parsed components, or 0.
3049 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3050 cam_argmask *arglst)
3055 while (isspace(*tstr) && (*tstr != '\0'))
3058 tmpstr = (char *)strtok(tstr, ":");
3059 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3060 *bus = strtol(tmpstr, NULL, 0);
3061 *arglst |= CAM_ARG_BUS;
3063 tmpstr = (char *)strtok(NULL, ":");
3064 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3065 *target = strtol(tmpstr, NULL, 0);
3066 *arglst |= CAM_ARG_TARGET;
3068 tmpstr = (char *)strtok(NULL, ":");
3069 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3070 *lun = strtol(tmpstr, NULL, 0);
3071 *arglst |= CAM_ARG_LUN;
3081 dorescan_or_reset(int argc, char **argv, int rescan)
3083 static const char must[] =
3084 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3086 path_id_t bus = CAM_BUS_WILDCARD;
3087 target_id_t target = CAM_TARGET_WILDCARD;
3088 lun_id_t lun = CAM_LUN_WILDCARD;
3092 warnx(must, rescan? "rescan" : "reset");
3096 tstr = argv[optind];
3097 while (isspace(*tstr) && (*tstr != '\0'))
3099 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3100 arglist |= CAM_ARG_BUS;
3102 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3103 if (rv != 1 && rv != 3) {
3104 warnx(must, rescan? "rescan" : "reset");
3109 if ((arglist & CAM_ARG_BUS)
3110 && (arglist & CAM_ARG_TARGET)
3111 && (arglist & CAM_ARG_LUN))
3112 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3114 error = rescan_or_reset_bus(bus, rescan);
3120 rescan_or_reset_bus(path_id_t bus, int rescan)
3122 union ccb ccb, matchccb;
3128 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3129 warnx("error opening transport layer device %s", XPT_DEVICE);
3130 warn("%s", XPT_DEVICE);
3134 if (bus != CAM_BUS_WILDCARD) {
3135 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3136 ccb.ccb_h.path_id = bus;
3137 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3138 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3139 ccb.crcn.flags = CAM_FLAG_NONE;
3141 /* run this at a low priority */
3142 ccb.ccb_h.pinfo.priority = 5;
3144 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3145 warn("CAMIOCOMMAND ioctl failed");
3150 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3151 fprintf(stdout, "%s of bus %d was successful\n",
3152 rescan ? "Re-scan" : "Reset", bus);
3154 fprintf(stdout, "%s of bus %d returned error %#x\n",
3155 rescan ? "Re-scan" : "Reset", bus,
3156 ccb.ccb_h.status & CAM_STATUS_MASK);
3167 * The right way to handle this is to modify the xpt so that it can
3168 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3169 * that isn't implemented, so instead we enumerate the busses and
3170 * send the rescan or reset to those busses in the case where the
3171 * given bus is -1 (wildcard). We don't send a rescan or reset
3172 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3173 * no-op, sending a rescan to the xpt bus would result in a status of
3176 bzero(&(&matchccb.ccb_h)[1],
3177 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3178 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3179 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3180 bufsize = sizeof(struct dev_match_result) * 20;
3181 matchccb.cdm.match_buf_len = bufsize;
3182 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3183 if (matchccb.cdm.matches == NULL) {
3184 warnx("can't malloc memory for matches");
3188 matchccb.cdm.num_matches = 0;
3190 matchccb.cdm.num_patterns = 1;
3191 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3193 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3194 matchccb.cdm.pattern_buf_len);
3195 if (matchccb.cdm.patterns == NULL) {
3196 warnx("can't malloc memory for patterns");
3200 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3201 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3206 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3207 warn("CAMIOCOMMAND ioctl failed");
3212 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3213 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3214 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3215 warnx("got CAM error %#x, CDM error %d\n",
3216 matchccb.ccb_h.status, matchccb.cdm.status);
3221 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3222 struct bus_match_result *bus_result;
3224 /* This shouldn't happen. */
3225 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3228 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3231 * We don't want to rescan or reset the xpt bus.
3234 if (bus_result->path_id == CAM_XPT_PATH_ID)
3237 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3239 ccb.ccb_h.path_id = bus_result->path_id;
3240 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3241 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3242 ccb.crcn.flags = CAM_FLAG_NONE;
3244 /* run this at a low priority */
3245 ccb.ccb_h.pinfo.priority = 5;
3247 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3248 warn("CAMIOCOMMAND ioctl failed");
3253 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3254 fprintf(stdout, "%s of bus %d was successful\n",
3255 rescan? "Re-scan" : "Reset",
3256 bus_result->path_id);
3259 * Don't bail out just yet, maybe the other
3260 * rescan or reset commands will complete
3263 fprintf(stderr, "%s of bus %d returned error "
3264 "%#x\n", rescan? "Re-scan" : "Reset",
3265 bus_result->path_id,
3266 ccb.ccb_h.status & CAM_STATUS_MASK);
3270 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3271 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3278 if (matchccb.cdm.patterns != NULL)
3279 free(matchccb.cdm.patterns);
3280 if (matchccb.cdm.matches != NULL)
3281 free(matchccb.cdm.matches);
3287 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3290 struct cam_device *device;
3295 if (bus == CAM_BUS_WILDCARD) {
3296 warnx("invalid bus number %d", bus);
3300 if (target == CAM_TARGET_WILDCARD) {
3301 warnx("invalid target number %d", target);
3305 if (lun == CAM_LUN_WILDCARD) {
3306 warnx("invalid lun number %jx", (uintmax_t)lun);
3312 bzero(&ccb, sizeof(union ccb));
3315 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3316 warnx("error opening transport layer device %s\n",
3318 warn("%s", XPT_DEVICE);
3322 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3323 if (device == NULL) {
3324 warnx("%s", cam_errbuf);
3329 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3330 ccb.ccb_h.path_id = bus;
3331 ccb.ccb_h.target_id = target;
3332 ccb.ccb_h.target_lun = lun;
3333 ccb.ccb_h.timeout = 5000;
3334 ccb.crcn.flags = CAM_FLAG_NONE;
3336 /* run this at a low priority */
3337 ccb.ccb_h.pinfo.priority = 5;
3340 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3341 warn("CAMIOCOMMAND ioctl failed");
3346 if (cam_send_ccb(device, &ccb) < 0) {
3347 warn("error sending XPT_RESET_DEV CCB");
3348 cam_close_device(device);
3356 cam_close_device(device);
3359 * An error code of CAM_BDR_SENT is normal for a BDR request.
3361 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3363 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3364 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3365 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3368 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3369 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3370 ccb.ccb_h.status & CAM_STATUS_MASK);
3375 #ifndef MINIMALISTIC
3377 readdefects(struct cam_device *device, int argc, char **argv,
3378 char *combinedopt, int retry_count, int timeout)
3380 union ccb *ccb = NULL;
3381 struct scsi_read_defect_data_10 *rdd_cdb;
3382 u_int8_t *defect_list = NULL;
3383 u_int32_t max_dlist_length = SRDD10_MAX_LENGTH, dlist_length = 0;
3384 u_int32_t returned_length = 0;
3385 u_int32_t num_returned = 0;
3386 u_int8_t returned_format;
3389 int lists_specified;
3392 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3398 while (isspace(*tstr) && (*tstr != '\0'))
3400 if (strcmp(tstr, "block") == 0)
3401 arglist |= CAM_ARG_FORMAT_BLOCK;
3402 else if (strcmp(tstr, "bfi") == 0)
3403 arglist |= CAM_ARG_FORMAT_BFI;
3404 else if (strcmp(tstr, "phys") == 0)
3405 arglist |= CAM_ARG_FORMAT_PHYS;
3408 warnx("invalid defect format %s", tstr);
3409 goto defect_bailout;
3414 arglist |= CAM_ARG_GLIST;
3417 arglist |= CAM_ARG_PLIST;
3424 ccb = cam_getccb(device);
3427 * Eventually we should probably support the 12 byte READ DEFECT
3428 * DATA command. It supports a longer parameter list, which may be
3429 * necessary on newer drives with lots of defects. According to
3430 * the SBC-3 spec, drives are supposed to return an illegal request
3431 * if they have more defect data than will fit in 64K.
3433 defect_list = malloc(max_dlist_length);
3434 if (defect_list == NULL) {
3435 warnx("can't malloc memory for defect list");
3437 goto defect_bailout;
3441 * We start off asking for just the header to determine how much
3442 * defect data is available. Some Hitachi drives return an error
3443 * if you ask for more data than the drive has. Once we know the
3444 * length, we retry the command with the returned length.
3446 dlist_length = sizeof(struct scsi_read_defect_data_hdr_10);
3448 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
3452 lists_specified = 0;
3455 * cam_getccb() zeros the CCB header only. So we need to zero the
3456 * payload portion of the ccb.
3458 bzero(&(&ccb->ccb_h)[1],
3459 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3461 cam_fill_csio(&ccb->csio,
3462 /*retries*/ retry_count,
3464 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
3465 CAM_PASS_ERR_RECOVER : 0),
3466 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3467 /*data_ptr*/ defect_list,
3468 /*dxfer_len*/ dlist_length,
3469 /*sense_len*/ SSD_FULL_SIZE,
3470 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
3471 /*timeout*/ timeout ? timeout : 5000);
3473 rdd_cdb->opcode = READ_DEFECT_DATA_10;
3474 if (arglist & CAM_ARG_FORMAT_BLOCK)
3475 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
3476 else if (arglist & CAM_ARG_FORMAT_BFI)
3477 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
3478 else if (arglist & CAM_ARG_FORMAT_PHYS)
3479 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
3482 warnx("no defect list format specified");
3483 goto defect_bailout;
3485 if (arglist & CAM_ARG_PLIST) {
3486 rdd_cdb->format |= SRDD10_PLIST;
3490 if (arglist & CAM_ARG_GLIST) {
3491 rdd_cdb->format |= SRDD10_GLIST;
3495 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
3497 /* Disable freezing the device queue */
3498 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3500 if (cam_send_ccb(device, ccb) < 0) {
3501 perror("error reading defect list");
3503 if (arglist & CAM_ARG_VERBOSE) {
3504 cam_error_print(device, ccb, CAM_ESF_ALL,
3505 CAM_EPF_ALL, stderr);
3509 goto defect_bailout;
3512 returned_length = scsi_2btoul(((struct
3513 scsi_read_defect_data_hdr_10 *)defect_list)->length);
3515 if (get_length != 0) {
3518 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3519 CAM_SCSI_STATUS_ERROR) {
3520 struct scsi_sense_data *sense;
3521 int error_code, sense_key, asc, ascq;
3523 sense = &ccb->csio.sense_data;
3524 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3525 ccb->csio.sense_resid, &error_code, &sense_key,
3526 &asc, &ascq, /*show_errors*/ 1);
3529 * If the drive is reporting that it just doesn't
3530 * support the defect list format, go ahead and use
3531 * the length it reported. Otherwise, the length
3532 * may not be valid, so use the maximum.
3534 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3535 && (asc == 0x1c) && (ascq == 0x00)
3536 && (returned_length > 0)) {
3537 dlist_length = returned_length +
3538 sizeof(struct scsi_read_defect_data_hdr_10);
3539 dlist_length = min(dlist_length,
3542 dlist_length = max_dlist_length;
3543 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3546 warnx("Error reading defect header");
3547 if (arglist & CAM_ARG_VERBOSE)
3548 cam_error_print(device, ccb, CAM_ESF_ALL,
3549 CAM_EPF_ALL, stderr);
3550 goto defect_bailout;
3552 dlist_length = returned_length +
3553 sizeof(struct scsi_read_defect_data_hdr_10);
3554 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3560 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
3561 defect_list)->format;
3563 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3564 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3565 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3566 struct scsi_sense_data *sense;
3567 int error_code, sense_key, asc, ascq;
3569 sense = &ccb->csio.sense_data;
3570 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3571 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3572 &ascq, /*show_errors*/ 1);
3575 * According to the SCSI spec, if the disk doesn't support
3576 * the requested format, it will generally return a sense
3577 * key of RECOVERED ERROR, and an additional sense code
3578 * of "DEFECT LIST NOT FOUND". So, we check for that, and
3579 * also check to make sure that the returned length is
3580 * greater than 0, and then print out whatever format the
3583 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3584 && (asc == 0x1c) && (ascq == 0x00)
3585 && (returned_length > 0)) {
3586 warnx("requested defect format not available");
3587 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
3588 case SRDD10_BLOCK_FORMAT:
3589 warnx("Device returned block format");
3591 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3592 warnx("Device returned bytes from index"
3595 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3596 warnx("Device returned physical sector format");
3600 warnx("Device returned unknown defect"
3601 " data format %#x", returned_format);
3602 goto defect_bailout;
3603 break; /* NOTREACHED */
3607 warnx("Error returned from read defect data command");
3608 if (arglist & CAM_ARG_VERBOSE)
3609 cam_error_print(device, ccb, CAM_ESF_ALL,
3610 CAM_EPF_ALL, stderr);
3611 goto defect_bailout;
3613 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3615 warnx("Error returned from read defect data command");
3616 if (arglist & CAM_ARG_VERBOSE)
3617 cam_error_print(device, ccb, CAM_ESF_ALL,
3618 CAM_EPF_ALL, stderr);
3619 goto defect_bailout;
3623 * XXX KDM I should probably clean up the printout format for the
3626 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
3627 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
3629 struct scsi_defect_desc_phys_sector *dlist;
3631 dlist = (struct scsi_defect_desc_phys_sector *)
3633 sizeof(struct scsi_read_defect_data_hdr_10));
3635 num_returned = returned_length /
3636 sizeof(struct scsi_defect_desc_phys_sector);
3638 fprintf(stderr, "Got %d defect", num_returned);
3640 if ((lists_specified == 0) || (num_returned == 0)) {
3641 fprintf(stderr, "s.\n");
3643 } else if (num_returned == 1)
3644 fprintf(stderr, ":\n");
3646 fprintf(stderr, "s:\n");
3648 for (i = 0; i < num_returned; i++) {
3649 fprintf(stdout, "%d:%d:%d\n",
3650 scsi_3btoul(dlist[i].cylinder),
3652 scsi_4btoul(dlist[i].sector));
3656 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
3658 struct scsi_defect_desc_bytes_from_index *dlist;
3660 dlist = (struct scsi_defect_desc_bytes_from_index *)
3662 sizeof(struct scsi_read_defect_data_hdr_10));
3664 num_returned = returned_length /
3665 sizeof(struct scsi_defect_desc_bytes_from_index);
3667 fprintf(stderr, "Got %d defect", num_returned);
3669 if ((lists_specified == 0) || (num_returned == 0)) {
3670 fprintf(stderr, "s.\n");
3672 } else if (num_returned == 1)
3673 fprintf(stderr, ":\n");
3675 fprintf(stderr, "s:\n");
3677 for (i = 0; i < num_returned; i++) {
3678 fprintf(stdout, "%d:%d:%d\n",
3679 scsi_3btoul(dlist[i].cylinder),
3681 scsi_4btoul(dlist[i].bytes_from_index));
3685 case SRDDH10_BLOCK_FORMAT:
3687 struct scsi_defect_desc_block *dlist;
3689 dlist = (struct scsi_defect_desc_block *)(defect_list +
3690 sizeof(struct scsi_read_defect_data_hdr_10));
3692 num_returned = returned_length /
3693 sizeof(struct scsi_defect_desc_block);
3695 fprintf(stderr, "Got %d defect", num_returned);
3697 if ((lists_specified == 0) || (num_returned == 0)) {
3698 fprintf(stderr, "s.\n");
3700 } else if (num_returned == 1)
3701 fprintf(stderr, ":\n");
3703 fprintf(stderr, "s:\n");
3705 for (i = 0; i < num_returned; i++)
3706 fprintf(stdout, "%u\n",
3707 scsi_4btoul(dlist[i].address));
3711 fprintf(stderr, "Unknown defect format %d\n",
3712 returned_format & SRDDH10_DLIST_FORMAT_MASK);
3718 if (defect_list != NULL)
3726 #endif /* MINIMALISTIC */
3730 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3734 ccb = cam_getccb(device);
3740 #ifndef MINIMALISTIC
3742 mode_sense(struct cam_device *device, int mode_page, int page_control,
3743 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3748 ccb = cam_getccb(device);
3751 errx(1, "mode_sense: couldn't allocate CCB");
3753 bzero(&(&ccb->ccb_h)[1],
3754 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3756 scsi_mode_sense(&ccb->csio,
3757 /* retries */ retry_count,
3759 /* tag_action */ MSG_SIMPLE_Q_TAG,
3761 /* page_code */ page_control << 6,
3762 /* page */ mode_page,
3763 /* param_buf */ data,
3764 /* param_len */ datalen,
3765 /* sense_len */ SSD_FULL_SIZE,
3766 /* timeout */ timeout ? timeout : 5000);
3768 if (arglist & CAM_ARG_ERR_RECOVER)
3769 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3771 /* Disable freezing the device queue */
3772 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3774 if (((retval = cam_send_ccb(device, ccb)) < 0)
3775 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3776 if (arglist & CAM_ARG_VERBOSE) {
3777 cam_error_print(device, ccb, CAM_ESF_ALL,
3778 CAM_EPF_ALL, stderr);
3781 cam_close_device(device);
3783 err(1, "error sending mode sense command");
3785 errx(1, "error sending mode sense command");
3792 mode_select(struct cam_device *device, int save_pages, int retry_count,
3793 int timeout, u_int8_t *data, int datalen)
3798 ccb = cam_getccb(device);
3801 errx(1, "mode_select: couldn't allocate CCB");
3803 bzero(&(&ccb->ccb_h)[1],
3804 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3806 scsi_mode_select(&ccb->csio,
3807 /* retries */ retry_count,
3809 /* tag_action */ MSG_SIMPLE_Q_TAG,
3810 /* scsi_page_fmt */ 1,
3811 /* save_pages */ save_pages,
3812 /* param_buf */ data,
3813 /* param_len */ datalen,
3814 /* sense_len */ SSD_FULL_SIZE,
3815 /* timeout */ timeout ? timeout : 5000);
3817 if (arglist & CAM_ARG_ERR_RECOVER)
3818 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3820 /* Disable freezing the device queue */
3821 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3823 if (((retval = cam_send_ccb(device, ccb)) < 0)
3824 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3825 if (arglist & CAM_ARG_VERBOSE) {
3826 cam_error_print(device, ccb, CAM_ESF_ALL,
3827 CAM_EPF_ALL, stderr);
3830 cam_close_device(device);
3833 err(1, "error sending mode select command");
3835 errx(1, "error sending mode select command");
3843 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
3844 int retry_count, int timeout)
3846 int c, mode_page = -1, page_control = 0;
3847 int binary = 0, list = 0;
3849 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3855 arglist |= CAM_ARG_DBD;
3858 arglist |= CAM_ARG_MODE_EDIT;
3864 mode_page = strtol(optarg, NULL, 0);
3866 errx(1, "invalid mode page %d", mode_page);
3869 page_control = strtol(optarg, NULL, 0);
3870 if ((page_control < 0) || (page_control > 3))
3871 errx(1, "invalid page control field %d",
3873 arglist |= CAM_ARG_PAGE_CNTL;
3880 if (mode_page == -1 && list == 0)
3881 errx(1, "you must specify a mode page!");
3884 mode_list(device, page_control, arglist & CAM_ARG_DBD,
3885 retry_count, timeout);
3887 mode_edit(device, mode_page, page_control,
3888 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
3889 retry_count, timeout);
3894 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
3895 int retry_count, int timeout)
3898 u_int32_t flags = CAM_DIR_NONE;
3899 u_int8_t *data_ptr = NULL;
3901 u_int8_t atacmd[12];
3902 struct get_hook hook;
3903 int c, data_bytes = 0;
3909 char *datastr = NULL, *tstr, *resstr = NULL;
3911 int fd_data = 0, fd_res = 0;
3914 ccb = cam_getccb(device);
3917 warnx("scsicmd: error allocating ccb");
3921 bzero(&(&ccb->ccb_h)[1],
3922 sizeof(union ccb) - sizeof(struct ccb_hdr));
3924 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3928 while (isspace(*tstr) && (*tstr != '\0'))
3930 hook.argc = argc - optind;
3931 hook.argv = argv + optind;
3933 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
3936 * Increment optind by the number of arguments the
3937 * encoding routine processed. After each call to
3938 * getopt(3), optind points to the argument that
3939 * getopt should process _next_. In this case,
3940 * that means it points to the first command string
3941 * argument, if there is one. Once we increment
3942 * this, it should point to either the next command
3943 * line argument, or it should be past the end of
3950 while (isspace(*tstr) && (*tstr != '\0'))
3952 hook.argc = argc - optind;
3953 hook.argv = argv + optind;
3955 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
3958 * Increment optind by the number of arguments the
3959 * encoding routine processed. After each call to
3960 * getopt(3), optind points to the argument that
3961 * getopt should process _next_. In this case,
3962 * that means it points to the first command string
3963 * argument, if there is one. Once we increment
3964 * this, it should point to either the next command
3965 * line argument, or it should be past the end of
3977 if (arglist & CAM_ARG_CMD_OUT) {
3978 warnx("command must either be "
3979 "read or write, not both");
3981 goto scsicmd_bailout;
3983 arglist |= CAM_ARG_CMD_IN;
3985 data_bytes = strtol(optarg, NULL, 0);
3986 if (data_bytes <= 0) {
3987 warnx("invalid number of input bytes %d",
3990 goto scsicmd_bailout;
3992 hook.argc = argc - optind;
3993 hook.argv = argv + optind;
3996 datastr = cget(&hook, NULL);
3998 * If the user supplied "-" instead of a format, he
3999 * wants the data to be written to stdout.
4001 if ((datastr != NULL)
4002 && (datastr[0] == '-'))
4005 data_ptr = (u_int8_t *)malloc(data_bytes);
4006 if (data_ptr == NULL) {
4007 warnx("can't malloc memory for data_ptr");
4009 goto scsicmd_bailout;
4013 if (arglist & CAM_ARG_CMD_IN) {
4014 warnx("command must either be "
4015 "read or write, not both");
4017 goto scsicmd_bailout;
4019 arglist |= CAM_ARG_CMD_OUT;
4020 flags = CAM_DIR_OUT;
4021 data_bytes = strtol(optarg, NULL, 0);
4022 if (data_bytes <= 0) {
4023 warnx("invalid number of output bytes %d",
4026 goto scsicmd_bailout;
4028 hook.argc = argc - optind;
4029 hook.argv = argv + optind;
4031 datastr = cget(&hook, NULL);
4032 data_ptr = (u_int8_t *)malloc(data_bytes);
4033 if (data_ptr == NULL) {
4034 warnx("can't malloc memory for data_ptr");
4036 goto scsicmd_bailout;
4038 bzero(data_ptr, data_bytes);
4040 * If the user supplied "-" instead of a format, he
4041 * wants the data to be read from stdin.
4043 if ((datastr != NULL)
4044 && (datastr[0] == '-'))
4047 buff_encode_visit(data_ptr, data_bytes, datastr,
4053 hook.argc = argc - optind;
4054 hook.argv = argv + optind;
4056 resstr = cget(&hook, NULL);
4057 if ((resstr != NULL) && (resstr[0] == '-'))
4067 * If fd_data is set, and we're writing to the device, we need to
4068 * read the data the user wants written from stdin.
4070 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4072 int amt_to_read = data_bytes;
4073 u_int8_t *buf_ptr = data_ptr;
4075 for (amt_read = 0; amt_to_read > 0;
4076 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4077 if (amt_read == -1) {
4078 warn("error reading data from stdin");
4080 goto scsicmd_bailout;
4082 amt_to_read -= amt_read;
4083 buf_ptr += amt_read;
4087 if (arglist & CAM_ARG_ERR_RECOVER)
4088 flags |= CAM_PASS_ERR_RECOVER;
4090 /* Disable freezing the device queue */
4091 flags |= CAM_DEV_QFRZDIS;
4095 * This is taken from the SCSI-3 draft spec.
4096 * (T10/1157D revision 0.3)
4097 * The top 3 bits of an opcode are the group code.
4098 * The next 5 bits are the command code.
4099 * Group 0: six byte commands
4100 * Group 1: ten byte commands
4101 * Group 2: ten byte commands
4103 * Group 4: sixteen byte commands
4104 * Group 5: twelve byte commands
4105 * Group 6: vendor specific
4106 * Group 7: vendor specific
4108 switch((cdb[0] >> 5) & 0x7) {
4119 /* computed by buff_encode_visit */
4130 * We should probably use csio_build_visit or something like that
4131 * here, but it's easier to encode arguments as you go. The
4132 * alternative would be skipping the CDB argument and then encoding
4133 * it here, since we've got the data buffer argument by now.
4135 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4137 cam_fill_csio(&ccb->csio,
4138 /*retries*/ retry_count,
4141 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4142 /*data_ptr*/ data_ptr,
4143 /*dxfer_len*/ data_bytes,
4144 /*sense_len*/ SSD_FULL_SIZE,
4145 /*cdb_len*/ cdb_len,
4146 /*timeout*/ timeout ? timeout : 5000);
4149 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4151 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4153 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4155 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4157 cam_fill_ataio(&ccb->ataio,
4158 /*retries*/ retry_count,
4162 /*data_ptr*/ data_ptr,
4163 /*dxfer_len*/ data_bytes,
4164 /*timeout*/ timeout ? timeout : 5000);
4167 if (((retval = cam_send_ccb(device, ccb)) < 0)
4168 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4169 const char warnstr[] = "error sending command";
4176 if (arglist & CAM_ARG_VERBOSE) {
4177 cam_error_print(device, ccb, CAM_ESF_ALL,
4178 CAM_EPF_ALL, stderr);
4182 goto scsicmd_bailout;
4185 if (atacmd_len && need_res) {
4187 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4189 fprintf(stdout, "\n");
4192 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4193 ccb->ataio.res.status,
4194 ccb->ataio.res.error,
4195 ccb->ataio.res.lba_low,
4196 ccb->ataio.res.lba_mid,
4197 ccb->ataio.res.lba_high,
4198 ccb->ataio.res.device,
4199 ccb->ataio.res.lba_low_exp,
4200 ccb->ataio.res.lba_mid_exp,
4201 ccb->ataio.res.lba_high_exp,
4202 ccb->ataio.res.sector_count,
4203 ccb->ataio.res.sector_count_exp);
4208 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4209 && (arglist & CAM_ARG_CMD_IN)
4210 && (data_bytes > 0)) {
4212 buff_decode_visit(data_ptr, data_bytes, datastr,
4214 fprintf(stdout, "\n");
4216 ssize_t amt_written;
4217 int amt_to_write = data_bytes;
4218 u_int8_t *buf_ptr = data_ptr;
4220 for (amt_written = 0; (amt_to_write > 0) &&
4221 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4222 amt_to_write -= amt_written;
4223 buf_ptr += amt_written;
4225 if (amt_written == -1) {
4226 warn("error writing data to stdout");
4228 goto scsicmd_bailout;
4229 } else if ((amt_written == 0)
4230 && (amt_to_write > 0)) {
4231 warnx("only wrote %u bytes out of %u",
4232 data_bytes - amt_to_write, data_bytes);
4239 if ((data_bytes > 0) && (data_ptr != NULL))
4248 camdebug(int argc, char **argv, char *combinedopt)
4251 path_id_t bus = CAM_BUS_WILDCARD;
4252 target_id_t target = CAM_TARGET_WILDCARD;
4253 lun_id_t lun = CAM_LUN_WILDCARD;
4254 char *tstr, *tmpstr = NULL;
4258 bzero(&ccb, sizeof(union ccb));
4260 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4263 arglist |= CAM_ARG_DEBUG_INFO;
4264 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4267 arglist |= CAM_ARG_DEBUG_PERIPH;
4268 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4271 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4272 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4275 arglist |= CAM_ARG_DEBUG_TRACE;
4276 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4279 arglist |= CAM_ARG_DEBUG_XPT;
4280 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4283 arglist |= CAM_ARG_DEBUG_CDB;
4284 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4287 arglist |= CAM_ARG_DEBUG_PROBE;
4288 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4295 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4296 warnx("error opening transport layer device %s", XPT_DEVICE);
4297 warn("%s", XPT_DEVICE);
4304 warnx("you must specify \"off\", \"all\" or a bus,");
4305 warnx("bus:target, or bus:target:lun");
4312 while (isspace(*tstr) && (*tstr != '\0'))
4315 if (strncmp(tstr, "off", 3) == 0) {
4316 ccb.cdbg.flags = CAM_DEBUG_NONE;
4317 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4318 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4319 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4320 } else if (strncmp(tstr, "all", 3) != 0) {
4321 tmpstr = (char *)strtok(tstr, ":");
4322 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4323 bus = strtol(tmpstr, NULL, 0);
4324 arglist |= CAM_ARG_BUS;
4325 tmpstr = (char *)strtok(NULL, ":");
4326 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4327 target = strtol(tmpstr, NULL, 0);
4328 arglist |= CAM_ARG_TARGET;
4329 tmpstr = (char *)strtok(NULL, ":");
4330 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4331 lun = strtol(tmpstr, NULL, 0);
4332 arglist |= CAM_ARG_LUN;
4337 warnx("you must specify \"all\", \"off\", or a bus,");
4338 warnx("bus:target, or bus:target:lun to debug");
4344 ccb.ccb_h.func_code = XPT_DEBUG;
4345 ccb.ccb_h.path_id = bus;
4346 ccb.ccb_h.target_id = target;
4347 ccb.ccb_h.target_lun = lun;
4349 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4350 warn("CAMIOCOMMAND ioctl failed");
4355 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4356 CAM_FUNC_NOTAVAIL) {
4357 warnx("CAM debugging not available");
4358 warnx("you need to put options CAMDEBUG in"
4359 " your kernel config file!");
4361 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4363 warnx("XPT_DEBUG CCB failed with status %#x",
4367 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4369 "Debugging turned off\n");
4372 "Debugging enabled for "
4374 bus, target, (uintmax_t)lun);
4385 tagcontrol(struct cam_device *device, int argc, char **argv,
4395 ccb = cam_getccb(device);
4398 warnx("tagcontrol: error allocating ccb");
4402 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4405 numtags = strtol(optarg, NULL, 0);
4407 warnx("tag count %d is < 0", numtags);
4409 goto tagcontrol_bailout;
4420 cam_path_string(device, pathstr, sizeof(pathstr));
4423 bzero(&(&ccb->ccb_h)[1],
4424 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4425 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4426 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4427 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4428 ccb->crs.openings = numtags;
4431 if (cam_send_ccb(device, ccb) < 0) {
4432 perror("error sending XPT_REL_SIMQ CCB");
4434 goto tagcontrol_bailout;
4437 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4438 warnx("XPT_REL_SIMQ CCB failed");
4439 cam_error_print(device, ccb, CAM_ESF_ALL,
4440 CAM_EPF_ALL, stderr);
4442 goto tagcontrol_bailout;
4447 fprintf(stdout, "%stagged openings now %d\n",
4448 pathstr, ccb->crs.openings);
4451 bzero(&(&ccb->ccb_h)[1],
4452 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4454 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4456 if (cam_send_ccb(device, ccb) < 0) {
4457 perror("error sending XPT_GDEV_STATS CCB");
4459 goto tagcontrol_bailout;
4462 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4463 warnx("XPT_GDEV_STATS CCB failed");
4464 cam_error_print(device, ccb, CAM_ESF_ALL,
4465 CAM_EPF_ALL, stderr);
4467 goto tagcontrol_bailout;
4470 if (arglist & CAM_ARG_VERBOSE) {
4471 fprintf(stdout, "%s", pathstr);
4472 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4473 fprintf(stdout, "%s", pathstr);
4474 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4475 fprintf(stdout, "%s", pathstr);
4476 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
4477 fprintf(stdout, "%s", pathstr);
4478 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
4479 fprintf(stdout, "%s", pathstr);
4480 fprintf(stdout, "held %d\n", ccb->cgds.held);
4481 fprintf(stdout, "%s", pathstr);
4482 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4483 fprintf(stdout, "%s", pathstr);
4484 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4487 fprintf(stdout, "%s", pathstr);
4488 fprintf(stdout, "device openings: ");
4490 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4491 ccb->cgds.dev_active);
4501 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4505 cam_path_string(device, pathstr, sizeof(pathstr));
4507 if (cts->transport == XPORT_SPI) {
4508 struct ccb_trans_settings_spi *spi =
4509 &cts->xport_specific.spi;
4511 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4513 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4516 if (spi->sync_offset != 0) {
4519 freq = scsi_calc_syncsrate(spi->sync_period);
4520 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4521 pathstr, freq / 1000, freq % 1000);
4525 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4526 fprintf(stdout, "%soffset: %d\n", pathstr,
4530 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4531 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4532 (0x01 << spi->bus_width) * 8);
4535 if (spi->valid & CTS_SPI_VALID_DISC) {
4536 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4537 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4538 "enabled" : "disabled");
4541 if (cts->transport == XPORT_FC) {
4542 struct ccb_trans_settings_fc *fc =
4543 &cts->xport_specific.fc;
4545 if (fc->valid & CTS_FC_VALID_WWNN)
4546 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4547 (long long) fc->wwnn);
4548 if (fc->valid & CTS_FC_VALID_WWPN)
4549 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4550 (long long) fc->wwpn);
4551 if (fc->valid & CTS_FC_VALID_PORT)
4552 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4553 if (fc->valid & CTS_FC_VALID_SPEED)
4554 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4555 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4557 if (cts->transport == XPORT_SAS) {
4558 struct ccb_trans_settings_sas *sas =
4559 &cts->xport_specific.sas;
4561 if (sas->valid & CTS_SAS_VALID_SPEED)
4562 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4563 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4565 if (cts->transport == XPORT_ATA) {
4566 struct ccb_trans_settings_pata *pata =
4567 &cts->xport_specific.ata;
4569 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4570 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4571 ata_mode2string(pata->mode));
4573 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4574 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4577 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4578 fprintf(stdout, "%sPIO transaction length: %d\n",
4579 pathstr, pata->bytecount);
4582 if (cts->transport == XPORT_SATA) {
4583 struct ccb_trans_settings_sata *sata =
4584 &cts->xport_specific.sata;
4586 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4587 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4590 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4591 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4592 ata_mode2string(sata->mode));
4594 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4595 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4598 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4599 fprintf(stdout, "%sPIO transaction length: %d\n",
4600 pathstr, sata->bytecount);
4602 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4603 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4606 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4607 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4610 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4611 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4615 if (cts->protocol == PROTO_ATA) {
4616 struct ccb_trans_settings_ata *ata=
4617 &cts->proto_specific.ata;
4619 if (ata->valid & CTS_ATA_VALID_TQ) {
4620 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4621 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4622 "enabled" : "disabled");
4625 if (cts->protocol == PROTO_SCSI) {
4626 struct ccb_trans_settings_scsi *scsi=
4627 &cts->proto_specific.scsi;
4629 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4630 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4631 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4632 "enabled" : "disabled");
4639 * Get a path inquiry CCB for the specified device.
4642 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4647 ccb = cam_getccb(device);
4649 warnx("get_cpi: couldn't allocate CCB");
4652 bzero(&(&ccb->ccb_h)[1],
4653 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4654 ccb->ccb_h.func_code = XPT_PATH_INQ;
4655 if (cam_send_ccb(device, ccb) < 0) {
4656 warn("get_cpi: error sending Path Inquiry CCB");
4657 if (arglist & CAM_ARG_VERBOSE)
4658 cam_error_print(device, ccb, CAM_ESF_ALL,
4659 CAM_EPF_ALL, stderr);
4661 goto get_cpi_bailout;
4663 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4664 if (arglist & CAM_ARG_VERBOSE)
4665 cam_error_print(device, ccb, CAM_ESF_ALL,
4666 CAM_EPF_ALL, stderr);
4668 goto get_cpi_bailout;
4670 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4678 * Get a get device CCB for the specified device.
4681 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4686 ccb = cam_getccb(device);
4688 warnx("get_cgd: couldn't allocate CCB");
4691 bzero(&(&ccb->ccb_h)[1],
4692 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4693 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4694 if (cam_send_ccb(device, ccb) < 0) {
4695 warn("get_cgd: error sending Path Inquiry CCB");
4696 if (arglist & CAM_ARG_VERBOSE)
4697 cam_error_print(device, ccb, CAM_ESF_ALL,
4698 CAM_EPF_ALL, stderr);
4700 goto get_cgd_bailout;
4702 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4703 if (arglist & CAM_ARG_VERBOSE)
4704 cam_error_print(device, ccb, CAM_ESF_ALL,
4705 CAM_EPF_ALL, stderr);
4707 goto get_cgd_bailout;
4709 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4716 /* return the type of disk (really the command type) */
4718 get_disk_type(struct cam_device *device)
4720 struct ccb_getdev cgd;
4722 (void) memset(&cgd, 0x0, sizeof(cgd));
4723 get_cgd(device, &cgd);
4724 switch(cgd.protocol) {
4737 cpi_print(struct ccb_pathinq *cpi)
4739 char adapter_str[1024];
4742 snprintf(adapter_str, sizeof(adapter_str),
4743 "%s%d:", cpi->dev_name, cpi->unit_number);
4745 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
4748 for (i = 1; i < 0xff; i = i << 1) {
4751 if ((i & cpi->hba_inquiry) == 0)
4754 fprintf(stdout, "%s supports ", adapter_str);
4758 str = "MDP message";
4761 str = "32 bit wide SCSI";
4764 str = "16 bit wide SCSI";
4767 str = "SDTR message";
4770 str = "linked CDBs";
4773 str = "tag queue messages";
4776 str = "soft reset alternative";
4779 str = "SATA Port Multiplier";
4782 str = "unknown PI bit set";
4785 fprintf(stdout, "%s\n", str);
4788 for (i = 1; i < 0xff; i = i << 1) {
4791 if ((i & cpi->hba_misc) == 0)
4794 fprintf(stdout, "%s ", adapter_str);
4798 str = "bus scans from high ID to low ID";
4801 str = "removable devices not included in scan";
4803 case PIM_NOINITIATOR:
4804 str = "initiator role not supported";
4806 case PIM_NOBUSRESET:
4807 str = "user has disabled initial BUS RESET or"
4808 " controller is in target/mixed mode";
4811 str = "do not send 6-byte commands";
4814 str = "scan bus sequentially";
4817 str = "unknown PIM bit set";
4820 fprintf(stdout, "%s\n", str);
4823 for (i = 1; i < 0xff; i = i << 1) {
4826 if ((i & cpi->target_sprt) == 0)
4829 fprintf(stdout, "%s supports ", adapter_str);
4832 str = "target mode processor mode";
4835 str = "target mode phase cog. mode";
4837 case PIT_DISCONNECT:
4838 str = "disconnects in target mode";
4841 str = "terminate I/O message in target mode";
4844 str = "group 6 commands in target mode";
4847 str = "group 7 commands in target mode";
4850 str = "unknown PIT bit set";
4854 fprintf(stdout, "%s\n", str);
4856 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
4858 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
4860 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
4862 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
4863 adapter_str, cpi->hpath_id);
4864 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
4866 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
4867 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
4868 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
4869 adapter_str, cpi->hba_vendor);
4870 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
4871 adapter_str, cpi->hba_device);
4872 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
4873 adapter_str, cpi->hba_subvendor);
4874 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
4875 adapter_str, cpi->hba_subdevice);
4876 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
4877 fprintf(stdout, "%s base transfer speed: ", adapter_str);
4878 if (cpi->base_transfer_speed > 1000)
4879 fprintf(stdout, "%d.%03dMB/sec\n",
4880 cpi->base_transfer_speed / 1000,
4881 cpi->base_transfer_speed % 1000);
4883 fprintf(stdout, "%dKB/sec\n",
4884 (cpi->base_transfer_speed % 1000) * 1000);
4885 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
4886 adapter_str, cpi->maxio);
4890 get_print_cts(struct cam_device *device, int user_settings, int quiet,
4891 struct ccb_trans_settings *cts)
4897 ccb = cam_getccb(device);
4900 warnx("get_print_cts: error allocating ccb");
4904 bzero(&(&ccb->ccb_h)[1],
4905 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4907 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
4909 if (user_settings == 0)
4910 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
4912 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
4914 if (cam_send_ccb(device, ccb) < 0) {
4915 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
4916 if (arglist & CAM_ARG_VERBOSE)
4917 cam_error_print(device, ccb, CAM_ESF_ALL,
4918 CAM_EPF_ALL, stderr);
4920 goto get_print_cts_bailout;
4923 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4924 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
4925 if (arglist & CAM_ARG_VERBOSE)
4926 cam_error_print(device, ccb, CAM_ESF_ALL,
4927 CAM_EPF_ALL, stderr);
4929 goto get_print_cts_bailout;
4933 cts_print(device, &ccb->cts);
4936 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
4938 get_print_cts_bailout:
4946 ratecontrol(struct cam_device *device, int retry_count, int timeout,
4947 int argc, char **argv, char *combinedopt)
4951 int user_settings = 0;
4953 int disc_enable = -1, tag_enable = -1;
4956 double syncrate = -1;
4959 int change_settings = 0, send_tur = 0;
4960 struct ccb_pathinq cpi;
4962 ccb = cam_getccb(device);
4964 warnx("ratecontrol: error allocating ccb");
4967 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4976 if (strncasecmp(optarg, "enable", 6) == 0)
4978 else if (strncasecmp(optarg, "disable", 7) == 0)
4981 warnx("-D argument \"%s\" is unknown", optarg);
4983 goto ratecontrol_bailout;
4985 change_settings = 1;
4988 mode = ata_string2mode(optarg);
4990 warnx("unknown mode '%s'", optarg);
4992 goto ratecontrol_bailout;
4994 change_settings = 1;
4997 offset = strtol(optarg, NULL, 0);
4999 warnx("offset value %d is < 0", offset);
5001 goto ratecontrol_bailout;
5003 change_settings = 1;
5009 syncrate = atof(optarg);
5011 warnx("sync rate %f is < 0", syncrate);
5013 goto ratecontrol_bailout;
5015 change_settings = 1;
5018 if (strncasecmp(optarg, "enable", 6) == 0)
5020 else if (strncasecmp(optarg, "disable", 7) == 0)
5023 warnx("-T argument \"%s\" is unknown", optarg);
5025 goto ratecontrol_bailout;
5027 change_settings = 1;
5033 bus_width = strtol(optarg, NULL, 0);
5034 if (bus_width < 0) {
5035 warnx("bus width %d is < 0", bus_width);
5037 goto ratecontrol_bailout;
5039 change_settings = 1;
5045 bzero(&(&ccb->ccb_h)[1],
5046 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
5048 * Grab path inquiry information, so we can determine whether
5049 * or not the initiator is capable of the things that the user
5052 ccb->ccb_h.func_code = XPT_PATH_INQ;
5053 if (cam_send_ccb(device, ccb) < 0) {
5054 perror("error sending XPT_PATH_INQ CCB");
5055 if (arglist & CAM_ARG_VERBOSE) {
5056 cam_error_print(device, ccb, CAM_ESF_ALL,
5057 CAM_EPF_ALL, stderr);
5060 goto ratecontrol_bailout;
5062 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5063 warnx("XPT_PATH_INQ CCB failed");
5064 if (arglist & CAM_ARG_VERBOSE) {
5065 cam_error_print(device, ccb, CAM_ESF_ALL,
5066 CAM_EPF_ALL, stderr);
5069 goto ratecontrol_bailout;
5071 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5072 bzero(&(&ccb->ccb_h)[1],
5073 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5075 fprintf(stdout, "%s parameters:\n",
5076 user_settings ? "User" : "Current");
5078 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5080 goto ratecontrol_bailout;
5082 if (arglist & CAM_ARG_VERBOSE)
5085 if (change_settings) {
5086 int didsettings = 0;
5087 struct ccb_trans_settings_spi *spi = NULL;
5088 struct ccb_trans_settings_pata *pata = NULL;
5089 struct ccb_trans_settings_sata *sata = NULL;
5090 struct ccb_trans_settings_ata *ata = NULL;
5091 struct ccb_trans_settings_scsi *scsi = NULL;
5093 if (ccb->cts.transport == XPORT_SPI)
5094 spi = &ccb->cts.xport_specific.spi;
5095 if (ccb->cts.transport == XPORT_ATA)
5096 pata = &ccb->cts.xport_specific.ata;
5097 if (ccb->cts.transport == XPORT_SATA)
5098 sata = &ccb->cts.xport_specific.sata;
5099 if (ccb->cts.protocol == PROTO_ATA)
5100 ata = &ccb->cts.proto_specific.ata;
5101 if (ccb->cts.protocol == PROTO_SCSI)
5102 scsi = &ccb->cts.proto_specific.scsi;
5103 ccb->cts.xport_specific.valid = 0;
5104 ccb->cts.proto_specific.valid = 0;
5105 if (spi && disc_enable != -1) {
5106 spi->valid |= CTS_SPI_VALID_DISC;
5107 if (disc_enable == 0)
5108 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5110 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5113 if (tag_enable != -1) {
5114 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5115 warnx("HBA does not support tagged queueing, "
5116 "so you cannot modify tag settings");
5118 goto ratecontrol_bailout;
5121 ata->valid |= CTS_SCSI_VALID_TQ;
5122 if (tag_enable == 0)
5123 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5125 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5128 scsi->valid |= CTS_SCSI_VALID_TQ;
5129 if (tag_enable == 0)
5130 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5132 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5136 if (spi && offset != -1) {
5137 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5138 warnx("HBA is not capable of changing offset");
5140 goto ratecontrol_bailout;
5142 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5143 spi->sync_offset = offset;
5146 if (spi && syncrate != -1) {
5147 int prelim_sync_period;
5149 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5150 warnx("HBA is not capable of changing "
5153 goto ratecontrol_bailout;
5155 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5157 * The sync rate the user gives us is in MHz.
5158 * We need to translate it into KHz for this
5163 * Next, we calculate a "preliminary" sync period
5164 * in tenths of a nanosecond.
5167 prelim_sync_period = 0;
5169 prelim_sync_period = 10000000 / syncrate;
5171 scsi_calc_syncparam(prelim_sync_period);
5174 if (sata && syncrate != -1) {
5175 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5176 warnx("HBA is not capable of changing "
5179 goto ratecontrol_bailout;
5181 if (!user_settings) {
5182 warnx("You can modify only user rate "
5183 "settings for SATA");
5185 goto ratecontrol_bailout;
5187 sata->revision = ata_speed2revision(syncrate * 100);
5188 if (sata->revision < 0) {
5189 warnx("Invalid rate %f", syncrate);
5191 goto ratecontrol_bailout;
5193 sata->valid |= CTS_SATA_VALID_REVISION;
5196 if ((pata || sata) && mode != -1) {
5197 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5198 warnx("HBA is not capable of changing "
5201 goto ratecontrol_bailout;
5203 if (!user_settings) {
5204 warnx("You can modify only user mode "
5205 "settings for ATA/SATA");
5207 goto ratecontrol_bailout;
5211 pata->valid |= CTS_ATA_VALID_MODE;
5214 sata->valid |= CTS_SATA_VALID_MODE;
5219 * The bus_width argument goes like this:
5223 * Therefore, if you shift the number of bits given on the
5224 * command line right by 4, you should get the correct
5227 if (spi && bus_width != -1) {
5229 * We might as well validate things here with a
5230 * decipherable error message, rather than what
5231 * will probably be an indecipherable error message
5232 * by the time it gets back to us.
5234 if ((bus_width == 16)
5235 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5236 warnx("HBA does not support 16 bit bus width");
5238 goto ratecontrol_bailout;
5239 } else if ((bus_width == 32)
5240 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5241 warnx("HBA does not support 32 bit bus width");
5243 goto ratecontrol_bailout;
5244 } else if ((bus_width != 8)
5245 && (bus_width != 16)
5246 && (bus_width != 32)) {
5247 warnx("Invalid bus width %d", bus_width);
5249 goto ratecontrol_bailout;
5251 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5252 spi->bus_width = bus_width >> 4;
5255 if (didsettings == 0) {
5256 goto ratecontrol_bailout;
5258 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5259 if (cam_send_ccb(device, ccb) < 0) {
5260 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5261 if (arglist & CAM_ARG_VERBOSE) {
5262 cam_error_print(device, ccb, CAM_ESF_ALL,
5263 CAM_EPF_ALL, stderr);
5266 goto ratecontrol_bailout;
5268 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5269 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5270 if (arglist & CAM_ARG_VERBOSE) {
5271 cam_error_print(device, ccb, CAM_ESF_ALL,
5272 CAM_EPF_ALL, stderr);
5275 goto ratecontrol_bailout;
5279 retval = testunitready(device, retry_count, timeout,
5280 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5282 * If the TUR didn't succeed, just bail.
5286 fprintf(stderr, "Test Unit Ready failed\n");
5287 goto ratecontrol_bailout;
5290 if ((change_settings || send_tur) && !quiet &&
5291 (ccb->cts.transport == XPORT_ATA ||
5292 ccb->cts.transport == XPORT_SATA || send_tur)) {
5293 fprintf(stdout, "New parameters:\n");
5294 retval = get_print_cts(device, user_settings, 0, NULL);
5297 ratecontrol_bailout:
5303 scsiformat(struct cam_device *device, int argc, char **argv,
5304 char *combinedopt, int retry_count, int timeout)
5308 int ycount = 0, quiet = 0;
5309 int error = 0, retval = 0;
5310 int use_timeout = 10800 * 1000;
5312 struct format_defect_list_header fh;
5313 u_int8_t *data_ptr = NULL;
5314 u_int32_t dxfer_len = 0;
5316 int num_warnings = 0;
5319 ccb = cam_getccb(device);
5322 warnx("scsiformat: error allocating ccb");
5326 bzero(&(&ccb->ccb_h)[1],
5327 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5329 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5350 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5351 "following device:\n");
5353 error = scsidoinquiry(device, argc, argv, combinedopt,
5354 retry_count, timeout);
5357 warnx("scsiformat: error sending inquiry");
5358 goto scsiformat_bailout;
5363 if (!get_confirmation()) {
5365 goto scsiformat_bailout;
5370 use_timeout = timeout;
5373 fprintf(stdout, "Current format timeout is %d seconds\n",
5374 use_timeout / 1000);
5378 * If the user hasn't disabled questions and didn't specify a
5379 * timeout on the command line, ask them if they want the current
5383 && (timeout == 0)) {
5385 int new_timeout = 0;
5387 fprintf(stdout, "Enter new timeout in seconds or press\n"
5388 "return to keep the current timeout [%d] ",
5389 use_timeout / 1000);
5391 if (fgets(str, sizeof(str), stdin) != NULL) {
5393 new_timeout = atoi(str);
5396 if (new_timeout != 0) {
5397 use_timeout = new_timeout * 1000;
5398 fprintf(stdout, "Using new timeout value %d\n",
5399 use_timeout / 1000);
5404 * Keep this outside the if block below to silence any unused
5405 * variable warnings.
5407 bzero(&fh, sizeof(fh));
5410 * If we're in immediate mode, we've got to include the format
5413 if (immediate != 0) {
5414 fh.byte2 = FU_DLH_IMMED;
5415 data_ptr = (u_int8_t *)&fh;
5416 dxfer_len = sizeof(fh);
5417 byte2 = FU_FMT_DATA;
5418 } else if (quiet == 0) {
5419 fprintf(stdout, "Formatting...");
5423 scsi_format_unit(&ccb->csio,
5424 /* retries */ retry_count,
5426 /* tag_action */ MSG_SIMPLE_Q_TAG,
5429 /* data_ptr */ data_ptr,
5430 /* dxfer_len */ dxfer_len,
5431 /* sense_len */ SSD_FULL_SIZE,
5432 /* timeout */ use_timeout);
5434 /* Disable freezing the device queue */
5435 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5437 if (arglist & CAM_ARG_ERR_RECOVER)
5438 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5440 if (((retval = cam_send_ccb(device, ccb)) < 0)
5441 || ((immediate == 0)
5442 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5443 const char errstr[] = "error sending format command";
5450 if (arglist & CAM_ARG_VERBOSE) {
5451 cam_error_print(device, ccb, CAM_ESF_ALL,
5452 CAM_EPF_ALL, stderr);
5455 goto scsiformat_bailout;
5459 * If we ran in non-immediate mode, we already checked for errors
5460 * above and printed out any necessary information. If we're in
5461 * immediate mode, we need to loop through and get status
5462 * information periodically.
5464 if (immediate == 0) {
5466 fprintf(stdout, "Format Complete\n");
5468 goto scsiformat_bailout;
5475 bzero(&(&ccb->ccb_h)[1],
5476 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5479 * There's really no need to do error recovery or
5480 * retries here, since we're just going to sit in a
5481 * loop and wait for the device to finish formatting.
5483 scsi_test_unit_ready(&ccb->csio,
5486 /* tag_action */ MSG_SIMPLE_Q_TAG,
5487 /* sense_len */ SSD_FULL_SIZE,
5488 /* timeout */ 5000);
5490 /* Disable freezing the device queue */
5491 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5493 retval = cam_send_ccb(device, ccb);
5496 * If we get an error from the ioctl, bail out. SCSI
5497 * errors are expected.
5500 warn("error sending CAMIOCOMMAND ioctl");
5501 if (arglist & CAM_ARG_VERBOSE) {
5502 cam_error_print(device, ccb, CAM_ESF_ALL,
5503 CAM_EPF_ALL, stderr);
5506 goto scsiformat_bailout;
5509 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5511 if ((status != CAM_REQ_CMP)
5512 && (status == CAM_SCSI_STATUS_ERROR)
5513 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5514 struct scsi_sense_data *sense;
5515 int error_code, sense_key, asc, ascq;
5517 sense = &ccb->csio.sense_data;
5518 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5519 ccb->csio.sense_resid, &error_code, &sense_key,
5520 &asc, &ascq, /*show_errors*/ 1);
5523 * According to the SCSI-2 and SCSI-3 specs, a
5524 * drive that is in the middle of a format should
5525 * return NOT READY with an ASC of "logical unit
5526 * not ready, format in progress". The sense key
5527 * specific bytes will then be a progress indicator.
5529 if ((sense_key == SSD_KEY_NOT_READY)
5530 && (asc == 0x04) && (ascq == 0x04)) {
5533 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5534 ccb->csio.sense_resid, sks) == 0)
5537 u_int64_t percentage;
5539 val = scsi_2btoul(&sks[1]);
5540 percentage = 10000 * val;
5543 "\rFormatting: %ju.%02u %% "
5545 (uintmax_t)(percentage /
5547 (unsigned)((percentage /
5551 } else if ((quiet == 0)
5552 && (++num_warnings <= 1)) {
5553 warnx("Unexpected SCSI Sense Key "
5554 "Specific value returned "
5556 scsi_sense_print(device, &ccb->csio,
5558 warnx("Unable to print status "
5559 "information, but format will "
5561 warnx("will exit when format is "
5566 warnx("Unexpected SCSI error during format");
5567 cam_error_print(device, ccb, CAM_ESF_ALL,
5568 CAM_EPF_ALL, stderr);
5570 goto scsiformat_bailout;
5573 } else if (status != CAM_REQ_CMP) {
5574 warnx("Unexpected CAM status %#x", status);
5575 if (arglist & CAM_ARG_VERBOSE)
5576 cam_error_print(device, ccb, CAM_ESF_ALL,
5577 CAM_EPF_ALL, stderr);
5579 goto scsiformat_bailout;
5582 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5585 fprintf(stdout, "\nFormat Complete\n");
5595 scsisanitize(struct cam_device *device, int argc, char **argv,
5596 char *combinedopt, int retry_count, int timeout)
5599 u_int8_t action = 0;
5601 int ycount = 0, quiet = 0;
5602 int error = 0, retval = 0;
5603 int use_timeout = 10800 * 1000;
5609 const char *pattern = NULL;
5610 u_int8_t *data_ptr = NULL;
5611 u_int32_t dxfer_len = 0;
5613 int num_warnings = 0;
5616 ccb = cam_getccb(device);
5619 warnx("scsisanitize: error allocating ccb");
5623 bzero(&(&ccb->ccb_h)[1],
5624 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5626 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5629 if (strcasecmp(optarg, "overwrite") == 0)
5630 action = SSZ_SERVICE_ACTION_OVERWRITE;
5631 else if (strcasecmp(optarg, "block") == 0)
5632 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
5633 else if (strcasecmp(optarg, "crypto") == 0)
5634 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
5635 else if (strcasecmp(optarg, "exitfailure") == 0)
5636 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
5638 warnx("invalid service operation \"%s\"",
5641 goto scsisanitize_bailout;
5645 passes = strtol(optarg, NULL, 0);
5646 if (passes < 1 || passes > 31) {
5647 warnx("invalid passes value %d", passes);
5649 goto scsisanitize_bailout;
5680 warnx("an action is required");
5682 goto scsisanitize_bailout;
5683 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
5684 struct scsi_sanitize_parameter_list *pl;
5688 if (pattern == NULL) {
5689 warnx("overwrite action requires -P argument");
5691 goto scsisanitize_bailout;
5693 fd = open(pattern, O_RDONLY);
5695 warn("cannot open pattern file %s", pattern);
5697 goto scsisanitize_bailout;
5699 if (fstat(fd, &sb) < 0) {
5700 warn("cannot stat pattern file %s", pattern);
5702 goto scsisanitize_bailout;
5705 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
5706 warnx("pattern file size exceeds maximum value %d",
5707 SSZPL_MAX_PATTERN_LENGTH);
5709 goto scsisanitize_bailout;
5711 dxfer_len = sizeof(*pl) + sz;
5712 data_ptr = calloc(1, dxfer_len);
5713 if (data_ptr == NULL) {
5714 warnx("cannot allocate parameter list buffer");
5716 goto scsisanitize_bailout;
5719 amt = read(fd, data_ptr + sizeof(*pl), sz);
5721 warn("cannot read pattern file");
5723 goto scsisanitize_bailout;
5724 } else if (amt != sz) {
5725 warnx("short pattern file read");
5727 goto scsisanitize_bailout;
5730 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
5736 pl->byte1 |= SSZPL_INVERT;
5737 scsi_ulto2b(sz, pl->length);
5743 else if (invert != 0)
5745 else if (pattern != NULL)
5750 warnx("%s argument only valid with overwrite "
5753 goto scsisanitize_bailout;
5758 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5759 "following device:\n");
5761 error = scsidoinquiry(device, argc, argv, combinedopt,
5762 retry_count, timeout);
5765 warnx("scsisanitize: error sending inquiry");
5766 goto scsisanitize_bailout;
5771 if (!get_confirmation()) {
5773 goto scsisanitize_bailout;
5778 use_timeout = timeout;
5781 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
5782 use_timeout / 1000);
5786 * If the user hasn't disabled questions and didn't specify a
5787 * timeout on the command line, ask them if they want the current
5791 && (timeout == 0)) {
5793 int new_timeout = 0;
5795 fprintf(stdout, "Enter new timeout in seconds or press\n"
5796 "return to keep the current timeout [%d] ",
5797 use_timeout / 1000);
5799 if (fgets(str, sizeof(str), stdin) != NULL) {
5801 new_timeout = atoi(str);
5804 if (new_timeout != 0) {
5805 use_timeout = new_timeout * 1000;
5806 fprintf(stdout, "Using new timeout value %d\n",
5807 use_timeout / 1000);
5813 byte2 |= SSZ_UNRESTRICTED_EXIT;
5817 scsi_sanitize(&ccb->csio,
5818 /* retries */ retry_count,
5820 /* tag_action */ MSG_SIMPLE_Q_TAG,
5823 /* data_ptr */ data_ptr,
5824 /* dxfer_len */ dxfer_len,
5825 /* sense_len */ SSD_FULL_SIZE,
5826 /* timeout */ use_timeout);
5828 /* Disable freezing the device queue */
5829 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5831 if (arglist & CAM_ARG_ERR_RECOVER)
5832 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5834 if (((retval = cam_send_ccb(device, ccb)) < 0)
5835 || ((immediate == 0)
5836 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5837 const char errstr[] = "error sending sanitize command";
5844 if (arglist & CAM_ARG_VERBOSE) {
5845 cam_error_print(device, ccb, CAM_ESF_ALL,
5846 CAM_EPF_ALL, stderr);
5849 goto scsisanitize_bailout;
5853 * If we ran in non-immediate mode, we already checked for errors
5854 * above and printed out any necessary information. If we're in
5855 * immediate mode, we need to loop through and get status
5856 * information periodically.
5858 if (immediate == 0) {
5860 fprintf(stdout, "Sanitize Complete\n");
5862 goto scsisanitize_bailout;
5869 bzero(&(&ccb->ccb_h)[1],
5870 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5873 * There's really no need to do error recovery or
5874 * retries here, since we're just going to sit in a
5875 * loop and wait for the device to finish sanitizing.
5877 scsi_test_unit_ready(&ccb->csio,
5880 /* tag_action */ MSG_SIMPLE_Q_TAG,
5881 /* sense_len */ SSD_FULL_SIZE,
5882 /* timeout */ 5000);
5884 /* Disable freezing the device queue */
5885 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5887 retval = cam_send_ccb(device, ccb);
5890 * If we get an error from the ioctl, bail out. SCSI
5891 * errors are expected.
5894 warn("error sending CAMIOCOMMAND ioctl");
5895 if (arglist & CAM_ARG_VERBOSE) {
5896 cam_error_print(device, ccb, CAM_ESF_ALL,
5897 CAM_EPF_ALL, stderr);
5900 goto scsisanitize_bailout;
5903 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5905 if ((status != CAM_REQ_CMP)
5906 && (status == CAM_SCSI_STATUS_ERROR)
5907 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5908 struct scsi_sense_data *sense;
5909 int error_code, sense_key, asc, ascq;
5911 sense = &ccb->csio.sense_data;
5912 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5913 ccb->csio.sense_resid, &error_code, &sense_key,
5914 &asc, &ascq, /*show_errors*/ 1);
5917 * According to the SCSI-3 spec, a drive that is in the
5918 * middle of a sanitize should return NOT READY with an
5919 * ASC of "logical unit not ready, sanitize in
5920 * progress". The sense key specific bytes will then
5921 * be a progress indicator.
5923 if ((sense_key == SSD_KEY_NOT_READY)
5924 && (asc == 0x04) && (ascq == 0x1b)) {
5927 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5928 ccb->csio.sense_resid, sks) == 0)
5931 u_int64_t percentage;
5933 val = scsi_2btoul(&sks[1]);
5934 percentage = 10000 * val;
5937 "\rSanitizing: %ju.%02u %% "
5939 (uintmax_t)(percentage /
5941 (unsigned)((percentage /
5945 } else if ((quiet == 0)
5946 && (++num_warnings <= 1)) {
5947 warnx("Unexpected SCSI Sense Key "
5948 "Specific value returned "
5949 "during sanitize:");
5950 scsi_sense_print(device, &ccb->csio,
5952 warnx("Unable to print status "
5953 "information, but sanitze will "
5955 warnx("will exit when sanitize is "
5960 warnx("Unexpected SCSI error during sanitize");
5961 cam_error_print(device, ccb, CAM_ESF_ALL,
5962 CAM_EPF_ALL, stderr);
5964 goto scsisanitize_bailout;
5967 } else if (status != CAM_REQ_CMP) {
5968 warnx("Unexpected CAM status %#x", status);
5969 if (arglist & CAM_ARG_VERBOSE)
5970 cam_error_print(device, ccb, CAM_ESF_ALL,
5971 CAM_EPF_ALL, stderr);
5973 goto scsisanitize_bailout;
5975 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5978 fprintf(stdout, "\nSanitize Complete\n");
5980 scsisanitize_bailout:
5983 if (data_ptr != NULL)
5991 scsireportluns(struct cam_device *device, int argc, char **argv,
5992 char *combinedopt, int retry_count, int timeout)
5995 int c, countonly, lunsonly;
5996 struct scsi_report_luns_data *lundata;
5998 uint8_t report_type;
5999 uint32_t list_len, i, j;
6004 report_type = RPL_REPORT_DEFAULT;
6005 ccb = cam_getccb(device);
6008 warnx("%s: error allocating ccb", __func__);
6012 bzero(&(&ccb->ccb_h)[1],
6013 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6018 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6027 if (strcasecmp(optarg, "default") == 0)
6028 report_type = RPL_REPORT_DEFAULT;
6029 else if (strcasecmp(optarg, "wellknown") == 0)
6030 report_type = RPL_REPORT_WELLKNOWN;
6031 else if (strcasecmp(optarg, "all") == 0)
6032 report_type = RPL_REPORT_ALL;
6034 warnx("%s: invalid report type \"%s\"",
6045 if ((countonly != 0)
6046 && (lunsonly != 0)) {
6047 warnx("%s: you can only specify one of -c or -l", __func__);
6052 * According to SPC-4, the allocation length must be at least 16
6053 * bytes -- enough for the header and one LUN.
6055 alloc_len = sizeof(*lundata) + 8;
6059 lundata = malloc(alloc_len);
6061 if (lundata == NULL) {
6062 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6067 scsi_report_luns(&ccb->csio,
6068 /*retries*/ retry_count,
6070 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6071 /*select_report*/ report_type,
6072 /*rpl_buf*/ lundata,
6073 /*alloc_len*/ alloc_len,
6074 /*sense_len*/ SSD_FULL_SIZE,
6075 /*timeout*/ timeout ? timeout : 5000);
6077 /* Disable freezing the device queue */
6078 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6080 if (arglist & CAM_ARG_ERR_RECOVER)
6081 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6083 if (cam_send_ccb(device, ccb) < 0) {
6084 warn("error sending REPORT LUNS command");
6086 if (arglist & CAM_ARG_VERBOSE)
6087 cam_error_print(device, ccb, CAM_ESF_ALL,
6088 CAM_EPF_ALL, stderr);
6094 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6095 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6101 list_len = scsi_4btoul(lundata->length);
6104 * If we need to list the LUNs, and our allocation
6105 * length was too short, reallocate and retry.
6107 if ((countonly == 0)
6108 && (list_len > (alloc_len - sizeof(*lundata)))) {
6109 alloc_len = list_len + sizeof(*lundata);
6115 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6116 ((list_len / 8) > 1) ? "s" : "");
6121 for (i = 0; i < (list_len / 8); i++) {
6125 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6127 fprintf(stdout, ",");
6128 switch (lundata->luns[i].lundata[j] &
6129 RPL_LUNDATA_ATYP_MASK) {
6130 case RPL_LUNDATA_ATYP_PERIPH:
6131 if ((lundata->luns[i].lundata[j] &
6132 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6133 fprintf(stdout, "%d:",
6134 lundata->luns[i].lundata[j] &
6135 RPL_LUNDATA_PERIPH_BUS_MASK);
6137 && ((lundata->luns[i].lundata[j+2] &
6138 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6141 fprintf(stdout, "%d",
6142 lundata->luns[i].lundata[j+1]);
6144 case RPL_LUNDATA_ATYP_FLAT: {
6146 tmplun[0] = lundata->luns[i].lundata[j] &
6147 RPL_LUNDATA_FLAT_LUN_MASK;
6148 tmplun[1] = lundata->luns[i].lundata[j+1];
6150 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6154 case RPL_LUNDATA_ATYP_LUN:
6155 fprintf(stdout, "%d:%d:%d",
6156 (lundata->luns[i].lundata[j+1] &
6157 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6158 lundata->luns[i].lundata[j] &
6159 RPL_LUNDATA_LUN_TARG_MASK,
6160 lundata->luns[i].lundata[j+1] &
6161 RPL_LUNDATA_LUN_LUN_MASK);
6163 case RPL_LUNDATA_ATYP_EXTLUN: {
6164 int field_len_code, eam_code;
6166 eam_code = lundata->luns[i].lundata[j] &
6167 RPL_LUNDATA_EXT_EAM_MASK;
6168 field_len_code = (lundata->luns[i].lundata[j] &
6169 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6171 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6172 && (field_len_code == 0x00)) {
6173 fprintf(stdout, "%d",
6174 lundata->luns[i].lundata[j+1]);
6175 } else if ((eam_code ==
6176 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6177 && (field_len_code == 0x03)) {
6181 * This format takes up all 8 bytes.
6182 * If we aren't starting at offset 0,
6186 fprintf(stdout, "Invalid "
6189 "specified format", j);
6193 bzero(tmp_lun, sizeof(tmp_lun));
6194 bcopy(&lundata->luns[i].lundata[j+1],
6195 &tmp_lun[1], sizeof(tmp_lun) - 1);
6196 fprintf(stdout, "%#jx",
6197 (intmax_t)scsi_8btou64(tmp_lun));
6200 fprintf(stderr, "Unknown Extended LUN"
6201 "Address method %#x, length "
6202 "code %#x", eam_code,
6209 fprintf(stderr, "Unknown LUN address method "
6210 "%#x\n", lundata->luns[i].lundata[0] &
6211 RPL_LUNDATA_ATYP_MASK);
6215 * For the flat addressing method, there are no
6216 * other levels after it.
6221 fprintf(stdout, "\n");
6234 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6235 char *combinedopt, int retry_count, int timeout)
6238 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6239 struct scsi_read_capacity_data rcap;
6240 struct scsi_read_capacity_data_long rcaplong;
6254 ccb = cam_getccb(device);
6257 warnx("%s: error allocating ccb", __func__);
6261 bzero(&(&ccb->ccb_h)[1],
6262 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6264 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6291 if ((blocksizeonly != 0)
6292 && (numblocks != 0)) {
6293 warnx("%s: you can only specify one of -b or -N", __func__);
6298 if ((blocksizeonly != 0)
6299 && (sizeonly != 0)) {
6300 warnx("%s: you can only specify one of -b or -s", __func__);
6307 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6313 && (blocksizeonly != 0)) {
6314 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6319 scsi_read_capacity(&ccb->csio,
6320 /*retries*/ retry_count,
6322 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6325 /*timeout*/ timeout ? timeout : 5000);
6327 /* Disable freezing the device queue */
6328 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6330 if (arglist & CAM_ARG_ERR_RECOVER)
6331 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6333 if (cam_send_ccb(device, ccb) < 0) {
6334 warn("error sending READ CAPACITY command");
6336 if (arglist & CAM_ARG_VERBOSE)
6337 cam_error_print(device, ccb, CAM_ESF_ALL,
6338 CAM_EPF_ALL, stderr);
6344 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6345 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6350 maxsector = scsi_4btoul(rcap.addr);
6351 block_len = scsi_4btoul(rcap.length);
6354 * A last block of 2^32-1 means that the true capacity is over 2TB,
6355 * and we need to issue the long READ CAPACITY to get the real
6356 * capacity. Otherwise, we're all set.
6358 if (maxsector != 0xffffffff)
6361 scsi_read_capacity_16(&ccb->csio,
6362 /*retries*/ retry_count,
6364 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6368 /*rcap_buf*/ (uint8_t *)&rcaplong,
6369 /*rcap_buf_len*/ sizeof(rcaplong),
6370 /*sense_len*/ SSD_FULL_SIZE,
6371 /*timeout*/ timeout ? timeout : 5000);
6373 /* Disable freezing the device queue */
6374 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6376 if (arglist & CAM_ARG_ERR_RECOVER)
6377 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6379 if (cam_send_ccb(device, ccb) < 0) {
6380 warn("error sending READ CAPACITY (16) command");
6382 if (arglist & CAM_ARG_VERBOSE)
6383 cam_error_print(device, ccb, CAM_ESF_ALL,
6384 CAM_EPF_ALL, stderr);
6390 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6391 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6396 maxsector = scsi_8btou64(rcaplong.addr);
6397 block_len = scsi_4btoul(rcaplong.length);
6400 if (blocksizeonly == 0) {
6402 * Humanize implies !quiet, and also implies numblocks.
6404 if (humanize != 0) {
6409 tmpbytes = (maxsector + 1) * block_len;
6410 ret = humanize_number(tmpstr, sizeof(tmpstr),
6411 tmpbytes, "", HN_AUTOSCALE,
6414 HN_DIVISOR_1000 : 0));
6416 warnx("%s: humanize_number failed!", __func__);
6420 fprintf(stdout, "Device Size: %s%s", tmpstr,
6421 (sizeonly == 0) ? ", " : "\n");
6422 } else if (numblocks != 0) {
6423 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6424 "Blocks: " : "", (uintmax_t)maxsector + 1,
6425 (sizeonly == 0) ? ", " : "\n");
6427 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6428 "Last Block: " : "", (uintmax_t)maxsector,
6429 (sizeonly == 0) ? ", " : "\n");
6433 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6434 "Block Length: " : "", block_len, (quiet == 0) ?
6443 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6444 int retry_count, int timeout)
6448 uint8_t *smp_request = NULL, *smp_response = NULL;
6449 int request_size = 0, response_size = 0;
6450 int fd_request = 0, fd_response = 0;
6451 char *datastr = NULL;
6452 struct get_hook hook;
6457 * Note that at the moment we don't support sending SMP CCBs to
6458 * devices that aren't probed by CAM.
6460 ccb = cam_getccb(device);
6462 warnx("%s: error allocating CCB", __func__);
6466 bzero(&(&ccb->ccb_h)[1],
6467 sizeof(union ccb) - sizeof(struct ccb_hdr));
6469 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6472 arglist |= CAM_ARG_CMD_IN;
6473 response_size = strtol(optarg, NULL, 0);
6474 if (response_size <= 0) {
6475 warnx("invalid number of response bytes %d",
6478 goto smpcmd_bailout;
6480 hook.argc = argc - optind;
6481 hook.argv = argv + optind;
6484 datastr = cget(&hook, NULL);
6486 * If the user supplied "-" instead of a format, he
6487 * wants the data to be written to stdout.
6489 if ((datastr != NULL)
6490 && (datastr[0] == '-'))
6493 smp_response = (u_int8_t *)malloc(response_size);
6494 if (smp_response == NULL) {
6495 warn("can't malloc memory for SMP response");
6497 goto smpcmd_bailout;
6501 arglist |= CAM_ARG_CMD_OUT;
6502 request_size = strtol(optarg, NULL, 0);
6503 if (request_size <= 0) {
6504 warnx("invalid number of request bytes %d",
6507 goto smpcmd_bailout;
6509 hook.argc = argc - optind;
6510 hook.argv = argv + optind;
6512 datastr = cget(&hook, NULL);
6513 smp_request = (u_int8_t *)malloc(request_size);
6514 if (smp_request == NULL) {
6515 warn("can't malloc memory for SMP request");
6517 goto smpcmd_bailout;
6519 bzero(smp_request, request_size);
6521 * If the user supplied "-" instead of a format, he
6522 * wants the data to be read from stdin.
6524 if ((datastr != NULL)
6525 && (datastr[0] == '-'))
6528 buff_encode_visit(smp_request, request_size,
6539 * If fd_data is set, and we're writing to the device, we need to
6540 * read the data the user wants written from stdin.
6542 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6544 int amt_to_read = request_size;
6545 u_int8_t *buf_ptr = smp_request;
6547 for (amt_read = 0; amt_to_read > 0;
6548 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6549 if (amt_read == -1) {
6550 warn("error reading data from stdin");
6552 goto smpcmd_bailout;
6554 amt_to_read -= amt_read;
6555 buf_ptr += amt_read;
6559 if (((arglist & CAM_ARG_CMD_IN) == 0)
6560 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6561 warnx("%s: need both the request (-r) and response (-R) "
6562 "arguments", __func__);
6564 goto smpcmd_bailout;
6567 flags |= CAM_DEV_QFRZDIS;
6569 cam_fill_smpio(&ccb->smpio,
6570 /*retries*/ retry_count,
6573 /*smp_request*/ smp_request,
6574 /*smp_request_len*/ request_size,
6575 /*smp_response*/ smp_response,
6576 /*smp_response_len*/ response_size,
6577 /*timeout*/ timeout ? timeout : 5000);
6579 ccb->smpio.flags = SMP_FLAG_NONE;
6581 if (((retval = cam_send_ccb(device, ccb)) < 0)
6582 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6583 const char warnstr[] = "error sending command";
6590 if (arglist & CAM_ARG_VERBOSE) {
6591 cam_error_print(device, ccb, CAM_ESF_ALL,
6592 CAM_EPF_ALL, stderr);
6596 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6597 && (response_size > 0)) {
6598 if (fd_response == 0) {
6599 buff_decode_visit(smp_response, response_size,
6600 datastr, arg_put, NULL);
6601 fprintf(stdout, "\n");
6603 ssize_t amt_written;
6604 int amt_to_write = response_size;
6605 u_int8_t *buf_ptr = smp_response;
6607 for (amt_written = 0; (amt_to_write > 0) &&
6608 (amt_written = write(STDOUT_FILENO, buf_ptr,
6609 amt_to_write)) > 0;){
6610 amt_to_write -= amt_written;
6611 buf_ptr += amt_written;
6613 if (amt_written == -1) {
6614 warn("error writing data to stdout");
6616 goto smpcmd_bailout;
6617 } else if ((amt_written == 0)
6618 && (amt_to_write > 0)) {
6619 warnx("only wrote %u bytes out of %u",
6620 response_size - amt_to_write,
6629 if (smp_request != NULL)
6632 if (smp_response != NULL)
6639 smpreportgeneral(struct cam_device *device, int argc, char **argv,
6640 char *combinedopt, int retry_count, int timeout)
6643 struct smp_report_general_request *request = NULL;
6644 struct smp_report_general_response *response = NULL;
6645 struct sbuf *sb = NULL;
6647 int c, long_response = 0;
6651 * Note that at the moment we don't support sending SMP CCBs to
6652 * devices that aren't probed by CAM.
6654 ccb = cam_getccb(device);
6656 warnx("%s: error allocating CCB", __func__);
6660 bzero(&(&ccb->ccb_h)[1],
6661 sizeof(union ccb) - sizeof(struct ccb_hdr));
6663 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6672 request = malloc(sizeof(*request));
6673 if (request == NULL) {
6674 warn("%s: unable to allocate %zd bytes", __func__,
6680 response = malloc(sizeof(*response));
6681 if (response == NULL) {
6682 warn("%s: unable to allocate %zd bytes", __func__,
6689 smp_report_general(&ccb->smpio,
6693 /*request_len*/ sizeof(*request),
6694 (uint8_t *)response,
6695 /*response_len*/ sizeof(*response),
6696 /*long_response*/ long_response,
6699 if (((retval = cam_send_ccb(device, ccb)) < 0)
6700 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6701 const char warnstr[] = "error sending command";
6708 if (arglist & CAM_ARG_VERBOSE) {
6709 cam_error_print(device, ccb, CAM_ESF_ALL,
6710 CAM_EPF_ALL, stderr);
6717 * If the device supports the long response bit, try again and see
6718 * if we can get all of the data.
6720 if ((response->long_response & SMP_RG_LONG_RESPONSE)
6721 && (long_response == 0)) {
6722 ccb->ccb_h.status = CAM_REQ_INPROG;
6723 bzero(&(&ccb->ccb_h)[1],
6724 sizeof(union ccb) - sizeof(struct ccb_hdr));
6730 * XXX KDM detect and decode SMP errors here.
6732 sb = sbuf_new_auto();
6734 warnx("%s: error allocating sbuf", __func__);
6738 smp_report_general_sbuf(response, sizeof(*response), sb);
6740 if (sbuf_finish(sb) != 0) {
6741 warnx("%s: sbuf_finish", __func__);
6745 printf("%s", sbuf_data(sb));
6751 if (request != NULL)
6754 if (response != NULL)
6763 static struct camcontrol_opts phy_ops[] = {
6764 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
6765 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
6766 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
6767 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
6768 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
6769 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
6770 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
6771 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
6772 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
6777 smpphycontrol(struct cam_device *device, int argc, char **argv,
6778 char *combinedopt, int retry_count, int timeout)
6781 struct smp_phy_control_request *request = NULL;
6782 struct smp_phy_control_response *response = NULL;
6783 int long_response = 0;
6786 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
6788 uint64_t attached_dev_name = 0;
6789 int dev_name_set = 0;
6790 uint32_t min_plr = 0, max_plr = 0;
6791 uint32_t pp_timeout_val = 0;
6792 int slumber_partial = 0;
6793 int set_pp_timeout_val = 0;
6797 * Note that at the moment we don't support sending SMP CCBs to
6798 * devices that aren't probed by CAM.
6800 ccb = cam_getccb(device);
6802 warnx("%s: error allocating CCB", __func__);
6806 bzero(&(&ccb->ccb_h)[1],
6807 sizeof(union ccb) - sizeof(struct ccb_hdr));
6809 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6817 if (strcasecmp(optarg, "enable") == 0)
6819 else if (strcasecmp(optarg, "disable") == 0)
6822 warnx("%s: Invalid argument %s", __func__,
6829 slumber_partial |= enable <<
6830 SMP_PC_SAS_SLUMBER_SHIFT;
6833 slumber_partial |= enable <<
6834 SMP_PC_SAS_PARTIAL_SHIFT;
6837 slumber_partial |= enable <<
6838 SMP_PC_SATA_SLUMBER_SHIFT;
6841 slumber_partial |= enable <<
6842 SMP_PC_SATA_PARTIAL_SHIFT;
6845 warnx("%s: programmer error", __func__);
6848 break; /*NOTREACHED*/
6853 attached_dev_name = (uintmax_t)strtoumax(optarg,
6862 * We don't do extensive checking here, so this
6863 * will continue to work when new speeds come out.
6865 min_plr = strtoul(optarg, NULL, 0);
6867 || (min_plr > 0xf)) {
6868 warnx("%s: invalid link rate %x",
6876 * We don't do extensive checking here, so this
6877 * will continue to work when new speeds come out.
6879 max_plr = strtoul(optarg, NULL, 0);
6881 || (max_plr > 0xf)) {
6882 warnx("%s: invalid link rate %x",
6889 camcontrol_optret optreturn;
6890 cam_argmask argnums;
6893 if (phy_op_set != 0) {
6894 warnx("%s: only one phy operation argument "
6895 "(-o) allowed", __func__);
6903 * Allow the user to specify the phy operation
6904 * numerically, as well as with a name. This will
6905 * future-proof it a bit, so options that are added
6906 * in future specs can be used.
6908 if (isdigit(optarg[0])) {
6909 phy_operation = strtoul(optarg, NULL, 0);
6910 if ((phy_operation == 0)
6911 || (phy_operation > 0xff)) {
6912 warnx("%s: invalid phy operation %#x",
6913 __func__, phy_operation);
6919 optreturn = getoption(phy_ops, optarg, &phy_operation,
6922 if (optreturn == CC_OR_AMBIGUOUS) {
6923 warnx("%s: ambiguous option %s", __func__,
6928 } else if (optreturn == CC_OR_NOT_FOUND) {
6929 warnx("%s: option %s not found", __func__,
6941 pp_timeout_val = strtoul(optarg, NULL, 0);
6942 if (pp_timeout_val > 15) {
6943 warnx("%s: invalid partial pathway timeout "
6944 "value %u, need a value less than 16",
6945 __func__, pp_timeout_val);
6949 set_pp_timeout_val = 1;
6957 warnx("%s: a PHY (-p phy) argument is required",__func__);
6962 if (((dev_name_set != 0)
6963 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
6964 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
6965 && (dev_name_set == 0))) {
6966 warnx("%s: -d name and -o setdevname arguments both "
6967 "required to set device name", __func__);
6972 request = malloc(sizeof(*request));
6973 if (request == NULL) {
6974 warn("%s: unable to allocate %zd bytes", __func__,
6980 response = malloc(sizeof(*response));
6981 if (response == NULL) {
6982 warn("%s: unable to allocate %zd bytes", __func__,
6988 smp_phy_control(&ccb->smpio,
6993 (uint8_t *)response,
6996 /*expected_exp_change_count*/ 0,
6999 (set_pp_timeout_val != 0) ? 1 : 0,
7007 if (((retval = cam_send_ccb(device, ccb)) < 0)
7008 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7009 const char warnstr[] = "error sending command";
7016 if (arglist & CAM_ARG_VERBOSE) {
7018 * Use CAM_EPF_NORMAL so we only get one line of
7019 * SMP command decoding.
7021 cam_error_print(device, ccb, CAM_ESF_ALL,
7022 CAM_EPF_NORMAL, stderr);
7028 /* XXX KDM print out something here for success? */
7033 if (request != NULL)
7036 if (response != NULL)
7043 smpmaninfo(struct cam_device *device, int argc, char **argv,
7044 char *combinedopt, int retry_count, int timeout)
7047 struct smp_report_manuf_info_request request;
7048 struct smp_report_manuf_info_response response;
7049 struct sbuf *sb = NULL;
7050 int long_response = 0;
7055 * Note that at the moment we don't support sending SMP CCBs to
7056 * devices that aren't probed by CAM.
7058 ccb = cam_getccb(device);
7060 warnx("%s: error allocating CCB", __func__);
7064 bzero(&(&ccb->ccb_h)[1],
7065 sizeof(union ccb) - sizeof(struct ccb_hdr));
7067 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7076 bzero(&request, sizeof(request));
7077 bzero(&response, sizeof(response));
7079 smp_report_manuf_info(&ccb->smpio,
7084 (uint8_t *)&response,
7089 if (((retval = cam_send_ccb(device, ccb)) < 0)
7090 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7091 const char warnstr[] = "error sending command";
7098 if (arglist & CAM_ARG_VERBOSE) {
7099 cam_error_print(device, ccb, CAM_ESF_ALL,
7100 CAM_EPF_ALL, stderr);
7106 sb = sbuf_new_auto();
7108 warnx("%s: error allocating sbuf", __func__);
7112 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7114 if (sbuf_finish(sb) != 0) {
7115 warnx("%s: sbuf_finish", __func__);
7119 printf("%s", sbuf_data(sb));
7133 getdevid(struct cam_devitem *item)
7136 union ccb *ccb = NULL;
7138 struct cam_device *dev;
7140 dev = cam_open_btl(item->dev_match.path_id,
7141 item->dev_match.target_id,
7142 item->dev_match.target_lun, O_RDWR, NULL);
7145 warnx("%s", cam_errbuf);
7150 item->device_id_len = 0;
7152 ccb = cam_getccb(dev);
7154 warnx("%s: error allocating CCB", __func__);
7159 bzero(&(&ccb->ccb_h)[1],
7160 sizeof(union ccb) - sizeof(struct ccb_hdr));
7163 * On the first try, we just probe for the size of the data, and
7164 * then allocate that much memory and try again.
7167 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7168 ccb->ccb_h.flags = CAM_DIR_IN;
7169 ccb->cdai.flags = 0;
7170 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7171 ccb->cdai.bufsiz = item->device_id_len;
7172 if (item->device_id_len != 0)
7173 ccb->cdai.buf = (uint8_t *)item->device_id;
7175 if (cam_send_ccb(dev, ccb) < 0) {
7176 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7181 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7182 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7187 if (item->device_id_len == 0) {
7189 * This is our first time through. Allocate the buffer,
7190 * and then go back to get the data.
7192 if (ccb->cdai.provsiz == 0) {
7193 warnx("%s: invalid .provsiz field returned with "
7194 "XPT_GDEV_ADVINFO CCB", __func__);
7198 item->device_id_len = ccb->cdai.provsiz;
7199 item->device_id = malloc(item->device_id_len);
7200 if (item->device_id == NULL) {
7201 warn("%s: unable to allocate %d bytes", __func__,
7202 item->device_id_len);
7206 ccb->ccb_h.status = CAM_REQ_INPROG;
7212 cam_close_device(dev);
7221 * XXX KDM merge this code with getdevtree()?
7224 buildbusdevlist(struct cam_devlist *devlist)
7227 int bufsize, fd = -1;
7228 struct dev_match_pattern *patterns;
7229 struct cam_devitem *item = NULL;
7230 int skip_device = 0;
7233 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7234 warn("couldn't open %s", XPT_DEVICE);
7238 bzero(&ccb, sizeof(union ccb));
7240 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7241 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7242 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7244 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7245 bufsize = sizeof(struct dev_match_result) * 100;
7246 ccb.cdm.match_buf_len = bufsize;
7247 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7248 if (ccb.cdm.matches == NULL) {
7249 warnx("can't malloc memory for matches");
7253 ccb.cdm.num_matches = 0;
7254 ccb.cdm.num_patterns = 2;
7255 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7256 ccb.cdm.num_patterns;
7258 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7259 if (patterns == NULL) {
7260 warnx("can't malloc memory for patterns");
7265 ccb.cdm.patterns = patterns;
7266 bzero(patterns, ccb.cdm.pattern_buf_len);
7268 patterns[0].type = DEV_MATCH_DEVICE;
7269 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7270 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7271 patterns[1].type = DEV_MATCH_PERIPH;
7272 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7273 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7276 * We do the ioctl multiple times if necessary, in case there are
7277 * more than 100 nodes in the EDT.
7282 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7283 warn("error sending CAMIOCOMMAND ioctl");
7288 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7289 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7290 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7291 warnx("got CAM error %#x, CDM error %d\n",
7292 ccb.ccb_h.status, ccb.cdm.status);
7297 for (i = 0; i < ccb.cdm.num_matches; i++) {
7298 switch (ccb.cdm.matches[i].type) {
7299 case DEV_MATCH_DEVICE: {
7300 struct device_match_result *dev_result;
7303 &ccb.cdm.matches[i].result.device_result;
7305 if (dev_result->flags &
7306 DEV_RESULT_UNCONFIGURED) {
7312 item = malloc(sizeof(*item));
7314 warn("%s: unable to allocate %zd bytes",
7315 __func__, sizeof(*item));
7319 bzero(item, sizeof(*item));
7320 bcopy(dev_result, &item->dev_match,
7321 sizeof(*dev_result));
7322 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7325 if (getdevid(item) != 0) {
7331 case DEV_MATCH_PERIPH: {
7332 struct periph_match_result *periph_result;
7335 &ccb.cdm.matches[i].result.periph_result;
7337 if (skip_device != 0)
7339 item->num_periphs++;
7340 item->periph_matches = realloc(
7341 item->periph_matches,
7343 sizeof(struct periph_match_result));
7344 if (item->periph_matches == NULL) {
7345 warn("%s: error allocating periph "
7350 bcopy(periph_result, &item->periph_matches[
7351 item->num_periphs - 1],
7352 sizeof(*periph_result));
7356 fprintf(stderr, "%s: unexpected match "
7357 "type %d\n", __func__,
7358 ccb.cdm.matches[i].type);
7361 break; /*NOTREACHED*/
7364 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7365 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7373 free(ccb.cdm.matches);
7376 freebusdevlist(devlist);
7382 freebusdevlist(struct cam_devlist *devlist)
7384 struct cam_devitem *item, *item2;
7386 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7387 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7389 free(item->device_id);
7390 free(item->periph_matches);
7395 static struct cam_devitem *
7396 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7398 struct cam_devitem *item;
7400 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7401 struct scsi_vpd_id_descriptor *idd;
7404 * XXX KDM look for LUN IDs as well?
7406 idd = scsi_get_devid(item->device_id,
7407 item->device_id_len,
7408 scsi_devid_is_sas_target);
7412 if (scsi_8btou64(idd->identifier) == sasaddr)
7420 smpphylist(struct cam_device *device, int argc, char **argv,
7421 char *combinedopt, int retry_count, int timeout)
7423 struct smp_report_general_request *rgrequest = NULL;
7424 struct smp_report_general_response *rgresponse = NULL;
7425 struct smp_discover_request *disrequest = NULL;
7426 struct smp_discover_response *disresponse = NULL;
7427 struct cam_devlist devlist;
7429 int long_response = 0;
7436 * Note that at the moment we don't support sending SMP CCBs to
7437 * devices that aren't probed by CAM.
7439 ccb = cam_getccb(device);
7441 warnx("%s: error allocating CCB", __func__);
7445 bzero(&(&ccb->ccb_h)[1],
7446 sizeof(union ccb) - sizeof(struct ccb_hdr));
7447 STAILQ_INIT(&devlist.dev_queue);
7449 rgrequest = malloc(sizeof(*rgrequest));
7450 if (rgrequest == NULL) {
7451 warn("%s: unable to allocate %zd bytes", __func__,
7452 sizeof(*rgrequest));
7457 rgresponse = malloc(sizeof(*rgresponse));
7458 if (rgresponse == NULL) {
7459 warn("%s: unable to allocate %zd bytes", __func__,
7460 sizeof(*rgresponse));
7465 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7478 smp_report_general(&ccb->smpio,
7482 /*request_len*/ sizeof(*rgrequest),
7483 (uint8_t *)rgresponse,
7484 /*response_len*/ sizeof(*rgresponse),
7485 /*long_response*/ long_response,
7488 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7490 if (((retval = cam_send_ccb(device, ccb)) < 0)
7491 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7492 const char warnstr[] = "error sending command";
7499 if (arglist & CAM_ARG_VERBOSE) {
7500 cam_error_print(device, ccb, CAM_ESF_ALL,
7501 CAM_EPF_ALL, stderr);
7507 num_phys = rgresponse->num_phys;
7509 if (num_phys == 0) {
7511 fprintf(stdout, "%s: No Phys reported\n", __func__);
7516 devlist.path_id = device->path_id;
7518 retval = buildbusdevlist(&devlist);
7523 fprintf(stdout, "%d PHYs:\n", num_phys);
7524 fprintf(stdout, "PHY Attached SAS Address\n");
7527 disrequest = malloc(sizeof(*disrequest));
7528 if (disrequest == NULL) {
7529 warn("%s: unable to allocate %zd bytes", __func__,
7530 sizeof(*disrequest));
7535 disresponse = malloc(sizeof(*disresponse));
7536 if (disresponse == NULL) {
7537 warn("%s: unable to allocate %zd bytes", __func__,
7538 sizeof(*disresponse));
7543 for (i = 0; i < num_phys; i++) {
7544 struct cam_devitem *item;
7545 struct device_match_result *dev_match;
7546 char vendor[16], product[48], revision[16];
7550 bzero(&(&ccb->ccb_h)[1],
7551 sizeof(union ccb) - sizeof(struct ccb_hdr));
7553 ccb->ccb_h.status = CAM_REQ_INPROG;
7554 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7556 smp_discover(&ccb->smpio,
7560 sizeof(*disrequest),
7561 (uint8_t *)disresponse,
7562 sizeof(*disresponse),
7564 /*ignore_zone_group*/ 0,
7568 if (((retval = cam_send_ccb(device, ccb)) < 0)
7569 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7570 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7571 const char warnstr[] = "error sending command";
7578 if (arglist & CAM_ARG_VERBOSE) {
7579 cam_error_print(device, ccb, CAM_ESF_ALL,
7580 CAM_EPF_ALL, stderr);
7586 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7588 fprintf(stdout, "%3d <vacant>\n", i);
7592 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7595 item = findsasdevice(&devlist,
7596 scsi_8btou64(disresponse->attached_sas_address));
7600 || (item != NULL)) {
7601 fprintf(stdout, "%3d 0x%016jx", i,
7602 (uintmax_t)scsi_8btou64(
7603 disresponse->attached_sas_address));
7605 fprintf(stdout, "\n");
7608 } else if (quiet != 0)
7611 dev_match = &item->dev_match;
7613 if (dev_match->protocol == PROTO_SCSI) {
7614 cam_strvis(vendor, dev_match->inq_data.vendor,
7615 sizeof(dev_match->inq_data.vendor),
7617 cam_strvis(product, dev_match->inq_data.product,
7618 sizeof(dev_match->inq_data.product),
7620 cam_strvis(revision, dev_match->inq_data.revision,
7621 sizeof(dev_match->inq_data.revision),
7623 sprintf(tmpstr, "<%s %s %s>", vendor, product,
7625 } else if ((dev_match->protocol == PROTO_ATA)
7626 || (dev_match->protocol == PROTO_SATAPM)) {
7627 cam_strvis(product, dev_match->ident_data.model,
7628 sizeof(dev_match->ident_data.model),
7630 cam_strvis(revision, dev_match->ident_data.revision,
7631 sizeof(dev_match->ident_data.revision),
7633 sprintf(tmpstr, "<%s %s>", product, revision);
7635 sprintf(tmpstr, "<>");
7637 fprintf(stdout, " %-33s ", tmpstr);
7640 * If we have 0 periphs, that's a bug...
7642 if (item->num_periphs == 0) {
7643 fprintf(stdout, "\n");
7647 fprintf(stdout, "(");
7648 for (j = 0; j < item->num_periphs; j++) {
7650 fprintf(stdout, ",");
7652 fprintf(stdout, "%s%d",
7653 item->periph_matches[j].periph_name,
7654 item->periph_matches[j].unit_number);
7657 fprintf(stdout, ")\n");
7671 freebusdevlist(&devlist);
7677 atapm(struct cam_device *device, int argc, char **argv,
7678 char *combinedopt, int retry_count, int timeout)
7686 ccb = cam_getccb(device);
7689 warnx("%s: error allocating ccb", __func__);
7693 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7702 if (strcmp(argv[1], "idle") == 0) {
7704 cmd = ATA_IDLE_IMMEDIATE;
7707 } else if (strcmp(argv[1], "standby") == 0) {
7709 cmd = ATA_STANDBY_IMMEDIATE;
7711 cmd = ATA_STANDBY_CMD;
7719 else if (t <= (240 * 5))
7721 else if (t <= (252 * 5))
7722 /* special encoding for 21 minutes */
7724 else if (t <= (11 * 30 * 60))
7725 sc = (t - 1) / (30 * 60) + 241;
7729 cam_fill_ataio(&ccb->ataio,
7732 /*flags*/CAM_DIR_NONE,
7736 timeout ? timeout : 30 * 1000);
7737 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
7739 /* Disable freezing the device queue */
7740 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7742 if (arglist & CAM_ARG_ERR_RECOVER)
7743 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7745 if (cam_send_ccb(device, ccb) < 0) {
7746 warn("error sending command");
7748 if (arglist & CAM_ARG_VERBOSE)
7749 cam_error_print(device, ccb, CAM_ESF_ALL,
7750 CAM_EPF_ALL, stderr);
7756 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7757 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7766 #endif /* MINIMALISTIC */
7769 usage(int printlong)
7772 fprintf(printlong ? stdout : stderr,
7773 "usage: camcontrol <command> [device id][generic args][command args]\n"
7774 " camcontrol devlist [-v]\n"
7775 #ifndef MINIMALISTIC
7776 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
7777 " camcontrol tur [dev_id][generic args]\n"
7778 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
7779 " camcontrol identify [dev_id][generic args] [-v]\n"
7780 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
7781 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
7783 " camcontrol start [dev_id][generic args]\n"
7784 " camcontrol stop [dev_id][generic args]\n"
7785 " camcontrol load [dev_id][generic args]\n"
7786 " camcontrol eject [dev_id][generic args]\n"
7787 #endif /* MINIMALISTIC */
7788 " camcontrol rescan <all | bus[:target:lun]>\n"
7789 " camcontrol reset <all | bus[:target:lun]>\n"
7790 #ifndef MINIMALISTIC
7791 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
7792 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
7793 " [-P pagectl][-e | -b][-d]\n"
7794 " camcontrol cmd [dev_id][generic args]\n"
7795 " <-a cmd [args] | -c cmd [args]>\n"
7796 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
7797 " camcontrol smpcmd [dev_id][generic args]\n"
7798 " <-r len fmt [args]> <-R len fmt [args]>\n"
7799 " camcontrol smprg [dev_id][generic args][-l]\n"
7800 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
7801 " [-o operation][-d name][-m rate][-M rate]\n"
7802 " [-T pp_timeout][-a enable|disable]\n"
7803 " [-A enable|disable][-s enable|disable]\n"
7804 " [-S enable|disable]\n"
7805 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
7806 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
7807 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
7808 " <all|bus[:target[:lun]]|off>\n"
7809 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
7810 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
7811 " [-D <enable|disable>][-M mode][-O offset]\n"
7812 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
7813 " [-U][-W bus_width]\n"
7814 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
7815 " camcontrol sanitize [dev_id][generic args]\n"
7816 " [-a overwrite|block|crypto|exitfailure]\n"
7817 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
7819 " camcontrol idle [dev_id][generic args][-t time]\n"
7820 " camcontrol standby [dev_id][generic args][-t time]\n"
7821 " camcontrol sleep [dev_id][generic args]\n"
7822 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
7823 " camcontrol security [dev_id][generic args]\n"
7824 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
7825 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
7826 " [-U <user|master>] [-y]\n"
7827 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
7828 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
7829 #endif /* MINIMALISTIC */
7830 " camcontrol help\n");
7833 #ifndef MINIMALISTIC
7835 "Specify one of the following options:\n"
7836 "devlist list all CAM devices\n"
7837 "periphlist list all CAM peripheral drivers attached to a device\n"
7838 "tur send a test unit ready to the named device\n"
7839 "inquiry send a SCSI inquiry command to the named device\n"
7840 "identify send a ATA identify command to the named device\n"
7841 "reportluns send a SCSI report luns command to the device\n"
7842 "readcap send a SCSI read capacity command to the device\n"
7843 "start send a Start Unit command to the device\n"
7844 "stop send a Stop Unit command to the device\n"
7845 "load send a Start Unit command to the device with the load bit set\n"
7846 "eject send a Stop Unit command to the device with the eject bit set\n"
7847 "rescan rescan all busses, the given bus, or bus:target:lun\n"
7848 "reset reset all busses, the given bus, or bus:target:lun\n"
7849 "defects read the defect list of the specified device\n"
7850 "modepage display or edit (-e) the given mode page\n"
7851 "cmd send the given SCSI command, may need -i or -o as well\n"
7852 "smpcmd send the given SMP command, requires -o and -i\n"
7853 "smprg send the SMP Report General command\n"
7854 "smppc send the SMP PHY Control command, requires -p\n"
7855 "smpphylist display phys attached to a SAS expander\n"
7856 "smpmaninfo send the SMP Report Manufacturer Info command\n"
7857 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
7858 "tags report or set the number of transaction slots for a device\n"
7859 "negotiate report or set device negotiation parameters\n"
7860 "format send the SCSI FORMAT UNIT command to the named device\n"
7861 "sanitize send the SCSI SANITIZE command to the named device\n"
7862 "idle send the ATA IDLE command to the named device\n"
7863 "standby send the ATA STANDBY command to the named device\n"
7864 "sleep send the ATA SLEEP command to the named device\n"
7865 "fwdownload program firmware of the named device with the given image"
7866 "security report or send ATA security commands to the named device\n"
7867 "help this message\n"
7868 "Device Identifiers:\n"
7869 "bus:target specify the bus and target, lun defaults to 0\n"
7870 "bus:target:lun specify the bus, target and lun\n"
7871 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
7872 "Generic arguments:\n"
7873 "-v be verbose, print out sense information\n"
7874 "-t timeout command timeout in seconds, overrides default timeout\n"
7875 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
7876 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
7877 "-E have the kernel attempt to perform SCSI error recovery\n"
7878 "-C count specify the SCSI command retry count (needs -E to work)\n"
7879 "modepage arguments:\n"
7880 "-l list all available mode pages\n"
7881 "-m page specify the mode page to view or edit\n"
7882 "-e edit the specified mode page\n"
7883 "-b force view to binary mode\n"
7884 "-d disable block descriptors for mode sense\n"
7885 "-P pgctl page control field 0-3\n"
7886 "defects arguments:\n"
7887 "-f format specify defect list format (block, bfi or phys)\n"
7888 "-G get the grown defect list\n"
7889 "-P get the permanent defect list\n"
7890 "inquiry arguments:\n"
7891 "-D get the standard inquiry data\n"
7892 "-S get the serial number\n"
7893 "-R get the transfer rate, etc.\n"
7894 "reportluns arguments:\n"
7895 "-c only report a count of available LUNs\n"
7896 "-l only print out luns, and not a count\n"
7897 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
7898 "readcap arguments\n"
7899 "-b only report the blocksize\n"
7900 "-h human readable device size, base 2\n"
7901 "-H human readable device size, base 10\n"
7902 "-N print the number of blocks instead of last block\n"
7903 "-q quiet, print numbers only\n"
7904 "-s only report the last block/device size\n"
7906 "-c cdb [args] specify the SCSI CDB\n"
7907 "-i len fmt specify input data and input data format\n"
7908 "-o len fmt [args] specify output data and output data fmt\n"
7909 "smpcmd arguments:\n"
7910 "-r len fmt [args] specify the SMP command to be sent\n"
7911 "-R len fmt [args] specify SMP response format\n"
7912 "smprg arguments:\n"
7913 "-l specify the long response format\n"
7914 "smppc arguments:\n"
7915 "-p phy specify the PHY to operate on\n"
7916 "-l specify the long request/response format\n"
7917 "-o operation specify the phy control operation\n"
7918 "-d name set the attached device name\n"
7919 "-m rate set the minimum physical link rate\n"
7920 "-M rate set the maximum physical link rate\n"
7921 "-T pp_timeout set the partial pathway timeout value\n"
7922 "-a enable|disable enable or disable SATA slumber\n"
7923 "-A enable|disable enable or disable SATA partial phy power\n"
7924 "-s enable|disable enable or disable SAS slumber\n"
7925 "-S enable|disable enable or disable SAS partial phy power\n"
7926 "smpphylist arguments:\n"
7927 "-l specify the long response format\n"
7928 "-q only print phys with attached devices\n"
7929 "smpmaninfo arguments:\n"
7930 "-l specify the long response format\n"
7931 "debug arguments:\n"
7932 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
7933 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
7934 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
7935 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
7937 "-N tags specify the number of tags to use for this device\n"
7938 "-q be quiet, don't report the number of tags\n"
7939 "-v report a number of tag-related parameters\n"
7940 "negotiate arguments:\n"
7941 "-a send a test unit ready after negotiation\n"
7942 "-c report/set current negotiation settings\n"
7943 "-D <arg> \"enable\" or \"disable\" disconnection\n"
7944 "-M mode set ATA mode\n"
7945 "-O offset set command delay offset\n"
7946 "-q be quiet, don't report anything\n"
7947 "-R syncrate synchronization rate in MHz\n"
7948 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
7949 "-U report/set user negotiation settings\n"
7950 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
7951 "-v also print a Path Inquiry CCB for the controller\n"
7952 "format arguments:\n"
7953 "-q be quiet, don't print status messages\n"
7954 "-r run in report only mode\n"
7955 "-w don't send immediate format command\n"
7956 "-y don't ask any questions\n"
7957 "sanitize arguments:\n"
7958 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
7959 "-c passes overwrite passes to perform (1 to 31)\n"
7960 "-I invert overwrite pattern after each pass\n"
7961 "-P pattern path to overwrite pattern file\n"
7962 "-q be quiet, don't print status messages\n"
7963 "-r run in report only mode\n"
7964 "-U run operation in unrestricted completion exit mode\n"
7965 "-w don't send immediate sanitize command\n"
7966 "-y don't ask any questions\n"
7967 "idle/standby arguments:\n"
7968 "-t <arg> number of seconds before respective state.\n"
7969 "fwdownload arguments:\n"
7970 "-f fw_image path to firmware image file\n"
7971 "-y don't ask any questions\n"
7972 "-s run in simulation mode\n"
7973 "-v print info for every firmware segment sent to device\n"
7974 "security arguments:\n"
7975 "-d pwd disable security using the given password for the selected\n"
7977 "-e pwd erase the device using the given pwd for the selected user\n"
7978 "-f freeze the security configuration of the specified device\n"
7979 "-h pwd enhanced erase the device using the given pwd for the\n"
7981 "-k pwd unlock the device using the given pwd for the selected\n"
7983 "-l <high|maximum> specifies which security level to set: high or maximum\n"
7984 "-q be quiet, do not print any status messages\n"
7985 "-s pwd password the device (enable security) using the given\n"
7986 " pwd for the selected user\n"
7987 "-T timeout overrides the timeout (seconds) used for erase operation\n"
7988 "-U <user|master> specifies which user to set: user or master\n"
7989 "-y don't ask any questions\n"
7991 "-f freeze the HPA configuration of the device\n"
7992 "-l lock the HPA configuration of the device\n"
7993 "-P make the HPA max sectors persist\n"
7994 "-p pwd Set the HPA configuration password required for unlock\n"
7996 "-q be quiet, do not print any status messages\n"
7997 "-s sectors configures the maximum user accessible sectors of the\n"
7999 "-U pwd unlock the HPA configuration of the device\n"
8000 "-y don't ask any questions\n"
8002 #endif /* MINIMALISTIC */
8006 main(int argc, char **argv)
8009 char *device = NULL;
8011 struct cam_device *cam_dev = NULL;
8012 int timeout = 0, retry_count = 1;
8013 camcontrol_optret optreturn;
8015 const char *mainopt = "C:En:t:u:v";
8016 const char *subopt = NULL;
8017 char combinedopt[256];
8018 int error = 0, optstart = 2;
8020 #ifndef MINIMALISTIC
8024 #endif /* MINIMALISTIC */
8026 cmdlist = CAM_CMD_NONE;
8027 arglist = CAM_ARG_NONE;
8035 * Get the base option.
8037 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
8039 if (optreturn == CC_OR_AMBIGUOUS) {
8040 warnx("ambiguous option %s", argv[1]);
8043 } else if (optreturn == CC_OR_NOT_FOUND) {
8044 warnx("option %s not found", argv[1]);
8050 * Ahh, getopt(3) is a pain.
8052 * This is a gross hack. There really aren't many other good
8053 * options (excuse the pun) for parsing options in a situation like
8054 * this. getopt is kinda braindead, so you end up having to run
8055 * through the options twice, and give each invocation of getopt
8056 * the option string for the other invocation.
8058 * You would think that you could just have two groups of options.
8059 * The first group would get parsed by the first invocation of
8060 * getopt, and the second group would get parsed by the second
8061 * invocation of getopt. It doesn't quite work out that way. When
8062 * the first invocation of getopt finishes, it leaves optind pointing
8063 * to the argument _after_ the first argument in the second group.
8064 * So when the second invocation of getopt comes around, it doesn't
8065 * recognize the first argument it gets and then bails out.
8067 * A nice alternative would be to have a flag for getopt that says
8068 * "just keep parsing arguments even when you encounter an unknown
8069 * argument", but there isn't one. So there's no real clean way to
8070 * easily parse two sets of arguments without having one invocation
8071 * of getopt know about the other.
8073 * Without this hack, the first invocation of getopt would work as
8074 * long as the generic arguments are first, but the second invocation
8075 * (in the subfunction) would fail in one of two ways. In the case
8076 * where you don't set optreset, it would fail because optind may be
8077 * pointing to the argument after the one it should be pointing at.
8078 * In the case where you do set optreset, and reset optind, it would
8079 * fail because getopt would run into the first set of options, which
8080 * it doesn't understand.
8082 * All of this would "sort of" work if you could somehow figure out
8083 * whether optind had been incremented one option too far. The
8084 * mechanics of that, however, are more daunting than just giving
8085 * both invocations all of the expect options for either invocation.
8087 * Needless to say, I wouldn't mind if someone invented a better
8088 * (non-GPL!) command line parsing interface than getopt. I
8089 * wouldn't mind if someone added more knobs to getopt to make it
8090 * work better. Who knows, I may talk myself into doing it someday,
8091 * if the standards weenies let me. As it is, it just leads to
8092 * hackery like this and causes people to avoid it in some cases.
8094 * KDM, September 8th, 1998
8097 sprintf(combinedopt, "%s%s", mainopt, subopt);
8099 sprintf(combinedopt, "%s", mainopt);
8102 * For these options we do not parse optional device arguments and
8103 * we do not open a passthrough device.
8105 if ((cmdlist == CAM_CMD_RESCAN)
8106 || (cmdlist == CAM_CMD_RESET)
8107 || (cmdlist == CAM_CMD_DEVTREE)
8108 || (cmdlist == CAM_CMD_USAGE)
8109 || (cmdlist == CAM_CMD_DEBUG))
8112 #ifndef MINIMALISTIC
8114 && (argc > 2 && argv[2][0] != '-')) {
8118 if (isdigit(argv[2][0])) {
8119 /* device specified as bus:target[:lun] */
8120 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
8122 errx(1, "numeric device specification must "
8123 "be either bus:target, or "
8125 /* default to 0 if lun was not specified */
8126 if ((arglist & CAM_ARG_LUN) == 0) {
8128 arglist |= CAM_ARG_LUN;
8132 if (cam_get_device(argv[2], name, sizeof name, &unit)
8134 errx(1, "%s", cam_errbuf);
8135 device = strdup(name);
8136 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
8140 #endif /* MINIMALISTIC */
8142 * Start getopt processing at argv[2/3], since we've already
8143 * accepted argv[1..2] as the command name, and as a possible
8149 * Now we run through the argument list looking for generic
8150 * options, and ignoring options that possibly belong to
8153 while ((c = getopt(argc, argv, combinedopt))!= -1){
8156 retry_count = strtol(optarg, NULL, 0);
8157 if (retry_count < 0)
8158 errx(1, "retry count %d is < 0",
8160 arglist |= CAM_ARG_RETRIES;
8163 arglist |= CAM_ARG_ERR_RECOVER;
8166 arglist |= CAM_ARG_DEVICE;
8168 while (isspace(*tstr) && (*tstr != '\0'))
8170 device = (char *)strdup(tstr);
8173 timeout = strtol(optarg, NULL, 0);
8175 errx(1, "invalid timeout %d", timeout);
8176 /* Convert the timeout from seconds to ms */
8178 arglist |= CAM_ARG_TIMEOUT;
8181 arglist |= CAM_ARG_UNIT;
8182 unit = strtol(optarg, NULL, 0);
8185 arglist |= CAM_ARG_VERBOSE;
8192 #ifndef MINIMALISTIC
8194 * For most commands we'll want to open the passthrough device
8195 * associated with the specified device. In the case of the rescan
8196 * commands, we don't use a passthrough device at all, just the
8197 * transport layer device.
8200 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
8201 && (((arglist & CAM_ARG_DEVICE) == 0)
8202 || ((arglist & CAM_ARG_UNIT) == 0))) {
8203 errx(1, "subcommand \"%s\" requires a valid device "
8204 "identifier", argv[1]);
8207 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
8208 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
8209 cam_open_spec_device(device,unit,O_RDWR,NULL)))
8211 errx(1,"%s", cam_errbuf);
8213 #endif /* MINIMALISTIC */
8216 * Reset optind to 2, and reset getopt, so these routines can parse
8217 * the arguments again.
8223 #ifndef MINIMALISTIC
8224 case CAM_CMD_DEVLIST:
8225 error = getdevlist(cam_dev);
8228 error = atahpa(cam_dev, retry_count, timeout,
8229 argc, argv, combinedopt);
8231 #endif /* MINIMALISTIC */
8232 case CAM_CMD_DEVTREE:
8233 error = getdevtree(argc, argv, combinedopt);
8235 #ifndef MINIMALISTIC
8237 error = testunitready(cam_dev, retry_count, timeout, 0);
8239 case CAM_CMD_INQUIRY:
8240 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
8241 retry_count, timeout);
8243 case CAM_CMD_IDENTIFY:
8244 error = ataidentify(cam_dev, retry_count, timeout);
8246 case CAM_CMD_STARTSTOP:
8247 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
8248 arglist & CAM_ARG_EJECT, retry_count,
8251 #endif /* MINIMALISTIC */
8252 case CAM_CMD_RESCAN:
8253 error = dorescan_or_reset(argc, argv, 1);
8256 error = dorescan_or_reset(argc, argv, 0);
8258 #ifndef MINIMALISTIC
8259 case CAM_CMD_READ_DEFECTS:
8260 error = readdefects(cam_dev, argc, argv, combinedopt,
8261 retry_count, timeout);
8263 case CAM_CMD_MODE_PAGE:
8264 modepage(cam_dev, argc, argv, combinedopt,
8265 retry_count, timeout);
8267 case CAM_CMD_SCSI_CMD:
8268 error = scsicmd(cam_dev, argc, argv, combinedopt,
8269 retry_count, timeout);
8271 case CAM_CMD_SMP_CMD:
8272 error = smpcmd(cam_dev, argc, argv, combinedopt,
8273 retry_count, timeout);
8275 case CAM_CMD_SMP_RG:
8276 error = smpreportgeneral(cam_dev, argc, argv,
8277 combinedopt, retry_count,
8280 case CAM_CMD_SMP_PC:
8281 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
8282 retry_count, timeout);
8284 case CAM_CMD_SMP_PHYLIST:
8285 error = smpphylist(cam_dev, argc, argv, combinedopt,
8286 retry_count, timeout);
8288 case CAM_CMD_SMP_MANINFO:
8289 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
8290 retry_count, timeout);
8293 error = camdebug(argc, argv, combinedopt);
8296 error = tagcontrol(cam_dev, argc, argv, combinedopt);
8299 error = ratecontrol(cam_dev, retry_count, timeout,
8300 argc, argv, combinedopt);
8302 case CAM_CMD_FORMAT:
8303 error = scsiformat(cam_dev, argc, argv,
8304 combinedopt, retry_count, timeout);
8306 case CAM_CMD_REPORTLUNS:
8307 error = scsireportluns(cam_dev, argc, argv,
8308 combinedopt, retry_count,
8311 case CAM_CMD_READCAP:
8312 error = scsireadcapacity(cam_dev, argc, argv,
8313 combinedopt, retry_count,
8317 case CAM_CMD_STANDBY:
8319 error = atapm(cam_dev, argc, argv,
8320 combinedopt, retry_count, timeout);
8322 case CAM_CMD_SECURITY:
8323 error = atasecurity(cam_dev, retry_count, timeout,
8324 argc, argv, combinedopt);
8326 case CAM_CMD_DOWNLOAD_FW:
8327 error = fwdownload(cam_dev, argc, argv, combinedopt,
8328 arglist & CAM_ARG_VERBOSE, retry_count, timeout,
8329 get_disk_type(cam_dev));
8331 case CAM_CMD_SANITIZE:
8332 error = scsisanitize(cam_dev, argc, argv,
8333 combinedopt, retry_count, timeout);
8335 #endif /* MINIMALISTIC */
8345 if (cam_dev != NULL)
8346 cam_close_device(cam_dev);