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 atacapprint(struct ata_params *parm)
1220 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1221 ((u_int32_t)parm->lba_size_2 << 16);
1223 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1224 ((u_int64_t)parm->lba_size48_2 << 16) |
1225 ((u_int64_t)parm->lba_size48_3 << 32) |
1226 ((u_int64_t)parm->lba_size48_4 << 48);
1229 printf("protocol ");
1230 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1231 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1232 if (parm->satacapabilities & ATA_SATA_GEN3)
1233 printf(" SATA 3.x\n");
1234 else if (parm->satacapabilities & ATA_SATA_GEN2)
1235 printf(" SATA 2.x\n");
1236 else if (parm->satacapabilities & ATA_SATA_GEN1)
1237 printf(" SATA 1.x\n");
1243 printf("device model %.40s\n", parm->model);
1244 printf("firmware revision %.8s\n", parm->revision);
1245 printf("serial number %.20s\n", parm->serial);
1246 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1247 printf("WWN %04x%04x%04x%04x\n",
1248 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1250 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1251 printf("media serial number %.30s\n",
1252 parm->media_serial);
1255 printf("cylinders %d\n", parm->cylinders);
1256 printf("heads %d\n", parm->heads);
1257 printf("sectors/track %d\n", parm->sectors);
1258 printf("sector size logical %u, physical %lu, offset %lu\n",
1259 ata_logical_sector_size(parm),
1260 (unsigned long)ata_physical_sector_size(parm),
1261 (unsigned long)ata_logical_sector_offset(parm));
1263 if (parm->config == ATA_PROTO_CFA ||
1264 (parm->support.command2 & ATA_SUPPORT_CFA))
1265 printf("CFA supported\n");
1267 printf("LBA%ssupported ",
1268 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1270 printf("%d sectors\n", lbasize);
1274 printf("LBA48%ssupported ",
1275 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1277 printf("%ju sectors\n", (uintmax_t)lbasize48);
1281 printf("PIO supported PIO");
1282 switch (ata_max_pmode(parm)) {
1298 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1299 printf(" w/o IORDY");
1302 printf("DMA%ssupported ",
1303 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1304 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1305 if (parm->mwdmamodes & 0xff) {
1307 if (parm->mwdmamodes & 0x04)
1309 else if (parm->mwdmamodes & 0x02)
1311 else if (parm->mwdmamodes & 0x01)
1315 if ((parm->atavalid & ATA_FLAG_88) &&
1316 (parm->udmamodes & 0xff)) {
1318 if (parm->udmamodes & 0x40)
1320 else if (parm->udmamodes & 0x20)
1322 else if (parm->udmamodes & 0x10)
1324 else if (parm->udmamodes & 0x08)
1326 else if (parm->udmamodes & 0x04)
1328 else if (parm->udmamodes & 0x02)
1330 else if (parm->udmamodes & 0x01)
1337 if (parm->media_rotation_rate == 1) {
1338 printf("media RPM non-rotating\n");
1339 } else if (parm->media_rotation_rate >= 0x0401 &&
1340 parm->media_rotation_rate <= 0xFFFE) {
1341 printf("media RPM %d\n",
1342 parm->media_rotation_rate);
1346 "Support Enabled Value Vendor\n");
1347 printf("read ahead %s %s\n",
1348 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1349 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1350 printf("write cache %s %s\n",
1351 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1352 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1353 printf("flush cache %s %s\n",
1354 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1355 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1356 printf("overlap %s\n",
1357 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1358 printf("Tagged Command Queuing (TCQ) %s %s",
1359 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1360 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1361 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1362 printf(" %d tags\n",
1363 ATA_QUEUE_LEN(parm->queue) + 1);
1366 printf("Native Command Queuing (NCQ) ");
1367 if (parm->satacapabilities != 0xffff &&
1368 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1369 printf("yes %d tags\n",
1370 ATA_QUEUE_LEN(parm->queue) + 1);
1373 printf("SMART %s %s\n",
1374 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1375 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1376 printf("microcode download %s %s\n",
1377 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1378 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1379 printf("security %s %s\n",
1380 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1381 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1382 printf("power management %s %s\n",
1383 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1384 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1385 printf("advanced power management %s %s",
1386 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1387 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1388 if (parm->support.command2 & ATA_SUPPORT_APM) {
1389 printf(" %d/0x%02X\n",
1390 parm->apm_value, parm->apm_value);
1393 printf("automatic acoustic management %s %s",
1394 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1395 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1396 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1397 printf(" %d/0x%02X %d/0x%02X\n",
1398 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1399 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1400 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1401 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1404 printf("media status notification %s %s\n",
1405 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1406 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1407 printf("power-up in Standby %s %s\n",
1408 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1409 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1410 printf("write-read-verify %s %s",
1411 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1412 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1413 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1414 printf(" %d/0x%x\n",
1415 parm->wrv_mode, parm->wrv_mode);
1418 printf("unload %s %s\n",
1419 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1420 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1421 printf("free-fall %s %s\n",
1422 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1423 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1424 printf("Data Set Management (DSM/TRIM) ");
1425 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1427 printf("DSM - max 512byte blocks ");
1428 if (parm->max_dsm_blocks == 0x00)
1429 printf("yes not specified\n");
1432 parm->max_dsm_blocks);
1434 printf("DSM - deterministic read ");
1435 if (parm->support3 & ATA_SUPPORT_DRAT) {
1436 if (parm->support3 & ATA_SUPPORT_RZAT)
1437 printf("yes zeroed\n");
1439 printf("yes any value\n");
1449 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1451 struct ata_pass_16 *ata_pass_16;
1452 struct ata_cmd ata_cmd;
1454 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1455 ata_cmd.command = ata_pass_16->command;
1456 ata_cmd.control = ata_pass_16->control;
1457 ata_cmd.features = ata_pass_16->features;
1459 if (arglist & CAM_ARG_VERBOSE) {
1460 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1461 ata_op_string(&ata_cmd),
1462 ccb->csio.ccb_h.timeout);
1465 /* Disable freezing the device queue */
1466 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1468 if (arglist & CAM_ARG_ERR_RECOVER)
1469 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1471 if (cam_send_ccb(device, ccb) < 0) {
1472 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1473 warn("error sending ATA %s via pass_16",
1474 ata_op_string(&ata_cmd));
1477 if (arglist & CAM_ARG_VERBOSE) {
1478 cam_error_print(device, ccb, CAM_ESF_ALL,
1479 CAM_EPF_ALL, stderr);
1485 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1486 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1487 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1488 warnx("ATA %s via pass_16 failed",
1489 ata_op_string(&ata_cmd));
1491 if (arglist & CAM_ARG_VERBOSE) {
1492 cam_error_print(device, ccb, CAM_ESF_ALL,
1493 CAM_EPF_ALL, stderr);
1504 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1506 if (arglist & CAM_ARG_VERBOSE) {
1507 warnx("sending ATA %s with timeout of %u msecs",
1508 ata_op_string(&(ccb->ataio.cmd)),
1509 ccb->ataio.ccb_h.timeout);
1512 /* Disable freezing the device queue */
1513 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1515 if (arglist & CAM_ARG_ERR_RECOVER)
1516 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1518 if (cam_send_ccb(device, ccb) < 0) {
1519 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1520 warn("error sending ATA %s",
1521 ata_op_string(&(ccb->ataio.cmd)));
1524 if (arglist & CAM_ARG_VERBOSE) {
1525 cam_error_print(device, ccb, CAM_ESF_ALL,
1526 CAM_EPF_ALL, stderr);
1532 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1533 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1534 warnx("ATA %s failed: %d",
1535 ata_op_string(&(ccb->ataio.cmd)), quiet);
1538 if (arglist & CAM_ARG_VERBOSE) {
1539 cam_error_print(device, ccb, CAM_ESF_ALL,
1540 CAM_EPF_ALL, stderr);
1550 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1551 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1552 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1553 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1554 u_int16_t dxfer_len, int timeout, int quiet)
1556 if (data_ptr != NULL) {
1557 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1558 AP_FLAG_TLEN_SECT_CNT;
1559 if (flags & CAM_DIR_OUT)
1560 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1562 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1564 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1567 bzero(&(&ccb->ccb_h)[1],
1568 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1570 scsi_ata_pass_16(&ccb->csio,
1584 /*sense_len*/SSD_FULL_SIZE,
1587 return scsi_cam_pass_16_send(device, ccb, quiet);
1591 ata_try_pass_16(struct cam_device *device)
1593 struct ccb_pathinq cpi;
1595 if (get_cpi(device, &cpi) != 0) {
1596 warnx("couldn't get CPI");
1600 if (cpi.protocol == PROTO_SCSI) {
1601 /* possibly compatible with pass_16 */
1605 /* likely not compatible with pass_16 */
1610 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1611 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1612 u_int8_t command, u_int8_t features, u_int32_t lba,
1613 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1614 int timeout, int quiet)
1618 switch (ata_try_pass_16(device)) {
1622 /* Try using SCSI Passthrough */
1623 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1624 0, tag_action, command, features, lba,
1625 sector_count, data_ptr, dxfer_len,
1629 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1630 sizeof(struct ccb_hdr));
1631 cam_fill_ataio(&ccb->ataio,
1640 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1641 return ata_cam_send(device, ccb, quiet);
1645 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1646 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1647 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1648 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1649 u_int16_t dxfer_len, int timeout, int force48bit)
1653 retval = ata_try_pass_16(device);
1660 /* Try using SCSI Passthrough */
1661 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1662 ata_flags, tag_action, command, features,
1663 lba, sector_count, data_ptr, dxfer_len,
1666 if (ata_flags & AP_FLAG_CHK_COND) {
1667 /* Decode ata_res from sense data */
1668 struct ata_res_pass16 *res_pass16;
1669 struct ata_res *res;
1673 /* sense_data is 4 byte aligned */
1674 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1675 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1676 ptr[i] = le16toh(ptr[i]);
1678 /* sense_data is 4 byte aligned */
1679 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1680 &ccb->csio.sense_data;
1681 res = &ccb->ataio.res;
1682 res->flags = res_pass16->flags;
1683 res->status = res_pass16->status;
1684 res->error = res_pass16->error;
1685 res->lba_low = res_pass16->lba_low;
1686 res->lba_mid = res_pass16->lba_mid;
1687 res->lba_high = res_pass16->lba_high;
1688 res->device = res_pass16->device;
1689 res->lba_low_exp = res_pass16->lba_low_exp;
1690 res->lba_mid_exp = res_pass16->lba_mid_exp;
1691 res->lba_high_exp = res_pass16->lba_high_exp;
1692 res->sector_count = res_pass16->sector_count;
1693 res->sector_count_exp = res_pass16->sector_count_exp;
1699 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1700 sizeof(struct ccb_hdr));
1701 cam_fill_ataio(&ccb->ataio,
1710 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1711 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1713 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1715 if (ata_flags & AP_FLAG_CHK_COND)
1716 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1718 return ata_cam_send(device, ccb, 0);
1722 dump_data(uint16_t *ptr, uint32_t len)
1726 for (i = 0; i < len / 2; i++) {
1728 printf(" %3d: ", i);
1729 printf("%04hx ", ptr[i]);
1738 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1739 int is48bit, u_int64_t *hpasize)
1741 struct ata_res *res;
1743 res = &ccb->ataio.res;
1744 if (res->status & ATA_STATUS_ERROR) {
1745 if (arglist & CAM_ARG_VERBOSE) {
1746 cam_error_print(device, ccb, CAM_ESF_ALL,
1747 CAM_EPF_ALL, stderr);
1748 printf("error = 0x%02x, sector_count = 0x%04x, "
1749 "device = 0x%02x, status = 0x%02x\n",
1750 res->error, res->sector_count,
1751 res->device, res->status);
1754 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1755 warnx("Max address has already been set since "
1756 "last power-on or hardware reset");
1762 if (arglist & CAM_ARG_VERBOSE) {
1763 fprintf(stdout, "%s%d: Raw native max data:\n",
1764 device->device_name, device->dev_unit_num);
1765 /* res is 4 byte aligned */
1766 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1768 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1769 "status = 0x%02x\n", res->error, res->sector_count,
1770 res->device, res->status);
1773 if (hpasize != NULL) {
1775 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1776 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1777 ((res->lba_high << 16) | (res->lba_mid << 8) |
1780 *hpasize = (((res->device & 0x0f) << 24) |
1781 (res->lba_high << 16) | (res->lba_mid << 8) |
1790 ata_read_native_max(struct cam_device *device, int retry_count,
1791 u_int32_t timeout, union ccb *ccb,
1792 struct ata_params *parm, u_int64_t *hpasize)
1798 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1799 protocol = AP_PROTO_NON_DATA;
1802 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1803 protocol |= AP_EXTEND;
1805 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1808 error = ata_do_cmd(device,
1811 /*flags*/CAM_DIR_NONE,
1812 /*protocol*/protocol,
1813 /*ata_flags*/AP_FLAG_CHK_COND,
1814 /*tag_action*/MSG_SIMPLE_Q_TAG,
1821 timeout ? timeout : 1000,
1827 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1831 atahpa_set_max(struct cam_device *device, int retry_count,
1832 u_int32_t timeout, union ccb *ccb,
1833 int is48bit, u_int64_t maxsize, int persist)
1839 protocol = AP_PROTO_NON_DATA;
1842 cmd = ATA_SET_MAX_ADDRESS48;
1843 protocol |= AP_EXTEND;
1845 cmd = ATA_SET_MAX_ADDRESS;
1848 /* lba's are zero indexed so the max lba is requested max - 1 */
1852 error = ata_do_cmd(device,
1855 /*flags*/CAM_DIR_NONE,
1856 /*protocol*/protocol,
1857 /*ata_flags*/AP_FLAG_CHK_COND,
1858 /*tag_action*/MSG_SIMPLE_Q_TAG,
1860 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1862 /*sector_count*/persist,
1865 timeout ? timeout : 1000,
1871 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1875 atahpa_password(struct cam_device *device, int retry_count,
1876 u_int32_t timeout, union ccb *ccb,
1877 int is48bit, struct ata_set_max_pwd *pwd)
1883 protocol = AP_PROTO_PIO_OUT;
1884 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1886 error = ata_do_cmd(device,
1889 /*flags*/CAM_DIR_OUT,
1890 /*protocol*/protocol,
1891 /*ata_flags*/AP_FLAG_CHK_COND,
1892 /*tag_action*/MSG_SIMPLE_Q_TAG,
1894 /*features*/ATA_HPA_FEAT_SET_PWD,
1897 /*data_ptr*/(u_int8_t*)pwd,
1898 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1899 timeout ? timeout : 1000,
1905 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1909 atahpa_lock(struct cam_device *device, int retry_count,
1910 u_int32_t timeout, union ccb *ccb, int is48bit)
1916 protocol = AP_PROTO_NON_DATA;
1917 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1919 error = ata_do_cmd(device,
1922 /*flags*/CAM_DIR_NONE,
1923 /*protocol*/protocol,
1924 /*ata_flags*/AP_FLAG_CHK_COND,
1925 /*tag_action*/MSG_SIMPLE_Q_TAG,
1927 /*features*/ATA_HPA_FEAT_LOCK,
1932 timeout ? timeout : 1000,
1938 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1942 atahpa_unlock(struct cam_device *device, int retry_count,
1943 u_int32_t timeout, union ccb *ccb,
1944 int is48bit, struct ata_set_max_pwd *pwd)
1950 protocol = AP_PROTO_PIO_OUT;
1951 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1953 error = ata_do_cmd(device,
1956 /*flags*/CAM_DIR_OUT,
1957 /*protocol*/protocol,
1958 /*ata_flags*/AP_FLAG_CHK_COND,
1959 /*tag_action*/MSG_SIMPLE_Q_TAG,
1961 /*features*/ATA_HPA_FEAT_UNLOCK,
1964 /*data_ptr*/(u_int8_t*)pwd,
1965 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1966 timeout ? timeout : 1000,
1972 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1976 atahpa_freeze_lock(struct cam_device *device, int retry_count,
1977 u_int32_t timeout, union ccb *ccb, int is48bit)
1983 protocol = AP_PROTO_NON_DATA;
1984 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1986 error = ata_do_cmd(device,
1989 /*flags*/CAM_DIR_NONE,
1990 /*protocol*/protocol,
1991 /*ata_flags*/AP_FLAG_CHK_COND,
1992 /*tag_action*/MSG_SIMPLE_Q_TAG,
1994 /*features*/ATA_HPA_FEAT_FREEZE,
1999 timeout ? timeout : 1000,
2005 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2010 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2011 union ccb *ccb, struct ata_params** ident_bufp)
2013 struct ata_params *ident_buf;
2014 struct ccb_pathinq cpi;
2015 struct ccb_getdev cgd;
2018 u_int8_t command, retry_command;
2020 if (get_cpi(device, &cpi) != 0) {
2021 warnx("couldn't get CPI");
2025 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2026 if (cpi.protocol == PROTO_ATA) {
2027 if (get_cgd(device, &cgd) != 0) {
2028 warnx("couldn't get CGD");
2032 command = (cgd.protocol == PROTO_ATA) ?
2033 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2036 /* We don't know which for sure so try both */
2037 command = ATA_ATA_IDENTIFY;
2038 retry_command = ATA_ATAPI_IDENTIFY;
2041 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2043 warnx("can't calloc memory for identify\n");
2047 error = ata_do_28bit_cmd(device,
2049 /*retries*/retry_count,
2050 /*flags*/CAM_DIR_IN,
2051 /*protocol*/AP_PROTO_PIO_IN,
2052 /*tag_action*/MSG_SIMPLE_Q_TAG,
2056 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2057 /*data_ptr*/(u_int8_t *)ptr,
2058 /*dxfer_len*/sizeof(struct ata_params),
2059 /*timeout*/timeout ? timeout : 30 * 1000,
2063 if (retry_command == 0) {
2067 error = ata_do_28bit_cmd(device,
2069 /*retries*/retry_count,
2070 /*flags*/CAM_DIR_IN,
2071 /*protocol*/AP_PROTO_PIO_IN,
2072 /*tag_action*/MSG_SIMPLE_Q_TAG,
2073 /*command*/retry_command,
2076 /*sector_count*/(u_int8_t)
2077 sizeof(struct ata_params),
2078 /*data_ptr*/(u_int8_t *)ptr,
2079 /*dxfer_len*/sizeof(struct ata_params),
2080 /*timeout*/timeout ? timeout : 30 * 1000,
2090 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2091 ptr[i] = le16toh(ptr[i]);
2096 if (arglist & CAM_ARG_VERBOSE) {
2097 fprintf(stdout, "%s%d: Raw identify data:\n",
2098 device->device_name, device->dev_unit_num);
2099 dump_data(ptr, sizeof(struct ata_params));
2102 /* check for invalid (all zero) response */
2104 warnx("Invalid identify response detected");
2109 ident_buf = (struct ata_params *)ptr;
2110 if (strncmp(ident_buf->model, "FX", 2) &&
2111 strncmp(ident_buf->model, "NEC", 3) &&
2112 strncmp(ident_buf->model, "Pioneer", 7) &&
2113 strncmp(ident_buf->model, "SHARP", 5)) {
2114 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2115 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2116 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2117 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2119 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2120 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2121 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2122 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2123 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2124 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2125 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2126 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2127 sizeof(ident_buf->media_serial));
2129 *ident_bufp = ident_buf;
2136 ataidentify(struct cam_device *device, int retry_count, int timeout)
2139 struct ata_params *ident_buf;
2142 if ((ccb = cam_getccb(device)) == NULL) {
2143 warnx("couldn't allocate CCB");
2147 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2152 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2153 if (ata_read_native_max(device, retry_count, timeout, ccb,
2154 ident_buf, &hpasize) != 0) {
2162 printf("%s%d: ", device->device_name, device->dev_unit_num);
2163 ata_print_ident(ident_buf);
2164 camxferrate(device);
2165 atacapprint(ident_buf);
2166 atahpa_print(ident_buf, hpasize, 0);
2173 #endif /* MINIMALISTIC */
2176 #ifndef MINIMALISTIC
2178 ATA_SECURITY_ACTION_PRINT,
2179 ATA_SECURITY_ACTION_FREEZE,
2180 ATA_SECURITY_ACTION_UNLOCK,
2181 ATA_SECURITY_ACTION_DISABLE,
2182 ATA_SECURITY_ACTION_ERASE,
2183 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2184 ATA_SECURITY_ACTION_SET_PASSWORD
2188 atasecurity_print_time(u_int16_t tw)
2192 printf("unspecified");
2194 printf("> 508 min");
2196 printf("%i min", 2 * tw);
2200 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2204 return 2 * 3600 * 1000; /* default: two hours */
2205 else if (timeout > 255)
2206 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2208 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2213 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2217 bzero(&cmd, sizeof(cmd));
2218 cmd.command = command;
2219 printf("Issuing %s", ata_op_string(&cmd));
2222 char pass[sizeof(pwd->password)+1];
2224 /* pwd->password may not be null terminated */
2225 pass[sizeof(pwd->password)] = '\0';
2226 strncpy(pass, pwd->password, sizeof(pwd->password));
2227 printf(" password='%s', user='%s'",
2229 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2232 if (command == ATA_SECURITY_SET_PASSWORD) {
2233 printf(", mode='%s'",
2234 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2235 "maximum" : "high");
2243 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2244 int retry_count, u_int32_t timeout, int quiet)
2248 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2250 return ata_do_28bit_cmd(device,
2253 /*flags*/CAM_DIR_NONE,
2254 /*protocol*/AP_PROTO_NON_DATA,
2255 /*tag_action*/MSG_SIMPLE_Q_TAG,
2256 /*command*/ATA_SECURITY_FREEZE_LOCK,
2267 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2268 int retry_count, u_int32_t timeout,
2269 struct ata_security_password *pwd, int quiet)
2273 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2275 return ata_do_28bit_cmd(device,
2278 /*flags*/CAM_DIR_OUT,
2279 /*protocol*/AP_PROTO_PIO_OUT,
2280 /*tag_action*/MSG_SIMPLE_Q_TAG,
2281 /*command*/ATA_SECURITY_UNLOCK,
2285 /*data_ptr*/(u_int8_t *)pwd,
2286 /*dxfer_len*/sizeof(*pwd),
2292 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2293 int retry_count, u_int32_t timeout,
2294 struct ata_security_password *pwd, int quiet)
2298 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2299 return ata_do_28bit_cmd(device,
2302 /*flags*/CAM_DIR_OUT,
2303 /*protocol*/AP_PROTO_PIO_OUT,
2304 /*tag_action*/MSG_SIMPLE_Q_TAG,
2305 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2309 /*data_ptr*/(u_int8_t *)pwd,
2310 /*dxfer_len*/sizeof(*pwd),
2317 atasecurity_erase_confirm(struct cam_device *device,
2318 struct ata_params* ident_buf)
2321 printf("\nYou are about to ERASE ALL DATA from the following"
2322 " device:\n%s%d,%s%d: ", device->device_name,
2323 device->dev_unit_num, device->given_dev_name,
2324 device->given_unit_number);
2325 ata_print_ident(ident_buf);
2329 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2331 if (fgets(str, sizeof(str), stdin) != NULL) {
2332 if (strncasecmp(str, "yes", 3) == 0) {
2334 } else if (strncasecmp(str, "no", 2) == 0) {
2337 printf("Please answer \"yes\" or "
2348 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2349 int retry_count, u_int32_t timeout,
2350 u_int32_t erase_timeout,
2351 struct ata_security_password *pwd, int quiet)
2356 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2358 error = ata_do_28bit_cmd(device,
2361 /*flags*/CAM_DIR_NONE,
2362 /*protocol*/AP_PROTO_NON_DATA,
2363 /*tag_action*/MSG_SIMPLE_Q_TAG,
2364 /*command*/ATA_SECURITY_ERASE_PREPARE,
2377 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2379 error = ata_do_28bit_cmd(device,
2382 /*flags*/CAM_DIR_OUT,
2383 /*protocol*/AP_PROTO_PIO_OUT,
2384 /*tag_action*/MSG_SIMPLE_Q_TAG,
2385 /*command*/ATA_SECURITY_ERASE_UNIT,
2389 /*data_ptr*/(u_int8_t *)pwd,
2390 /*dxfer_len*/sizeof(*pwd),
2391 /*timeout*/erase_timeout,
2394 if (error == 0 && quiet == 0)
2395 printf("\nErase Complete\n");
2401 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2402 int retry_count, u_int32_t timeout,
2403 struct ata_security_password *pwd, int quiet)
2407 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2409 return ata_do_28bit_cmd(device,
2412 /*flags*/CAM_DIR_OUT,
2413 /*protocol*/AP_PROTO_PIO_OUT,
2414 /*tag_action*/MSG_SIMPLE_Q_TAG,
2415 /*command*/ATA_SECURITY_SET_PASSWORD,
2419 /*data_ptr*/(u_int8_t *)pwd,
2420 /*dxfer_len*/sizeof(*pwd),
2426 atasecurity_print(struct ata_params *parm)
2429 printf("\nSecurity Option Value\n");
2430 if (arglist & CAM_ARG_VERBOSE) {
2431 printf("status %04x\n",
2432 parm->security_status);
2434 printf("supported %s\n",
2435 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2436 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2438 printf("enabled %s\n",
2439 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2440 printf("drive locked %s\n",
2441 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2442 printf("security config frozen %s\n",
2443 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2444 printf("count expired %s\n",
2445 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2446 printf("security level %s\n",
2447 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2448 printf("enhanced erase supported %s\n",
2449 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2450 printf("erase time ");
2451 atasecurity_print_time(parm->erase_time);
2453 printf("enhanced erase time ");
2454 atasecurity_print_time(parm->enhanced_erase_time);
2456 printf("master password rev %04x%s\n",
2457 parm->master_passwd_revision,
2458 parm->master_passwd_revision == 0x0000 ||
2459 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2463 * Validates and copies the password in optarg to the passed buffer.
2464 * If the password in optarg is the same length as the buffer then
2465 * the data will still be copied but no null termination will occur.
2468 ata_getpwd(u_int8_t *passwd, int max, char opt)
2472 len = strlen(optarg);
2474 warnx("-%c password is too long", opt);
2476 } else if (len == 0) {
2477 warnx("-%c password is missing", opt);
2479 } else if (optarg[0] == '-'){
2480 warnx("-%c password starts with '-' (generic arg?)", opt);
2482 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2483 warnx("-%c password conflicts with existing password from -%c",
2488 /* Callers pass in a buffer which does NOT need to be terminated */
2489 strncpy(passwd, optarg, max);
2496 ATA_HPA_ACTION_PRINT,
2497 ATA_HPA_ACTION_SET_MAX,
2498 ATA_HPA_ACTION_SET_PWD,
2499 ATA_HPA_ACTION_LOCK,
2500 ATA_HPA_ACTION_UNLOCK,
2501 ATA_HPA_ACTION_FREEZE_LOCK
2505 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2506 u_int64_t maxsize, int persist)
2508 printf("\nYou are about to configure HPA to limit the user accessible\n"
2509 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2510 persist ? "persistently" : "temporarily",
2511 device->device_name, device->dev_unit_num,
2512 device->given_dev_name, device->given_unit_number);
2513 ata_print_ident(ident_buf);
2517 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2519 if (NULL != fgets(str, sizeof(str), stdin)) {
2520 if (0 == strncasecmp(str, "yes", 3)) {
2522 } else if (0 == strncasecmp(str, "no", 2)) {
2525 printf("Please answer \"yes\" or "
2536 atahpa(struct cam_device *device, int retry_count, int timeout,
2537 int argc, char **argv, char *combinedopt)
2540 struct ata_params *ident_buf;
2541 struct ccb_getdev cgd;
2542 struct ata_set_max_pwd pwd;
2543 int error, confirm, quiet, c, action, actions, setpwd, persist;
2544 int security, is48bit, pwdsize;
2545 u_int64_t hpasize, maxsize;
2555 memset(&pwd, 0, sizeof(pwd));
2557 /* default action is to print hpa information */
2558 action = ATA_HPA_ACTION_PRINT;
2559 pwdsize = sizeof(pwd.password);
2561 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2564 action = ATA_HPA_ACTION_SET_MAX;
2565 maxsize = strtoumax(optarg, NULL, 0);
2570 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2572 action = ATA_HPA_ACTION_SET_PWD;
2578 action = ATA_HPA_ACTION_LOCK;
2584 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2586 action = ATA_HPA_ACTION_UNLOCK;
2592 action = ATA_HPA_ACTION_FREEZE_LOCK;
2612 warnx("too many hpa actions specified");
2616 if (get_cgd(device, &cgd) != 0) {
2617 warnx("couldn't get CGD");
2621 ccb = cam_getccb(device);
2623 warnx("couldn't allocate CCB");
2627 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2634 printf("%s%d: ", device->device_name, device->dev_unit_num);
2635 ata_print_ident(ident_buf);
2636 camxferrate(device);
2639 if (action == ATA_HPA_ACTION_PRINT) {
2640 error = ata_read_native_max(device, retry_count, timeout, ccb,
2641 ident_buf, &hpasize);
2643 atahpa_print(ident_buf, hpasize, 1);
2650 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2651 warnx("HPA is not supported by this device");
2657 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2658 warnx("HPA Security is not supported by this device");
2664 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2667 * The ATA spec requires:
2668 * 1. Read native max addr is called directly before set max addr
2669 * 2. Read native max addr is NOT called before any other set max call
2672 case ATA_HPA_ACTION_SET_MAX:
2674 atahpa_set_confirm(device, ident_buf, maxsize,
2681 error = ata_read_native_max(device, retry_count, timeout,
2682 ccb, ident_buf, &hpasize);
2684 error = atahpa_set_max(device, retry_count, timeout,
2685 ccb, is48bit, maxsize, persist);
2687 /* redo identify to get new lba values */
2688 error = ata_do_identify(device, retry_count,
2691 atahpa_print(ident_buf, hpasize, 1);
2696 case ATA_HPA_ACTION_SET_PWD:
2697 error = atahpa_password(device, retry_count, timeout,
2698 ccb, is48bit, &pwd);
2700 printf("HPA password has been set\n");
2703 case ATA_HPA_ACTION_LOCK:
2704 error = atahpa_lock(device, retry_count, timeout,
2707 printf("HPA has been locked\n");
2710 case ATA_HPA_ACTION_UNLOCK:
2711 error = atahpa_unlock(device, retry_count, timeout,
2712 ccb, is48bit, &pwd);
2714 printf("HPA has been unlocked\n");
2717 case ATA_HPA_ACTION_FREEZE_LOCK:
2718 error = atahpa_freeze_lock(device, retry_count, timeout,
2721 printf("HPA has been frozen\n");
2725 errx(1, "Option currently not supported");
2735 atasecurity(struct cam_device *device, int retry_count, int timeout,
2736 int argc, char **argv, char *combinedopt)
2739 struct ata_params *ident_buf;
2740 int error, confirm, quiet, c, action, actions, setpwd;
2741 int security_enabled, erase_timeout, pwdsize;
2742 struct ata_security_password pwd;
2750 memset(&pwd, 0, sizeof(pwd));
2752 /* default action is to print security information */
2753 action = ATA_SECURITY_ACTION_PRINT;
2755 /* user is master by default as its safer that way */
2756 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2757 pwdsize = sizeof(pwd.password);
2759 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2762 action = ATA_SECURITY_ACTION_FREEZE;
2767 if (strcasecmp(optarg, "user") == 0) {
2768 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2769 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2770 } else if (strcasecmp(optarg, "master") == 0) {
2771 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2772 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2774 warnx("-U argument '%s' is invalid (must be "
2775 "'user' or 'master')", optarg);
2781 if (strcasecmp(optarg, "high") == 0) {
2782 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2783 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2784 } else if (strcasecmp(optarg, "maximum") == 0) {
2785 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2786 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2788 warnx("-l argument '%s' is unknown (must be "
2789 "'high' or 'maximum')", optarg);
2795 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2797 action = ATA_SECURITY_ACTION_UNLOCK;
2802 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2804 action = ATA_SECURITY_ACTION_DISABLE;
2809 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2811 action = ATA_SECURITY_ACTION_ERASE;
2816 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2818 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2819 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2824 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2827 if (action == ATA_SECURITY_ACTION_PRINT)
2828 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2830 * Don't increment action as this can be combined
2831 * with other actions.
2844 erase_timeout = atoi(optarg) * 1000;
2850 warnx("too many security actions specified");
2854 if ((ccb = cam_getccb(device)) == NULL) {
2855 warnx("couldn't allocate CCB");
2859 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2866 printf("%s%d: ", device->device_name, device->dev_unit_num);
2867 ata_print_ident(ident_buf);
2868 camxferrate(device);
2871 if (action == ATA_SECURITY_ACTION_PRINT) {
2872 atasecurity_print(ident_buf);
2878 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2879 warnx("Security not supported");
2885 /* default timeout 15 seconds the same as linux hdparm */
2886 timeout = timeout ? timeout : 15 * 1000;
2888 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2890 /* first set the password if requested */
2892 /* confirm we can erase before setting the password if erasing */
2894 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2895 action == ATA_SECURITY_ACTION_ERASE) &&
2896 atasecurity_erase_confirm(device, ident_buf) == 0) {
2902 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2903 pwd.revision = ident_buf->master_passwd_revision;
2904 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2905 --pwd.revision == 0) {
2906 pwd.revision = 0xfffe;
2909 error = atasecurity_set_password(device, ccb, retry_count,
2910 timeout, &pwd, quiet);
2916 security_enabled = 1;
2920 case ATA_SECURITY_ACTION_FREEZE:
2921 error = atasecurity_freeze(device, ccb, retry_count,
2925 case ATA_SECURITY_ACTION_UNLOCK:
2926 if (security_enabled) {
2927 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2928 error = atasecurity_unlock(device, ccb,
2929 retry_count, timeout, &pwd, quiet);
2931 warnx("Can't unlock, drive is not locked");
2935 warnx("Can't unlock, security is disabled");
2940 case ATA_SECURITY_ACTION_DISABLE:
2941 if (security_enabled) {
2942 /* First unlock the drive if its locked */
2943 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2944 error = atasecurity_unlock(device, ccb,
2952 error = atasecurity_disable(device,
2960 warnx("Can't disable security (already disabled)");
2965 case ATA_SECURITY_ACTION_ERASE:
2966 if (security_enabled) {
2967 if (erase_timeout == 0) {
2968 erase_timeout = atasecurity_erase_timeout_msecs(
2969 ident_buf->erase_time);
2972 error = atasecurity_erase(device, ccb, retry_count,
2973 timeout, erase_timeout, &pwd,
2976 warnx("Can't secure erase (security is disabled)");
2981 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
2982 if (security_enabled) {
2983 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
2984 if (erase_timeout == 0) {
2986 atasecurity_erase_timeout_msecs(
2987 ident_buf->enhanced_erase_time);
2990 error = atasecurity_erase(device, ccb,
2991 retry_count, timeout,
2992 erase_timeout, &pwd,
2995 warnx("Enhanced erase is not supported");
2999 warnx("Can't secure erase (enhanced), "
3000 "(security is disabled)");
3011 #endif /* MINIMALISTIC */
3014 * Parse out a bus, or a bus, target and lun in the following
3020 * Returns the number of parsed components, or 0.
3023 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3024 cam_argmask *arglst)
3029 while (isspace(*tstr) && (*tstr != '\0'))
3032 tmpstr = (char *)strtok(tstr, ":");
3033 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3034 *bus = strtol(tmpstr, NULL, 0);
3035 *arglst |= CAM_ARG_BUS;
3037 tmpstr = (char *)strtok(NULL, ":");
3038 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3039 *target = strtol(tmpstr, NULL, 0);
3040 *arglst |= CAM_ARG_TARGET;
3042 tmpstr = (char *)strtok(NULL, ":");
3043 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3044 *lun = strtol(tmpstr, NULL, 0);
3045 *arglst |= CAM_ARG_LUN;
3055 dorescan_or_reset(int argc, char **argv, int rescan)
3057 static const char must[] =
3058 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3060 path_id_t bus = CAM_BUS_WILDCARD;
3061 target_id_t target = CAM_TARGET_WILDCARD;
3062 lun_id_t lun = CAM_LUN_WILDCARD;
3066 warnx(must, rescan? "rescan" : "reset");
3070 tstr = argv[optind];
3071 while (isspace(*tstr) && (*tstr != '\0'))
3073 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3074 arglist |= CAM_ARG_BUS;
3076 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3077 if (rv != 1 && rv != 3) {
3078 warnx(must, rescan? "rescan" : "reset");
3083 if ((arglist & CAM_ARG_BUS)
3084 && (arglist & CAM_ARG_TARGET)
3085 && (arglist & CAM_ARG_LUN))
3086 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3088 error = rescan_or_reset_bus(bus, rescan);
3094 rescan_or_reset_bus(path_id_t bus, int rescan)
3096 union ccb ccb, matchccb;
3102 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3103 warnx("error opening transport layer device %s", XPT_DEVICE);
3104 warn("%s", XPT_DEVICE);
3108 if (bus != CAM_BUS_WILDCARD) {
3109 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3110 ccb.ccb_h.path_id = bus;
3111 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3112 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3113 ccb.crcn.flags = CAM_FLAG_NONE;
3115 /* run this at a low priority */
3116 ccb.ccb_h.pinfo.priority = 5;
3118 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3119 warn("CAMIOCOMMAND ioctl failed");
3124 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3125 fprintf(stdout, "%s of bus %d was successful\n",
3126 rescan ? "Re-scan" : "Reset", bus);
3128 fprintf(stdout, "%s of bus %d returned error %#x\n",
3129 rescan ? "Re-scan" : "Reset", bus,
3130 ccb.ccb_h.status & CAM_STATUS_MASK);
3141 * The right way to handle this is to modify the xpt so that it can
3142 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3143 * that isn't implemented, so instead we enumerate the busses and
3144 * send the rescan or reset to those busses in the case where the
3145 * given bus is -1 (wildcard). We don't send a rescan or reset
3146 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3147 * no-op, sending a rescan to the xpt bus would result in a status of
3150 bzero(&(&matchccb.ccb_h)[1],
3151 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3152 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3153 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3154 bufsize = sizeof(struct dev_match_result) * 20;
3155 matchccb.cdm.match_buf_len = bufsize;
3156 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3157 if (matchccb.cdm.matches == NULL) {
3158 warnx("can't malloc memory for matches");
3162 matchccb.cdm.num_matches = 0;
3164 matchccb.cdm.num_patterns = 1;
3165 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3167 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3168 matchccb.cdm.pattern_buf_len);
3169 if (matchccb.cdm.patterns == NULL) {
3170 warnx("can't malloc memory for patterns");
3174 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3175 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3180 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3181 warn("CAMIOCOMMAND ioctl failed");
3186 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3187 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3188 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3189 warnx("got CAM error %#x, CDM error %d\n",
3190 matchccb.ccb_h.status, matchccb.cdm.status);
3195 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3196 struct bus_match_result *bus_result;
3198 /* This shouldn't happen. */
3199 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3202 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3205 * We don't want to rescan or reset the xpt bus.
3208 if (bus_result->path_id == CAM_XPT_PATH_ID)
3211 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3213 ccb.ccb_h.path_id = bus_result->path_id;
3214 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3215 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3216 ccb.crcn.flags = CAM_FLAG_NONE;
3218 /* run this at a low priority */
3219 ccb.ccb_h.pinfo.priority = 5;
3221 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3222 warn("CAMIOCOMMAND ioctl failed");
3227 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3228 fprintf(stdout, "%s of bus %d was successful\n",
3229 rescan? "Re-scan" : "Reset",
3230 bus_result->path_id);
3233 * Don't bail out just yet, maybe the other
3234 * rescan or reset commands will complete
3237 fprintf(stderr, "%s of bus %d returned error "
3238 "%#x\n", rescan? "Re-scan" : "Reset",
3239 bus_result->path_id,
3240 ccb.ccb_h.status & CAM_STATUS_MASK);
3244 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3245 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3252 if (matchccb.cdm.patterns != NULL)
3253 free(matchccb.cdm.patterns);
3254 if (matchccb.cdm.matches != NULL)
3255 free(matchccb.cdm.matches);
3261 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3264 struct cam_device *device;
3269 if (bus == CAM_BUS_WILDCARD) {
3270 warnx("invalid bus number %d", bus);
3274 if (target == CAM_TARGET_WILDCARD) {
3275 warnx("invalid target number %d", target);
3279 if (lun == CAM_LUN_WILDCARD) {
3280 warnx("invalid lun number %jx", (uintmax_t)lun);
3286 bzero(&ccb, sizeof(union ccb));
3289 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3290 warnx("error opening transport layer device %s\n",
3292 warn("%s", XPT_DEVICE);
3296 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3297 if (device == NULL) {
3298 warnx("%s", cam_errbuf);
3303 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3304 ccb.ccb_h.path_id = bus;
3305 ccb.ccb_h.target_id = target;
3306 ccb.ccb_h.target_lun = lun;
3307 ccb.ccb_h.timeout = 5000;
3308 ccb.crcn.flags = CAM_FLAG_NONE;
3310 /* run this at a low priority */
3311 ccb.ccb_h.pinfo.priority = 5;
3314 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3315 warn("CAMIOCOMMAND ioctl failed");
3320 if (cam_send_ccb(device, &ccb) < 0) {
3321 warn("error sending XPT_RESET_DEV CCB");
3322 cam_close_device(device);
3330 cam_close_device(device);
3333 * An error code of CAM_BDR_SENT is normal for a BDR request.
3335 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3337 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3338 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3339 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3342 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3343 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3344 ccb.ccb_h.status & CAM_STATUS_MASK);
3349 #ifndef MINIMALISTIC
3351 readdefects(struct cam_device *device, int argc, char **argv,
3352 char *combinedopt, int retry_count, int timeout)
3354 union ccb *ccb = NULL;
3355 struct scsi_read_defect_data_10 *rdd_cdb;
3356 u_int8_t *defect_list = NULL;
3357 u_int32_t max_dlist_length = SRDD10_MAX_LENGTH, dlist_length = 0;
3358 u_int32_t returned_length = 0;
3359 u_int32_t num_returned = 0;
3360 u_int8_t returned_format;
3363 int lists_specified;
3366 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3372 while (isspace(*tstr) && (*tstr != '\0'))
3374 if (strcmp(tstr, "block") == 0)
3375 arglist |= CAM_ARG_FORMAT_BLOCK;
3376 else if (strcmp(tstr, "bfi") == 0)
3377 arglist |= CAM_ARG_FORMAT_BFI;
3378 else if (strcmp(tstr, "phys") == 0)
3379 arglist |= CAM_ARG_FORMAT_PHYS;
3382 warnx("invalid defect format %s", tstr);
3383 goto defect_bailout;
3388 arglist |= CAM_ARG_GLIST;
3391 arglist |= CAM_ARG_PLIST;
3398 ccb = cam_getccb(device);
3401 * Eventually we should probably support the 12 byte READ DEFECT
3402 * DATA command. It supports a longer parameter list, which may be
3403 * necessary on newer drives with lots of defects. According to
3404 * the SBC-3 spec, drives are supposed to return an illegal request
3405 * if they have more defect data than will fit in 64K.
3407 defect_list = malloc(max_dlist_length);
3408 if (defect_list == NULL) {
3409 warnx("can't malloc memory for defect list");
3411 goto defect_bailout;
3415 * We start off asking for just the header to determine how much
3416 * defect data is available. Some Hitachi drives return an error
3417 * if you ask for more data than the drive has. Once we know the
3418 * length, we retry the command with the returned length.
3420 dlist_length = sizeof(struct scsi_read_defect_data_hdr_10);
3422 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
3426 lists_specified = 0;
3429 * cam_getccb() zeros the CCB header only. So we need to zero the
3430 * payload portion of the ccb.
3432 bzero(&(&ccb->ccb_h)[1],
3433 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3435 cam_fill_csio(&ccb->csio,
3436 /*retries*/ retry_count,
3438 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
3439 CAM_PASS_ERR_RECOVER : 0),
3440 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3441 /*data_ptr*/ defect_list,
3442 /*dxfer_len*/ dlist_length,
3443 /*sense_len*/ SSD_FULL_SIZE,
3444 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
3445 /*timeout*/ timeout ? timeout : 5000);
3447 rdd_cdb->opcode = READ_DEFECT_DATA_10;
3448 if (arglist & CAM_ARG_FORMAT_BLOCK)
3449 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
3450 else if (arglist & CAM_ARG_FORMAT_BFI)
3451 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
3452 else if (arglist & CAM_ARG_FORMAT_PHYS)
3453 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
3456 warnx("no defect list format specified");
3457 goto defect_bailout;
3459 if (arglist & CAM_ARG_PLIST) {
3460 rdd_cdb->format |= SRDD10_PLIST;
3464 if (arglist & CAM_ARG_GLIST) {
3465 rdd_cdb->format |= SRDD10_GLIST;
3469 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
3471 /* Disable freezing the device queue */
3472 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3474 if (cam_send_ccb(device, ccb) < 0) {
3475 perror("error reading defect list");
3477 if (arglist & CAM_ARG_VERBOSE) {
3478 cam_error_print(device, ccb, CAM_ESF_ALL,
3479 CAM_EPF_ALL, stderr);
3483 goto defect_bailout;
3486 returned_length = scsi_2btoul(((struct
3487 scsi_read_defect_data_hdr_10 *)defect_list)->length);
3489 if (get_length != 0) {
3492 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3493 CAM_SCSI_STATUS_ERROR) {
3494 struct scsi_sense_data *sense;
3495 int error_code, sense_key, asc, ascq;
3497 sense = &ccb->csio.sense_data;
3498 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3499 ccb->csio.sense_resid, &error_code, &sense_key,
3500 &asc, &ascq, /*show_errors*/ 1);
3503 * If the drive is reporting that it just doesn't
3504 * support the defect list format, go ahead and use
3505 * the length it reported. Otherwise, the length
3506 * may not be valid, so use the maximum.
3508 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3509 && (asc == 0x1c) && (ascq == 0x00)
3510 && (returned_length > 0)) {
3511 dlist_length = returned_length +
3512 sizeof(struct scsi_read_defect_data_hdr_10);
3513 dlist_length = min(dlist_length,
3516 dlist_length = max_dlist_length;
3517 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3520 warnx("Error reading defect header");
3521 if (arglist & CAM_ARG_VERBOSE)
3522 cam_error_print(device, ccb, CAM_ESF_ALL,
3523 CAM_EPF_ALL, stderr);
3524 goto defect_bailout;
3526 dlist_length = returned_length +
3527 sizeof(struct scsi_read_defect_data_hdr_10);
3528 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3534 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
3535 defect_list)->format;
3537 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3538 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3539 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3540 struct scsi_sense_data *sense;
3541 int error_code, sense_key, asc, ascq;
3543 sense = &ccb->csio.sense_data;
3544 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3545 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3546 &ascq, /*show_errors*/ 1);
3549 * According to the SCSI spec, if the disk doesn't support
3550 * the requested format, it will generally return a sense
3551 * key of RECOVERED ERROR, and an additional sense code
3552 * of "DEFECT LIST NOT FOUND". So, we check for that, and
3553 * also check to make sure that the returned length is
3554 * greater than 0, and then print out whatever format the
3557 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3558 && (asc == 0x1c) && (ascq == 0x00)
3559 && (returned_length > 0)) {
3560 warnx("requested defect format not available");
3561 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
3562 case SRDD10_BLOCK_FORMAT:
3563 warnx("Device returned block format");
3565 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3566 warnx("Device returned bytes from index"
3569 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3570 warnx("Device returned physical sector format");
3574 warnx("Device returned unknown defect"
3575 " data format %#x", returned_format);
3576 goto defect_bailout;
3577 break; /* NOTREACHED */
3581 warnx("Error returned from read defect data command");
3582 if (arglist & CAM_ARG_VERBOSE)
3583 cam_error_print(device, ccb, CAM_ESF_ALL,
3584 CAM_EPF_ALL, stderr);
3585 goto defect_bailout;
3587 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3589 warnx("Error returned from read defect data command");
3590 if (arglist & CAM_ARG_VERBOSE)
3591 cam_error_print(device, ccb, CAM_ESF_ALL,
3592 CAM_EPF_ALL, stderr);
3593 goto defect_bailout;
3597 * XXX KDM I should probably clean up the printout format for the
3600 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
3601 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
3603 struct scsi_defect_desc_phys_sector *dlist;
3605 dlist = (struct scsi_defect_desc_phys_sector *)
3607 sizeof(struct scsi_read_defect_data_hdr_10));
3609 num_returned = returned_length /
3610 sizeof(struct scsi_defect_desc_phys_sector);
3612 fprintf(stderr, "Got %d defect", num_returned);
3614 if ((lists_specified == 0) || (num_returned == 0)) {
3615 fprintf(stderr, "s.\n");
3617 } else if (num_returned == 1)
3618 fprintf(stderr, ":\n");
3620 fprintf(stderr, "s:\n");
3622 for (i = 0; i < num_returned; i++) {
3623 fprintf(stdout, "%d:%d:%d\n",
3624 scsi_3btoul(dlist[i].cylinder),
3626 scsi_4btoul(dlist[i].sector));
3630 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
3632 struct scsi_defect_desc_bytes_from_index *dlist;
3634 dlist = (struct scsi_defect_desc_bytes_from_index *)
3636 sizeof(struct scsi_read_defect_data_hdr_10));
3638 num_returned = returned_length /
3639 sizeof(struct scsi_defect_desc_bytes_from_index);
3641 fprintf(stderr, "Got %d defect", num_returned);
3643 if ((lists_specified == 0) || (num_returned == 0)) {
3644 fprintf(stderr, "s.\n");
3646 } else if (num_returned == 1)
3647 fprintf(stderr, ":\n");
3649 fprintf(stderr, "s:\n");
3651 for (i = 0; i < num_returned; i++) {
3652 fprintf(stdout, "%d:%d:%d\n",
3653 scsi_3btoul(dlist[i].cylinder),
3655 scsi_4btoul(dlist[i].bytes_from_index));
3659 case SRDDH10_BLOCK_FORMAT:
3661 struct scsi_defect_desc_block *dlist;
3663 dlist = (struct scsi_defect_desc_block *)(defect_list +
3664 sizeof(struct scsi_read_defect_data_hdr_10));
3666 num_returned = returned_length /
3667 sizeof(struct scsi_defect_desc_block);
3669 fprintf(stderr, "Got %d defect", num_returned);
3671 if ((lists_specified == 0) || (num_returned == 0)) {
3672 fprintf(stderr, "s.\n");
3674 } else if (num_returned == 1)
3675 fprintf(stderr, ":\n");
3677 fprintf(stderr, "s:\n");
3679 for (i = 0; i < num_returned; i++)
3680 fprintf(stdout, "%u\n",
3681 scsi_4btoul(dlist[i].address));
3685 fprintf(stderr, "Unknown defect format %d\n",
3686 returned_format & SRDDH10_DLIST_FORMAT_MASK);
3692 if (defect_list != NULL)
3700 #endif /* MINIMALISTIC */
3704 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3708 ccb = cam_getccb(device);
3714 #ifndef MINIMALISTIC
3716 mode_sense(struct cam_device *device, int mode_page, int page_control,
3717 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3722 ccb = cam_getccb(device);
3725 errx(1, "mode_sense: couldn't allocate CCB");
3727 bzero(&(&ccb->ccb_h)[1],
3728 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3730 scsi_mode_sense(&ccb->csio,
3731 /* retries */ retry_count,
3733 /* tag_action */ MSG_SIMPLE_Q_TAG,
3735 /* page_code */ page_control << 6,
3736 /* page */ mode_page,
3737 /* param_buf */ data,
3738 /* param_len */ datalen,
3739 /* sense_len */ SSD_FULL_SIZE,
3740 /* timeout */ timeout ? timeout : 5000);
3742 if (arglist & CAM_ARG_ERR_RECOVER)
3743 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3745 /* Disable freezing the device queue */
3746 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3748 if (((retval = cam_send_ccb(device, ccb)) < 0)
3749 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3750 if (arglist & CAM_ARG_VERBOSE) {
3751 cam_error_print(device, ccb, CAM_ESF_ALL,
3752 CAM_EPF_ALL, stderr);
3755 cam_close_device(device);
3757 err(1, "error sending mode sense command");
3759 errx(1, "error sending mode sense command");
3766 mode_select(struct cam_device *device, int save_pages, int retry_count,
3767 int timeout, u_int8_t *data, int datalen)
3772 ccb = cam_getccb(device);
3775 errx(1, "mode_select: couldn't allocate CCB");
3777 bzero(&(&ccb->ccb_h)[1],
3778 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3780 scsi_mode_select(&ccb->csio,
3781 /* retries */ retry_count,
3783 /* tag_action */ MSG_SIMPLE_Q_TAG,
3784 /* scsi_page_fmt */ 1,
3785 /* save_pages */ save_pages,
3786 /* param_buf */ data,
3787 /* param_len */ datalen,
3788 /* sense_len */ SSD_FULL_SIZE,
3789 /* timeout */ timeout ? timeout : 5000);
3791 if (arglist & CAM_ARG_ERR_RECOVER)
3792 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3794 /* Disable freezing the device queue */
3795 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3797 if (((retval = cam_send_ccb(device, ccb)) < 0)
3798 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3799 if (arglist & CAM_ARG_VERBOSE) {
3800 cam_error_print(device, ccb, CAM_ESF_ALL,
3801 CAM_EPF_ALL, stderr);
3804 cam_close_device(device);
3807 err(1, "error sending mode select command");
3809 errx(1, "error sending mode select command");
3817 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
3818 int retry_count, int timeout)
3820 int c, mode_page = -1, page_control = 0;
3821 int binary = 0, list = 0;
3823 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3829 arglist |= CAM_ARG_DBD;
3832 arglist |= CAM_ARG_MODE_EDIT;
3838 mode_page = strtol(optarg, NULL, 0);
3840 errx(1, "invalid mode page %d", mode_page);
3843 page_control = strtol(optarg, NULL, 0);
3844 if ((page_control < 0) || (page_control > 3))
3845 errx(1, "invalid page control field %d",
3847 arglist |= CAM_ARG_PAGE_CNTL;
3854 if (mode_page == -1 && list == 0)
3855 errx(1, "you must specify a mode page!");
3858 mode_list(device, page_control, arglist & CAM_ARG_DBD,
3859 retry_count, timeout);
3861 mode_edit(device, mode_page, page_control,
3862 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
3863 retry_count, timeout);
3868 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
3869 int retry_count, int timeout)
3872 u_int32_t flags = CAM_DIR_NONE;
3873 u_int8_t *data_ptr = NULL;
3875 u_int8_t atacmd[12];
3876 struct get_hook hook;
3877 int c, data_bytes = 0;
3883 char *datastr = NULL, *tstr, *resstr = NULL;
3885 int fd_data = 0, fd_res = 0;
3888 ccb = cam_getccb(device);
3891 warnx("scsicmd: error allocating ccb");
3895 bzero(&(&ccb->ccb_h)[1],
3896 sizeof(union ccb) - sizeof(struct ccb_hdr));
3898 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3902 while (isspace(*tstr) && (*tstr != '\0'))
3904 hook.argc = argc - optind;
3905 hook.argv = argv + optind;
3907 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
3910 * Increment optind by the number of arguments the
3911 * encoding routine processed. After each call to
3912 * getopt(3), optind points to the argument that
3913 * getopt should process _next_. In this case,
3914 * that means it points to the first command string
3915 * argument, if there is one. Once we increment
3916 * this, it should point to either the next command
3917 * line argument, or it should be past the end of
3924 while (isspace(*tstr) && (*tstr != '\0'))
3926 hook.argc = argc - optind;
3927 hook.argv = argv + optind;
3929 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
3932 * Increment optind by the number of arguments the
3933 * encoding routine processed. After each call to
3934 * getopt(3), optind points to the argument that
3935 * getopt should process _next_. In this case,
3936 * that means it points to the first command string
3937 * argument, if there is one. Once we increment
3938 * this, it should point to either the next command
3939 * line argument, or it should be past the end of
3951 if (arglist & CAM_ARG_CMD_OUT) {
3952 warnx("command must either be "
3953 "read or write, not both");
3955 goto scsicmd_bailout;
3957 arglist |= CAM_ARG_CMD_IN;
3959 data_bytes = strtol(optarg, NULL, 0);
3960 if (data_bytes <= 0) {
3961 warnx("invalid number of input bytes %d",
3964 goto scsicmd_bailout;
3966 hook.argc = argc - optind;
3967 hook.argv = argv + optind;
3970 datastr = cget(&hook, NULL);
3972 * If the user supplied "-" instead of a format, he
3973 * wants the data to be written to stdout.
3975 if ((datastr != NULL)
3976 && (datastr[0] == '-'))
3979 data_ptr = (u_int8_t *)malloc(data_bytes);
3980 if (data_ptr == NULL) {
3981 warnx("can't malloc memory for data_ptr");
3983 goto scsicmd_bailout;
3987 if (arglist & CAM_ARG_CMD_IN) {
3988 warnx("command must either be "
3989 "read or write, not both");
3991 goto scsicmd_bailout;
3993 arglist |= CAM_ARG_CMD_OUT;
3994 flags = CAM_DIR_OUT;
3995 data_bytes = strtol(optarg, NULL, 0);
3996 if (data_bytes <= 0) {
3997 warnx("invalid number of output bytes %d",
4000 goto scsicmd_bailout;
4002 hook.argc = argc - optind;
4003 hook.argv = argv + optind;
4005 datastr = cget(&hook, NULL);
4006 data_ptr = (u_int8_t *)malloc(data_bytes);
4007 if (data_ptr == NULL) {
4008 warnx("can't malloc memory for data_ptr");
4010 goto scsicmd_bailout;
4012 bzero(data_ptr, data_bytes);
4014 * If the user supplied "-" instead of a format, he
4015 * wants the data to be read from stdin.
4017 if ((datastr != NULL)
4018 && (datastr[0] == '-'))
4021 buff_encode_visit(data_ptr, data_bytes, datastr,
4027 hook.argc = argc - optind;
4028 hook.argv = argv + optind;
4030 resstr = cget(&hook, NULL);
4031 if ((resstr != NULL) && (resstr[0] == '-'))
4041 * If fd_data is set, and we're writing to the device, we need to
4042 * read the data the user wants written from stdin.
4044 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4046 int amt_to_read = data_bytes;
4047 u_int8_t *buf_ptr = data_ptr;
4049 for (amt_read = 0; amt_to_read > 0;
4050 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4051 if (amt_read == -1) {
4052 warn("error reading data from stdin");
4054 goto scsicmd_bailout;
4056 amt_to_read -= amt_read;
4057 buf_ptr += amt_read;
4061 if (arglist & CAM_ARG_ERR_RECOVER)
4062 flags |= CAM_PASS_ERR_RECOVER;
4064 /* Disable freezing the device queue */
4065 flags |= CAM_DEV_QFRZDIS;
4069 * This is taken from the SCSI-3 draft spec.
4070 * (T10/1157D revision 0.3)
4071 * The top 3 bits of an opcode are the group code.
4072 * The next 5 bits are the command code.
4073 * Group 0: six byte commands
4074 * Group 1: ten byte commands
4075 * Group 2: ten byte commands
4077 * Group 4: sixteen byte commands
4078 * Group 5: twelve byte commands
4079 * Group 6: vendor specific
4080 * Group 7: vendor specific
4082 switch((cdb[0] >> 5) & 0x7) {
4093 /* computed by buff_encode_visit */
4104 * We should probably use csio_build_visit or something like that
4105 * here, but it's easier to encode arguments as you go. The
4106 * alternative would be skipping the CDB argument and then encoding
4107 * it here, since we've got the data buffer argument by now.
4109 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4111 cam_fill_csio(&ccb->csio,
4112 /*retries*/ retry_count,
4115 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4116 /*data_ptr*/ data_ptr,
4117 /*dxfer_len*/ data_bytes,
4118 /*sense_len*/ SSD_FULL_SIZE,
4119 /*cdb_len*/ cdb_len,
4120 /*timeout*/ timeout ? timeout : 5000);
4123 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4125 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4127 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4129 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4131 cam_fill_ataio(&ccb->ataio,
4132 /*retries*/ retry_count,
4136 /*data_ptr*/ data_ptr,
4137 /*dxfer_len*/ data_bytes,
4138 /*timeout*/ timeout ? timeout : 5000);
4141 if (((retval = cam_send_ccb(device, ccb)) < 0)
4142 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4143 const char warnstr[] = "error sending command";
4150 if (arglist & CAM_ARG_VERBOSE) {
4151 cam_error_print(device, ccb, CAM_ESF_ALL,
4152 CAM_EPF_ALL, stderr);
4156 goto scsicmd_bailout;
4159 if (atacmd_len && need_res) {
4161 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4163 fprintf(stdout, "\n");
4166 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4167 ccb->ataio.res.status,
4168 ccb->ataio.res.error,
4169 ccb->ataio.res.lba_low,
4170 ccb->ataio.res.lba_mid,
4171 ccb->ataio.res.lba_high,
4172 ccb->ataio.res.device,
4173 ccb->ataio.res.lba_low_exp,
4174 ccb->ataio.res.lba_mid_exp,
4175 ccb->ataio.res.lba_high_exp,
4176 ccb->ataio.res.sector_count,
4177 ccb->ataio.res.sector_count_exp);
4182 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4183 && (arglist & CAM_ARG_CMD_IN)
4184 && (data_bytes > 0)) {
4186 buff_decode_visit(data_ptr, data_bytes, datastr,
4188 fprintf(stdout, "\n");
4190 ssize_t amt_written;
4191 int amt_to_write = data_bytes;
4192 u_int8_t *buf_ptr = data_ptr;
4194 for (amt_written = 0; (amt_to_write > 0) &&
4195 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4196 amt_to_write -= amt_written;
4197 buf_ptr += amt_written;
4199 if (amt_written == -1) {
4200 warn("error writing data to stdout");
4202 goto scsicmd_bailout;
4203 } else if ((amt_written == 0)
4204 && (amt_to_write > 0)) {
4205 warnx("only wrote %u bytes out of %u",
4206 data_bytes - amt_to_write, data_bytes);
4213 if ((data_bytes > 0) && (data_ptr != NULL))
4222 camdebug(int argc, char **argv, char *combinedopt)
4225 path_id_t bus = CAM_BUS_WILDCARD;
4226 target_id_t target = CAM_TARGET_WILDCARD;
4227 lun_id_t lun = CAM_LUN_WILDCARD;
4228 char *tstr, *tmpstr = NULL;
4232 bzero(&ccb, sizeof(union ccb));
4234 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4237 arglist |= CAM_ARG_DEBUG_INFO;
4238 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4241 arglist |= CAM_ARG_DEBUG_PERIPH;
4242 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4245 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4246 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4249 arglist |= CAM_ARG_DEBUG_TRACE;
4250 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4253 arglist |= CAM_ARG_DEBUG_XPT;
4254 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4257 arglist |= CAM_ARG_DEBUG_CDB;
4258 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4261 arglist |= CAM_ARG_DEBUG_PROBE;
4262 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4269 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4270 warnx("error opening transport layer device %s", XPT_DEVICE);
4271 warn("%s", XPT_DEVICE);
4278 warnx("you must specify \"off\", \"all\" or a bus,");
4279 warnx("bus:target, or bus:target:lun");
4286 while (isspace(*tstr) && (*tstr != '\0'))
4289 if (strncmp(tstr, "off", 3) == 0) {
4290 ccb.cdbg.flags = CAM_DEBUG_NONE;
4291 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4292 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4293 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4294 } else if (strncmp(tstr, "all", 3) != 0) {
4295 tmpstr = (char *)strtok(tstr, ":");
4296 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4297 bus = strtol(tmpstr, NULL, 0);
4298 arglist |= CAM_ARG_BUS;
4299 tmpstr = (char *)strtok(NULL, ":");
4300 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4301 target = strtol(tmpstr, NULL, 0);
4302 arglist |= CAM_ARG_TARGET;
4303 tmpstr = (char *)strtok(NULL, ":");
4304 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4305 lun = strtol(tmpstr, NULL, 0);
4306 arglist |= CAM_ARG_LUN;
4311 warnx("you must specify \"all\", \"off\", or a bus,");
4312 warnx("bus:target, or bus:target:lun to debug");
4318 ccb.ccb_h.func_code = XPT_DEBUG;
4319 ccb.ccb_h.path_id = bus;
4320 ccb.ccb_h.target_id = target;
4321 ccb.ccb_h.target_lun = lun;
4323 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4324 warn("CAMIOCOMMAND ioctl failed");
4329 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4330 CAM_FUNC_NOTAVAIL) {
4331 warnx("CAM debugging not available");
4332 warnx("you need to put options CAMDEBUG in"
4333 " your kernel config file!");
4335 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4337 warnx("XPT_DEBUG CCB failed with status %#x",
4341 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4343 "Debugging turned off\n");
4346 "Debugging enabled for "
4348 bus, target, (uintmax_t)lun);
4359 tagcontrol(struct cam_device *device, int argc, char **argv,
4369 ccb = cam_getccb(device);
4372 warnx("tagcontrol: error allocating ccb");
4376 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4379 numtags = strtol(optarg, NULL, 0);
4381 warnx("tag count %d is < 0", numtags);
4383 goto tagcontrol_bailout;
4394 cam_path_string(device, pathstr, sizeof(pathstr));
4397 bzero(&(&ccb->ccb_h)[1],
4398 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4399 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4400 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4401 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4402 ccb->crs.openings = numtags;
4405 if (cam_send_ccb(device, ccb) < 0) {
4406 perror("error sending XPT_REL_SIMQ CCB");
4408 goto tagcontrol_bailout;
4411 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4412 warnx("XPT_REL_SIMQ CCB failed");
4413 cam_error_print(device, ccb, CAM_ESF_ALL,
4414 CAM_EPF_ALL, stderr);
4416 goto tagcontrol_bailout;
4421 fprintf(stdout, "%stagged openings now %d\n",
4422 pathstr, ccb->crs.openings);
4425 bzero(&(&ccb->ccb_h)[1],
4426 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4428 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4430 if (cam_send_ccb(device, ccb) < 0) {
4431 perror("error sending XPT_GDEV_STATS CCB");
4433 goto tagcontrol_bailout;
4436 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4437 warnx("XPT_GDEV_STATS CCB failed");
4438 cam_error_print(device, ccb, CAM_ESF_ALL,
4439 CAM_EPF_ALL, stderr);
4441 goto tagcontrol_bailout;
4444 if (arglist & CAM_ARG_VERBOSE) {
4445 fprintf(stdout, "%s", pathstr);
4446 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4447 fprintf(stdout, "%s", pathstr);
4448 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4449 fprintf(stdout, "%s", pathstr);
4450 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
4451 fprintf(stdout, "%s", pathstr);
4452 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
4453 fprintf(stdout, "%s", pathstr);
4454 fprintf(stdout, "held %d\n", ccb->cgds.held);
4455 fprintf(stdout, "%s", pathstr);
4456 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4457 fprintf(stdout, "%s", pathstr);
4458 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4461 fprintf(stdout, "%s", pathstr);
4462 fprintf(stdout, "device openings: ");
4464 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4465 ccb->cgds.dev_active);
4475 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4479 cam_path_string(device, pathstr, sizeof(pathstr));
4481 if (cts->transport == XPORT_SPI) {
4482 struct ccb_trans_settings_spi *spi =
4483 &cts->xport_specific.spi;
4485 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4487 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4490 if (spi->sync_offset != 0) {
4493 freq = scsi_calc_syncsrate(spi->sync_period);
4494 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4495 pathstr, freq / 1000, freq % 1000);
4499 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4500 fprintf(stdout, "%soffset: %d\n", pathstr,
4504 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4505 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4506 (0x01 << spi->bus_width) * 8);
4509 if (spi->valid & CTS_SPI_VALID_DISC) {
4510 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4511 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4512 "enabled" : "disabled");
4515 if (cts->transport == XPORT_FC) {
4516 struct ccb_trans_settings_fc *fc =
4517 &cts->xport_specific.fc;
4519 if (fc->valid & CTS_FC_VALID_WWNN)
4520 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4521 (long long) fc->wwnn);
4522 if (fc->valid & CTS_FC_VALID_WWPN)
4523 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4524 (long long) fc->wwpn);
4525 if (fc->valid & CTS_FC_VALID_PORT)
4526 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4527 if (fc->valid & CTS_FC_VALID_SPEED)
4528 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4529 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4531 if (cts->transport == XPORT_SAS) {
4532 struct ccb_trans_settings_sas *sas =
4533 &cts->xport_specific.sas;
4535 if (sas->valid & CTS_SAS_VALID_SPEED)
4536 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4537 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4539 if (cts->transport == XPORT_ATA) {
4540 struct ccb_trans_settings_pata *pata =
4541 &cts->xport_specific.ata;
4543 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4544 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4545 ata_mode2string(pata->mode));
4547 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4548 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4551 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4552 fprintf(stdout, "%sPIO transaction length: %d\n",
4553 pathstr, pata->bytecount);
4556 if (cts->transport == XPORT_SATA) {
4557 struct ccb_trans_settings_sata *sata =
4558 &cts->xport_specific.sata;
4560 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4561 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4564 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4565 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4566 ata_mode2string(sata->mode));
4568 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4569 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4572 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4573 fprintf(stdout, "%sPIO transaction length: %d\n",
4574 pathstr, sata->bytecount);
4576 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4577 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4580 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4581 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4584 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4585 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4589 if (cts->protocol == PROTO_ATA) {
4590 struct ccb_trans_settings_ata *ata=
4591 &cts->proto_specific.ata;
4593 if (ata->valid & CTS_ATA_VALID_TQ) {
4594 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4595 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4596 "enabled" : "disabled");
4599 if (cts->protocol == PROTO_SCSI) {
4600 struct ccb_trans_settings_scsi *scsi=
4601 &cts->proto_specific.scsi;
4603 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4604 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4605 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4606 "enabled" : "disabled");
4613 * Get a path inquiry CCB for the specified device.
4616 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4621 ccb = cam_getccb(device);
4623 warnx("get_cpi: couldn't allocate CCB");
4626 bzero(&(&ccb->ccb_h)[1],
4627 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4628 ccb->ccb_h.func_code = XPT_PATH_INQ;
4629 if (cam_send_ccb(device, ccb) < 0) {
4630 warn("get_cpi: error sending Path Inquiry CCB");
4631 if (arglist & CAM_ARG_VERBOSE)
4632 cam_error_print(device, ccb, CAM_ESF_ALL,
4633 CAM_EPF_ALL, stderr);
4635 goto get_cpi_bailout;
4637 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4638 if (arglist & CAM_ARG_VERBOSE)
4639 cam_error_print(device, ccb, CAM_ESF_ALL,
4640 CAM_EPF_ALL, stderr);
4642 goto get_cpi_bailout;
4644 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4652 * Get a get device CCB for the specified device.
4655 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4660 ccb = cam_getccb(device);
4662 warnx("get_cgd: couldn't allocate CCB");
4665 bzero(&(&ccb->ccb_h)[1],
4666 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4667 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4668 if (cam_send_ccb(device, ccb) < 0) {
4669 warn("get_cgd: error sending Path Inquiry CCB");
4670 if (arglist & CAM_ARG_VERBOSE)
4671 cam_error_print(device, ccb, CAM_ESF_ALL,
4672 CAM_EPF_ALL, stderr);
4674 goto get_cgd_bailout;
4676 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4677 if (arglist & CAM_ARG_VERBOSE)
4678 cam_error_print(device, ccb, CAM_ESF_ALL,
4679 CAM_EPF_ALL, stderr);
4681 goto get_cgd_bailout;
4683 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4690 /* return the type of disk (really the command type) */
4692 get_disk_type(struct cam_device *device)
4694 struct ccb_getdev cgd;
4696 (void) memset(&cgd, 0x0, sizeof(cgd));
4697 get_cgd(device, &cgd);
4698 switch(cgd.protocol) {
4711 cpi_print(struct ccb_pathinq *cpi)
4713 char adapter_str[1024];
4716 snprintf(adapter_str, sizeof(adapter_str),
4717 "%s%d:", cpi->dev_name, cpi->unit_number);
4719 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
4722 for (i = 1; i < 0xff; i = i << 1) {
4725 if ((i & cpi->hba_inquiry) == 0)
4728 fprintf(stdout, "%s supports ", adapter_str);
4732 str = "MDP message";
4735 str = "32 bit wide SCSI";
4738 str = "16 bit wide SCSI";
4741 str = "SDTR message";
4744 str = "linked CDBs";
4747 str = "tag queue messages";
4750 str = "soft reset alternative";
4753 str = "SATA Port Multiplier";
4756 str = "unknown PI bit set";
4759 fprintf(stdout, "%s\n", str);
4762 for (i = 1; i < 0xff; i = i << 1) {
4765 if ((i & cpi->hba_misc) == 0)
4768 fprintf(stdout, "%s ", adapter_str);
4772 str = "bus scans from high ID to low ID";
4775 str = "removable devices not included in scan";
4777 case PIM_NOINITIATOR:
4778 str = "initiator role not supported";
4780 case PIM_NOBUSRESET:
4781 str = "user has disabled initial BUS RESET or"
4782 " controller is in target/mixed mode";
4785 str = "do not send 6-byte commands";
4788 str = "scan bus sequentially";
4791 str = "unknown PIM bit set";
4794 fprintf(stdout, "%s\n", str);
4797 for (i = 1; i < 0xff; i = i << 1) {
4800 if ((i & cpi->target_sprt) == 0)
4803 fprintf(stdout, "%s supports ", adapter_str);
4806 str = "target mode processor mode";
4809 str = "target mode phase cog. mode";
4811 case PIT_DISCONNECT:
4812 str = "disconnects in target mode";
4815 str = "terminate I/O message in target mode";
4818 str = "group 6 commands in target mode";
4821 str = "group 7 commands in target mode";
4824 str = "unknown PIT bit set";
4828 fprintf(stdout, "%s\n", str);
4830 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
4832 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
4834 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
4836 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
4837 adapter_str, cpi->hpath_id);
4838 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
4840 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
4841 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
4842 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
4843 adapter_str, cpi->hba_vendor);
4844 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
4845 adapter_str, cpi->hba_device);
4846 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
4847 adapter_str, cpi->hba_subvendor);
4848 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
4849 adapter_str, cpi->hba_subdevice);
4850 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
4851 fprintf(stdout, "%s base transfer speed: ", adapter_str);
4852 if (cpi->base_transfer_speed > 1000)
4853 fprintf(stdout, "%d.%03dMB/sec\n",
4854 cpi->base_transfer_speed / 1000,
4855 cpi->base_transfer_speed % 1000);
4857 fprintf(stdout, "%dKB/sec\n",
4858 (cpi->base_transfer_speed % 1000) * 1000);
4859 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
4860 adapter_str, cpi->maxio);
4864 get_print_cts(struct cam_device *device, int user_settings, int quiet,
4865 struct ccb_trans_settings *cts)
4871 ccb = cam_getccb(device);
4874 warnx("get_print_cts: error allocating ccb");
4878 bzero(&(&ccb->ccb_h)[1],
4879 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4881 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
4883 if (user_settings == 0)
4884 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
4886 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
4888 if (cam_send_ccb(device, ccb) < 0) {
4889 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
4890 if (arglist & CAM_ARG_VERBOSE)
4891 cam_error_print(device, ccb, CAM_ESF_ALL,
4892 CAM_EPF_ALL, stderr);
4894 goto get_print_cts_bailout;
4897 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4898 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
4899 if (arglist & CAM_ARG_VERBOSE)
4900 cam_error_print(device, ccb, CAM_ESF_ALL,
4901 CAM_EPF_ALL, stderr);
4903 goto get_print_cts_bailout;
4907 cts_print(device, &ccb->cts);
4910 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
4912 get_print_cts_bailout:
4920 ratecontrol(struct cam_device *device, int retry_count, int timeout,
4921 int argc, char **argv, char *combinedopt)
4925 int user_settings = 0;
4927 int disc_enable = -1, tag_enable = -1;
4930 double syncrate = -1;
4933 int change_settings = 0, send_tur = 0;
4934 struct ccb_pathinq cpi;
4936 ccb = cam_getccb(device);
4938 warnx("ratecontrol: error allocating ccb");
4941 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4950 if (strncasecmp(optarg, "enable", 6) == 0)
4952 else if (strncasecmp(optarg, "disable", 7) == 0)
4955 warnx("-D argument \"%s\" is unknown", optarg);
4957 goto ratecontrol_bailout;
4959 change_settings = 1;
4962 mode = ata_string2mode(optarg);
4964 warnx("unknown mode '%s'", optarg);
4966 goto ratecontrol_bailout;
4968 change_settings = 1;
4971 offset = strtol(optarg, NULL, 0);
4973 warnx("offset value %d is < 0", offset);
4975 goto ratecontrol_bailout;
4977 change_settings = 1;
4983 syncrate = atof(optarg);
4985 warnx("sync rate %f is < 0", syncrate);
4987 goto ratecontrol_bailout;
4989 change_settings = 1;
4992 if (strncasecmp(optarg, "enable", 6) == 0)
4994 else if (strncasecmp(optarg, "disable", 7) == 0)
4997 warnx("-T argument \"%s\" is unknown", optarg);
4999 goto ratecontrol_bailout;
5001 change_settings = 1;
5007 bus_width = strtol(optarg, NULL, 0);
5008 if (bus_width < 0) {
5009 warnx("bus width %d is < 0", bus_width);
5011 goto ratecontrol_bailout;
5013 change_settings = 1;
5019 bzero(&(&ccb->ccb_h)[1],
5020 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
5022 * Grab path inquiry information, so we can determine whether
5023 * or not the initiator is capable of the things that the user
5026 ccb->ccb_h.func_code = XPT_PATH_INQ;
5027 if (cam_send_ccb(device, ccb) < 0) {
5028 perror("error sending XPT_PATH_INQ CCB");
5029 if (arglist & CAM_ARG_VERBOSE) {
5030 cam_error_print(device, ccb, CAM_ESF_ALL,
5031 CAM_EPF_ALL, stderr);
5034 goto ratecontrol_bailout;
5036 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5037 warnx("XPT_PATH_INQ CCB failed");
5038 if (arglist & CAM_ARG_VERBOSE) {
5039 cam_error_print(device, ccb, CAM_ESF_ALL,
5040 CAM_EPF_ALL, stderr);
5043 goto ratecontrol_bailout;
5045 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5046 bzero(&(&ccb->ccb_h)[1],
5047 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5049 fprintf(stdout, "%s parameters:\n",
5050 user_settings ? "User" : "Current");
5052 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5054 goto ratecontrol_bailout;
5056 if (arglist & CAM_ARG_VERBOSE)
5059 if (change_settings) {
5060 int didsettings = 0;
5061 struct ccb_trans_settings_spi *spi = NULL;
5062 struct ccb_trans_settings_pata *pata = NULL;
5063 struct ccb_trans_settings_sata *sata = NULL;
5064 struct ccb_trans_settings_ata *ata = NULL;
5065 struct ccb_trans_settings_scsi *scsi = NULL;
5067 if (ccb->cts.transport == XPORT_SPI)
5068 spi = &ccb->cts.xport_specific.spi;
5069 if (ccb->cts.transport == XPORT_ATA)
5070 pata = &ccb->cts.xport_specific.ata;
5071 if (ccb->cts.transport == XPORT_SATA)
5072 sata = &ccb->cts.xport_specific.sata;
5073 if (ccb->cts.protocol == PROTO_ATA)
5074 ata = &ccb->cts.proto_specific.ata;
5075 if (ccb->cts.protocol == PROTO_SCSI)
5076 scsi = &ccb->cts.proto_specific.scsi;
5077 ccb->cts.xport_specific.valid = 0;
5078 ccb->cts.proto_specific.valid = 0;
5079 if (spi && disc_enable != -1) {
5080 spi->valid |= CTS_SPI_VALID_DISC;
5081 if (disc_enable == 0)
5082 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5084 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5087 if (tag_enable != -1) {
5088 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5089 warnx("HBA does not support tagged queueing, "
5090 "so you cannot modify tag settings");
5092 goto ratecontrol_bailout;
5095 ata->valid |= CTS_SCSI_VALID_TQ;
5096 if (tag_enable == 0)
5097 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5099 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5102 scsi->valid |= CTS_SCSI_VALID_TQ;
5103 if (tag_enable == 0)
5104 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5106 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5110 if (spi && offset != -1) {
5111 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5112 warnx("HBA is not capable of changing offset");
5114 goto ratecontrol_bailout;
5116 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5117 spi->sync_offset = offset;
5120 if (spi && syncrate != -1) {
5121 int prelim_sync_period;
5123 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5124 warnx("HBA is not capable of changing "
5127 goto ratecontrol_bailout;
5129 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5131 * The sync rate the user gives us is in MHz.
5132 * We need to translate it into KHz for this
5137 * Next, we calculate a "preliminary" sync period
5138 * in tenths of a nanosecond.
5141 prelim_sync_period = 0;
5143 prelim_sync_period = 10000000 / syncrate;
5145 scsi_calc_syncparam(prelim_sync_period);
5148 if (sata && syncrate != -1) {
5149 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5150 warnx("HBA is not capable of changing "
5153 goto ratecontrol_bailout;
5155 if (!user_settings) {
5156 warnx("You can modify only user rate "
5157 "settings for SATA");
5159 goto ratecontrol_bailout;
5161 sata->revision = ata_speed2revision(syncrate * 100);
5162 if (sata->revision < 0) {
5163 warnx("Invalid rate %f", syncrate);
5165 goto ratecontrol_bailout;
5167 sata->valid |= CTS_SATA_VALID_REVISION;
5170 if ((pata || sata) && mode != -1) {
5171 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5172 warnx("HBA is not capable of changing "
5175 goto ratecontrol_bailout;
5177 if (!user_settings) {
5178 warnx("You can modify only user mode "
5179 "settings for ATA/SATA");
5181 goto ratecontrol_bailout;
5185 pata->valid |= CTS_ATA_VALID_MODE;
5188 sata->valid |= CTS_SATA_VALID_MODE;
5193 * The bus_width argument goes like this:
5197 * Therefore, if you shift the number of bits given on the
5198 * command line right by 4, you should get the correct
5201 if (spi && bus_width != -1) {
5203 * We might as well validate things here with a
5204 * decipherable error message, rather than what
5205 * will probably be an indecipherable error message
5206 * by the time it gets back to us.
5208 if ((bus_width == 16)
5209 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5210 warnx("HBA does not support 16 bit bus width");
5212 goto ratecontrol_bailout;
5213 } else if ((bus_width == 32)
5214 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5215 warnx("HBA does not support 32 bit bus width");
5217 goto ratecontrol_bailout;
5218 } else if ((bus_width != 8)
5219 && (bus_width != 16)
5220 && (bus_width != 32)) {
5221 warnx("Invalid bus width %d", bus_width);
5223 goto ratecontrol_bailout;
5225 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5226 spi->bus_width = bus_width >> 4;
5229 if (didsettings == 0) {
5230 goto ratecontrol_bailout;
5232 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5233 if (cam_send_ccb(device, ccb) < 0) {
5234 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5235 if (arglist & CAM_ARG_VERBOSE) {
5236 cam_error_print(device, ccb, CAM_ESF_ALL,
5237 CAM_EPF_ALL, stderr);
5240 goto ratecontrol_bailout;
5242 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5243 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5244 if (arglist & CAM_ARG_VERBOSE) {
5245 cam_error_print(device, ccb, CAM_ESF_ALL,
5246 CAM_EPF_ALL, stderr);
5249 goto ratecontrol_bailout;
5253 retval = testunitready(device, retry_count, timeout,
5254 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5256 * If the TUR didn't succeed, just bail.
5260 fprintf(stderr, "Test Unit Ready failed\n");
5261 goto ratecontrol_bailout;
5264 if ((change_settings || send_tur) && !quiet &&
5265 (ccb->cts.transport == XPORT_ATA ||
5266 ccb->cts.transport == XPORT_SATA || send_tur)) {
5267 fprintf(stdout, "New parameters:\n");
5268 retval = get_print_cts(device, user_settings, 0, NULL);
5271 ratecontrol_bailout:
5277 scsiformat(struct cam_device *device, int argc, char **argv,
5278 char *combinedopt, int retry_count, int timeout)
5282 int ycount = 0, quiet = 0;
5283 int error = 0, retval = 0;
5284 int use_timeout = 10800 * 1000;
5286 struct format_defect_list_header fh;
5287 u_int8_t *data_ptr = NULL;
5288 u_int32_t dxfer_len = 0;
5290 int num_warnings = 0;
5293 ccb = cam_getccb(device);
5296 warnx("scsiformat: error allocating ccb");
5300 bzero(&(&ccb->ccb_h)[1],
5301 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5303 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5324 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5325 "following device:\n");
5327 error = scsidoinquiry(device, argc, argv, combinedopt,
5328 retry_count, timeout);
5331 warnx("scsiformat: error sending inquiry");
5332 goto scsiformat_bailout;
5337 if (!get_confirmation()) {
5339 goto scsiformat_bailout;
5344 use_timeout = timeout;
5347 fprintf(stdout, "Current format timeout is %d seconds\n",
5348 use_timeout / 1000);
5352 * If the user hasn't disabled questions and didn't specify a
5353 * timeout on the command line, ask them if they want the current
5357 && (timeout == 0)) {
5359 int new_timeout = 0;
5361 fprintf(stdout, "Enter new timeout in seconds or press\n"
5362 "return to keep the current timeout [%d] ",
5363 use_timeout / 1000);
5365 if (fgets(str, sizeof(str), stdin) != NULL) {
5367 new_timeout = atoi(str);
5370 if (new_timeout != 0) {
5371 use_timeout = new_timeout * 1000;
5372 fprintf(stdout, "Using new timeout value %d\n",
5373 use_timeout / 1000);
5378 * Keep this outside the if block below to silence any unused
5379 * variable warnings.
5381 bzero(&fh, sizeof(fh));
5384 * If we're in immediate mode, we've got to include the format
5387 if (immediate != 0) {
5388 fh.byte2 = FU_DLH_IMMED;
5389 data_ptr = (u_int8_t *)&fh;
5390 dxfer_len = sizeof(fh);
5391 byte2 = FU_FMT_DATA;
5392 } else if (quiet == 0) {
5393 fprintf(stdout, "Formatting...");
5397 scsi_format_unit(&ccb->csio,
5398 /* retries */ retry_count,
5400 /* tag_action */ MSG_SIMPLE_Q_TAG,
5403 /* data_ptr */ data_ptr,
5404 /* dxfer_len */ dxfer_len,
5405 /* sense_len */ SSD_FULL_SIZE,
5406 /* timeout */ use_timeout);
5408 /* Disable freezing the device queue */
5409 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5411 if (arglist & CAM_ARG_ERR_RECOVER)
5412 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5414 if (((retval = cam_send_ccb(device, ccb)) < 0)
5415 || ((immediate == 0)
5416 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5417 const char errstr[] = "error sending format command";
5424 if (arglist & CAM_ARG_VERBOSE) {
5425 cam_error_print(device, ccb, CAM_ESF_ALL,
5426 CAM_EPF_ALL, stderr);
5429 goto scsiformat_bailout;
5433 * If we ran in non-immediate mode, we already checked for errors
5434 * above and printed out any necessary information. If we're in
5435 * immediate mode, we need to loop through and get status
5436 * information periodically.
5438 if (immediate == 0) {
5440 fprintf(stdout, "Format Complete\n");
5442 goto scsiformat_bailout;
5449 bzero(&(&ccb->ccb_h)[1],
5450 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5453 * There's really no need to do error recovery or
5454 * retries here, since we're just going to sit in a
5455 * loop and wait for the device to finish formatting.
5457 scsi_test_unit_ready(&ccb->csio,
5460 /* tag_action */ MSG_SIMPLE_Q_TAG,
5461 /* sense_len */ SSD_FULL_SIZE,
5462 /* timeout */ 5000);
5464 /* Disable freezing the device queue */
5465 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5467 retval = cam_send_ccb(device, ccb);
5470 * If we get an error from the ioctl, bail out. SCSI
5471 * errors are expected.
5474 warn("error sending CAMIOCOMMAND ioctl");
5475 if (arglist & CAM_ARG_VERBOSE) {
5476 cam_error_print(device, ccb, CAM_ESF_ALL,
5477 CAM_EPF_ALL, stderr);
5480 goto scsiformat_bailout;
5483 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5485 if ((status != CAM_REQ_CMP)
5486 && (status == CAM_SCSI_STATUS_ERROR)
5487 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5488 struct scsi_sense_data *sense;
5489 int error_code, sense_key, asc, ascq;
5491 sense = &ccb->csio.sense_data;
5492 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5493 ccb->csio.sense_resid, &error_code, &sense_key,
5494 &asc, &ascq, /*show_errors*/ 1);
5497 * According to the SCSI-2 and SCSI-3 specs, a
5498 * drive that is in the middle of a format should
5499 * return NOT READY with an ASC of "logical unit
5500 * not ready, format in progress". The sense key
5501 * specific bytes will then be a progress indicator.
5503 if ((sense_key == SSD_KEY_NOT_READY)
5504 && (asc == 0x04) && (ascq == 0x04)) {
5507 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5508 ccb->csio.sense_resid, sks) == 0)
5511 u_int64_t percentage;
5513 val = scsi_2btoul(&sks[1]);
5514 percentage = 10000 * val;
5517 "\rFormatting: %ju.%02u %% "
5519 (uintmax_t)(percentage /
5521 (unsigned)((percentage /
5525 } else if ((quiet == 0)
5526 && (++num_warnings <= 1)) {
5527 warnx("Unexpected SCSI Sense Key "
5528 "Specific value returned "
5530 scsi_sense_print(device, &ccb->csio,
5532 warnx("Unable to print status "
5533 "information, but format will "
5535 warnx("will exit when format is "
5540 warnx("Unexpected SCSI error during format");
5541 cam_error_print(device, ccb, CAM_ESF_ALL,
5542 CAM_EPF_ALL, stderr);
5544 goto scsiformat_bailout;
5547 } else if (status != CAM_REQ_CMP) {
5548 warnx("Unexpected CAM status %#x", status);
5549 if (arglist & CAM_ARG_VERBOSE)
5550 cam_error_print(device, ccb, CAM_ESF_ALL,
5551 CAM_EPF_ALL, stderr);
5553 goto scsiformat_bailout;
5556 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5559 fprintf(stdout, "\nFormat Complete\n");
5569 scsisanitize(struct cam_device *device, int argc, char **argv,
5570 char *combinedopt, int retry_count, int timeout)
5573 u_int8_t action = 0;
5575 int ycount = 0, quiet = 0;
5576 int error = 0, retval = 0;
5577 int use_timeout = 10800 * 1000;
5583 const char *pattern = NULL;
5584 u_int8_t *data_ptr = NULL;
5585 u_int32_t dxfer_len = 0;
5587 int num_warnings = 0;
5590 ccb = cam_getccb(device);
5593 warnx("scsisanitize: error allocating ccb");
5597 bzero(&(&ccb->ccb_h)[1],
5598 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5600 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5603 if (strcasecmp(optarg, "overwrite") == 0)
5604 action = SSZ_SERVICE_ACTION_OVERWRITE;
5605 else if (strcasecmp(optarg, "block") == 0)
5606 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
5607 else if (strcasecmp(optarg, "crypto") == 0)
5608 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
5609 else if (strcasecmp(optarg, "exitfailure") == 0)
5610 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
5612 warnx("invalid service operation \"%s\"",
5615 goto scsisanitize_bailout;
5619 passes = strtol(optarg, NULL, 0);
5620 if (passes < 1 || passes > 31) {
5621 warnx("invalid passes value %d", passes);
5623 goto scsisanitize_bailout;
5654 warnx("an action is required");
5656 goto scsisanitize_bailout;
5657 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
5658 struct scsi_sanitize_parameter_list *pl;
5662 if (pattern == NULL) {
5663 warnx("overwrite action requires -P argument");
5665 goto scsisanitize_bailout;
5667 fd = open(pattern, O_RDONLY);
5669 warn("cannot open pattern file %s", pattern);
5671 goto scsisanitize_bailout;
5673 if (fstat(fd, &sb) < 0) {
5674 warn("cannot stat pattern file %s", pattern);
5676 goto scsisanitize_bailout;
5679 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
5680 warnx("pattern file size exceeds maximum value %d",
5681 SSZPL_MAX_PATTERN_LENGTH);
5683 goto scsisanitize_bailout;
5685 dxfer_len = sizeof(*pl) + sz;
5686 data_ptr = calloc(1, dxfer_len);
5687 if (data_ptr == NULL) {
5688 warnx("cannot allocate parameter list buffer");
5690 goto scsisanitize_bailout;
5693 amt = read(fd, data_ptr + sizeof(*pl), sz);
5695 warn("cannot read pattern file");
5697 goto scsisanitize_bailout;
5698 } else if (amt != sz) {
5699 warnx("short pattern file read");
5701 goto scsisanitize_bailout;
5704 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
5710 pl->byte1 |= SSZPL_INVERT;
5711 scsi_ulto2b(sz, pl->length);
5717 else if (invert != 0)
5719 else if (pattern != NULL)
5724 warnx("%s argument only valid with overwrite "
5727 goto scsisanitize_bailout;
5732 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5733 "following device:\n");
5735 error = scsidoinquiry(device, argc, argv, combinedopt,
5736 retry_count, timeout);
5739 warnx("scsisanitize: error sending inquiry");
5740 goto scsisanitize_bailout;
5745 if (!get_confirmation()) {
5747 goto scsisanitize_bailout;
5752 use_timeout = timeout;
5755 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
5756 use_timeout / 1000);
5760 * If the user hasn't disabled questions and didn't specify a
5761 * timeout on the command line, ask them if they want the current
5765 && (timeout == 0)) {
5767 int new_timeout = 0;
5769 fprintf(stdout, "Enter new timeout in seconds or press\n"
5770 "return to keep the current timeout [%d] ",
5771 use_timeout / 1000);
5773 if (fgets(str, sizeof(str), stdin) != NULL) {
5775 new_timeout = atoi(str);
5778 if (new_timeout != 0) {
5779 use_timeout = new_timeout * 1000;
5780 fprintf(stdout, "Using new timeout value %d\n",
5781 use_timeout / 1000);
5787 byte2 |= SSZ_UNRESTRICTED_EXIT;
5791 scsi_sanitize(&ccb->csio,
5792 /* retries */ retry_count,
5794 /* tag_action */ MSG_SIMPLE_Q_TAG,
5797 /* data_ptr */ data_ptr,
5798 /* dxfer_len */ dxfer_len,
5799 /* sense_len */ SSD_FULL_SIZE,
5800 /* timeout */ use_timeout);
5802 /* Disable freezing the device queue */
5803 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5805 if (arglist & CAM_ARG_ERR_RECOVER)
5806 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5808 if (((retval = cam_send_ccb(device, ccb)) < 0)
5809 || ((immediate == 0)
5810 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5811 const char errstr[] = "error sending sanitize command";
5818 if (arglist & CAM_ARG_VERBOSE) {
5819 cam_error_print(device, ccb, CAM_ESF_ALL,
5820 CAM_EPF_ALL, stderr);
5823 goto scsisanitize_bailout;
5827 * If we ran in non-immediate mode, we already checked for errors
5828 * above and printed out any necessary information. If we're in
5829 * immediate mode, we need to loop through and get status
5830 * information periodically.
5832 if (immediate == 0) {
5834 fprintf(stdout, "Sanitize Complete\n");
5836 goto scsisanitize_bailout;
5843 bzero(&(&ccb->ccb_h)[1],
5844 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5847 * There's really no need to do error recovery or
5848 * retries here, since we're just going to sit in a
5849 * loop and wait for the device to finish sanitizing.
5851 scsi_test_unit_ready(&ccb->csio,
5854 /* tag_action */ MSG_SIMPLE_Q_TAG,
5855 /* sense_len */ SSD_FULL_SIZE,
5856 /* timeout */ 5000);
5858 /* Disable freezing the device queue */
5859 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5861 retval = cam_send_ccb(device, ccb);
5864 * If we get an error from the ioctl, bail out. SCSI
5865 * errors are expected.
5868 warn("error sending CAMIOCOMMAND ioctl");
5869 if (arglist & CAM_ARG_VERBOSE) {
5870 cam_error_print(device, ccb, CAM_ESF_ALL,
5871 CAM_EPF_ALL, stderr);
5874 goto scsisanitize_bailout;
5877 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5879 if ((status != CAM_REQ_CMP)
5880 && (status == CAM_SCSI_STATUS_ERROR)
5881 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5882 struct scsi_sense_data *sense;
5883 int error_code, sense_key, asc, ascq;
5885 sense = &ccb->csio.sense_data;
5886 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5887 ccb->csio.sense_resid, &error_code, &sense_key,
5888 &asc, &ascq, /*show_errors*/ 1);
5891 * According to the SCSI-3 spec, a drive that is in the
5892 * middle of a sanitize should return NOT READY with an
5893 * ASC of "logical unit not ready, sanitize in
5894 * progress". The sense key specific bytes will then
5895 * be a progress indicator.
5897 if ((sense_key == SSD_KEY_NOT_READY)
5898 && (asc == 0x04) && (ascq == 0x1b)) {
5901 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5902 ccb->csio.sense_resid, sks) == 0)
5905 u_int64_t percentage;
5907 val = scsi_2btoul(&sks[1]);
5908 percentage = 10000 * val;
5911 "\rSanitizing: %ju.%02u %% "
5913 (uintmax_t)(percentage /
5915 (unsigned)((percentage /
5919 } else if ((quiet == 0)
5920 && (++num_warnings <= 1)) {
5921 warnx("Unexpected SCSI Sense Key "
5922 "Specific value returned "
5923 "during sanitize:");
5924 scsi_sense_print(device, &ccb->csio,
5926 warnx("Unable to print status "
5927 "information, but sanitze will "
5929 warnx("will exit when sanitize is "
5934 warnx("Unexpected SCSI error during sanitize");
5935 cam_error_print(device, ccb, CAM_ESF_ALL,
5936 CAM_EPF_ALL, stderr);
5938 goto scsisanitize_bailout;
5941 } else if (status != CAM_REQ_CMP) {
5942 warnx("Unexpected CAM status %#x", status);
5943 if (arglist & CAM_ARG_VERBOSE)
5944 cam_error_print(device, ccb, CAM_ESF_ALL,
5945 CAM_EPF_ALL, stderr);
5947 goto scsisanitize_bailout;
5949 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5952 fprintf(stdout, "\nSanitize Complete\n");
5954 scsisanitize_bailout:
5957 if (data_ptr != NULL)
5965 scsireportluns(struct cam_device *device, int argc, char **argv,
5966 char *combinedopt, int retry_count, int timeout)
5969 int c, countonly, lunsonly;
5970 struct scsi_report_luns_data *lundata;
5972 uint8_t report_type;
5973 uint32_t list_len, i, j;
5978 report_type = RPL_REPORT_DEFAULT;
5979 ccb = cam_getccb(device);
5982 warnx("%s: error allocating ccb", __func__);
5986 bzero(&(&ccb->ccb_h)[1],
5987 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5992 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6001 if (strcasecmp(optarg, "default") == 0)
6002 report_type = RPL_REPORT_DEFAULT;
6003 else if (strcasecmp(optarg, "wellknown") == 0)
6004 report_type = RPL_REPORT_WELLKNOWN;
6005 else if (strcasecmp(optarg, "all") == 0)
6006 report_type = RPL_REPORT_ALL;
6008 warnx("%s: invalid report type \"%s\"",
6019 if ((countonly != 0)
6020 && (lunsonly != 0)) {
6021 warnx("%s: you can only specify one of -c or -l", __func__);
6026 * According to SPC-4, the allocation length must be at least 16
6027 * bytes -- enough for the header and one LUN.
6029 alloc_len = sizeof(*lundata) + 8;
6033 lundata = malloc(alloc_len);
6035 if (lundata == NULL) {
6036 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6041 scsi_report_luns(&ccb->csio,
6042 /*retries*/ retry_count,
6044 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6045 /*select_report*/ report_type,
6046 /*rpl_buf*/ lundata,
6047 /*alloc_len*/ alloc_len,
6048 /*sense_len*/ SSD_FULL_SIZE,
6049 /*timeout*/ timeout ? timeout : 5000);
6051 /* Disable freezing the device queue */
6052 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6054 if (arglist & CAM_ARG_ERR_RECOVER)
6055 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6057 if (cam_send_ccb(device, ccb) < 0) {
6058 warn("error sending REPORT LUNS command");
6060 if (arglist & CAM_ARG_VERBOSE)
6061 cam_error_print(device, ccb, CAM_ESF_ALL,
6062 CAM_EPF_ALL, stderr);
6068 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6069 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6075 list_len = scsi_4btoul(lundata->length);
6078 * If we need to list the LUNs, and our allocation
6079 * length was too short, reallocate and retry.
6081 if ((countonly == 0)
6082 && (list_len > (alloc_len - sizeof(*lundata)))) {
6083 alloc_len = list_len + sizeof(*lundata);
6089 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6090 ((list_len / 8) > 1) ? "s" : "");
6095 for (i = 0; i < (list_len / 8); i++) {
6099 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6101 fprintf(stdout, ",");
6102 switch (lundata->luns[i].lundata[j] &
6103 RPL_LUNDATA_ATYP_MASK) {
6104 case RPL_LUNDATA_ATYP_PERIPH:
6105 if ((lundata->luns[i].lundata[j] &
6106 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6107 fprintf(stdout, "%d:",
6108 lundata->luns[i].lundata[j] &
6109 RPL_LUNDATA_PERIPH_BUS_MASK);
6111 && ((lundata->luns[i].lundata[j+2] &
6112 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6115 fprintf(stdout, "%d",
6116 lundata->luns[i].lundata[j+1]);
6118 case RPL_LUNDATA_ATYP_FLAT: {
6120 tmplun[0] = lundata->luns[i].lundata[j] &
6121 RPL_LUNDATA_FLAT_LUN_MASK;
6122 tmplun[1] = lundata->luns[i].lundata[j+1];
6124 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6128 case RPL_LUNDATA_ATYP_LUN:
6129 fprintf(stdout, "%d:%d:%d",
6130 (lundata->luns[i].lundata[j+1] &
6131 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6132 lundata->luns[i].lundata[j] &
6133 RPL_LUNDATA_LUN_TARG_MASK,
6134 lundata->luns[i].lundata[j+1] &
6135 RPL_LUNDATA_LUN_LUN_MASK);
6137 case RPL_LUNDATA_ATYP_EXTLUN: {
6138 int field_len_code, eam_code;
6140 eam_code = lundata->luns[i].lundata[j] &
6141 RPL_LUNDATA_EXT_EAM_MASK;
6142 field_len_code = (lundata->luns[i].lundata[j] &
6143 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6145 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6146 && (field_len_code == 0x00)) {
6147 fprintf(stdout, "%d",
6148 lundata->luns[i].lundata[j+1]);
6149 } else if ((eam_code ==
6150 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6151 && (field_len_code == 0x03)) {
6155 * This format takes up all 8 bytes.
6156 * If we aren't starting at offset 0,
6160 fprintf(stdout, "Invalid "
6163 "specified format", j);
6167 bzero(tmp_lun, sizeof(tmp_lun));
6168 bcopy(&lundata->luns[i].lundata[j+1],
6169 &tmp_lun[1], sizeof(tmp_lun) - 1);
6170 fprintf(stdout, "%#jx",
6171 (intmax_t)scsi_8btou64(tmp_lun));
6174 fprintf(stderr, "Unknown Extended LUN"
6175 "Address method %#x, length "
6176 "code %#x", eam_code,
6183 fprintf(stderr, "Unknown LUN address method "
6184 "%#x\n", lundata->luns[i].lundata[0] &
6185 RPL_LUNDATA_ATYP_MASK);
6189 * For the flat addressing method, there are no
6190 * other levels after it.
6195 fprintf(stdout, "\n");
6208 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6209 char *combinedopt, int retry_count, int timeout)
6212 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6213 struct scsi_read_capacity_data rcap;
6214 struct scsi_read_capacity_data_long rcaplong;
6228 ccb = cam_getccb(device);
6231 warnx("%s: error allocating ccb", __func__);
6235 bzero(&(&ccb->ccb_h)[1],
6236 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
6238 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6265 if ((blocksizeonly != 0)
6266 && (numblocks != 0)) {
6267 warnx("%s: you can only specify one of -b or -N", __func__);
6272 if ((blocksizeonly != 0)
6273 && (sizeonly != 0)) {
6274 warnx("%s: you can only specify one of -b or -s", __func__);
6281 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6287 && (blocksizeonly != 0)) {
6288 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6293 scsi_read_capacity(&ccb->csio,
6294 /*retries*/ retry_count,
6296 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6299 /*timeout*/ timeout ? timeout : 5000);
6301 /* Disable freezing the device queue */
6302 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6304 if (arglist & CAM_ARG_ERR_RECOVER)
6305 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6307 if (cam_send_ccb(device, ccb) < 0) {
6308 warn("error sending READ CAPACITY command");
6310 if (arglist & CAM_ARG_VERBOSE)
6311 cam_error_print(device, ccb, CAM_ESF_ALL,
6312 CAM_EPF_ALL, stderr);
6318 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6319 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6324 maxsector = scsi_4btoul(rcap.addr);
6325 block_len = scsi_4btoul(rcap.length);
6328 * A last block of 2^32-1 means that the true capacity is over 2TB,
6329 * and we need to issue the long READ CAPACITY to get the real
6330 * capacity. Otherwise, we're all set.
6332 if (maxsector != 0xffffffff)
6335 scsi_read_capacity_16(&ccb->csio,
6336 /*retries*/ retry_count,
6338 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6342 /*rcap_buf*/ (uint8_t *)&rcaplong,
6343 /*rcap_buf_len*/ sizeof(rcaplong),
6344 /*sense_len*/ SSD_FULL_SIZE,
6345 /*timeout*/ timeout ? timeout : 5000);
6347 /* Disable freezing the device queue */
6348 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6350 if (arglist & CAM_ARG_ERR_RECOVER)
6351 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6353 if (cam_send_ccb(device, ccb) < 0) {
6354 warn("error sending READ CAPACITY (16) command");
6356 if (arglist & CAM_ARG_VERBOSE)
6357 cam_error_print(device, ccb, CAM_ESF_ALL,
6358 CAM_EPF_ALL, stderr);
6364 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6365 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6370 maxsector = scsi_8btou64(rcaplong.addr);
6371 block_len = scsi_4btoul(rcaplong.length);
6374 if (blocksizeonly == 0) {
6376 * Humanize implies !quiet, and also implies numblocks.
6378 if (humanize != 0) {
6383 tmpbytes = (maxsector + 1) * block_len;
6384 ret = humanize_number(tmpstr, sizeof(tmpstr),
6385 tmpbytes, "", HN_AUTOSCALE,
6388 HN_DIVISOR_1000 : 0));
6390 warnx("%s: humanize_number failed!", __func__);
6394 fprintf(stdout, "Device Size: %s%s", tmpstr,
6395 (sizeonly == 0) ? ", " : "\n");
6396 } else if (numblocks != 0) {
6397 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6398 "Blocks: " : "", (uintmax_t)maxsector + 1,
6399 (sizeonly == 0) ? ", " : "\n");
6401 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6402 "Last Block: " : "", (uintmax_t)maxsector,
6403 (sizeonly == 0) ? ", " : "\n");
6407 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6408 "Block Length: " : "", block_len, (quiet == 0) ?
6417 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6418 int retry_count, int timeout)
6422 uint8_t *smp_request = NULL, *smp_response = NULL;
6423 int request_size = 0, response_size = 0;
6424 int fd_request = 0, fd_response = 0;
6425 char *datastr = NULL;
6426 struct get_hook hook;
6431 * Note that at the moment we don't support sending SMP CCBs to
6432 * devices that aren't probed by CAM.
6434 ccb = cam_getccb(device);
6436 warnx("%s: error allocating CCB", __func__);
6440 bzero(&(&ccb->ccb_h)[1],
6441 sizeof(union ccb) - sizeof(struct ccb_hdr));
6443 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6446 arglist |= CAM_ARG_CMD_IN;
6447 response_size = strtol(optarg, NULL, 0);
6448 if (response_size <= 0) {
6449 warnx("invalid number of response bytes %d",
6452 goto smpcmd_bailout;
6454 hook.argc = argc - optind;
6455 hook.argv = argv + optind;
6458 datastr = cget(&hook, NULL);
6460 * If the user supplied "-" instead of a format, he
6461 * wants the data to be written to stdout.
6463 if ((datastr != NULL)
6464 && (datastr[0] == '-'))
6467 smp_response = (u_int8_t *)malloc(response_size);
6468 if (smp_response == NULL) {
6469 warn("can't malloc memory for SMP response");
6471 goto smpcmd_bailout;
6475 arglist |= CAM_ARG_CMD_OUT;
6476 request_size = strtol(optarg, NULL, 0);
6477 if (request_size <= 0) {
6478 warnx("invalid number of request bytes %d",
6481 goto smpcmd_bailout;
6483 hook.argc = argc - optind;
6484 hook.argv = argv + optind;
6486 datastr = cget(&hook, NULL);
6487 smp_request = (u_int8_t *)malloc(request_size);
6488 if (smp_request == NULL) {
6489 warn("can't malloc memory for SMP request");
6491 goto smpcmd_bailout;
6493 bzero(smp_request, request_size);
6495 * If the user supplied "-" instead of a format, he
6496 * wants the data to be read from stdin.
6498 if ((datastr != NULL)
6499 && (datastr[0] == '-'))
6502 buff_encode_visit(smp_request, request_size,
6513 * If fd_data is set, and we're writing to the device, we need to
6514 * read the data the user wants written from stdin.
6516 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6518 int amt_to_read = request_size;
6519 u_int8_t *buf_ptr = smp_request;
6521 for (amt_read = 0; amt_to_read > 0;
6522 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6523 if (amt_read == -1) {
6524 warn("error reading data from stdin");
6526 goto smpcmd_bailout;
6528 amt_to_read -= amt_read;
6529 buf_ptr += amt_read;
6533 if (((arglist & CAM_ARG_CMD_IN) == 0)
6534 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6535 warnx("%s: need both the request (-r) and response (-R) "
6536 "arguments", __func__);
6538 goto smpcmd_bailout;
6541 flags |= CAM_DEV_QFRZDIS;
6543 cam_fill_smpio(&ccb->smpio,
6544 /*retries*/ retry_count,
6547 /*smp_request*/ smp_request,
6548 /*smp_request_len*/ request_size,
6549 /*smp_response*/ smp_response,
6550 /*smp_response_len*/ response_size,
6551 /*timeout*/ timeout ? timeout : 5000);
6553 ccb->smpio.flags = SMP_FLAG_NONE;
6555 if (((retval = cam_send_ccb(device, ccb)) < 0)
6556 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6557 const char warnstr[] = "error sending command";
6564 if (arglist & CAM_ARG_VERBOSE) {
6565 cam_error_print(device, ccb, CAM_ESF_ALL,
6566 CAM_EPF_ALL, stderr);
6570 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6571 && (response_size > 0)) {
6572 if (fd_response == 0) {
6573 buff_decode_visit(smp_response, response_size,
6574 datastr, arg_put, NULL);
6575 fprintf(stdout, "\n");
6577 ssize_t amt_written;
6578 int amt_to_write = response_size;
6579 u_int8_t *buf_ptr = smp_response;
6581 for (amt_written = 0; (amt_to_write > 0) &&
6582 (amt_written = write(STDOUT_FILENO, buf_ptr,
6583 amt_to_write)) > 0;){
6584 amt_to_write -= amt_written;
6585 buf_ptr += amt_written;
6587 if (amt_written == -1) {
6588 warn("error writing data to stdout");
6590 goto smpcmd_bailout;
6591 } else if ((amt_written == 0)
6592 && (amt_to_write > 0)) {
6593 warnx("only wrote %u bytes out of %u",
6594 response_size - amt_to_write,
6603 if (smp_request != NULL)
6606 if (smp_response != NULL)
6613 smpreportgeneral(struct cam_device *device, int argc, char **argv,
6614 char *combinedopt, int retry_count, int timeout)
6617 struct smp_report_general_request *request = NULL;
6618 struct smp_report_general_response *response = NULL;
6619 struct sbuf *sb = NULL;
6621 int c, long_response = 0;
6625 * Note that at the moment we don't support sending SMP CCBs to
6626 * devices that aren't probed by CAM.
6628 ccb = cam_getccb(device);
6630 warnx("%s: error allocating CCB", __func__);
6634 bzero(&(&ccb->ccb_h)[1],
6635 sizeof(union ccb) - sizeof(struct ccb_hdr));
6637 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6646 request = malloc(sizeof(*request));
6647 if (request == NULL) {
6648 warn("%s: unable to allocate %zd bytes", __func__,
6654 response = malloc(sizeof(*response));
6655 if (response == NULL) {
6656 warn("%s: unable to allocate %zd bytes", __func__,
6663 smp_report_general(&ccb->smpio,
6667 /*request_len*/ sizeof(*request),
6668 (uint8_t *)response,
6669 /*response_len*/ sizeof(*response),
6670 /*long_response*/ long_response,
6673 if (((retval = cam_send_ccb(device, ccb)) < 0)
6674 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6675 const char warnstr[] = "error sending command";
6682 if (arglist & CAM_ARG_VERBOSE) {
6683 cam_error_print(device, ccb, CAM_ESF_ALL,
6684 CAM_EPF_ALL, stderr);
6691 * If the device supports the long response bit, try again and see
6692 * if we can get all of the data.
6694 if ((response->long_response & SMP_RG_LONG_RESPONSE)
6695 && (long_response == 0)) {
6696 ccb->ccb_h.status = CAM_REQ_INPROG;
6697 bzero(&(&ccb->ccb_h)[1],
6698 sizeof(union ccb) - sizeof(struct ccb_hdr));
6704 * XXX KDM detect and decode SMP errors here.
6706 sb = sbuf_new_auto();
6708 warnx("%s: error allocating sbuf", __func__);
6712 smp_report_general_sbuf(response, sizeof(*response), sb);
6714 if (sbuf_finish(sb) != 0) {
6715 warnx("%s: sbuf_finish", __func__);
6719 printf("%s", sbuf_data(sb));
6725 if (request != NULL)
6728 if (response != NULL)
6737 static struct camcontrol_opts phy_ops[] = {
6738 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
6739 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
6740 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
6741 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
6742 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
6743 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
6744 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
6745 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
6746 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
6751 smpphycontrol(struct cam_device *device, int argc, char **argv,
6752 char *combinedopt, int retry_count, int timeout)
6755 struct smp_phy_control_request *request = NULL;
6756 struct smp_phy_control_response *response = NULL;
6757 int long_response = 0;
6760 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
6762 uint64_t attached_dev_name = 0;
6763 int dev_name_set = 0;
6764 uint32_t min_plr = 0, max_plr = 0;
6765 uint32_t pp_timeout_val = 0;
6766 int slumber_partial = 0;
6767 int set_pp_timeout_val = 0;
6771 * Note that at the moment we don't support sending SMP CCBs to
6772 * devices that aren't probed by CAM.
6774 ccb = cam_getccb(device);
6776 warnx("%s: error allocating CCB", __func__);
6780 bzero(&(&ccb->ccb_h)[1],
6781 sizeof(union ccb) - sizeof(struct ccb_hdr));
6783 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6791 if (strcasecmp(optarg, "enable") == 0)
6793 else if (strcasecmp(optarg, "disable") == 0)
6796 warnx("%s: Invalid argument %s", __func__,
6803 slumber_partial |= enable <<
6804 SMP_PC_SAS_SLUMBER_SHIFT;
6807 slumber_partial |= enable <<
6808 SMP_PC_SAS_PARTIAL_SHIFT;
6811 slumber_partial |= enable <<
6812 SMP_PC_SATA_SLUMBER_SHIFT;
6815 slumber_partial |= enable <<
6816 SMP_PC_SATA_PARTIAL_SHIFT;
6819 warnx("%s: programmer error", __func__);
6822 break; /*NOTREACHED*/
6827 attached_dev_name = (uintmax_t)strtoumax(optarg,
6836 * We don't do extensive checking here, so this
6837 * will continue to work when new speeds come out.
6839 min_plr = strtoul(optarg, NULL, 0);
6841 || (min_plr > 0xf)) {
6842 warnx("%s: invalid link rate %x",
6850 * We don't do extensive checking here, so this
6851 * will continue to work when new speeds come out.
6853 max_plr = strtoul(optarg, NULL, 0);
6855 || (max_plr > 0xf)) {
6856 warnx("%s: invalid link rate %x",
6863 camcontrol_optret optreturn;
6864 cam_argmask argnums;
6867 if (phy_op_set != 0) {
6868 warnx("%s: only one phy operation argument "
6869 "(-o) allowed", __func__);
6877 * Allow the user to specify the phy operation
6878 * numerically, as well as with a name. This will
6879 * future-proof it a bit, so options that are added
6880 * in future specs can be used.
6882 if (isdigit(optarg[0])) {
6883 phy_operation = strtoul(optarg, NULL, 0);
6884 if ((phy_operation == 0)
6885 || (phy_operation > 0xff)) {
6886 warnx("%s: invalid phy operation %#x",
6887 __func__, phy_operation);
6893 optreturn = getoption(phy_ops, optarg, &phy_operation,
6896 if (optreturn == CC_OR_AMBIGUOUS) {
6897 warnx("%s: ambiguous option %s", __func__,
6902 } else if (optreturn == CC_OR_NOT_FOUND) {
6903 warnx("%s: option %s not found", __func__,
6915 pp_timeout_val = strtoul(optarg, NULL, 0);
6916 if (pp_timeout_val > 15) {
6917 warnx("%s: invalid partial pathway timeout "
6918 "value %u, need a value less than 16",
6919 __func__, pp_timeout_val);
6923 set_pp_timeout_val = 1;
6931 warnx("%s: a PHY (-p phy) argument is required",__func__);
6936 if (((dev_name_set != 0)
6937 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
6938 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
6939 && (dev_name_set == 0))) {
6940 warnx("%s: -d name and -o setdevname arguments both "
6941 "required to set device name", __func__);
6946 request = malloc(sizeof(*request));
6947 if (request == NULL) {
6948 warn("%s: unable to allocate %zd bytes", __func__,
6954 response = malloc(sizeof(*response));
6955 if (response == NULL) {
6956 warn("%s: unable to allocate %zd bytes", __func__,
6962 smp_phy_control(&ccb->smpio,
6967 (uint8_t *)response,
6970 /*expected_exp_change_count*/ 0,
6973 (set_pp_timeout_val != 0) ? 1 : 0,
6981 if (((retval = cam_send_ccb(device, ccb)) < 0)
6982 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6983 const char warnstr[] = "error sending command";
6990 if (arglist & CAM_ARG_VERBOSE) {
6992 * Use CAM_EPF_NORMAL so we only get one line of
6993 * SMP command decoding.
6995 cam_error_print(device, ccb, CAM_ESF_ALL,
6996 CAM_EPF_NORMAL, stderr);
7002 /* XXX KDM print out something here for success? */
7007 if (request != NULL)
7010 if (response != NULL)
7017 smpmaninfo(struct cam_device *device, int argc, char **argv,
7018 char *combinedopt, int retry_count, int timeout)
7021 struct smp_report_manuf_info_request request;
7022 struct smp_report_manuf_info_response response;
7023 struct sbuf *sb = NULL;
7024 int long_response = 0;
7029 * Note that at the moment we don't support sending SMP CCBs to
7030 * devices that aren't probed by CAM.
7032 ccb = cam_getccb(device);
7034 warnx("%s: error allocating CCB", __func__);
7038 bzero(&(&ccb->ccb_h)[1],
7039 sizeof(union ccb) - sizeof(struct ccb_hdr));
7041 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7050 bzero(&request, sizeof(request));
7051 bzero(&response, sizeof(response));
7053 smp_report_manuf_info(&ccb->smpio,
7058 (uint8_t *)&response,
7063 if (((retval = cam_send_ccb(device, ccb)) < 0)
7064 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7065 const char warnstr[] = "error sending command";
7072 if (arglist & CAM_ARG_VERBOSE) {
7073 cam_error_print(device, ccb, CAM_ESF_ALL,
7074 CAM_EPF_ALL, stderr);
7080 sb = sbuf_new_auto();
7082 warnx("%s: error allocating sbuf", __func__);
7086 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7088 if (sbuf_finish(sb) != 0) {
7089 warnx("%s: sbuf_finish", __func__);
7093 printf("%s", sbuf_data(sb));
7107 getdevid(struct cam_devitem *item)
7110 union ccb *ccb = NULL;
7112 struct cam_device *dev;
7114 dev = cam_open_btl(item->dev_match.path_id,
7115 item->dev_match.target_id,
7116 item->dev_match.target_lun, O_RDWR, NULL);
7119 warnx("%s", cam_errbuf);
7124 item->device_id_len = 0;
7126 ccb = cam_getccb(dev);
7128 warnx("%s: error allocating CCB", __func__);
7133 bzero(&(&ccb->ccb_h)[1],
7134 sizeof(union ccb) - sizeof(struct ccb_hdr));
7137 * On the first try, we just probe for the size of the data, and
7138 * then allocate that much memory and try again.
7141 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7142 ccb->ccb_h.flags = CAM_DIR_IN;
7143 ccb->cdai.flags = 0;
7144 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7145 ccb->cdai.bufsiz = item->device_id_len;
7146 if (item->device_id_len != 0)
7147 ccb->cdai.buf = (uint8_t *)item->device_id;
7149 if (cam_send_ccb(dev, ccb) < 0) {
7150 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7155 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7156 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7161 if (item->device_id_len == 0) {
7163 * This is our first time through. Allocate the buffer,
7164 * and then go back to get the data.
7166 if (ccb->cdai.provsiz == 0) {
7167 warnx("%s: invalid .provsiz field returned with "
7168 "XPT_GDEV_ADVINFO CCB", __func__);
7172 item->device_id_len = ccb->cdai.provsiz;
7173 item->device_id = malloc(item->device_id_len);
7174 if (item->device_id == NULL) {
7175 warn("%s: unable to allocate %d bytes", __func__,
7176 item->device_id_len);
7180 ccb->ccb_h.status = CAM_REQ_INPROG;
7186 cam_close_device(dev);
7195 * XXX KDM merge this code with getdevtree()?
7198 buildbusdevlist(struct cam_devlist *devlist)
7201 int bufsize, fd = -1;
7202 struct dev_match_pattern *patterns;
7203 struct cam_devitem *item = NULL;
7204 int skip_device = 0;
7207 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7208 warn("couldn't open %s", XPT_DEVICE);
7212 bzero(&ccb, sizeof(union ccb));
7214 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7215 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7216 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7218 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7219 bufsize = sizeof(struct dev_match_result) * 100;
7220 ccb.cdm.match_buf_len = bufsize;
7221 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7222 if (ccb.cdm.matches == NULL) {
7223 warnx("can't malloc memory for matches");
7227 ccb.cdm.num_matches = 0;
7228 ccb.cdm.num_patterns = 2;
7229 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7230 ccb.cdm.num_patterns;
7232 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7233 if (patterns == NULL) {
7234 warnx("can't malloc memory for patterns");
7239 ccb.cdm.patterns = patterns;
7240 bzero(patterns, ccb.cdm.pattern_buf_len);
7242 patterns[0].type = DEV_MATCH_DEVICE;
7243 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7244 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7245 patterns[1].type = DEV_MATCH_PERIPH;
7246 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7247 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7250 * We do the ioctl multiple times if necessary, in case there are
7251 * more than 100 nodes in the EDT.
7256 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7257 warn("error sending CAMIOCOMMAND ioctl");
7262 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7263 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7264 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7265 warnx("got CAM error %#x, CDM error %d\n",
7266 ccb.ccb_h.status, ccb.cdm.status);
7271 for (i = 0; i < ccb.cdm.num_matches; i++) {
7272 switch (ccb.cdm.matches[i].type) {
7273 case DEV_MATCH_DEVICE: {
7274 struct device_match_result *dev_result;
7277 &ccb.cdm.matches[i].result.device_result;
7279 if (dev_result->flags &
7280 DEV_RESULT_UNCONFIGURED) {
7286 item = malloc(sizeof(*item));
7288 warn("%s: unable to allocate %zd bytes",
7289 __func__, sizeof(*item));
7293 bzero(item, sizeof(*item));
7294 bcopy(dev_result, &item->dev_match,
7295 sizeof(*dev_result));
7296 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7299 if (getdevid(item) != 0) {
7305 case DEV_MATCH_PERIPH: {
7306 struct periph_match_result *periph_result;
7309 &ccb.cdm.matches[i].result.periph_result;
7311 if (skip_device != 0)
7313 item->num_periphs++;
7314 item->periph_matches = realloc(
7315 item->periph_matches,
7317 sizeof(struct periph_match_result));
7318 if (item->periph_matches == NULL) {
7319 warn("%s: error allocating periph "
7324 bcopy(periph_result, &item->periph_matches[
7325 item->num_periphs - 1],
7326 sizeof(*periph_result));
7330 fprintf(stderr, "%s: unexpected match "
7331 "type %d\n", __func__,
7332 ccb.cdm.matches[i].type);
7335 break; /*NOTREACHED*/
7338 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7339 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7347 free(ccb.cdm.matches);
7350 freebusdevlist(devlist);
7356 freebusdevlist(struct cam_devlist *devlist)
7358 struct cam_devitem *item, *item2;
7360 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7361 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7363 free(item->device_id);
7364 free(item->periph_matches);
7369 static struct cam_devitem *
7370 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7372 struct cam_devitem *item;
7374 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7375 struct scsi_vpd_id_descriptor *idd;
7378 * XXX KDM look for LUN IDs as well?
7380 idd = scsi_get_devid(item->device_id,
7381 item->device_id_len,
7382 scsi_devid_is_sas_target);
7386 if (scsi_8btou64(idd->identifier) == sasaddr)
7394 smpphylist(struct cam_device *device, int argc, char **argv,
7395 char *combinedopt, int retry_count, int timeout)
7397 struct smp_report_general_request *rgrequest = NULL;
7398 struct smp_report_general_response *rgresponse = NULL;
7399 struct smp_discover_request *disrequest = NULL;
7400 struct smp_discover_response *disresponse = NULL;
7401 struct cam_devlist devlist;
7403 int long_response = 0;
7410 * Note that at the moment we don't support sending SMP CCBs to
7411 * devices that aren't probed by CAM.
7413 ccb = cam_getccb(device);
7415 warnx("%s: error allocating CCB", __func__);
7419 bzero(&(&ccb->ccb_h)[1],
7420 sizeof(union ccb) - sizeof(struct ccb_hdr));
7421 STAILQ_INIT(&devlist.dev_queue);
7423 rgrequest = malloc(sizeof(*rgrequest));
7424 if (rgrequest == NULL) {
7425 warn("%s: unable to allocate %zd bytes", __func__,
7426 sizeof(*rgrequest));
7431 rgresponse = malloc(sizeof(*rgresponse));
7432 if (rgresponse == NULL) {
7433 warn("%s: unable to allocate %zd bytes", __func__,
7434 sizeof(*rgresponse));
7439 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7452 smp_report_general(&ccb->smpio,
7456 /*request_len*/ sizeof(*rgrequest),
7457 (uint8_t *)rgresponse,
7458 /*response_len*/ sizeof(*rgresponse),
7459 /*long_response*/ long_response,
7462 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7464 if (((retval = cam_send_ccb(device, ccb)) < 0)
7465 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7466 const char warnstr[] = "error sending command";
7473 if (arglist & CAM_ARG_VERBOSE) {
7474 cam_error_print(device, ccb, CAM_ESF_ALL,
7475 CAM_EPF_ALL, stderr);
7481 num_phys = rgresponse->num_phys;
7483 if (num_phys == 0) {
7485 fprintf(stdout, "%s: No Phys reported\n", __func__);
7490 devlist.path_id = device->path_id;
7492 retval = buildbusdevlist(&devlist);
7497 fprintf(stdout, "%d PHYs:\n", num_phys);
7498 fprintf(stdout, "PHY Attached SAS Address\n");
7501 disrequest = malloc(sizeof(*disrequest));
7502 if (disrequest == NULL) {
7503 warn("%s: unable to allocate %zd bytes", __func__,
7504 sizeof(*disrequest));
7509 disresponse = malloc(sizeof(*disresponse));
7510 if (disresponse == NULL) {
7511 warn("%s: unable to allocate %zd bytes", __func__,
7512 sizeof(*disresponse));
7517 for (i = 0; i < num_phys; i++) {
7518 struct cam_devitem *item;
7519 struct device_match_result *dev_match;
7520 char vendor[16], product[48], revision[16];
7524 bzero(&(&ccb->ccb_h)[1],
7525 sizeof(union ccb) - sizeof(struct ccb_hdr));
7527 ccb->ccb_h.status = CAM_REQ_INPROG;
7528 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7530 smp_discover(&ccb->smpio,
7534 sizeof(*disrequest),
7535 (uint8_t *)disresponse,
7536 sizeof(*disresponse),
7538 /*ignore_zone_group*/ 0,
7542 if (((retval = cam_send_ccb(device, ccb)) < 0)
7543 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7544 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7545 const char warnstr[] = "error sending command";
7552 if (arglist & CAM_ARG_VERBOSE) {
7553 cam_error_print(device, ccb, CAM_ESF_ALL,
7554 CAM_EPF_ALL, stderr);
7560 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7562 fprintf(stdout, "%3d <vacant>\n", i);
7566 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7569 item = findsasdevice(&devlist,
7570 scsi_8btou64(disresponse->attached_sas_address));
7574 || (item != NULL)) {
7575 fprintf(stdout, "%3d 0x%016jx", i,
7576 (uintmax_t)scsi_8btou64(
7577 disresponse->attached_sas_address));
7579 fprintf(stdout, "\n");
7582 } else if (quiet != 0)
7585 dev_match = &item->dev_match;
7587 if (dev_match->protocol == PROTO_SCSI) {
7588 cam_strvis(vendor, dev_match->inq_data.vendor,
7589 sizeof(dev_match->inq_data.vendor),
7591 cam_strvis(product, dev_match->inq_data.product,
7592 sizeof(dev_match->inq_data.product),
7594 cam_strvis(revision, dev_match->inq_data.revision,
7595 sizeof(dev_match->inq_data.revision),
7597 sprintf(tmpstr, "<%s %s %s>", vendor, product,
7599 } else if ((dev_match->protocol == PROTO_ATA)
7600 || (dev_match->protocol == PROTO_SATAPM)) {
7601 cam_strvis(product, dev_match->ident_data.model,
7602 sizeof(dev_match->ident_data.model),
7604 cam_strvis(revision, dev_match->ident_data.revision,
7605 sizeof(dev_match->ident_data.revision),
7607 sprintf(tmpstr, "<%s %s>", product, revision);
7609 sprintf(tmpstr, "<>");
7611 fprintf(stdout, " %-33s ", tmpstr);
7614 * If we have 0 periphs, that's a bug...
7616 if (item->num_periphs == 0) {
7617 fprintf(stdout, "\n");
7621 fprintf(stdout, "(");
7622 for (j = 0; j < item->num_periphs; j++) {
7624 fprintf(stdout, ",");
7626 fprintf(stdout, "%s%d",
7627 item->periph_matches[j].periph_name,
7628 item->periph_matches[j].unit_number);
7631 fprintf(stdout, ")\n");
7645 freebusdevlist(&devlist);
7651 atapm(struct cam_device *device, int argc, char **argv,
7652 char *combinedopt, int retry_count, int timeout)
7660 ccb = cam_getccb(device);
7663 warnx("%s: error allocating ccb", __func__);
7667 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7676 if (strcmp(argv[1], "idle") == 0) {
7678 cmd = ATA_IDLE_IMMEDIATE;
7681 } else if (strcmp(argv[1], "standby") == 0) {
7683 cmd = ATA_STANDBY_IMMEDIATE;
7685 cmd = ATA_STANDBY_CMD;
7693 else if (t <= (240 * 5))
7695 else if (t <= (252 * 5))
7696 /* special encoding for 21 minutes */
7698 else if (t <= (11 * 30 * 60))
7699 sc = (t - 1) / (30 * 60) + 241;
7703 cam_fill_ataio(&ccb->ataio,
7706 /*flags*/CAM_DIR_NONE,
7710 timeout ? timeout : 30 * 1000);
7711 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
7713 /* Disable freezing the device queue */
7714 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7716 if (arglist & CAM_ARG_ERR_RECOVER)
7717 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7719 if (cam_send_ccb(device, ccb) < 0) {
7720 warn("error sending command");
7722 if (arglist & CAM_ARG_VERBOSE)
7723 cam_error_print(device, ccb, CAM_ESF_ALL,
7724 CAM_EPF_ALL, stderr);
7730 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7731 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7740 #endif /* MINIMALISTIC */
7743 usage(int printlong)
7746 fprintf(printlong ? stdout : stderr,
7747 "usage: camcontrol <command> [device id][generic args][command args]\n"
7748 " camcontrol devlist [-v]\n"
7749 #ifndef MINIMALISTIC
7750 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
7751 " camcontrol tur [dev_id][generic args]\n"
7752 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
7753 " camcontrol identify [dev_id][generic args] [-v]\n"
7754 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
7755 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
7757 " camcontrol start [dev_id][generic args]\n"
7758 " camcontrol stop [dev_id][generic args]\n"
7759 " camcontrol load [dev_id][generic args]\n"
7760 " camcontrol eject [dev_id][generic args]\n"
7761 #endif /* MINIMALISTIC */
7762 " camcontrol rescan <all | bus[:target:lun]>\n"
7763 " camcontrol reset <all | bus[:target:lun]>\n"
7764 #ifndef MINIMALISTIC
7765 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
7766 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
7767 " [-P pagectl][-e | -b][-d]\n"
7768 " camcontrol cmd [dev_id][generic args]\n"
7769 " <-a cmd [args] | -c cmd [args]>\n"
7770 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
7771 " camcontrol smpcmd [dev_id][generic args]\n"
7772 " <-r len fmt [args]> <-R len fmt [args]>\n"
7773 " camcontrol smprg [dev_id][generic args][-l]\n"
7774 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
7775 " [-o operation][-d name][-m rate][-M rate]\n"
7776 " [-T pp_timeout][-a enable|disable]\n"
7777 " [-A enable|disable][-s enable|disable]\n"
7778 " [-S enable|disable]\n"
7779 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
7780 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
7781 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
7782 " <all|bus[:target[:lun]]|off>\n"
7783 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
7784 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
7785 " [-D <enable|disable>][-M mode][-O offset]\n"
7786 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
7787 " [-U][-W bus_width]\n"
7788 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
7789 " camcontrol sanitize [dev_id][generic args]\n"
7790 " [-a overwrite|block|crypto|exitfailure]\n"
7791 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
7793 " camcontrol idle [dev_id][generic args][-t time]\n"
7794 " camcontrol standby [dev_id][generic args][-t time]\n"
7795 " camcontrol sleep [dev_id][generic args]\n"
7796 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
7797 " camcontrol security [dev_id][generic args]\n"
7798 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
7799 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
7800 " [-U <user|master>] [-y]\n"
7801 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
7802 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
7803 #endif /* MINIMALISTIC */
7804 " camcontrol help\n");
7807 #ifndef MINIMALISTIC
7809 "Specify one of the following options:\n"
7810 "devlist list all CAM devices\n"
7811 "periphlist list all CAM peripheral drivers attached to a device\n"
7812 "tur send a test unit ready to the named device\n"
7813 "inquiry send a SCSI inquiry command to the named device\n"
7814 "identify send a ATA identify command to the named device\n"
7815 "reportluns send a SCSI report luns command to the device\n"
7816 "readcap send a SCSI read capacity command to the device\n"
7817 "start send a Start Unit command to the device\n"
7818 "stop send a Stop Unit command to the device\n"
7819 "load send a Start Unit command to the device with the load bit set\n"
7820 "eject send a Stop Unit command to the device with the eject bit set\n"
7821 "rescan rescan all busses, the given bus, or bus:target:lun\n"
7822 "reset reset all busses, the given bus, or bus:target:lun\n"
7823 "defects read the defect list of the specified device\n"
7824 "modepage display or edit (-e) the given mode page\n"
7825 "cmd send the given SCSI command, may need -i or -o as well\n"
7826 "smpcmd send the given SMP command, requires -o and -i\n"
7827 "smprg send the SMP Report General command\n"
7828 "smppc send the SMP PHY Control command, requires -p\n"
7829 "smpphylist display phys attached to a SAS expander\n"
7830 "smpmaninfo send the SMP Report Manufacturer Info command\n"
7831 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
7832 "tags report or set the number of transaction slots for a device\n"
7833 "negotiate report or set device negotiation parameters\n"
7834 "format send the SCSI FORMAT UNIT command to the named device\n"
7835 "sanitize send the SCSI SANITIZE command to the named device\n"
7836 "idle send the ATA IDLE command to the named device\n"
7837 "standby send the ATA STANDBY command to the named device\n"
7838 "sleep send the ATA SLEEP command to the named device\n"
7839 "fwdownload program firmware of the named device with the given image"
7840 "security report or send ATA security commands to the named device\n"
7841 "help this message\n"
7842 "Device Identifiers:\n"
7843 "bus:target specify the bus and target, lun defaults to 0\n"
7844 "bus:target:lun specify the bus, target and lun\n"
7845 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
7846 "Generic arguments:\n"
7847 "-v be verbose, print out sense information\n"
7848 "-t timeout command timeout in seconds, overrides default timeout\n"
7849 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
7850 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
7851 "-E have the kernel attempt to perform SCSI error recovery\n"
7852 "-C count specify the SCSI command retry count (needs -E to work)\n"
7853 "modepage arguments:\n"
7854 "-l list all available mode pages\n"
7855 "-m page specify the mode page to view or edit\n"
7856 "-e edit the specified mode page\n"
7857 "-b force view to binary mode\n"
7858 "-d disable block descriptors for mode sense\n"
7859 "-P pgctl page control field 0-3\n"
7860 "defects arguments:\n"
7861 "-f format specify defect list format (block, bfi or phys)\n"
7862 "-G get the grown defect list\n"
7863 "-P get the permanent defect list\n"
7864 "inquiry arguments:\n"
7865 "-D get the standard inquiry data\n"
7866 "-S get the serial number\n"
7867 "-R get the transfer rate, etc.\n"
7868 "reportluns arguments:\n"
7869 "-c only report a count of available LUNs\n"
7870 "-l only print out luns, and not a count\n"
7871 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
7872 "readcap arguments\n"
7873 "-b only report the blocksize\n"
7874 "-h human readable device size, base 2\n"
7875 "-H human readable device size, base 10\n"
7876 "-N print the number of blocks instead of last block\n"
7877 "-q quiet, print numbers only\n"
7878 "-s only report the last block/device size\n"
7880 "-c cdb [args] specify the SCSI CDB\n"
7881 "-i len fmt specify input data and input data format\n"
7882 "-o len fmt [args] specify output data and output data fmt\n"
7883 "smpcmd arguments:\n"
7884 "-r len fmt [args] specify the SMP command to be sent\n"
7885 "-R len fmt [args] specify SMP response format\n"
7886 "smprg arguments:\n"
7887 "-l specify the long response format\n"
7888 "smppc arguments:\n"
7889 "-p phy specify the PHY to operate on\n"
7890 "-l specify the long request/response format\n"
7891 "-o operation specify the phy control operation\n"
7892 "-d name set the attached device name\n"
7893 "-m rate set the minimum physical link rate\n"
7894 "-M rate set the maximum physical link rate\n"
7895 "-T pp_timeout set the partial pathway timeout value\n"
7896 "-a enable|disable enable or disable SATA slumber\n"
7897 "-A enable|disable enable or disable SATA partial phy power\n"
7898 "-s enable|disable enable or disable SAS slumber\n"
7899 "-S enable|disable enable or disable SAS partial phy power\n"
7900 "smpphylist arguments:\n"
7901 "-l specify the long response format\n"
7902 "-q only print phys with attached devices\n"
7903 "smpmaninfo arguments:\n"
7904 "-l specify the long response format\n"
7905 "debug arguments:\n"
7906 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
7907 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
7908 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
7909 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
7911 "-N tags specify the number of tags to use for this device\n"
7912 "-q be quiet, don't report the number of tags\n"
7913 "-v report a number of tag-related parameters\n"
7914 "negotiate arguments:\n"
7915 "-a send a test unit ready after negotiation\n"
7916 "-c report/set current negotiation settings\n"
7917 "-D <arg> \"enable\" or \"disable\" disconnection\n"
7918 "-M mode set ATA mode\n"
7919 "-O offset set command delay offset\n"
7920 "-q be quiet, don't report anything\n"
7921 "-R syncrate synchronization rate in MHz\n"
7922 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
7923 "-U report/set user negotiation settings\n"
7924 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
7925 "-v also print a Path Inquiry CCB for the controller\n"
7926 "format arguments:\n"
7927 "-q be quiet, don't print status messages\n"
7928 "-r run in report only mode\n"
7929 "-w don't send immediate format command\n"
7930 "-y don't ask any questions\n"
7931 "sanitize arguments:\n"
7932 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
7933 "-c passes overwrite passes to perform (1 to 31)\n"
7934 "-I invert overwrite pattern after each pass\n"
7935 "-P pattern path to overwrite pattern file\n"
7936 "-q be quiet, don't print status messages\n"
7937 "-r run in report only mode\n"
7938 "-U run operation in unrestricted completion exit mode\n"
7939 "-w don't send immediate sanitize command\n"
7940 "-y don't ask any questions\n"
7941 "idle/standby arguments:\n"
7942 "-t <arg> number of seconds before respective state.\n"
7943 "fwdownload arguments:\n"
7944 "-f fw_image path to firmware image file\n"
7945 "-y don't ask any questions\n"
7946 "-s run in simulation mode\n"
7947 "-v print info for every firmware segment sent to device\n"
7948 "security arguments:\n"
7949 "-d pwd disable security using the given password for the selected\n"
7951 "-e pwd erase the device using the given pwd for the selected user\n"
7952 "-f freeze the security configuration of the specified device\n"
7953 "-h pwd enhanced erase the device using the given pwd for the\n"
7955 "-k pwd unlock the device using the given pwd for the selected\n"
7957 "-l <high|maximum> specifies which security level to set: high or maximum\n"
7958 "-q be quiet, do not print any status messages\n"
7959 "-s pwd password the device (enable security) using the given\n"
7960 " pwd for the selected user\n"
7961 "-T timeout overrides the timeout (seconds) used for erase operation\n"
7962 "-U <user|master> specifies which user to set: user or master\n"
7963 "-y don't ask any questions\n"
7965 "-f freeze the HPA configuration of the device\n"
7966 "-l lock the HPA configuration of the device\n"
7967 "-P make the HPA max sectors persist\n"
7968 "-p pwd Set the HPA configuration password required for unlock\n"
7970 "-q be quiet, do not print any status messages\n"
7971 "-s sectors configures the maximum user accessible sectors of the\n"
7973 "-U pwd unlock the HPA configuration of the device\n"
7974 "-y don't ask any questions\n"
7976 #endif /* MINIMALISTIC */
7980 main(int argc, char **argv)
7983 char *device = NULL;
7985 struct cam_device *cam_dev = NULL;
7986 int timeout = 0, retry_count = 1;
7987 camcontrol_optret optreturn;
7989 const char *mainopt = "C:En:t:u:v";
7990 const char *subopt = NULL;
7991 char combinedopt[256];
7992 int error = 0, optstart = 2;
7994 #ifndef MINIMALISTIC
7998 #endif /* MINIMALISTIC */
8000 cmdlist = CAM_CMD_NONE;
8001 arglist = CAM_ARG_NONE;
8009 * Get the base option.
8011 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
8013 if (optreturn == CC_OR_AMBIGUOUS) {
8014 warnx("ambiguous option %s", argv[1]);
8017 } else if (optreturn == CC_OR_NOT_FOUND) {
8018 warnx("option %s not found", argv[1]);
8024 * Ahh, getopt(3) is a pain.
8026 * This is a gross hack. There really aren't many other good
8027 * options (excuse the pun) for parsing options in a situation like
8028 * this. getopt is kinda braindead, so you end up having to run
8029 * through the options twice, and give each invocation of getopt
8030 * the option string for the other invocation.
8032 * You would think that you could just have two groups of options.
8033 * The first group would get parsed by the first invocation of
8034 * getopt, and the second group would get parsed by the second
8035 * invocation of getopt. It doesn't quite work out that way. When
8036 * the first invocation of getopt finishes, it leaves optind pointing
8037 * to the argument _after_ the first argument in the second group.
8038 * So when the second invocation of getopt comes around, it doesn't
8039 * recognize the first argument it gets and then bails out.
8041 * A nice alternative would be to have a flag for getopt that says
8042 * "just keep parsing arguments even when you encounter an unknown
8043 * argument", but there isn't one. So there's no real clean way to
8044 * easily parse two sets of arguments without having one invocation
8045 * of getopt know about the other.
8047 * Without this hack, the first invocation of getopt would work as
8048 * long as the generic arguments are first, but the second invocation
8049 * (in the subfunction) would fail in one of two ways. In the case
8050 * where you don't set optreset, it would fail because optind may be
8051 * pointing to the argument after the one it should be pointing at.
8052 * In the case where you do set optreset, and reset optind, it would
8053 * fail because getopt would run into the first set of options, which
8054 * it doesn't understand.
8056 * All of this would "sort of" work if you could somehow figure out
8057 * whether optind had been incremented one option too far. The
8058 * mechanics of that, however, are more daunting than just giving
8059 * both invocations all of the expect options for either invocation.
8061 * Needless to say, I wouldn't mind if someone invented a better
8062 * (non-GPL!) command line parsing interface than getopt. I
8063 * wouldn't mind if someone added more knobs to getopt to make it
8064 * work better. Who knows, I may talk myself into doing it someday,
8065 * if the standards weenies let me. As it is, it just leads to
8066 * hackery like this and causes people to avoid it in some cases.
8068 * KDM, September 8th, 1998
8071 sprintf(combinedopt, "%s%s", mainopt, subopt);
8073 sprintf(combinedopt, "%s", mainopt);
8076 * For these options we do not parse optional device arguments and
8077 * we do not open a passthrough device.
8079 if ((cmdlist == CAM_CMD_RESCAN)
8080 || (cmdlist == CAM_CMD_RESET)
8081 || (cmdlist == CAM_CMD_DEVTREE)
8082 || (cmdlist == CAM_CMD_USAGE)
8083 || (cmdlist == CAM_CMD_DEBUG))
8086 #ifndef MINIMALISTIC
8088 && (argc > 2 && argv[2][0] != '-')) {
8092 if (isdigit(argv[2][0])) {
8093 /* device specified as bus:target[:lun] */
8094 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
8096 errx(1, "numeric device specification must "
8097 "be either bus:target, or "
8099 /* default to 0 if lun was not specified */
8100 if ((arglist & CAM_ARG_LUN) == 0) {
8102 arglist |= CAM_ARG_LUN;
8106 if (cam_get_device(argv[2], name, sizeof name, &unit)
8108 errx(1, "%s", cam_errbuf);
8109 device = strdup(name);
8110 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
8114 #endif /* MINIMALISTIC */
8116 * Start getopt processing at argv[2/3], since we've already
8117 * accepted argv[1..2] as the command name, and as a possible
8123 * Now we run through the argument list looking for generic
8124 * options, and ignoring options that possibly belong to
8127 while ((c = getopt(argc, argv, combinedopt))!= -1){
8130 retry_count = strtol(optarg, NULL, 0);
8131 if (retry_count < 0)
8132 errx(1, "retry count %d is < 0",
8134 arglist |= CAM_ARG_RETRIES;
8137 arglist |= CAM_ARG_ERR_RECOVER;
8140 arglist |= CAM_ARG_DEVICE;
8142 while (isspace(*tstr) && (*tstr != '\0'))
8144 device = (char *)strdup(tstr);
8147 timeout = strtol(optarg, NULL, 0);
8149 errx(1, "invalid timeout %d", timeout);
8150 /* Convert the timeout from seconds to ms */
8152 arglist |= CAM_ARG_TIMEOUT;
8155 arglist |= CAM_ARG_UNIT;
8156 unit = strtol(optarg, NULL, 0);
8159 arglist |= CAM_ARG_VERBOSE;
8166 #ifndef MINIMALISTIC
8168 * For most commands we'll want to open the passthrough device
8169 * associated with the specified device. In the case of the rescan
8170 * commands, we don't use a passthrough device at all, just the
8171 * transport layer device.
8174 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
8175 && (((arglist & CAM_ARG_DEVICE) == 0)
8176 || ((arglist & CAM_ARG_UNIT) == 0))) {
8177 errx(1, "subcommand \"%s\" requires a valid device "
8178 "identifier", argv[1]);
8181 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
8182 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
8183 cam_open_spec_device(device,unit,O_RDWR,NULL)))
8185 errx(1,"%s", cam_errbuf);
8187 #endif /* MINIMALISTIC */
8190 * Reset optind to 2, and reset getopt, so these routines can parse
8191 * the arguments again.
8197 #ifndef MINIMALISTIC
8198 case CAM_CMD_DEVLIST:
8199 error = getdevlist(cam_dev);
8202 error = atahpa(cam_dev, retry_count, timeout,
8203 argc, argv, combinedopt);
8205 #endif /* MINIMALISTIC */
8206 case CAM_CMD_DEVTREE:
8207 error = getdevtree(argc, argv, combinedopt);
8209 #ifndef MINIMALISTIC
8211 error = testunitready(cam_dev, retry_count, timeout, 0);
8213 case CAM_CMD_INQUIRY:
8214 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
8215 retry_count, timeout);
8217 case CAM_CMD_IDENTIFY:
8218 error = ataidentify(cam_dev, retry_count, timeout);
8220 case CAM_CMD_STARTSTOP:
8221 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
8222 arglist & CAM_ARG_EJECT, retry_count,
8225 #endif /* MINIMALISTIC */
8226 case CAM_CMD_RESCAN:
8227 error = dorescan_or_reset(argc, argv, 1);
8230 error = dorescan_or_reset(argc, argv, 0);
8232 #ifndef MINIMALISTIC
8233 case CAM_CMD_READ_DEFECTS:
8234 error = readdefects(cam_dev, argc, argv, combinedopt,
8235 retry_count, timeout);
8237 case CAM_CMD_MODE_PAGE:
8238 modepage(cam_dev, argc, argv, combinedopt,
8239 retry_count, timeout);
8241 case CAM_CMD_SCSI_CMD:
8242 error = scsicmd(cam_dev, argc, argv, combinedopt,
8243 retry_count, timeout);
8245 case CAM_CMD_SMP_CMD:
8246 error = smpcmd(cam_dev, argc, argv, combinedopt,
8247 retry_count, timeout);
8249 case CAM_CMD_SMP_RG:
8250 error = smpreportgeneral(cam_dev, argc, argv,
8251 combinedopt, retry_count,
8254 case CAM_CMD_SMP_PC:
8255 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
8256 retry_count, timeout);
8258 case CAM_CMD_SMP_PHYLIST:
8259 error = smpphylist(cam_dev, argc, argv, combinedopt,
8260 retry_count, timeout);
8262 case CAM_CMD_SMP_MANINFO:
8263 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
8264 retry_count, timeout);
8267 error = camdebug(argc, argv, combinedopt);
8270 error = tagcontrol(cam_dev, argc, argv, combinedopt);
8273 error = ratecontrol(cam_dev, retry_count, timeout,
8274 argc, argv, combinedopt);
8276 case CAM_CMD_FORMAT:
8277 error = scsiformat(cam_dev, argc, argv,
8278 combinedopt, retry_count, timeout);
8280 case CAM_CMD_REPORTLUNS:
8281 error = scsireportluns(cam_dev, argc, argv,
8282 combinedopt, retry_count,
8285 case CAM_CMD_READCAP:
8286 error = scsireadcapacity(cam_dev, argc, argv,
8287 combinedopt, retry_count,
8291 case CAM_CMD_STANDBY:
8293 error = atapm(cam_dev, argc, argv,
8294 combinedopt, retry_count, timeout);
8296 case CAM_CMD_SECURITY:
8297 error = atasecurity(cam_dev, retry_count, timeout,
8298 argc, argv, combinedopt);
8300 case CAM_CMD_DOWNLOAD_FW:
8301 error = fwdownload(cam_dev, argc, argv, combinedopt,
8302 arglist & CAM_ARG_VERBOSE, retry_count, timeout,
8303 get_disk_type(cam_dev));
8305 case CAM_CMD_SANITIZE:
8306 error = scsisanitize(cam_dev, argc, argv,
8307 combinedopt, retry_count, timeout);
8309 #endif /* MINIMALISTIC */
8319 if (cam_dev != NULL)
8320 cam_close_device(cam_dev);