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>
35 #include <sys/endian.h>
54 #include <cam/cam_debug.h>
55 #include <cam/cam_ccb.h>
56 #include <cam/scsi/scsi_all.h>
57 #include <cam/scsi/scsi_da.h>
58 #include <cam/scsi/scsi_pass.h>
59 #include <cam/scsi/scsi_message.h>
60 #include <cam/scsi/smp_all.h>
61 #include <cam/ata/ata_all.h>
63 #include "camcontrol.h"
66 CAM_CMD_NONE = 0x00000000,
67 CAM_CMD_DEVLIST = 0x00000001,
68 CAM_CMD_TUR = 0x00000002,
69 CAM_CMD_INQUIRY = 0x00000003,
70 CAM_CMD_STARTSTOP = 0x00000004,
71 CAM_CMD_RESCAN = 0x00000005,
72 CAM_CMD_READ_DEFECTS = 0x00000006,
73 CAM_CMD_MODE_PAGE = 0x00000007,
74 CAM_CMD_SCSI_CMD = 0x00000008,
75 CAM_CMD_DEVTREE = 0x00000009,
76 CAM_CMD_USAGE = 0x0000000a,
77 CAM_CMD_DEBUG = 0x0000000b,
78 CAM_CMD_RESET = 0x0000000c,
79 CAM_CMD_FORMAT = 0x0000000d,
80 CAM_CMD_TAG = 0x0000000e,
81 CAM_CMD_RATE = 0x0000000f,
82 CAM_CMD_DETACH = 0x00000010,
83 CAM_CMD_REPORTLUNS = 0x00000011,
84 CAM_CMD_READCAP = 0x00000012,
85 CAM_CMD_IDENTIFY = 0x00000013,
86 CAM_CMD_IDLE = 0x00000014,
87 CAM_CMD_STANDBY = 0x00000015,
88 CAM_CMD_SLEEP = 0x00000016,
89 CAM_CMD_SMP_CMD = 0x00000017,
90 CAM_CMD_SMP_RG = 0x00000018,
91 CAM_CMD_SMP_PC = 0x00000019,
92 CAM_CMD_SMP_PHYLIST = 0x0000001a,
93 CAM_CMD_SMP_MANINFO = 0x0000001b,
94 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
95 CAM_CMD_SECURITY = 0x0000001d,
96 CAM_CMD_HPA = 0x0000001e
100 CAM_ARG_NONE = 0x00000000,
101 CAM_ARG_VERBOSE = 0x00000001,
102 CAM_ARG_DEVICE = 0x00000002,
103 CAM_ARG_BUS = 0x00000004,
104 CAM_ARG_TARGET = 0x00000008,
105 CAM_ARG_LUN = 0x00000010,
106 CAM_ARG_EJECT = 0x00000020,
107 CAM_ARG_UNIT = 0x00000040,
108 CAM_ARG_FORMAT_BLOCK = 0x00000080,
109 CAM_ARG_FORMAT_BFI = 0x00000100,
110 CAM_ARG_FORMAT_PHYS = 0x00000200,
111 CAM_ARG_PLIST = 0x00000400,
112 CAM_ARG_GLIST = 0x00000800,
113 CAM_ARG_GET_SERIAL = 0x00001000,
114 CAM_ARG_GET_STDINQ = 0x00002000,
115 CAM_ARG_GET_XFERRATE = 0x00004000,
116 CAM_ARG_INQ_MASK = 0x00007000,
117 CAM_ARG_MODE_EDIT = 0x00008000,
118 CAM_ARG_PAGE_CNTL = 0x00010000,
119 CAM_ARG_TIMEOUT = 0x00020000,
120 CAM_ARG_CMD_IN = 0x00040000,
121 CAM_ARG_CMD_OUT = 0x00080000,
122 CAM_ARG_DBD = 0x00100000,
123 CAM_ARG_ERR_RECOVER = 0x00200000,
124 CAM_ARG_RETRIES = 0x00400000,
125 CAM_ARG_START_UNIT = 0x00800000,
126 CAM_ARG_DEBUG_INFO = 0x01000000,
127 CAM_ARG_DEBUG_TRACE = 0x02000000,
128 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
129 CAM_ARG_DEBUG_CDB = 0x08000000,
130 CAM_ARG_DEBUG_XPT = 0x10000000,
131 CAM_ARG_DEBUG_PERIPH = 0x20000000,
132 CAM_ARG_DEBUG_PROBE = 0x40000000,
135 struct camcontrol_opts {
143 struct ata_res_pass16 {
144 u_int16_t reserved[5];
147 u_int8_t sector_count_exp;
148 u_int8_t sector_count;
149 u_int8_t lba_low_exp;
151 u_int8_t lba_mid_exp;
153 u_int8_t lba_high_exp;
159 struct ata_set_max_pwd
162 u_int8_t password[32];
163 u_int16_t reserved2[239];
166 static const char scsicmd_opts[] = "a:c:dfi:o:r";
167 static const char readdefect_opts[] = "f:GP";
168 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
169 static const char smprg_opts[] = "l";
170 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
171 static const char smpphylist_opts[] = "lq";
175 static struct camcontrol_opts option_table[] = {
177 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
178 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
179 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
180 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
181 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
182 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
183 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
184 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
185 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
186 #endif /* MINIMALISTIC */
187 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
188 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
190 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
191 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
192 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
193 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
194 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
195 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
196 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
197 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
198 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
199 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
200 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
201 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
202 #endif /* MINIMALISTIC */
203 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL},
205 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
206 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
207 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
208 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
209 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
210 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
211 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
212 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
213 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
214 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
215 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:ys"},
216 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
217 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
218 #endif /* MINIMALISTIC */
219 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
220 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
221 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
232 struct device_match_result dev_match;
234 struct periph_match_result *periph_matches;
235 struct scsi_vpd_device_id *device_id;
237 STAILQ_ENTRY(cam_devitem) links;
241 STAILQ_HEAD(, cam_devitem) dev_queue;
245 static cam_cmdmask cmdlist;
246 static cam_argmask arglist;
248 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
249 uint32_t *cmdnum, cam_argmask *argnum,
250 const char **subopt);
252 static int getdevlist(struct cam_device *device);
253 #endif /* MINIMALISTIC */
254 static int getdevtree(void);
256 static int testunitready(struct cam_device *device, int retry_count,
257 int timeout, int quiet);
258 static int scsistart(struct cam_device *device, int startstop, int loadeject,
259 int retry_count, int timeout);
260 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
261 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
262 static int camxferrate(struct cam_device *device);
263 #endif /* MINIMALISTIC */
264 static int parse_btl(char *tstr, int *bus, int *target, int *lun,
265 cam_argmask *arglst);
266 static int dorescan_or_reset(int argc, char **argv, int rescan);
267 static int rescan_or_reset_bus(int bus, int rescan);
268 static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
270 static int readdefects(struct cam_device *device, int argc, char **argv,
271 char *combinedopt, int retry_count, int timeout);
272 static void modepage(struct cam_device *device, int argc, char **argv,
273 char *combinedopt, int retry_count, int timeout);
274 static int scsicmd(struct cam_device *device, int argc, char **argv,
275 char *combinedopt, int retry_count, int timeout);
276 static int smpcmd(struct cam_device *device, int argc, char **argv,
277 char *combinedopt, int retry_count, int timeout);
278 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
279 char *combinedopt, int retry_count, int timeout);
280 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
281 char *combinedopt, int retry_count, int timeout);
282 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
283 char *combinedopt, int retry_count, int timeout);
284 static int getdevid(struct cam_devitem *item);
285 static int buildbusdevlist(struct cam_devlist *devlist);
286 static void freebusdevlist(struct cam_devlist *devlist);
287 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
289 static int smpphylist(struct cam_device *device, int argc, char **argv,
290 char *combinedopt, int retry_count, int timeout);
291 static int tagcontrol(struct cam_device *device, int argc, char **argv,
293 static void cts_print(struct cam_device *device,
294 struct ccb_trans_settings *cts);
295 static void cpi_print(struct ccb_pathinq *cpi);
296 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
297 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
298 static int get_print_cts(struct cam_device *device, int user_settings,
299 int quiet, struct ccb_trans_settings *cts);
300 static int ratecontrol(struct cam_device *device, int retry_count,
301 int timeout, int argc, char **argv, char *combinedopt);
302 static int scsiformat(struct cam_device *device, int argc, char **argv,
303 char *combinedopt, int retry_count, int timeout);
304 static int scsireportluns(struct cam_device *device, int argc, char **argv,
305 char *combinedopt, int retry_count, int timeout);
306 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
307 char *combinedopt, int retry_count, int timeout);
308 static int atapm(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int retry_count, int timeout);
310 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
311 int argc, char **argv, char *combinedopt);
312 static int atahpa(struct cam_device *device, int retry_count, int timeout,
313 int argc, char **argv, char *combinedopt);
315 #endif /* MINIMALISTIC */
317 #define min(a,b) (((a)<(b))?(a):(b))
320 #define max(a,b) (((a)>(b))?(a):(b))
324 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
325 cam_argmask *argnum, const char **subopt)
327 struct camcontrol_opts *opts;
330 for (opts = table; (opts != NULL) && (opts->optname != NULL);
332 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
333 *cmdnum = opts->cmdnum;
334 *argnum = opts->argnum;
335 *subopt = opts->subopt;
336 if (++num_matches > 1)
337 return(CC_OR_AMBIGUOUS);
344 return(CC_OR_NOT_FOUND);
349 getdevlist(struct cam_device *device)
355 ccb = cam_getccb(device);
357 ccb->ccb_h.func_code = XPT_GDEVLIST;
358 ccb->ccb_h.flags = CAM_DIR_NONE;
359 ccb->ccb_h.retry_count = 1;
361 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
362 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
363 if (cam_send_ccb(device, ccb) < 0) {
364 perror("error getting device list");
371 switch (ccb->cgdl.status) {
372 case CAM_GDEVLIST_MORE_DEVS:
373 strcpy(status, "MORE");
375 case CAM_GDEVLIST_LAST_DEVICE:
376 strcpy(status, "LAST");
378 case CAM_GDEVLIST_LIST_CHANGED:
379 strcpy(status, "CHANGED");
381 case CAM_GDEVLIST_ERROR:
382 strcpy(status, "ERROR");
387 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
388 ccb->cgdl.periph_name,
389 ccb->cgdl.unit_number,
390 ccb->cgdl.generation,
395 * If the list has changed, we need to start over from the
398 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
406 #endif /* MINIMALISTIC */
418 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
419 warn("couldn't open %s", XPT_DEVICE);
423 bzero(&ccb, sizeof(union ccb));
425 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
426 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
427 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
429 ccb.ccb_h.func_code = XPT_DEV_MATCH;
430 bufsize = sizeof(struct dev_match_result) * 100;
431 ccb.cdm.match_buf_len = bufsize;
432 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
433 if (ccb.cdm.matches == NULL) {
434 warnx("can't malloc memory for matches");
438 ccb.cdm.num_matches = 0;
441 * We fetch all nodes, since we display most of them in the default
442 * case, and all in the verbose case.
444 ccb.cdm.num_patterns = 0;
445 ccb.cdm.pattern_buf_len = 0;
448 * We do the ioctl multiple times if necessary, in case there are
449 * more than 100 nodes in the EDT.
452 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
453 warn("error sending CAMIOCOMMAND ioctl");
458 if ((ccb.ccb_h.status != CAM_REQ_CMP)
459 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
460 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
461 warnx("got CAM error %#x, CDM error %d\n",
462 ccb.ccb_h.status, ccb.cdm.status);
467 for (i = 0; i < ccb.cdm.num_matches; i++) {
468 switch (ccb.cdm.matches[i].type) {
469 case DEV_MATCH_BUS: {
470 struct bus_match_result *bus_result;
473 * Only print the bus information if the
474 * user turns on the verbose flag.
476 if ((arglist & CAM_ARG_VERBOSE) == 0)
480 &ccb.cdm.matches[i].result.bus_result;
483 fprintf(stdout, ")\n");
487 fprintf(stdout, "scbus%d on %s%d bus %d:\n",
489 bus_result->dev_name,
490 bus_result->unit_number,
494 case DEV_MATCH_DEVICE: {
495 struct device_match_result *dev_result;
496 char vendor[16], product[48], revision[16];
497 char fw[5], tmpstr[256];
500 &ccb.cdm.matches[i].result.device_result;
502 if ((dev_result->flags
503 & DEV_RESULT_UNCONFIGURED)
504 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
510 if (dev_result->protocol == PROTO_SCSI) {
511 cam_strvis(vendor, dev_result->inq_data.vendor,
512 sizeof(dev_result->inq_data.vendor),
515 dev_result->inq_data.product,
516 sizeof(dev_result->inq_data.product),
519 dev_result->inq_data.revision,
520 sizeof(dev_result->inq_data.revision),
522 sprintf(tmpstr, "<%s %s %s>", vendor, product,
524 } else if (dev_result->protocol == PROTO_ATA ||
525 dev_result->protocol == PROTO_SATAPM) {
527 dev_result->ident_data.model,
528 sizeof(dev_result->ident_data.model),
531 dev_result->ident_data.revision,
532 sizeof(dev_result->ident_data.revision),
534 sprintf(tmpstr, "<%s %s>", product,
536 } else if (dev_result->protocol == PROTO_SEMB) {
537 struct sep_identify_data *sid;
539 sid = (struct sep_identify_data *)
540 &dev_result->ident_data;
541 cam_strvis(vendor, sid->vendor_id,
542 sizeof(sid->vendor_id),
544 cam_strvis(product, sid->product_id,
545 sizeof(sid->product_id),
547 cam_strvis(revision, sid->product_rev,
548 sizeof(sid->product_rev),
550 cam_strvis(fw, sid->firmware_rev,
551 sizeof(sid->firmware_rev),
553 sprintf(tmpstr, "<%s %s %s %s>",
554 vendor, product, revision, fw);
556 sprintf(tmpstr, "<>");
559 fprintf(stdout, ")\n");
563 fprintf(stdout, "%-33s at scbus%d "
564 "target %d lun %d (",
567 dev_result->target_id,
568 dev_result->target_lun);
574 case DEV_MATCH_PERIPH: {
575 struct periph_match_result *periph_result;
578 &ccb.cdm.matches[i].result.periph_result;
580 if (skip_device != 0)
584 fprintf(stdout, ",");
586 fprintf(stdout, "%s%d",
587 periph_result->periph_name,
588 periph_result->unit_number);
594 fprintf(stdout, "unknown match type\n");
599 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
600 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
603 fprintf(stdout, ")\n");
612 testunitready(struct cam_device *device, int retry_count, int timeout,
618 ccb = cam_getccb(device);
620 scsi_test_unit_ready(&ccb->csio,
621 /* retries */ retry_count,
623 /* tag_action */ MSG_SIMPLE_Q_TAG,
624 /* sense_len */ SSD_FULL_SIZE,
625 /* timeout */ timeout ? timeout : 5000);
627 /* Disable freezing the device queue */
628 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
630 if (arglist & CAM_ARG_ERR_RECOVER)
631 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
633 if (cam_send_ccb(device, ccb) < 0) {
635 perror("error sending test unit ready");
637 if (arglist & CAM_ARG_VERBOSE) {
638 cam_error_print(device, ccb, CAM_ESF_ALL,
639 CAM_EPF_ALL, stderr);
646 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
648 fprintf(stdout, "Unit is ready\n");
651 fprintf(stdout, "Unit is not ready\n");
654 if (arglist & CAM_ARG_VERBOSE) {
655 cam_error_print(device, ccb, CAM_ESF_ALL,
656 CAM_EPF_ALL, stderr);
666 scsistart(struct cam_device *device, int startstop, int loadeject,
667 int retry_count, int timeout)
672 ccb = cam_getccb(device);
675 * If we're stopping, send an ordered tag so the drive in question
676 * will finish any previously queued writes before stopping. If
677 * the device isn't capable of tagged queueing, or if tagged
678 * queueing is turned off, the tag action is a no-op.
680 scsi_start_stop(&ccb->csio,
681 /* retries */ retry_count,
683 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
685 /* start/stop */ startstop,
686 /* load_eject */ loadeject,
688 /* sense_len */ SSD_FULL_SIZE,
689 /* timeout */ timeout ? timeout : 120000);
691 /* Disable freezing the device queue */
692 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
694 if (arglist & CAM_ARG_ERR_RECOVER)
695 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
697 if (cam_send_ccb(device, ccb) < 0) {
698 perror("error sending start unit");
700 if (arglist & CAM_ARG_VERBOSE) {
701 cam_error_print(device, ccb, CAM_ESF_ALL,
702 CAM_EPF_ALL, stderr);
709 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
711 fprintf(stdout, "Unit started successfully");
713 fprintf(stdout,", Media loaded\n");
715 fprintf(stdout,"\n");
717 fprintf(stdout, "Unit stopped successfully");
719 fprintf(stdout, ", Media ejected\n");
721 fprintf(stdout, "\n");
727 "Error received from start unit command\n");
730 "Error received from stop unit command\n");
732 if (arglist & CAM_ARG_VERBOSE) {
733 cam_error_print(device, ccb, CAM_ESF_ALL,
734 CAM_EPF_ALL, stderr);
744 scsidoinquiry(struct cam_device *device, int argc, char **argv,
745 char *combinedopt, int retry_count, int timeout)
750 while ((c = getopt(argc, argv, combinedopt)) != -1) {
753 arglist |= CAM_ARG_GET_STDINQ;
756 arglist |= CAM_ARG_GET_XFERRATE;
759 arglist |= CAM_ARG_GET_SERIAL;
767 * If the user didn't specify any inquiry options, he wants all of
770 if ((arglist & CAM_ARG_INQ_MASK) == 0)
771 arglist |= CAM_ARG_INQ_MASK;
773 if (arglist & CAM_ARG_GET_STDINQ)
774 error = scsiinquiry(device, retry_count, timeout);
779 if (arglist & CAM_ARG_GET_SERIAL)
780 scsiserial(device, retry_count, timeout);
785 if (arglist & CAM_ARG_GET_XFERRATE)
786 error = camxferrate(device);
792 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
795 struct scsi_inquiry_data *inq_buf;
798 ccb = cam_getccb(device);
801 warnx("couldn't allocate CCB");
805 /* cam_getccb cleans up the header, caller has to zero the payload */
806 bzero(&(&ccb->ccb_h)[1],
807 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
809 inq_buf = (struct scsi_inquiry_data *)malloc(
810 sizeof(struct scsi_inquiry_data));
812 if (inq_buf == NULL) {
814 warnx("can't malloc memory for inquiry\n");
817 bzero(inq_buf, sizeof(*inq_buf));
820 * Note that although the size of the inquiry buffer is the full
821 * 256 bytes specified in the SCSI spec, we only tell the device
822 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
823 * two reasons for this:
825 * - The SCSI spec says that when a length field is only 1 byte,
826 * a value of 0 will be interpreted as 256. Therefore
827 * scsi_inquiry() will convert an inq_len (which is passed in as
828 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
829 * to 0. Evidently, very few devices meet the spec in that
830 * regard. Some devices, like many Seagate disks, take the 0 as
831 * 0, and don't return any data. One Pioneer DVD-R drive
832 * returns more data than the command asked for.
834 * So, since there are numerous devices that just don't work
835 * right with the full inquiry size, we don't send the full size.
837 * - The second reason not to use the full inquiry data length is
838 * that we don't need it here. The only reason we issue a
839 * standard inquiry is to get the vendor name, device name,
840 * and revision so scsi_print_inquiry() can print them.
842 * If, at some point in the future, more inquiry data is needed for
843 * some reason, this code should use a procedure similar to the
844 * probe code. i.e., issue a short inquiry, and determine from
845 * the additional length passed back from the device how much
846 * inquiry data the device supports. Once the amount the device
847 * supports is determined, issue an inquiry for that amount and no
852 scsi_inquiry(&ccb->csio,
853 /* retries */ retry_count,
855 /* tag_action */ MSG_SIMPLE_Q_TAG,
856 /* inq_buf */ (u_int8_t *)inq_buf,
857 /* inq_len */ SHORT_INQUIRY_LENGTH,
860 /* sense_len */ SSD_FULL_SIZE,
861 /* timeout */ timeout ? timeout : 5000);
863 /* Disable freezing the device queue */
864 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
866 if (arglist & CAM_ARG_ERR_RECOVER)
867 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
869 if (cam_send_ccb(device, ccb) < 0) {
870 perror("error sending SCSI inquiry");
872 if (arglist & CAM_ARG_VERBOSE) {
873 cam_error_print(device, ccb, CAM_ESF_ALL,
874 CAM_EPF_ALL, stderr);
881 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
884 if (arglist & CAM_ARG_VERBOSE) {
885 cam_error_print(device, ccb, CAM_ESF_ALL,
886 CAM_EPF_ALL, stderr);
897 fprintf(stdout, "%s%d: ", device->device_name,
898 device->dev_unit_num);
899 scsi_print_inquiry(inq_buf);
907 scsiserial(struct cam_device *device, int retry_count, int timeout)
910 struct scsi_vpd_unit_serial_number *serial_buf;
911 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
914 ccb = cam_getccb(device);
917 warnx("couldn't allocate CCB");
921 /* cam_getccb cleans up the header, caller has to zero the payload */
922 bzero(&(&ccb->ccb_h)[1],
923 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
925 serial_buf = (struct scsi_vpd_unit_serial_number *)
926 malloc(sizeof(*serial_buf));
928 if (serial_buf == NULL) {
930 warnx("can't malloc memory for serial number");
934 scsi_inquiry(&ccb->csio,
935 /*retries*/ retry_count,
937 /* tag_action */ MSG_SIMPLE_Q_TAG,
938 /* inq_buf */ (u_int8_t *)serial_buf,
939 /* inq_len */ sizeof(*serial_buf),
941 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
942 /* sense_len */ SSD_FULL_SIZE,
943 /* timeout */ timeout ? timeout : 5000);
945 /* Disable freezing the device queue */
946 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
948 if (arglist & CAM_ARG_ERR_RECOVER)
949 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
951 if (cam_send_ccb(device, ccb) < 0) {
952 warn("error getting serial number");
954 if (arglist & CAM_ARG_VERBOSE) {
955 cam_error_print(device, ccb, CAM_ESF_ALL,
956 CAM_EPF_ALL, stderr);
964 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
967 if (arglist & CAM_ARG_VERBOSE) {
968 cam_error_print(device, ccb, CAM_ESF_ALL,
969 CAM_EPF_ALL, stderr);
980 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
981 serial_num[serial_buf->length] = '\0';
983 if ((arglist & CAM_ARG_GET_STDINQ)
984 || (arglist & CAM_ARG_GET_XFERRATE))
985 fprintf(stdout, "%s%d: Serial Number ",
986 device->device_name, device->dev_unit_num);
988 fprintf(stdout, "%.60s\n", serial_num);
996 camxferrate(struct cam_device *device)
998 struct ccb_pathinq cpi;
1000 u_int32_t speed = 0;
1005 if ((retval = get_cpi(device, &cpi)) != 0)
1008 ccb = cam_getccb(device);
1011 warnx("couldn't allocate CCB");
1015 bzero(&(&ccb->ccb_h)[1],
1016 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
1018 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1019 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1021 if (((retval = cam_send_ccb(device, ccb)) < 0)
1022 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1023 const char error_string[] = "error getting transfer settings";
1028 warnx(error_string);
1030 if (arglist & CAM_ARG_VERBOSE)
1031 cam_error_print(device, ccb, CAM_ESF_ALL,
1032 CAM_EPF_ALL, stderr);
1036 goto xferrate_bailout;
1040 speed = cpi.base_transfer_speed;
1042 if (ccb->cts.transport == XPORT_SPI) {
1043 struct ccb_trans_settings_spi *spi =
1044 &ccb->cts.xport_specific.spi;
1046 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1047 freq = scsi_calc_syncsrate(spi->sync_period);
1050 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1051 speed *= (0x01 << spi->bus_width);
1053 } else if (ccb->cts.transport == XPORT_FC) {
1054 struct ccb_trans_settings_fc *fc =
1055 &ccb->cts.xport_specific.fc;
1057 if (fc->valid & CTS_FC_VALID_SPEED)
1058 speed = fc->bitrate;
1059 } else if (ccb->cts.transport == XPORT_SAS) {
1060 struct ccb_trans_settings_sas *sas =
1061 &ccb->cts.xport_specific.sas;
1063 if (sas->valid & CTS_SAS_VALID_SPEED)
1064 speed = sas->bitrate;
1065 } else if (ccb->cts.transport == XPORT_ATA) {
1066 struct ccb_trans_settings_pata *pata =
1067 &ccb->cts.xport_specific.ata;
1069 if (pata->valid & CTS_ATA_VALID_MODE)
1070 speed = ata_mode2speed(pata->mode);
1071 } else if (ccb->cts.transport == XPORT_SATA) {
1072 struct ccb_trans_settings_sata *sata =
1073 &ccb->cts.xport_specific.sata;
1075 if (sata->valid & CTS_SATA_VALID_REVISION)
1076 speed = ata_revision2speed(sata->revision);
1081 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1082 device->device_name, device->dev_unit_num,
1085 fprintf(stdout, "%s%d: %dKB/s transfers",
1086 device->device_name, device->dev_unit_num,
1090 if (ccb->cts.transport == XPORT_SPI) {
1091 struct ccb_trans_settings_spi *spi =
1092 &ccb->cts.xport_specific.spi;
1094 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1095 && (spi->sync_offset != 0))
1096 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1097 freq % 1000, spi->sync_offset);
1099 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1100 && (spi->bus_width > 0)) {
1101 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1102 && (spi->sync_offset != 0)) {
1103 fprintf(stdout, ", ");
1105 fprintf(stdout, " (");
1107 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1108 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1109 && (spi->sync_offset != 0)) {
1110 fprintf(stdout, ")");
1112 } else if (ccb->cts.transport == XPORT_ATA) {
1113 struct ccb_trans_settings_pata *pata =
1114 &ccb->cts.xport_specific.ata;
1117 if (pata->valid & CTS_ATA_VALID_MODE)
1118 printf("%s, ", ata_mode2string(pata->mode));
1119 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1120 printf("ATAPI %dbytes, ", pata->atapi);
1121 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1122 printf("PIO %dbytes", pata->bytecount);
1124 } else if (ccb->cts.transport == XPORT_SATA) {
1125 struct ccb_trans_settings_sata *sata =
1126 &ccb->cts.xport_specific.sata;
1129 if (sata->valid & CTS_SATA_VALID_REVISION)
1130 printf("SATA %d.x, ", sata->revision);
1133 if (sata->valid & CTS_SATA_VALID_MODE)
1134 printf("%s, ", ata_mode2string(sata->mode));
1135 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1136 printf("ATAPI %dbytes, ", sata->atapi);
1137 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1138 printf("PIO %dbytes", sata->bytecount);
1142 if (ccb->cts.protocol == PROTO_SCSI) {
1143 struct ccb_trans_settings_scsi *scsi =
1144 &ccb->cts.proto_specific.scsi;
1145 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1146 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1147 fprintf(stdout, ", Command Queueing Enabled");
1152 fprintf(stdout, "\n");
1162 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1164 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1165 ((u_int32_t)parm->lba_size_2 << 16);
1167 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1168 ((u_int64_t)parm->lba_size48_2 << 16) |
1169 ((u_int64_t)parm->lba_size48_3 << 32) |
1170 ((u_int64_t)parm->lba_size48_4 << 48);
1174 "Support Enabled Value\n");
1177 printf("Host Protected Area (HPA) ");
1178 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1179 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1180 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1183 printf("HPA - Security ");
1184 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1194 atacapprint(struct ata_params *parm)
1196 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1197 ((u_int32_t)parm->lba_size_2 << 16);
1199 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1200 ((u_int64_t)parm->lba_size48_2 << 16) |
1201 ((u_int64_t)parm->lba_size48_3 << 32) |
1202 ((u_int64_t)parm->lba_size48_4 << 48);
1205 printf("protocol ");
1206 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1207 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1208 if (parm->satacapabilities & ATA_SATA_GEN3)
1209 printf(" SATA 3.x\n");
1210 else if (parm->satacapabilities & ATA_SATA_GEN2)
1211 printf(" SATA 2.x\n");
1212 else if (parm->satacapabilities & ATA_SATA_GEN1)
1213 printf(" SATA 1.x\n");
1219 printf("device model %.40s\n", parm->model);
1220 printf("firmware revision %.8s\n", parm->revision);
1221 printf("serial number %.20s\n", parm->serial);
1222 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1223 printf("WWN %04x%04x%04x%04x\n",
1224 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1226 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1227 printf("media serial number %.30s\n",
1228 parm->media_serial);
1231 printf("cylinders %d\n", parm->cylinders);
1232 printf("heads %d\n", parm->heads);
1233 printf("sectors/track %d\n", parm->sectors);
1234 printf("sector size logical %u, physical %lu, offset %lu\n",
1235 ata_logical_sector_size(parm),
1236 (unsigned long)ata_physical_sector_size(parm),
1237 (unsigned long)ata_logical_sector_offset(parm));
1239 if (parm->config == ATA_PROTO_CFA ||
1240 (parm->support.command2 & ATA_SUPPORT_CFA))
1241 printf("CFA supported\n");
1243 printf("LBA%ssupported ",
1244 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1246 printf("%d sectors\n", lbasize);
1250 printf("LBA48%ssupported ",
1251 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1253 printf("%ju sectors\n", (uintmax_t)lbasize48);
1257 printf("PIO supported PIO");
1258 switch (ata_max_pmode(parm)) {
1274 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1275 printf(" w/o IORDY");
1278 printf("DMA%ssupported ",
1279 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1280 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1281 if (parm->mwdmamodes & 0xff) {
1283 if (parm->mwdmamodes & 0x04)
1285 else if (parm->mwdmamodes & 0x02)
1287 else if (parm->mwdmamodes & 0x01)
1291 if ((parm->atavalid & ATA_FLAG_88) &&
1292 (parm->udmamodes & 0xff)) {
1294 if (parm->udmamodes & 0x40)
1296 else if (parm->udmamodes & 0x20)
1298 else if (parm->udmamodes & 0x10)
1300 else if (parm->udmamodes & 0x08)
1302 else if (parm->udmamodes & 0x04)
1304 else if (parm->udmamodes & 0x02)
1306 else if (parm->udmamodes & 0x01)
1313 if (parm->media_rotation_rate == 1) {
1314 printf("media RPM non-rotating\n");
1315 } else if (parm->media_rotation_rate >= 0x0401 &&
1316 parm->media_rotation_rate <= 0xFFFE) {
1317 printf("media RPM %d\n",
1318 parm->media_rotation_rate);
1322 "Support Enabled Value Vendor\n");
1323 printf("read ahead %s %s\n",
1324 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1325 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1326 printf("write cache %s %s\n",
1327 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1328 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1329 printf("flush cache %s %s\n",
1330 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1331 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1332 printf("overlap %s\n",
1333 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1334 printf("Tagged Command Queuing (TCQ) %s %s",
1335 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1336 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1337 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1338 printf(" %d tags\n",
1339 ATA_QUEUE_LEN(parm->queue) + 1);
1342 printf("Native Command Queuing (NCQ) ");
1343 if (parm->satacapabilities != 0xffff &&
1344 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1345 printf("yes %d tags\n",
1346 ATA_QUEUE_LEN(parm->queue) + 1);
1349 printf("SMART %s %s\n",
1350 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1351 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1352 printf("microcode download %s %s\n",
1353 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1354 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1355 printf("security %s %s\n",
1356 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1357 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1358 printf("power management %s %s\n",
1359 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1360 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1361 printf("advanced power management %s %s",
1362 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1363 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1364 if (parm->support.command2 & ATA_SUPPORT_APM) {
1365 printf(" %d/0x%02X\n",
1366 parm->apm_value, parm->apm_value);
1369 printf("automatic acoustic management %s %s",
1370 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1371 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1372 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1373 printf(" %d/0x%02X %d/0x%02X\n",
1374 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1375 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1376 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1377 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1380 printf("media status notification %s %s\n",
1381 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1382 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1383 printf("power-up in Standby %s %s\n",
1384 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1385 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1386 printf("write-read-verify %s %s",
1387 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1388 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1389 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1390 printf(" %d/0x%x\n",
1391 parm->wrv_mode, parm->wrv_mode);
1394 printf("unload %s %s\n",
1395 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1396 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1397 printf("free-fall %s %s\n",
1398 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1399 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1400 printf("Data Set Management (DSM/TRIM) ");
1401 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1403 printf("DSM - max 512byte blocks ");
1404 if (parm->max_dsm_blocks == 0x00)
1405 printf("yes not specified\n");
1408 parm->max_dsm_blocks);
1410 printf("DSM - deterministic read ");
1411 if (parm->support3 & ATA_SUPPORT_DRAT) {
1412 if (parm->support3 & ATA_SUPPORT_RZAT)
1413 printf("yes zeroed\n");
1415 printf("yes any value\n");
1425 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1427 struct ata_pass_16 *ata_pass_16;
1428 struct ata_cmd ata_cmd;
1430 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1431 ata_cmd.command = ata_pass_16->command;
1432 ata_cmd.control = ata_pass_16->control;
1433 ata_cmd.features = ata_pass_16->features;
1435 if (arglist & CAM_ARG_VERBOSE) {
1436 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1437 ata_op_string(&ata_cmd),
1438 ccb->csio.ccb_h.timeout);
1441 /* Disable freezing the device queue */
1442 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1444 if (arglist & CAM_ARG_ERR_RECOVER)
1445 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1447 if (cam_send_ccb(device, ccb) < 0) {
1448 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1449 warn("error sending ATA %s via pass_16",
1450 ata_op_string(&ata_cmd));
1453 if (arglist & CAM_ARG_VERBOSE) {
1454 cam_error_print(device, ccb, CAM_ESF_ALL,
1455 CAM_EPF_ALL, stderr);
1461 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1462 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1463 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1464 warnx("ATA %s via pass_16 failed",
1465 ata_op_string(&ata_cmd));
1467 if (arglist & CAM_ARG_VERBOSE) {
1468 cam_error_print(device, ccb, CAM_ESF_ALL,
1469 CAM_EPF_ALL, stderr);
1480 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1482 if (arglist & CAM_ARG_VERBOSE) {
1483 warnx("sending ATA %s with timeout of %u msecs",
1484 ata_op_string(&(ccb->ataio.cmd)),
1485 ccb->ataio.ccb_h.timeout);
1488 /* Disable freezing the device queue */
1489 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1491 if (arglist & CAM_ARG_ERR_RECOVER)
1492 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1494 if (cam_send_ccb(device, ccb) < 0) {
1495 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1496 warn("error sending ATA %s",
1497 ata_op_string(&(ccb->ataio.cmd)));
1500 if (arglist & CAM_ARG_VERBOSE) {
1501 cam_error_print(device, ccb, CAM_ESF_ALL,
1502 CAM_EPF_ALL, stderr);
1508 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1509 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1510 warnx("ATA %s failed: %d",
1511 ata_op_string(&(ccb->ataio.cmd)), quiet);
1514 if (arglist & CAM_ARG_VERBOSE) {
1515 cam_error_print(device, ccb, CAM_ESF_ALL,
1516 CAM_EPF_ALL, stderr);
1526 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1527 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1528 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1529 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1530 u_int16_t dxfer_len, int timeout, int quiet)
1532 if (data_ptr != NULL) {
1533 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1534 AP_FLAG_TLEN_SECT_CNT;
1535 if (flags & CAM_DIR_OUT)
1536 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1538 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1540 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1543 bzero(&(&ccb->ccb_h)[1],
1544 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1546 scsi_ata_pass_16(&ccb->csio,
1560 /*sense_len*/SSD_FULL_SIZE,
1563 return scsi_cam_pass_16_send(device, ccb, quiet);
1567 ata_try_pass_16(struct cam_device *device)
1569 struct ccb_pathinq cpi;
1571 if (get_cpi(device, &cpi) != 0) {
1572 warnx("couldn't get CPI");
1576 if (cpi.protocol == PROTO_SCSI) {
1577 /* possibly compatible with pass_16 */
1581 /* likely not compatible with pass_16 */
1586 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1587 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1588 u_int8_t command, u_int8_t features, u_int32_t lba,
1589 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1590 int timeout, int quiet)
1594 switch (ata_try_pass_16(device)) {
1598 /* Try using SCSI Passthrough */
1599 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1600 0, tag_action, command, features, lba,
1601 sector_count, data_ptr, dxfer_len,
1605 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1606 sizeof(struct ccb_hdr));
1607 cam_fill_ataio(&ccb->ataio,
1616 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1617 return ata_cam_send(device, ccb, quiet);
1621 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1622 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1623 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1624 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1625 u_int16_t dxfer_len, int timeout, int force48bit)
1629 retval = ata_try_pass_16(device);
1636 /* Try using SCSI Passthrough */
1637 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1638 ata_flags, tag_action, command, features,
1639 lba, sector_count, data_ptr, dxfer_len,
1642 if (ata_flags & AP_FLAG_CHK_COND) {
1643 /* Decode ata_res from sense data */
1644 struct ata_res_pass16 *res_pass16;
1645 struct ata_res *res;
1649 /* sense_data is 4 byte aligned */
1650 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1651 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1652 ptr[i] = le16toh(ptr[i]);
1654 /* sense_data is 4 byte aligned */
1655 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1656 &ccb->csio.sense_data;
1657 res = &ccb->ataio.res;
1658 res->flags = res_pass16->flags;
1659 res->status = res_pass16->status;
1660 res->error = res_pass16->error;
1661 res->lba_low = res_pass16->lba_low;
1662 res->lba_mid = res_pass16->lba_mid;
1663 res->lba_high = res_pass16->lba_high;
1664 res->device = res_pass16->device;
1665 res->lba_low_exp = res_pass16->lba_low_exp;
1666 res->lba_mid_exp = res_pass16->lba_mid_exp;
1667 res->lba_high_exp = res_pass16->lba_high_exp;
1668 res->sector_count = res_pass16->sector_count;
1669 res->sector_count_exp = res_pass16->sector_count_exp;
1675 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1676 sizeof(struct ccb_hdr));
1677 cam_fill_ataio(&ccb->ataio,
1686 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1687 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1689 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1691 if (ata_flags & AP_FLAG_CHK_COND)
1692 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1694 return ata_cam_send(device, ccb, 0);
1698 dump_data(uint16_t *ptr, uint32_t len)
1702 for (i = 0; i < len / 2; i++) {
1704 printf(" %3d: ", i);
1705 printf("%04hx ", ptr[i]);
1714 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1715 int is48bit, u_int64_t *hpasize)
1717 struct ata_res *res;
1719 res = &ccb->ataio.res;
1720 if (res->status & ATA_STATUS_ERROR) {
1721 if (arglist & CAM_ARG_VERBOSE) {
1722 cam_error_print(device, ccb, CAM_ESF_ALL,
1723 CAM_EPF_ALL, stderr);
1724 printf("error = 0x%02x, sector_count = 0x%04x, "
1725 "device = 0x%02x, status = 0x%02x\n",
1726 res->error, res->sector_count,
1727 res->device, res->status);
1730 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1731 warnx("Max address has already been set since "
1732 "last power-on or hardware reset");
1738 if (arglist & CAM_ARG_VERBOSE) {
1739 fprintf(stdout, "%s%d: Raw native max data:\n",
1740 device->device_name, device->dev_unit_num);
1741 /* res is 4 byte aligned */
1742 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1744 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1745 "status = 0x%02x\n", res->error, res->sector_count,
1746 res->device, res->status);
1749 if (hpasize != NULL) {
1751 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1752 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1753 ((res->lba_high << 16) | (res->lba_mid << 8) |
1756 *hpasize = (((res->device & 0x0f) << 24) |
1757 (res->lba_high << 16) | (res->lba_mid << 8) |
1766 ata_read_native_max(struct cam_device *device, int retry_count,
1767 u_int32_t timeout, union ccb *ccb,
1768 struct ata_params *parm, u_int64_t *hpasize)
1774 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1775 protocol = AP_PROTO_NON_DATA;
1778 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1779 protocol |= AP_EXTEND;
1781 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1784 error = ata_do_cmd(device,
1787 /*flags*/CAM_DIR_IN,
1788 /*protocol*/protocol,
1789 /*ata_flags*/AP_FLAG_CHK_COND,
1790 /*tag_action*/MSG_SIMPLE_Q_TAG,
1797 timeout ? timeout : 1000,
1803 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1807 atahpa_set_max(struct cam_device *device, int retry_count,
1808 u_int32_t timeout, union ccb *ccb,
1809 int is48bit, u_int64_t maxsize, int persist)
1815 protocol = AP_PROTO_NON_DATA;
1818 cmd = ATA_SET_MAX_ADDRESS48;
1819 protocol |= AP_EXTEND;
1821 cmd = ATA_SET_MAX_ADDRESS;
1824 /* lba's are zero indexed so the max lba is requested max - 1 */
1828 error = ata_do_cmd(device,
1831 /*flags*/CAM_DIR_OUT,
1832 /*protocol*/protocol,
1833 /*ata_flags*/AP_FLAG_CHK_COND,
1834 /*tag_action*/MSG_SIMPLE_Q_TAG,
1836 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1838 /*sector_count*/persist,
1841 timeout ? timeout : 1000,
1847 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1851 atahpa_password(struct cam_device *device, int retry_count,
1852 u_int32_t timeout, union ccb *ccb,
1853 int is48bit, struct ata_set_max_pwd *pwd)
1859 protocol = AP_PROTO_PIO_OUT;
1860 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1862 error = ata_do_cmd(device,
1865 /*flags*/CAM_DIR_OUT,
1866 /*protocol*/protocol,
1867 /*ata_flags*/AP_FLAG_CHK_COND,
1868 /*tag_action*/MSG_SIMPLE_Q_TAG,
1870 /*features*/ATA_HPA_FEAT_SET_PWD,
1873 /*data_ptr*/(u_int8_t*)pwd,
1874 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1875 timeout ? timeout : 1000,
1881 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1885 atahpa_lock(struct cam_device *device, int retry_count,
1886 u_int32_t timeout, union ccb *ccb, int is48bit)
1892 protocol = AP_PROTO_NON_DATA;
1893 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1895 error = ata_do_cmd(device,
1898 /*flags*/CAM_DIR_OUT,
1899 /*protocol*/protocol,
1900 /*ata_flags*/AP_FLAG_CHK_COND,
1901 /*tag_action*/MSG_SIMPLE_Q_TAG,
1903 /*features*/ATA_HPA_FEAT_LOCK,
1908 timeout ? timeout : 1000,
1914 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1918 atahpa_unlock(struct cam_device *device, int retry_count,
1919 u_int32_t timeout, union ccb *ccb,
1920 int is48bit, struct ata_set_max_pwd *pwd)
1926 protocol = AP_PROTO_PIO_OUT;
1927 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1929 error = ata_do_cmd(device,
1932 /*flags*/CAM_DIR_OUT,
1933 /*protocol*/protocol,
1934 /*ata_flags*/AP_FLAG_CHK_COND,
1935 /*tag_action*/MSG_SIMPLE_Q_TAG,
1937 /*features*/ATA_HPA_FEAT_UNLOCK,
1940 /*data_ptr*/(u_int8_t*)pwd,
1941 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1942 timeout ? timeout : 1000,
1948 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1952 atahpa_freeze_lock(struct cam_device *device, int retry_count,
1953 u_int32_t timeout, union ccb *ccb, int is48bit)
1959 protocol = AP_PROTO_NON_DATA;
1960 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1962 error = ata_do_cmd(device,
1965 /*flags*/CAM_DIR_OUT,
1966 /*protocol*/protocol,
1967 /*ata_flags*/AP_FLAG_CHK_COND,
1968 /*tag_action*/MSG_SIMPLE_Q_TAG,
1970 /*features*/ATA_HPA_FEAT_FREEZE,
1975 timeout ? timeout : 1000,
1981 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1986 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
1987 union ccb *ccb, struct ata_params** ident_bufp)
1989 struct ata_params *ident_buf;
1990 struct ccb_pathinq cpi;
1991 struct ccb_getdev cgd;
1994 u_int8_t command, retry_command;
1996 if (get_cpi(device, &cpi) != 0) {
1997 warnx("couldn't get CPI");
2001 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2002 if (cpi.protocol == PROTO_ATA) {
2003 if (get_cgd(device, &cgd) != 0) {
2004 warnx("couldn't get CGD");
2008 command = (cgd.protocol == PROTO_ATA) ?
2009 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2012 /* We don't know which for sure so try both */
2013 command = ATA_ATA_IDENTIFY;
2014 retry_command = ATA_ATAPI_IDENTIFY;
2017 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2019 warnx("can't calloc memory for identify\n");
2023 error = ata_do_28bit_cmd(device,
2025 /*retries*/retry_count,
2026 /*flags*/CAM_DIR_IN,
2027 /*protocol*/AP_PROTO_PIO_IN,
2028 /*tag_action*/MSG_SIMPLE_Q_TAG,
2032 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2033 /*data_ptr*/(u_int8_t *)ptr,
2034 /*dxfer_len*/sizeof(struct ata_params),
2035 /*timeout*/timeout ? timeout : 30 * 1000,
2039 if (retry_command == 0) {
2043 error = ata_do_28bit_cmd(device,
2045 /*retries*/retry_count,
2046 /*flags*/CAM_DIR_IN,
2047 /*protocol*/AP_PROTO_PIO_IN,
2048 /*tag_action*/MSG_SIMPLE_Q_TAG,
2049 /*command*/retry_command,
2052 /*sector_count*/(u_int8_t)
2053 sizeof(struct ata_params),
2054 /*data_ptr*/(u_int8_t *)ptr,
2055 /*dxfer_len*/sizeof(struct ata_params),
2056 /*timeout*/timeout ? timeout : 30 * 1000,
2066 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2067 ptr[i] = le16toh(ptr[i]);
2072 if (arglist & CAM_ARG_VERBOSE) {
2073 fprintf(stdout, "%s%d: Raw identify data:\n",
2074 device->device_name, device->dev_unit_num);
2075 dump_data(ptr, sizeof(struct ata_params));
2078 /* check for invalid (all zero) response */
2080 warnx("Invalid identify response detected");
2085 ident_buf = (struct ata_params *)ptr;
2086 if (strncmp(ident_buf->model, "FX", 2) &&
2087 strncmp(ident_buf->model, "NEC", 3) &&
2088 strncmp(ident_buf->model, "Pioneer", 7) &&
2089 strncmp(ident_buf->model, "SHARP", 5)) {
2090 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2091 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2092 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2093 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2095 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2096 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2097 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2098 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2099 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2100 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2101 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2102 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2103 sizeof(ident_buf->media_serial));
2105 *ident_bufp = ident_buf;
2112 ataidentify(struct cam_device *device, int retry_count, int timeout)
2115 struct ata_params *ident_buf;
2118 if ((ccb = cam_getccb(device)) == NULL) {
2119 warnx("couldn't allocate CCB");
2123 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2128 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2129 if (ata_read_native_max(device, retry_count, timeout, ccb,
2130 ident_buf, &hpasize) != 0) {
2138 printf("%s%d: ", device->device_name, device->dev_unit_num);
2139 ata_print_ident(ident_buf);
2140 camxferrate(device);
2141 atacapprint(ident_buf);
2142 atahpa_print(ident_buf, hpasize, 0);
2149 #endif /* MINIMALISTIC */
2152 #ifndef MINIMALISTIC
2154 ATA_SECURITY_ACTION_PRINT,
2155 ATA_SECURITY_ACTION_FREEZE,
2156 ATA_SECURITY_ACTION_UNLOCK,
2157 ATA_SECURITY_ACTION_DISABLE,
2158 ATA_SECURITY_ACTION_ERASE,
2159 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2160 ATA_SECURITY_ACTION_SET_PASSWORD
2161 } atasecurity_action;
2164 atasecurity_print_time(u_int16_t tw)
2168 printf("unspecified");
2170 printf("> 508 min");
2172 printf("%i min", 2 * tw);
2176 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2180 return 2 * 3600 * 1000; /* default: two hours */
2181 else if (timeout > 255)
2182 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2184 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2189 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2193 bzero(&cmd, sizeof(cmd));
2194 cmd.command = command;
2195 printf("Issuing %s", ata_op_string(&cmd));
2198 char pass[sizeof(pwd->password)+1];
2200 /* pwd->password may not be null terminated */
2201 pass[sizeof(pwd->password)] = '\0';
2202 strncpy(pass, pwd->password, sizeof(pwd->password));
2203 printf(" password='%s', user='%s'",
2205 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2208 if (command == ATA_SECURITY_SET_PASSWORD) {
2209 printf(", mode='%s'",
2210 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2211 "maximum" : "high");
2219 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2220 int retry_count, u_int32_t timeout, int quiet)
2224 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2226 return ata_do_28bit_cmd(device,
2229 /*flags*/CAM_DIR_NONE,
2230 /*protocol*/AP_PROTO_NON_DATA,
2231 /*tag_action*/MSG_SIMPLE_Q_TAG,
2232 /*command*/ATA_SECURITY_FREEZE_LOCK,
2243 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2244 int retry_count, u_int32_t timeout,
2245 struct ata_security_password *pwd, int quiet)
2249 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2251 return ata_do_28bit_cmd(device,
2254 /*flags*/CAM_DIR_OUT,
2255 /*protocol*/AP_PROTO_PIO_OUT,
2256 /*tag_action*/MSG_SIMPLE_Q_TAG,
2257 /*command*/ATA_SECURITY_UNLOCK,
2261 /*data_ptr*/(u_int8_t *)pwd,
2262 /*dxfer_len*/sizeof(*pwd),
2268 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2269 int retry_count, u_int32_t timeout,
2270 struct ata_security_password *pwd, int quiet)
2274 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, 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_DISABLE_PASSWORD,
2285 /*data_ptr*/(u_int8_t *)pwd,
2286 /*dxfer_len*/sizeof(*pwd),
2293 atasecurity_erase_confirm(struct cam_device *device,
2294 struct ata_params* ident_buf)
2297 printf("\nYou are about to ERASE ALL DATA from the following"
2298 " device:\n%s%d,%s%d: ", device->device_name,
2299 device->dev_unit_num, device->given_dev_name,
2300 device->given_unit_number);
2301 ata_print_ident(ident_buf);
2305 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2307 if (fgets(str, sizeof(str), stdin) != NULL) {
2308 if (strncasecmp(str, "yes", 3) == 0) {
2310 } else if (strncasecmp(str, "no", 2) == 0) {
2313 printf("Please answer \"yes\" or "
2324 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2325 int retry_count, u_int32_t timeout,
2326 u_int32_t erase_timeout,
2327 struct ata_security_password *pwd, int quiet)
2332 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2334 error = ata_do_28bit_cmd(device,
2337 /*flags*/CAM_DIR_NONE,
2338 /*protocol*/AP_PROTO_NON_DATA,
2339 /*tag_action*/MSG_SIMPLE_Q_TAG,
2340 /*command*/ATA_SECURITY_ERASE_PREPARE,
2353 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2355 error = ata_do_28bit_cmd(device,
2358 /*flags*/CAM_DIR_OUT,
2359 /*protocol*/AP_PROTO_PIO_OUT,
2360 /*tag_action*/MSG_SIMPLE_Q_TAG,
2361 /*command*/ATA_SECURITY_ERASE_UNIT,
2365 /*data_ptr*/(u_int8_t *)pwd,
2366 /*dxfer_len*/sizeof(*pwd),
2367 /*timeout*/erase_timeout,
2370 if (error == 0 && quiet == 0)
2371 printf("\nErase Complete\n");
2377 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2378 int retry_count, u_int32_t timeout,
2379 struct ata_security_password *pwd, int quiet)
2383 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2385 return ata_do_28bit_cmd(device,
2388 /*flags*/CAM_DIR_OUT,
2389 /*protocol*/AP_PROTO_PIO_OUT,
2390 /*tag_action*/MSG_SIMPLE_Q_TAG,
2391 /*command*/ATA_SECURITY_SET_PASSWORD,
2395 /*data_ptr*/(u_int8_t *)pwd,
2396 /*dxfer_len*/sizeof(*pwd),
2402 atasecurity_print(struct ata_params *parm)
2405 printf("\nSecurity Option Value\n");
2406 if (arglist & CAM_ARG_VERBOSE) {
2407 printf("status %04x\n",
2408 parm->security_status);
2410 printf("supported %s\n",
2411 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2412 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2414 printf("enabled %s\n",
2415 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2416 printf("drive locked %s\n",
2417 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2418 printf("security config frozen %s\n",
2419 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2420 printf("count expired %s\n",
2421 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2422 printf("security level %s\n",
2423 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2424 printf("enhanced erase supported %s\n",
2425 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2426 printf("erase time ");
2427 atasecurity_print_time(parm->erase_time);
2429 printf("enhanced erase time ");
2430 atasecurity_print_time(parm->enhanced_erase_time);
2432 printf("master password rev %04x%s\n",
2433 parm->master_passwd_revision,
2434 parm->master_passwd_revision == 0x0000 ||
2435 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2439 * Validates and copies the password in optarg to the passed buffer.
2440 * If the password in optarg is the same length as the buffer then
2441 * the data will still be copied but no null termination will occur.
2444 ata_getpwd(u_int8_t *passwd, int max, char opt)
2448 len = strlen(optarg);
2450 warnx("-%c password is too long", opt);
2452 } else if (len == 0) {
2453 warnx("-%c password is missing", opt);
2455 } else if (optarg[0] == '-'){
2456 warnx("-%c password starts with '-' (generic arg?)", opt);
2458 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2459 warnx("-%c password conflicts with existing password from -%c",
2464 /* Callers pass in a buffer which does NOT need to be terminated */
2465 strncpy(passwd, optarg, max);
2472 ATA_HPA_ACTION_PRINT,
2473 ATA_HPA_ACTION_SET_MAX,
2474 ATA_HPA_ACTION_SET_PWD,
2475 ATA_HPA_ACTION_LOCK,
2476 ATA_HPA_ACTION_UNLOCK,
2477 ATA_HPA_ACTION_FREEZE_LOCK
2481 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2482 u_int64_t maxsize, int persist)
2484 printf("\nYou are about to configure HPA to limit the user accessible\n"
2485 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2486 persist ? "persistently" : "temporarily",
2487 device->device_name, device->dev_unit_num,
2488 device->given_dev_name, device->given_unit_number);
2489 ata_print_ident(ident_buf);
2493 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2495 if (NULL != fgets(str, sizeof(str), stdin)) {
2496 if (0 == strncasecmp(str, "yes", 3)) {
2498 } else if (0 == strncasecmp(str, "no", 2)) {
2501 printf("Please answer \"yes\" or "
2512 atahpa(struct cam_device *device, int retry_count, int timeout,
2513 int argc, char **argv, char *combinedopt)
2516 struct ata_params *ident_buf;
2517 struct ccb_getdev cgd;
2518 struct ata_set_max_pwd pwd;
2519 int error, confirm, quiet, c, action, actions, setpwd, persist;
2520 int security, is48bit, pwdsize;
2521 u_int64_t hpasize, maxsize;
2531 memset(&pwd, 0, sizeof(pwd));
2533 /* default action is to print hpa information */
2534 action = ATA_HPA_ACTION_PRINT;
2535 pwdsize = sizeof(pwd.password);
2537 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2540 action = ATA_HPA_ACTION_SET_MAX;
2541 maxsize = strtoumax(optarg, NULL, 0);
2546 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2548 action = ATA_HPA_ACTION_SET_PWD;
2554 action = ATA_HPA_ACTION_LOCK;
2560 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2562 action = ATA_HPA_ACTION_UNLOCK;
2568 action = ATA_HPA_ACTION_FREEZE_LOCK;
2588 warnx("too many hpa actions specified");
2592 if (get_cgd(device, &cgd) != 0) {
2593 warnx("couldn't get CGD");
2597 ccb = cam_getccb(device);
2599 warnx("couldn't allocate CCB");
2603 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2610 printf("%s%d: ", device->device_name, device->dev_unit_num);
2611 ata_print_ident(ident_buf);
2612 camxferrate(device);
2615 if (action == ATA_HPA_ACTION_PRINT) {
2616 error = ata_read_native_max(device, retry_count, timeout, ccb,
2617 ident_buf, &hpasize);
2619 atahpa_print(ident_buf, hpasize, 1);
2626 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2627 warnx("HPA is not supported by this device");
2633 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2634 warnx("HPA Security is not supported by this device");
2640 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2643 * The ATA spec requires:
2644 * 1. Read native max addr is called directly before set max addr
2645 * 2. Read native max addr is NOT called before any other set max call
2648 case ATA_HPA_ACTION_SET_MAX:
2650 atahpa_set_confirm(device, ident_buf, maxsize,
2657 error = ata_read_native_max(device, retry_count, timeout,
2658 ccb, ident_buf, &hpasize);
2660 error = atahpa_set_max(device, retry_count, timeout,
2661 ccb, is48bit, maxsize, persist);
2663 /* redo identify to get new lba values */
2664 error = ata_do_identify(device, retry_count,
2667 atahpa_print(ident_buf, hpasize, 1);
2672 case ATA_HPA_ACTION_SET_PWD:
2673 error = atahpa_password(device, retry_count, timeout,
2674 ccb, is48bit, &pwd);
2676 printf("HPA password has been set\n");
2679 case ATA_HPA_ACTION_LOCK:
2680 error = atahpa_lock(device, retry_count, timeout,
2683 printf("HPA has been locked\n");
2686 case ATA_HPA_ACTION_UNLOCK:
2687 error = atahpa_unlock(device, retry_count, timeout,
2688 ccb, is48bit, &pwd);
2690 printf("HPA has been unlocked\n");
2693 case ATA_HPA_ACTION_FREEZE_LOCK:
2694 error = atahpa_freeze_lock(device, retry_count, timeout,
2697 printf("HPA has been frozen\n");
2701 errx(1, "Option currently not supported");
2711 atasecurity(struct cam_device *device, int retry_count, int timeout,
2712 int argc, char **argv, char *combinedopt)
2715 struct ata_params *ident_buf;
2716 int error, confirm, quiet, c, action, actions, setpwd;
2717 int security_enabled, erase_timeout, pwdsize;
2718 struct ata_security_password pwd;
2726 memset(&pwd, 0, sizeof(pwd));
2728 /* default action is to print security information */
2729 action = ATA_SECURITY_ACTION_PRINT;
2731 /* user is master by default as its safer that way */
2732 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2733 pwdsize = sizeof(pwd.password);
2735 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2738 action = ATA_SECURITY_ACTION_FREEZE;
2743 if (strcasecmp(optarg, "user") == 0) {
2744 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2745 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2746 } else if (strcasecmp(optarg, "master") != 0) {
2747 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2748 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2750 warnx("-U argument '%s' is invalid (must be "
2751 "'user' or 'master')", optarg);
2757 if (strcasecmp(optarg, "high") == 0) {
2758 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2759 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2760 } else if (strcasecmp(optarg, "maximum") == 0) {
2761 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2762 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2764 warnx("-l argument '%s' is unknown (must be "
2765 "'high' or 'maximum')", optarg);
2771 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2773 action = ATA_SECURITY_ACTION_UNLOCK;
2778 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2780 action = ATA_SECURITY_ACTION_DISABLE;
2785 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2787 action = ATA_SECURITY_ACTION_ERASE;
2792 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2794 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2795 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2800 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2803 if (action == ATA_SECURITY_ACTION_PRINT)
2804 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2806 * Don't increment action as this can be combined
2807 * with other actions.
2820 erase_timeout = atoi(optarg) * 1000;
2826 warnx("too many security actions specified");
2830 if ((ccb = cam_getccb(device)) == NULL) {
2831 warnx("couldn't allocate CCB");
2835 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2842 printf("%s%d: ", device->device_name, device->dev_unit_num);
2843 ata_print_ident(ident_buf);
2844 camxferrate(device);
2847 if (action == ATA_SECURITY_ACTION_PRINT) {
2848 atasecurity_print(ident_buf);
2854 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2855 warnx("Security not supported");
2861 /* default timeout 15 seconds the same as linux hdparm */
2862 timeout = timeout ? timeout : 15 * 1000;
2864 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2866 /* first set the password if requested */
2868 /* confirm we can erase before setting the password if erasing */
2870 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2871 action == ATA_SECURITY_ACTION_ERASE) &&
2872 atasecurity_erase_confirm(device, ident_buf) == 0) {
2878 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2879 pwd.revision = ident_buf->master_passwd_revision;
2880 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2881 --pwd.revision == 0) {
2882 pwd.revision = 0xfffe;
2885 error = atasecurity_set_password(device, ccb, retry_count,
2886 timeout, &pwd, quiet);
2892 security_enabled = 1;
2896 case ATA_SECURITY_ACTION_FREEZE:
2897 error = atasecurity_freeze(device, ccb, retry_count,
2901 case ATA_SECURITY_ACTION_UNLOCK:
2902 if (security_enabled) {
2903 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2904 error = atasecurity_unlock(device, ccb,
2905 retry_count, timeout, &pwd, quiet);
2907 warnx("Can't unlock, drive is not locked");
2911 warnx("Can't unlock, security is disabled");
2916 case ATA_SECURITY_ACTION_DISABLE:
2917 if (security_enabled) {
2918 /* First unlock the drive if its locked */
2919 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2920 error = atasecurity_unlock(device, ccb,
2928 error = atasecurity_disable(device,
2936 warnx("Can't disable security (already disabled)");
2941 case ATA_SECURITY_ACTION_ERASE:
2942 if (security_enabled) {
2943 if (erase_timeout == 0) {
2944 erase_timeout = atasecurity_erase_timeout_msecs(
2945 ident_buf->erase_time);
2948 error = atasecurity_erase(device, ccb, retry_count,
2949 timeout, erase_timeout, &pwd,
2952 warnx("Can't secure erase (security is disabled)");
2957 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
2958 if (security_enabled) {
2959 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
2960 if (erase_timeout == 0) {
2962 atasecurity_erase_timeout_msecs(
2963 ident_buf->enhanced_erase_time);
2966 error = atasecurity_erase(device, ccb,
2967 retry_count, timeout,
2968 erase_timeout, &pwd,
2971 warnx("Enhanced erase is not supported");
2975 warnx("Can't secure erase (enhanced), "
2976 "(security is disabled)");
2987 #endif /* MINIMALISTIC */
2990 * Parse out a bus, or a bus, target and lun in the following
2996 * Returns the number of parsed components, or 0.
2999 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
3004 while (isspace(*tstr) && (*tstr != '\0'))
3007 tmpstr = (char *)strtok(tstr, ":");
3008 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3009 *bus = strtol(tmpstr, NULL, 0);
3010 *arglst |= CAM_ARG_BUS;
3012 tmpstr = (char *)strtok(NULL, ":");
3013 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3014 *target = strtol(tmpstr, NULL, 0);
3015 *arglst |= CAM_ARG_TARGET;
3017 tmpstr = (char *)strtok(NULL, ":");
3018 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3019 *lun = strtol(tmpstr, NULL, 0);
3020 *arglst |= CAM_ARG_LUN;
3030 dorescan_or_reset(int argc, char **argv, int rescan)
3032 static const char must[] =
3033 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3035 int bus = -1, target = -1, lun = -1;
3039 warnx(must, rescan? "rescan" : "reset");
3043 tstr = argv[optind];
3044 while (isspace(*tstr) && (*tstr != '\0'))
3046 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3047 arglist |= CAM_ARG_BUS;
3049 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3050 if (rv != 1 && rv != 3) {
3051 warnx(must, rescan? "rescan" : "reset");
3056 if ((arglist & CAM_ARG_BUS)
3057 && (arglist & CAM_ARG_TARGET)
3058 && (arglist & CAM_ARG_LUN))
3059 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3061 error = rescan_or_reset_bus(bus, rescan);
3067 rescan_or_reset_bus(int bus, int rescan)
3069 union ccb ccb, matchccb;
3075 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3076 warnx("error opening transport layer device %s", XPT_DEVICE);
3077 warn("%s", XPT_DEVICE);
3082 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3083 ccb.ccb_h.path_id = bus;
3084 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3085 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3086 ccb.crcn.flags = CAM_FLAG_NONE;
3088 /* run this at a low priority */
3089 ccb.ccb_h.pinfo.priority = 5;
3091 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3092 warn("CAMIOCOMMAND ioctl failed");
3097 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3098 fprintf(stdout, "%s of bus %d was successful\n",
3099 rescan ? "Re-scan" : "Reset", bus);
3101 fprintf(stdout, "%s of bus %d returned error %#x\n",
3102 rescan ? "Re-scan" : "Reset", bus,
3103 ccb.ccb_h.status & CAM_STATUS_MASK);
3114 * The right way to handle this is to modify the xpt so that it can
3115 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3116 * that isn't implemented, so instead we enumerate the busses and
3117 * send the rescan or reset to those busses in the case where the
3118 * given bus is -1 (wildcard). We don't send a rescan or reset
3119 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3120 * no-op, sending a rescan to the xpt bus would result in a status of
3123 bzero(&(&matchccb.ccb_h)[1],
3124 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3125 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3126 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3127 bufsize = sizeof(struct dev_match_result) * 20;
3128 matchccb.cdm.match_buf_len = bufsize;
3129 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3130 if (matchccb.cdm.matches == NULL) {
3131 warnx("can't malloc memory for matches");
3135 matchccb.cdm.num_matches = 0;
3137 matchccb.cdm.num_patterns = 1;
3138 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3140 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3141 matchccb.cdm.pattern_buf_len);
3142 if (matchccb.cdm.patterns == NULL) {
3143 warnx("can't malloc memory for patterns");
3147 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3148 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3153 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3154 warn("CAMIOCOMMAND ioctl failed");
3159 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3160 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3161 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3162 warnx("got CAM error %#x, CDM error %d\n",
3163 matchccb.ccb_h.status, matchccb.cdm.status);
3168 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3169 struct bus_match_result *bus_result;
3171 /* This shouldn't happen. */
3172 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3175 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3178 * We don't want to rescan or reset the xpt bus.
3181 if ((int)bus_result->path_id == -1)
3184 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3186 ccb.ccb_h.path_id = bus_result->path_id;
3187 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3188 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3189 ccb.crcn.flags = CAM_FLAG_NONE;
3191 /* run this at a low priority */
3192 ccb.ccb_h.pinfo.priority = 5;
3194 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3195 warn("CAMIOCOMMAND ioctl failed");
3200 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3201 fprintf(stdout, "%s of bus %d was successful\n",
3202 rescan? "Re-scan" : "Reset",
3203 bus_result->path_id);
3206 * Don't bail out just yet, maybe the other
3207 * rescan or reset commands will complete
3210 fprintf(stderr, "%s of bus %d returned error "
3211 "%#x\n", rescan? "Re-scan" : "Reset",
3212 bus_result->path_id,
3213 ccb.ccb_h.status & CAM_STATUS_MASK);
3217 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3218 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3225 if (matchccb.cdm.patterns != NULL)
3226 free(matchccb.cdm.patterns);
3227 if (matchccb.cdm.matches != NULL)
3228 free(matchccb.cdm.matches);
3234 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
3237 struct cam_device *device;
3243 warnx("invalid bus number %d", bus);
3248 warnx("invalid target number %d", target);
3253 warnx("invalid lun number %d", lun);
3259 bzero(&ccb, sizeof(union ccb));
3262 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3263 warnx("error opening transport layer device %s\n",
3265 warn("%s", XPT_DEVICE);
3269 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3270 if (device == NULL) {
3271 warnx("%s", cam_errbuf);
3276 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3277 ccb.ccb_h.path_id = bus;
3278 ccb.ccb_h.target_id = target;
3279 ccb.ccb_h.target_lun = lun;
3280 ccb.ccb_h.timeout = 5000;
3281 ccb.crcn.flags = CAM_FLAG_NONE;
3283 /* run this at a low priority */
3284 ccb.ccb_h.pinfo.priority = 5;
3287 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3288 warn("CAMIOCOMMAND ioctl failed");
3293 if (cam_send_ccb(device, &ccb) < 0) {
3294 warn("error sending XPT_RESET_DEV CCB");
3295 cam_close_device(device);
3303 cam_close_device(device);
3306 * An error code of CAM_BDR_SENT is normal for a BDR request.
3308 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3310 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3311 fprintf(stdout, "%s of %d:%d:%d was successful\n",
3312 scan? "Re-scan" : "Reset", bus, target, lun);
3315 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
3316 scan? "Re-scan" : "Reset", bus, target, lun,
3317 ccb.ccb_h.status & CAM_STATUS_MASK);
3322 #ifndef MINIMALISTIC
3324 readdefects(struct cam_device *device, int argc, char **argv,
3325 char *combinedopt, int retry_count, int timeout)
3327 union ccb *ccb = NULL;
3328 struct scsi_read_defect_data_10 *rdd_cdb;
3329 u_int8_t *defect_list = NULL;
3330 u_int32_t max_dlist_length = SRDD10_MAX_LENGTH, dlist_length = 0;
3331 u_int32_t returned_length = 0;
3332 u_int32_t num_returned = 0;
3333 u_int8_t returned_format;
3336 int lists_specified;
3339 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3345 while (isspace(*tstr) && (*tstr != '\0'))
3347 if (strcmp(tstr, "block") == 0)
3348 arglist |= CAM_ARG_FORMAT_BLOCK;
3349 else if (strcmp(tstr, "bfi") == 0)
3350 arglist |= CAM_ARG_FORMAT_BFI;
3351 else if (strcmp(tstr, "phys") == 0)
3352 arglist |= CAM_ARG_FORMAT_PHYS;
3355 warnx("invalid defect format %s", tstr);
3356 goto defect_bailout;
3361 arglist |= CAM_ARG_GLIST;
3364 arglist |= CAM_ARG_PLIST;
3371 ccb = cam_getccb(device);
3374 * Eventually we should probably support the 12 byte READ DEFECT
3375 * DATA command. It supports a longer parameter list, which may be
3376 * necessary on newer drives with lots of defects. According to
3377 * the SBC-3 spec, drives are supposed to return an illegal request
3378 * if they have more defect data than will fit in 64K.
3380 defect_list = malloc(max_dlist_length);
3381 if (defect_list == NULL) {
3382 warnx("can't malloc memory for defect list");
3384 goto defect_bailout;
3388 * We start off asking for just the header to determine how much
3389 * defect data is available. Some Hitachi drives return an error
3390 * if you ask for more data than the drive has. Once we know the
3391 * length, we retry the command with the returned length.
3393 dlist_length = sizeof(struct scsi_read_defect_data_hdr_10);
3395 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
3399 lists_specified = 0;
3402 * cam_getccb() zeros the CCB header only. So we need to zero the
3403 * payload portion of the ccb.
3405 bzero(&(&ccb->ccb_h)[1],
3406 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3408 cam_fill_csio(&ccb->csio,
3409 /*retries*/ retry_count,
3411 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
3412 CAM_PASS_ERR_RECOVER : 0),
3413 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3414 /*data_ptr*/ defect_list,
3415 /*dxfer_len*/ dlist_length,
3416 /*sense_len*/ SSD_FULL_SIZE,
3417 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
3418 /*timeout*/ timeout ? timeout : 5000);
3420 rdd_cdb->opcode = READ_DEFECT_DATA_10;
3421 if (arglist & CAM_ARG_FORMAT_BLOCK)
3422 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
3423 else if (arglist & CAM_ARG_FORMAT_BFI)
3424 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
3425 else if (arglist & CAM_ARG_FORMAT_PHYS)
3426 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
3429 warnx("no defect list format specified");
3430 goto defect_bailout;
3432 if (arglist & CAM_ARG_PLIST) {
3433 rdd_cdb->format |= SRDD10_PLIST;
3437 if (arglist & CAM_ARG_GLIST) {
3438 rdd_cdb->format |= SRDD10_GLIST;
3442 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
3444 /* Disable freezing the device queue */
3445 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3447 if (cam_send_ccb(device, ccb) < 0) {
3448 perror("error reading defect list");
3450 if (arglist & CAM_ARG_VERBOSE) {
3451 cam_error_print(device, ccb, CAM_ESF_ALL,
3452 CAM_EPF_ALL, stderr);
3456 goto defect_bailout;
3459 returned_length = scsi_2btoul(((struct
3460 scsi_read_defect_data_hdr_10 *)defect_list)->length);
3462 if (get_length != 0) {
3465 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3466 CAM_SCSI_STATUS_ERROR) {
3467 struct scsi_sense_data *sense;
3468 int error_code, sense_key, asc, ascq;
3470 sense = &ccb->csio.sense_data;
3471 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3472 ccb->csio.sense_resid, &error_code, &sense_key,
3473 &asc, &ascq, /*show_errors*/ 1);
3476 * If the drive is reporting that it just doesn't
3477 * support the defect list format, go ahead and use
3478 * the length it reported. Otherwise, the length
3479 * may not be valid, so use the maximum.
3481 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3482 && (asc == 0x1c) && (ascq == 0x00)
3483 && (returned_length > 0)) {
3484 dlist_length = returned_length +
3485 sizeof(struct scsi_read_defect_data_hdr_10);
3486 dlist_length = min(dlist_length,
3489 dlist_length = max_dlist_length;
3490 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3493 warnx("Error reading defect header");
3494 if (arglist & CAM_ARG_VERBOSE)
3495 cam_error_print(device, ccb, CAM_ESF_ALL,
3496 CAM_EPF_ALL, stderr);
3497 goto defect_bailout;
3499 dlist_length = returned_length +
3500 sizeof(struct scsi_read_defect_data_hdr_10);
3501 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3507 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
3508 defect_list)->format;
3510 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3511 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3512 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3513 struct scsi_sense_data *sense;
3514 int error_code, sense_key, asc, ascq;
3516 sense = &ccb->csio.sense_data;
3517 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3518 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3519 &ascq, /*show_errors*/ 1);
3522 * According to the SCSI spec, if the disk doesn't support
3523 * the requested format, it will generally return a sense
3524 * key of RECOVERED ERROR, and an additional sense code
3525 * of "DEFECT LIST NOT FOUND". So, we check for that, and
3526 * also check to make sure that the returned length is
3527 * greater than 0, and then print out whatever format the
3530 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3531 && (asc == 0x1c) && (ascq == 0x00)
3532 && (returned_length > 0)) {
3533 warnx("requested defect format not available");
3534 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
3535 case SRDD10_BLOCK_FORMAT:
3536 warnx("Device returned block format");
3538 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3539 warnx("Device returned bytes from index"
3542 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3543 warnx("Device returned physical sector format");
3547 warnx("Device returned unknown defect"
3548 " data format %#x", returned_format);
3549 goto defect_bailout;
3550 break; /* NOTREACHED */
3554 warnx("Error returned from read defect data command");
3555 if (arglist & CAM_ARG_VERBOSE)
3556 cam_error_print(device, ccb, CAM_ESF_ALL,
3557 CAM_EPF_ALL, stderr);
3558 goto defect_bailout;
3560 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3562 warnx("Error returned from read defect data command");
3563 if (arglist & CAM_ARG_VERBOSE)
3564 cam_error_print(device, ccb, CAM_ESF_ALL,
3565 CAM_EPF_ALL, stderr);
3566 goto defect_bailout;
3570 * XXX KDM I should probably clean up the printout format for the
3573 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
3574 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
3576 struct scsi_defect_desc_phys_sector *dlist;
3578 dlist = (struct scsi_defect_desc_phys_sector *)
3580 sizeof(struct scsi_read_defect_data_hdr_10));
3582 num_returned = returned_length /
3583 sizeof(struct scsi_defect_desc_phys_sector);
3585 fprintf(stderr, "Got %d defect", num_returned);
3587 if ((lists_specified == 0) || (num_returned == 0)) {
3588 fprintf(stderr, "s.\n");
3590 } else if (num_returned == 1)
3591 fprintf(stderr, ":\n");
3593 fprintf(stderr, "s:\n");
3595 for (i = 0; i < num_returned; i++) {
3596 fprintf(stdout, "%d:%d:%d\n",
3597 scsi_3btoul(dlist[i].cylinder),
3599 scsi_4btoul(dlist[i].sector));
3603 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
3605 struct scsi_defect_desc_bytes_from_index *dlist;
3607 dlist = (struct scsi_defect_desc_bytes_from_index *)
3609 sizeof(struct scsi_read_defect_data_hdr_10));
3611 num_returned = returned_length /
3612 sizeof(struct scsi_defect_desc_bytes_from_index);
3614 fprintf(stderr, "Got %d defect", num_returned);
3616 if ((lists_specified == 0) || (num_returned == 0)) {
3617 fprintf(stderr, "s.\n");
3619 } else if (num_returned == 1)
3620 fprintf(stderr, ":\n");
3622 fprintf(stderr, "s:\n");
3624 for (i = 0; i < num_returned; i++) {
3625 fprintf(stdout, "%d:%d:%d\n",
3626 scsi_3btoul(dlist[i].cylinder),
3628 scsi_4btoul(dlist[i].bytes_from_index));
3632 case SRDDH10_BLOCK_FORMAT:
3634 struct scsi_defect_desc_block *dlist;
3636 dlist = (struct scsi_defect_desc_block *)(defect_list +
3637 sizeof(struct scsi_read_defect_data_hdr_10));
3639 num_returned = returned_length /
3640 sizeof(struct scsi_defect_desc_block);
3642 fprintf(stderr, "Got %d defect", num_returned);
3644 if ((lists_specified == 0) || (num_returned == 0)) {
3645 fprintf(stderr, "s.\n");
3647 } else if (num_returned == 1)
3648 fprintf(stderr, ":\n");
3650 fprintf(stderr, "s:\n");
3652 for (i = 0; i < num_returned; i++)
3653 fprintf(stdout, "%u\n",
3654 scsi_4btoul(dlist[i].address));
3658 fprintf(stderr, "Unknown defect format %d\n",
3659 returned_format & SRDDH10_DLIST_FORMAT_MASK);
3665 if (defect_list != NULL)
3673 #endif /* MINIMALISTIC */
3677 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3681 ccb = cam_getccb(device);
3687 #ifndef MINIMALISTIC
3689 mode_sense(struct cam_device *device, int mode_page, int page_control,
3690 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3695 ccb = cam_getccb(device);
3698 errx(1, "mode_sense: couldn't allocate CCB");
3700 bzero(&(&ccb->ccb_h)[1],
3701 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3703 scsi_mode_sense(&ccb->csio,
3704 /* retries */ retry_count,
3706 /* tag_action */ MSG_SIMPLE_Q_TAG,
3708 /* page_code */ page_control << 6,
3709 /* page */ mode_page,
3710 /* param_buf */ data,
3711 /* param_len */ datalen,
3712 /* sense_len */ SSD_FULL_SIZE,
3713 /* timeout */ timeout ? timeout : 5000);
3715 if (arglist & CAM_ARG_ERR_RECOVER)
3716 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3718 /* Disable freezing the device queue */
3719 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3721 if (((retval = cam_send_ccb(device, ccb)) < 0)
3722 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3723 if (arglist & CAM_ARG_VERBOSE) {
3724 cam_error_print(device, ccb, CAM_ESF_ALL,
3725 CAM_EPF_ALL, stderr);
3728 cam_close_device(device);
3730 err(1, "error sending mode sense command");
3732 errx(1, "error sending mode sense command");
3739 mode_select(struct cam_device *device, int save_pages, int retry_count,
3740 int timeout, u_int8_t *data, int datalen)
3745 ccb = cam_getccb(device);
3748 errx(1, "mode_select: couldn't allocate CCB");
3750 bzero(&(&ccb->ccb_h)[1],
3751 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3753 scsi_mode_select(&ccb->csio,
3754 /* retries */ retry_count,
3756 /* tag_action */ MSG_SIMPLE_Q_TAG,
3757 /* scsi_page_fmt */ 1,
3758 /* save_pages */ save_pages,
3759 /* param_buf */ data,
3760 /* param_len */ datalen,
3761 /* sense_len */ SSD_FULL_SIZE,
3762 /* timeout */ timeout ? timeout : 5000);
3764 if (arglist & CAM_ARG_ERR_RECOVER)
3765 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3767 /* Disable freezing the device queue */
3768 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3770 if (((retval = cam_send_ccb(device, ccb)) < 0)
3771 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3772 if (arglist & CAM_ARG_VERBOSE) {
3773 cam_error_print(device, ccb, CAM_ESF_ALL,
3774 CAM_EPF_ALL, stderr);
3777 cam_close_device(device);
3780 err(1, "error sending mode select command");
3782 errx(1, "error sending mode select command");
3790 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
3791 int retry_count, int timeout)
3793 int c, mode_page = -1, page_control = 0;
3794 int binary = 0, list = 0;
3796 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3802 arglist |= CAM_ARG_DBD;
3805 arglist |= CAM_ARG_MODE_EDIT;
3811 mode_page = strtol(optarg, NULL, 0);
3813 errx(1, "invalid mode page %d", mode_page);
3816 page_control = strtol(optarg, NULL, 0);
3817 if ((page_control < 0) || (page_control > 3))
3818 errx(1, "invalid page control field %d",
3820 arglist |= CAM_ARG_PAGE_CNTL;
3827 if (mode_page == -1 && list == 0)
3828 errx(1, "you must specify a mode page!");
3831 mode_list(device, page_control, arglist & CAM_ARG_DBD,
3832 retry_count, timeout);
3834 mode_edit(device, mode_page, page_control,
3835 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
3836 retry_count, timeout);
3841 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
3842 int retry_count, int timeout)
3845 u_int32_t flags = CAM_DIR_NONE;
3846 u_int8_t *data_ptr = NULL;
3848 u_int8_t atacmd[12];
3849 struct get_hook hook;
3850 int c, data_bytes = 0;
3856 char *datastr = NULL, *tstr, *resstr = NULL;
3858 int fd_data = 0, fd_res = 0;
3861 ccb = cam_getccb(device);
3864 warnx("scsicmd: error allocating ccb");
3868 bzero(&(&ccb->ccb_h)[1],
3869 sizeof(union ccb) - sizeof(struct ccb_hdr));
3871 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3875 while (isspace(*tstr) && (*tstr != '\0'))
3877 hook.argc = argc - optind;
3878 hook.argv = argv + optind;
3880 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
3883 * Increment optind by the number of arguments the
3884 * encoding routine processed. After each call to
3885 * getopt(3), optind points to the argument that
3886 * getopt should process _next_. In this case,
3887 * that means it points to the first command string
3888 * argument, if there is one. Once we increment
3889 * this, it should point to either the next command
3890 * line argument, or it should be past the end of
3897 while (isspace(*tstr) && (*tstr != '\0'))
3899 hook.argc = argc - optind;
3900 hook.argv = argv + optind;
3902 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
3905 * Increment optind by the number of arguments the
3906 * encoding routine processed. After each call to
3907 * getopt(3), optind points to the argument that
3908 * getopt should process _next_. In this case,
3909 * that means it points to the first command string
3910 * argument, if there is one. Once we increment
3911 * this, it should point to either the next command
3912 * line argument, or it should be past the end of
3924 if (arglist & CAM_ARG_CMD_OUT) {
3925 warnx("command must either be "
3926 "read or write, not both");
3928 goto scsicmd_bailout;
3930 arglist |= CAM_ARG_CMD_IN;
3932 data_bytes = strtol(optarg, NULL, 0);
3933 if (data_bytes <= 0) {
3934 warnx("invalid number of input bytes %d",
3937 goto scsicmd_bailout;
3939 hook.argc = argc - optind;
3940 hook.argv = argv + optind;
3943 datastr = cget(&hook, NULL);
3945 * If the user supplied "-" instead of a format, he
3946 * wants the data to be written to stdout.
3948 if ((datastr != NULL)
3949 && (datastr[0] == '-'))
3952 data_ptr = (u_int8_t *)malloc(data_bytes);
3953 if (data_ptr == NULL) {
3954 warnx("can't malloc memory for data_ptr");
3956 goto scsicmd_bailout;
3960 if (arglist & CAM_ARG_CMD_IN) {
3961 warnx("command must either be "
3962 "read or write, not both");
3964 goto scsicmd_bailout;
3966 arglist |= CAM_ARG_CMD_OUT;
3967 flags = CAM_DIR_OUT;
3968 data_bytes = strtol(optarg, NULL, 0);
3969 if (data_bytes <= 0) {
3970 warnx("invalid number of output bytes %d",
3973 goto scsicmd_bailout;
3975 hook.argc = argc - optind;
3976 hook.argv = argv + optind;
3978 datastr = cget(&hook, NULL);
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;
3985 bzero(data_ptr, data_bytes);
3987 * If the user supplied "-" instead of a format, he
3988 * wants the data to be read from stdin.
3990 if ((datastr != NULL)
3991 && (datastr[0] == '-'))
3994 buff_encode_visit(data_ptr, data_bytes, datastr,
4000 hook.argc = argc - optind;
4001 hook.argv = argv + optind;
4003 resstr = cget(&hook, NULL);
4004 if ((resstr != NULL) && (resstr[0] == '-'))
4014 * If fd_data is set, and we're writing to the device, we need to
4015 * read the data the user wants written from stdin.
4017 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4019 int amt_to_read = data_bytes;
4020 u_int8_t *buf_ptr = data_ptr;
4022 for (amt_read = 0; amt_to_read > 0;
4023 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4024 if (amt_read == -1) {
4025 warn("error reading data from stdin");
4027 goto scsicmd_bailout;
4029 amt_to_read -= amt_read;
4030 buf_ptr += amt_read;
4034 if (arglist & CAM_ARG_ERR_RECOVER)
4035 flags |= CAM_PASS_ERR_RECOVER;
4037 /* Disable freezing the device queue */
4038 flags |= CAM_DEV_QFRZDIS;
4042 * This is taken from the SCSI-3 draft spec.
4043 * (T10/1157D revision 0.3)
4044 * The top 3 bits of an opcode are the group code.
4045 * The next 5 bits are the command code.
4046 * Group 0: six byte commands
4047 * Group 1: ten byte commands
4048 * Group 2: ten byte commands
4050 * Group 4: sixteen byte commands
4051 * Group 5: twelve byte commands
4052 * Group 6: vendor specific
4053 * Group 7: vendor specific
4055 switch((cdb[0] >> 5) & 0x7) {
4066 /* computed by buff_encode_visit */
4077 * We should probably use csio_build_visit or something like that
4078 * here, but it's easier to encode arguments as you go. The
4079 * alternative would be skipping the CDB argument and then encoding
4080 * it here, since we've got the data buffer argument by now.
4082 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4084 cam_fill_csio(&ccb->csio,
4085 /*retries*/ retry_count,
4088 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4089 /*data_ptr*/ data_ptr,
4090 /*dxfer_len*/ data_bytes,
4091 /*sense_len*/ SSD_FULL_SIZE,
4092 /*cdb_len*/ cdb_len,
4093 /*timeout*/ timeout ? timeout : 5000);
4096 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4098 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4100 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4102 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4104 cam_fill_ataio(&ccb->ataio,
4105 /*retries*/ retry_count,
4109 /*data_ptr*/ data_ptr,
4110 /*dxfer_len*/ data_bytes,
4111 /*timeout*/ timeout ? timeout : 5000);
4114 if (((retval = cam_send_ccb(device, ccb)) < 0)
4115 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4116 const char warnstr[] = "error sending command";
4123 if (arglist & CAM_ARG_VERBOSE) {
4124 cam_error_print(device, ccb, CAM_ESF_ALL,
4125 CAM_EPF_ALL, stderr);
4129 goto scsicmd_bailout;
4132 if (atacmd_len && need_res) {
4134 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4136 fprintf(stdout, "\n");
4139 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4140 ccb->ataio.res.status,
4141 ccb->ataio.res.error,
4142 ccb->ataio.res.lba_low,
4143 ccb->ataio.res.lba_mid,
4144 ccb->ataio.res.lba_high,
4145 ccb->ataio.res.device,
4146 ccb->ataio.res.lba_low_exp,
4147 ccb->ataio.res.lba_mid_exp,
4148 ccb->ataio.res.lba_high_exp,
4149 ccb->ataio.res.sector_count,
4150 ccb->ataio.res.sector_count_exp);
4155 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4156 && (arglist & CAM_ARG_CMD_IN)
4157 && (data_bytes > 0)) {
4159 buff_decode_visit(data_ptr, data_bytes, datastr,
4161 fprintf(stdout, "\n");
4163 ssize_t amt_written;
4164 int amt_to_write = data_bytes;
4165 u_int8_t *buf_ptr = data_ptr;
4167 for (amt_written = 0; (amt_to_write > 0) &&
4168 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4169 amt_to_write -= amt_written;
4170 buf_ptr += amt_written;
4172 if (amt_written == -1) {
4173 warn("error writing data to stdout");
4175 goto scsicmd_bailout;
4176 } else if ((amt_written == 0)
4177 && (amt_to_write > 0)) {
4178 warnx("only wrote %u bytes out of %u",
4179 data_bytes - amt_to_write, data_bytes);
4186 if ((data_bytes > 0) && (data_ptr != NULL))
4195 camdebug(int argc, char **argv, char *combinedopt)
4198 int bus = -1, target = -1, lun = -1;
4199 char *tstr, *tmpstr = NULL;
4203 bzero(&ccb, sizeof(union ccb));
4205 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4208 arglist |= CAM_ARG_DEBUG_INFO;
4209 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4212 arglist |= CAM_ARG_DEBUG_PERIPH;
4213 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4216 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4217 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4220 arglist |= CAM_ARG_DEBUG_TRACE;
4221 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4224 arglist |= CAM_ARG_DEBUG_XPT;
4225 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4228 arglist |= CAM_ARG_DEBUG_CDB;
4229 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4232 arglist |= CAM_ARG_DEBUG_PROBE;
4233 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4240 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4241 warnx("error opening transport layer device %s", XPT_DEVICE);
4242 warn("%s", XPT_DEVICE);
4249 warnx("you must specify \"off\", \"all\" or a bus,");
4250 warnx("bus:target, or bus:target:lun");
4257 while (isspace(*tstr) && (*tstr != '\0'))
4260 if (strncmp(tstr, "off", 3) == 0) {
4261 ccb.cdbg.flags = CAM_DEBUG_NONE;
4262 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4263 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4264 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4265 } else if (strncmp(tstr, "all", 3) != 0) {
4266 tmpstr = (char *)strtok(tstr, ":");
4267 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4268 bus = strtol(tmpstr, NULL, 0);
4269 arglist |= CAM_ARG_BUS;
4270 tmpstr = (char *)strtok(NULL, ":");
4271 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4272 target = strtol(tmpstr, NULL, 0);
4273 arglist |= CAM_ARG_TARGET;
4274 tmpstr = (char *)strtok(NULL, ":");
4275 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4276 lun = strtol(tmpstr, NULL, 0);
4277 arglist |= CAM_ARG_LUN;
4282 warnx("you must specify \"all\", \"off\", or a bus,");
4283 warnx("bus:target, or bus:target:lun to debug");
4289 ccb.ccb_h.func_code = XPT_DEBUG;
4290 ccb.ccb_h.path_id = bus;
4291 ccb.ccb_h.target_id = target;
4292 ccb.ccb_h.target_lun = lun;
4294 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4295 warn("CAMIOCOMMAND ioctl failed");
4300 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4301 CAM_FUNC_NOTAVAIL) {
4302 warnx("CAM debugging not available");
4303 warnx("you need to put options CAMDEBUG in"
4304 " your kernel config file!");
4306 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4308 warnx("XPT_DEBUG CCB failed with status %#x",
4312 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4314 "Debugging turned off\n");
4317 "Debugging enabled for "
4330 tagcontrol(struct cam_device *device, int argc, char **argv,
4340 ccb = cam_getccb(device);
4343 warnx("tagcontrol: error allocating ccb");
4347 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4350 numtags = strtol(optarg, NULL, 0);
4352 warnx("tag count %d is < 0", numtags);
4354 goto tagcontrol_bailout;
4365 cam_path_string(device, pathstr, sizeof(pathstr));
4368 bzero(&(&ccb->ccb_h)[1],
4369 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4370 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4371 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4372 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4373 ccb->crs.openings = numtags;
4376 if (cam_send_ccb(device, ccb) < 0) {
4377 perror("error sending XPT_REL_SIMQ CCB");
4379 goto tagcontrol_bailout;
4382 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4383 warnx("XPT_REL_SIMQ CCB failed");
4384 cam_error_print(device, ccb, CAM_ESF_ALL,
4385 CAM_EPF_ALL, stderr);
4387 goto tagcontrol_bailout;
4392 fprintf(stdout, "%stagged openings now %d\n",
4393 pathstr, ccb->crs.openings);
4396 bzero(&(&ccb->ccb_h)[1],
4397 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4399 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4401 if (cam_send_ccb(device, ccb) < 0) {
4402 perror("error sending XPT_GDEV_STATS CCB");
4404 goto tagcontrol_bailout;
4407 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4408 warnx("XPT_GDEV_STATS CCB failed");
4409 cam_error_print(device, ccb, CAM_ESF_ALL,
4410 CAM_EPF_ALL, stderr);
4412 goto tagcontrol_bailout;
4415 if (arglist & CAM_ARG_VERBOSE) {
4416 fprintf(stdout, "%s", pathstr);
4417 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4418 fprintf(stdout, "%s", pathstr);
4419 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4420 fprintf(stdout, "%s", pathstr);
4421 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
4422 fprintf(stdout, "%s", pathstr);
4423 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
4424 fprintf(stdout, "%s", pathstr);
4425 fprintf(stdout, "held %d\n", ccb->cgds.held);
4426 fprintf(stdout, "%s", pathstr);
4427 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4428 fprintf(stdout, "%s", pathstr);
4429 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4432 fprintf(stdout, "%s", pathstr);
4433 fprintf(stdout, "device openings: ");
4435 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4436 ccb->cgds.dev_active);
4446 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4450 cam_path_string(device, pathstr, sizeof(pathstr));
4452 if (cts->transport == XPORT_SPI) {
4453 struct ccb_trans_settings_spi *spi =
4454 &cts->xport_specific.spi;
4456 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4458 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4461 if (spi->sync_offset != 0) {
4464 freq = scsi_calc_syncsrate(spi->sync_period);
4465 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4466 pathstr, freq / 1000, freq % 1000);
4470 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4471 fprintf(stdout, "%soffset: %d\n", pathstr,
4475 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4476 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4477 (0x01 << spi->bus_width) * 8);
4480 if (spi->valid & CTS_SPI_VALID_DISC) {
4481 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4482 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4483 "enabled" : "disabled");
4486 if (cts->transport == XPORT_FC) {
4487 struct ccb_trans_settings_fc *fc =
4488 &cts->xport_specific.fc;
4490 if (fc->valid & CTS_FC_VALID_WWNN)
4491 fprintf(stdout, "%sWWNN: 0x%llx", pathstr,
4492 (long long) fc->wwnn);
4493 if (fc->valid & CTS_FC_VALID_WWPN)
4494 fprintf(stdout, "%sWWPN: 0x%llx", pathstr,
4495 (long long) fc->wwpn);
4496 if (fc->valid & CTS_FC_VALID_PORT)
4497 fprintf(stdout, "%sPortID: 0x%x", pathstr, fc->port);
4498 if (fc->valid & CTS_FC_VALID_SPEED)
4499 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4500 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4502 if (cts->transport == XPORT_SAS) {
4503 struct ccb_trans_settings_sas *sas =
4504 &cts->xport_specific.sas;
4506 if (sas->valid & CTS_SAS_VALID_SPEED)
4507 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4508 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4510 if (cts->transport == XPORT_ATA) {
4511 struct ccb_trans_settings_pata *pata =
4512 &cts->xport_specific.ata;
4514 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4515 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4516 ata_mode2string(pata->mode));
4518 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4519 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4522 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4523 fprintf(stdout, "%sPIO transaction length: %d\n",
4524 pathstr, pata->bytecount);
4527 if (cts->transport == XPORT_SATA) {
4528 struct ccb_trans_settings_sata *sata =
4529 &cts->xport_specific.sata;
4531 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4532 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4535 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4536 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4537 ata_mode2string(sata->mode));
4539 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4540 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4543 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4544 fprintf(stdout, "%sPIO transaction length: %d\n",
4545 pathstr, sata->bytecount);
4547 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4548 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4551 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4552 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4555 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4556 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4560 if (cts->protocol == PROTO_ATA) {
4561 struct ccb_trans_settings_ata *ata=
4562 &cts->proto_specific.ata;
4564 if (ata->valid & CTS_ATA_VALID_TQ) {
4565 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4566 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4567 "enabled" : "disabled");
4570 if (cts->protocol == PROTO_SCSI) {
4571 struct ccb_trans_settings_scsi *scsi=
4572 &cts->proto_specific.scsi;
4574 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4575 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4576 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4577 "enabled" : "disabled");
4584 * Get a path inquiry CCB for the specified device.
4587 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4592 ccb = cam_getccb(device);
4594 warnx("get_cpi: couldn't allocate CCB");
4597 bzero(&(&ccb->ccb_h)[1],
4598 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4599 ccb->ccb_h.func_code = XPT_PATH_INQ;
4600 if (cam_send_ccb(device, ccb) < 0) {
4601 warn("get_cpi: error sending Path Inquiry CCB");
4602 if (arglist & CAM_ARG_VERBOSE)
4603 cam_error_print(device, ccb, CAM_ESF_ALL,
4604 CAM_EPF_ALL, stderr);
4606 goto get_cpi_bailout;
4608 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4609 if (arglist & CAM_ARG_VERBOSE)
4610 cam_error_print(device, ccb, CAM_ESF_ALL,
4611 CAM_EPF_ALL, stderr);
4613 goto get_cpi_bailout;
4615 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4623 * Get a get device CCB for the specified device.
4626 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4631 ccb = cam_getccb(device);
4633 warnx("get_cgd: couldn't allocate CCB");
4636 bzero(&(&ccb->ccb_h)[1],
4637 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4638 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4639 if (cam_send_ccb(device, ccb) < 0) {
4640 warn("get_cgd: error sending Path Inquiry CCB");
4641 if (arglist & CAM_ARG_VERBOSE)
4642 cam_error_print(device, ccb, CAM_ESF_ALL,
4643 CAM_EPF_ALL, stderr);
4645 goto get_cgd_bailout;
4647 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4648 if (arglist & CAM_ARG_VERBOSE)
4649 cam_error_print(device, ccb, CAM_ESF_ALL,
4650 CAM_EPF_ALL, stderr);
4652 goto get_cgd_bailout;
4654 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4661 /* return the type of disk (really the command type) */
4663 get_disk_type(struct cam_device *device)
4665 struct ccb_getdev cgd;
4667 (void) memset(&cgd, 0x0, sizeof(cgd));
4668 get_cgd(device, &cgd);
4669 switch(cgd.protocol) {
4682 cpi_print(struct ccb_pathinq *cpi)
4684 char adapter_str[1024];
4687 snprintf(adapter_str, sizeof(adapter_str),
4688 "%s%d:", cpi->dev_name, cpi->unit_number);
4690 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
4693 for (i = 1; i < 0xff; i = i << 1) {
4696 if ((i & cpi->hba_inquiry) == 0)
4699 fprintf(stdout, "%s supports ", adapter_str);
4703 str = "MDP message";
4706 str = "32 bit wide SCSI";
4709 str = "16 bit wide SCSI";
4712 str = "SDTR message";
4715 str = "linked CDBs";
4718 str = "tag queue messages";
4721 str = "soft reset alternative";
4724 str = "SATA Port Multiplier";
4727 str = "unknown PI bit set";
4730 fprintf(stdout, "%s\n", str);
4733 for (i = 1; i < 0xff; i = i << 1) {
4736 if ((i & cpi->hba_misc) == 0)
4739 fprintf(stdout, "%s ", adapter_str);
4743 str = "bus scans from high ID to low ID";
4746 str = "removable devices not included in scan";
4748 case PIM_NOINITIATOR:
4749 str = "initiator role not supported";
4751 case PIM_NOBUSRESET:
4752 str = "user has disabled initial BUS RESET or"
4753 " controller is in target/mixed mode";
4756 str = "do not send 6-byte commands";
4759 str = "scan bus sequentially";
4762 str = "unknown PIM bit set";
4765 fprintf(stdout, "%s\n", str);
4768 for (i = 1; i < 0xff; i = i << 1) {
4771 if ((i & cpi->target_sprt) == 0)
4774 fprintf(stdout, "%s supports ", adapter_str);
4777 str = "target mode processor mode";
4780 str = "target mode phase cog. mode";
4782 case PIT_DISCONNECT:
4783 str = "disconnects in target mode";
4786 str = "terminate I/O message in target mode";
4789 str = "group 6 commands in target mode";
4792 str = "group 7 commands in target mode";
4795 str = "unknown PIT bit set";
4799 fprintf(stdout, "%s\n", str);
4801 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
4803 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
4805 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
4807 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
4808 adapter_str, cpi->hpath_id);
4809 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
4811 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
4812 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
4813 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
4814 adapter_str, cpi->hba_vendor);
4815 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
4816 adapter_str, cpi->hba_device);
4817 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
4818 adapter_str, cpi->hba_subvendor);
4819 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
4820 adapter_str, cpi->hba_subdevice);
4821 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
4822 fprintf(stdout, "%s base transfer speed: ", adapter_str);
4823 if (cpi->base_transfer_speed > 1000)
4824 fprintf(stdout, "%d.%03dMB/sec\n",
4825 cpi->base_transfer_speed / 1000,
4826 cpi->base_transfer_speed % 1000);
4828 fprintf(stdout, "%dKB/sec\n",
4829 (cpi->base_transfer_speed % 1000) * 1000);
4830 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
4831 adapter_str, cpi->maxio);
4835 get_print_cts(struct cam_device *device, int user_settings, int quiet,
4836 struct ccb_trans_settings *cts)
4842 ccb = cam_getccb(device);
4845 warnx("get_print_cts: error allocating ccb");
4849 bzero(&(&ccb->ccb_h)[1],
4850 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4852 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
4854 if (user_settings == 0)
4855 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
4857 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
4859 if (cam_send_ccb(device, ccb) < 0) {
4860 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
4861 if (arglist & CAM_ARG_VERBOSE)
4862 cam_error_print(device, ccb, CAM_ESF_ALL,
4863 CAM_EPF_ALL, stderr);
4865 goto get_print_cts_bailout;
4868 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4869 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
4870 if (arglist & CAM_ARG_VERBOSE)
4871 cam_error_print(device, ccb, CAM_ESF_ALL,
4872 CAM_EPF_ALL, stderr);
4874 goto get_print_cts_bailout;
4878 cts_print(device, &ccb->cts);
4881 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
4883 get_print_cts_bailout:
4891 ratecontrol(struct cam_device *device, int retry_count, int timeout,
4892 int argc, char **argv, char *combinedopt)
4896 int user_settings = 0;
4898 int disc_enable = -1, tag_enable = -1;
4901 double syncrate = -1;
4904 int change_settings = 0, send_tur = 0;
4905 struct ccb_pathinq cpi;
4907 ccb = cam_getccb(device);
4909 warnx("ratecontrol: error allocating ccb");
4912 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4921 if (strncasecmp(optarg, "enable", 6) == 0)
4923 else if (strncasecmp(optarg, "disable", 7) == 0)
4926 warnx("-D argument \"%s\" is unknown", optarg);
4928 goto ratecontrol_bailout;
4930 change_settings = 1;
4933 mode = ata_string2mode(optarg);
4935 warnx("unknown mode '%s'", optarg);
4937 goto ratecontrol_bailout;
4939 change_settings = 1;
4942 offset = strtol(optarg, NULL, 0);
4944 warnx("offset value %d is < 0", offset);
4946 goto ratecontrol_bailout;
4948 change_settings = 1;
4954 syncrate = atof(optarg);
4956 warnx("sync rate %f is < 0", syncrate);
4958 goto ratecontrol_bailout;
4960 change_settings = 1;
4963 if (strncasecmp(optarg, "enable", 6) == 0)
4965 else if (strncasecmp(optarg, "disable", 7) == 0)
4968 warnx("-T argument \"%s\" is unknown", optarg);
4970 goto ratecontrol_bailout;
4972 change_settings = 1;
4978 bus_width = strtol(optarg, NULL, 0);
4979 if (bus_width < 0) {
4980 warnx("bus width %d is < 0", bus_width);
4982 goto ratecontrol_bailout;
4984 change_settings = 1;
4990 bzero(&(&ccb->ccb_h)[1],
4991 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4993 * Grab path inquiry information, so we can determine whether
4994 * or not the initiator is capable of the things that the user
4997 ccb->ccb_h.func_code = XPT_PATH_INQ;
4998 if (cam_send_ccb(device, ccb) < 0) {
4999 perror("error sending XPT_PATH_INQ CCB");
5000 if (arglist & CAM_ARG_VERBOSE) {
5001 cam_error_print(device, ccb, CAM_ESF_ALL,
5002 CAM_EPF_ALL, stderr);
5005 goto ratecontrol_bailout;
5007 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5008 warnx("XPT_PATH_INQ CCB failed");
5009 if (arglist & CAM_ARG_VERBOSE) {
5010 cam_error_print(device, ccb, CAM_ESF_ALL,
5011 CAM_EPF_ALL, stderr);
5014 goto ratecontrol_bailout;
5016 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5017 bzero(&(&ccb->ccb_h)[1],
5018 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
5020 fprintf(stdout, "%s parameters:\n",
5021 user_settings ? "User" : "Current");
5023 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5025 goto ratecontrol_bailout;
5027 if (arglist & CAM_ARG_VERBOSE)
5030 if (change_settings) {
5031 int didsettings = 0;
5032 struct ccb_trans_settings_spi *spi = NULL;
5033 struct ccb_trans_settings_pata *pata = NULL;
5034 struct ccb_trans_settings_sata *sata = NULL;
5035 struct ccb_trans_settings_ata *ata = NULL;
5036 struct ccb_trans_settings_scsi *scsi = NULL;
5038 if (ccb->cts.transport == XPORT_SPI)
5039 spi = &ccb->cts.xport_specific.spi;
5040 if (ccb->cts.transport == XPORT_ATA)
5041 pata = &ccb->cts.xport_specific.ata;
5042 if (ccb->cts.transport == XPORT_SATA)
5043 sata = &ccb->cts.xport_specific.sata;
5044 if (ccb->cts.protocol == PROTO_ATA)
5045 ata = &ccb->cts.proto_specific.ata;
5046 if (ccb->cts.protocol == PROTO_SCSI)
5047 scsi = &ccb->cts.proto_specific.scsi;
5048 ccb->cts.xport_specific.valid = 0;
5049 ccb->cts.proto_specific.valid = 0;
5050 if (spi && disc_enable != -1) {
5051 spi->valid |= CTS_SPI_VALID_DISC;
5052 if (disc_enable == 0)
5053 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5055 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5058 if (tag_enable != -1) {
5059 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5060 warnx("HBA does not support tagged queueing, "
5061 "so you cannot modify tag settings");
5063 goto ratecontrol_bailout;
5066 ata->valid |= CTS_SCSI_VALID_TQ;
5067 if (tag_enable == 0)
5068 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5070 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5073 scsi->valid |= CTS_SCSI_VALID_TQ;
5074 if (tag_enable == 0)
5075 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5077 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5081 if (spi && offset != -1) {
5082 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5083 warnx("HBA is not capable of changing offset");
5085 goto ratecontrol_bailout;
5087 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5088 spi->sync_offset = offset;
5091 if (spi && syncrate != -1) {
5092 int prelim_sync_period;
5094 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5095 warnx("HBA is not capable of changing "
5098 goto ratecontrol_bailout;
5100 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5102 * The sync rate the user gives us is in MHz.
5103 * We need to translate it into KHz for this
5108 * Next, we calculate a "preliminary" sync period
5109 * in tenths of a nanosecond.
5112 prelim_sync_period = 0;
5114 prelim_sync_period = 10000000 / syncrate;
5116 scsi_calc_syncparam(prelim_sync_period);
5119 if (sata && syncrate != -1) {
5120 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5121 warnx("HBA is not capable of changing "
5124 goto ratecontrol_bailout;
5126 if (!user_settings) {
5127 warnx("You can modify only user rate "
5128 "settings for SATA");
5130 goto ratecontrol_bailout;
5132 sata->revision = ata_speed2revision(syncrate * 100);
5133 if (sata->revision < 0) {
5134 warnx("Invalid rate %f", syncrate);
5136 goto ratecontrol_bailout;
5138 sata->valid |= CTS_SATA_VALID_REVISION;
5141 if ((pata || sata) && mode != -1) {
5142 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5143 warnx("HBA is not capable of changing "
5146 goto ratecontrol_bailout;
5148 if (!user_settings) {
5149 warnx("You can modify only user mode "
5150 "settings for ATA/SATA");
5152 goto ratecontrol_bailout;
5156 pata->valid |= CTS_ATA_VALID_MODE;
5159 sata->valid |= CTS_SATA_VALID_MODE;
5164 * The bus_width argument goes like this:
5168 * Therefore, if you shift the number of bits given on the
5169 * command line right by 4, you should get the correct
5172 if (spi && bus_width != -1) {
5174 * We might as well validate things here with a
5175 * decipherable error message, rather than what
5176 * will probably be an indecipherable error message
5177 * by the time it gets back to us.
5179 if ((bus_width == 16)
5180 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5181 warnx("HBA does not support 16 bit bus width");
5183 goto ratecontrol_bailout;
5184 } else if ((bus_width == 32)
5185 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5186 warnx("HBA does not support 32 bit bus width");
5188 goto ratecontrol_bailout;
5189 } else if ((bus_width != 8)
5190 && (bus_width != 16)
5191 && (bus_width != 32)) {
5192 warnx("Invalid bus width %d", bus_width);
5194 goto ratecontrol_bailout;
5196 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5197 spi->bus_width = bus_width >> 4;
5200 if (didsettings == 0) {
5201 goto ratecontrol_bailout;
5203 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5204 if (cam_send_ccb(device, ccb) < 0) {
5205 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5206 if (arglist & CAM_ARG_VERBOSE) {
5207 cam_error_print(device, ccb, CAM_ESF_ALL,
5208 CAM_EPF_ALL, stderr);
5211 goto ratecontrol_bailout;
5213 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5214 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5215 if (arglist & CAM_ARG_VERBOSE) {
5216 cam_error_print(device, ccb, CAM_ESF_ALL,
5217 CAM_EPF_ALL, stderr);
5220 goto ratecontrol_bailout;
5224 retval = testunitready(device, retry_count, timeout,
5225 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5227 * If the TUR didn't succeed, just bail.
5231 fprintf(stderr, "Test Unit Ready failed\n");
5232 goto ratecontrol_bailout;
5235 if ((change_settings || send_tur) && !quiet &&
5236 (ccb->cts.transport == XPORT_ATA ||
5237 ccb->cts.transport == XPORT_SATA || send_tur)) {
5238 fprintf(stdout, "New parameters:\n");
5239 retval = get_print_cts(device, user_settings, 0, NULL);
5242 ratecontrol_bailout:
5248 scsiformat(struct cam_device *device, int argc, char **argv,
5249 char *combinedopt, int retry_count, int timeout)
5253 int ycount = 0, quiet = 0;
5254 int error = 0, retval = 0;
5255 int use_timeout = 10800 * 1000;
5257 struct format_defect_list_header fh;
5258 u_int8_t *data_ptr = NULL;
5259 u_int32_t dxfer_len = 0;
5261 int num_warnings = 0;
5264 ccb = cam_getccb(device);
5267 warnx("scsiformat: error allocating ccb");
5271 bzero(&(&ccb->ccb_h)[1],
5272 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5274 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5295 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5296 "following device:\n");
5298 error = scsidoinquiry(device, argc, argv, combinedopt,
5299 retry_count, timeout);
5302 warnx("scsiformat: error sending inquiry");
5303 goto scsiformat_bailout;
5308 if (!get_confirmation()) {
5310 goto scsiformat_bailout;
5315 use_timeout = timeout;
5318 fprintf(stdout, "Current format timeout is %d seconds\n",
5319 use_timeout / 1000);
5323 * If the user hasn't disabled questions and didn't specify a
5324 * timeout on the command line, ask them if they want the current
5328 && (timeout == 0)) {
5330 int new_timeout = 0;
5332 fprintf(stdout, "Enter new timeout in seconds or press\n"
5333 "return to keep the current timeout [%d] ",
5334 use_timeout / 1000);
5336 if (fgets(str, sizeof(str), stdin) != NULL) {
5338 new_timeout = atoi(str);
5341 if (new_timeout != 0) {
5342 use_timeout = new_timeout * 1000;
5343 fprintf(stdout, "Using new timeout value %d\n",
5344 use_timeout / 1000);
5349 * Keep this outside the if block below to silence any unused
5350 * variable warnings.
5352 bzero(&fh, sizeof(fh));
5355 * If we're in immediate mode, we've got to include the format
5358 if (immediate != 0) {
5359 fh.byte2 = FU_DLH_IMMED;
5360 data_ptr = (u_int8_t *)&fh;
5361 dxfer_len = sizeof(fh);
5362 byte2 = FU_FMT_DATA;
5363 } else if (quiet == 0) {
5364 fprintf(stdout, "Formatting...");
5368 scsi_format_unit(&ccb->csio,
5369 /* retries */ retry_count,
5371 /* tag_action */ MSG_SIMPLE_Q_TAG,
5374 /* data_ptr */ data_ptr,
5375 /* dxfer_len */ dxfer_len,
5376 /* sense_len */ SSD_FULL_SIZE,
5377 /* timeout */ use_timeout);
5379 /* Disable freezing the device queue */
5380 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5382 if (arglist & CAM_ARG_ERR_RECOVER)
5383 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5385 if (((retval = cam_send_ccb(device, ccb)) < 0)
5386 || ((immediate == 0)
5387 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5388 const char errstr[] = "error sending format command";
5395 if (arglist & CAM_ARG_VERBOSE) {
5396 cam_error_print(device, ccb, CAM_ESF_ALL,
5397 CAM_EPF_ALL, stderr);
5400 goto scsiformat_bailout;
5404 * If we ran in non-immediate mode, we already checked for errors
5405 * above and printed out any necessary information. If we're in
5406 * immediate mode, we need to loop through and get status
5407 * information periodically.
5409 if (immediate == 0) {
5411 fprintf(stdout, "Format Complete\n");
5413 goto scsiformat_bailout;
5420 bzero(&(&ccb->ccb_h)[1],
5421 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5424 * There's really no need to do error recovery or
5425 * retries here, since we're just going to sit in a
5426 * loop and wait for the device to finish formatting.
5428 scsi_test_unit_ready(&ccb->csio,
5431 /* tag_action */ MSG_SIMPLE_Q_TAG,
5432 /* sense_len */ SSD_FULL_SIZE,
5433 /* timeout */ 5000);
5435 /* Disable freezing the device queue */
5436 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5438 retval = cam_send_ccb(device, ccb);
5441 * If we get an error from the ioctl, bail out. SCSI
5442 * errors are expected.
5445 warn("error sending CAMIOCOMMAND ioctl");
5446 if (arglist & CAM_ARG_VERBOSE) {
5447 cam_error_print(device, ccb, CAM_ESF_ALL,
5448 CAM_EPF_ALL, stderr);
5451 goto scsiformat_bailout;
5454 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5456 if ((status != CAM_REQ_CMP)
5457 && (status == CAM_SCSI_STATUS_ERROR)
5458 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5459 struct scsi_sense_data *sense;
5460 int error_code, sense_key, asc, ascq;
5462 sense = &ccb->csio.sense_data;
5463 scsi_extract_sense_len(sense, ccb->csio.sense_len -
5464 ccb->csio.sense_resid, &error_code, &sense_key,
5465 &asc, &ascq, /*show_errors*/ 1);
5468 * According to the SCSI-2 and SCSI-3 specs, a
5469 * drive that is in the middle of a format should
5470 * return NOT READY with an ASC of "logical unit
5471 * not ready, format in progress". The sense key
5472 * specific bytes will then be a progress indicator.
5474 if ((sense_key == SSD_KEY_NOT_READY)
5475 && (asc == 0x04) && (ascq == 0x04)) {
5478 if ((scsi_get_sks(sense, ccb->csio.sense_len -
5479 ccb->csio.sense_resid, sks) == 0)
5482 u_int64_t percentage;
5484 val = scsi_2btoul(&sks[1]);
5485 percentage = 10000 * val;
5488 "\rFormatting: %ju.%02u %% "
5490 (uintmax_t)(percentage /
5492 (unsigned)((percentage /
5496 } else if ((quiet == 0)
5497 && (++num_warnings <= 1)) {
5498 warnx("Unexpected SCSI Sense Key "
5499 "Specific value returned "
5501 scsi_sense_print(device, &ccb->csio,
5503 warnx("Unable to print status "
5504 "information, but format will "
5506 warnx("will exit when format is "
5511 warnx("Unexpected SCSI error during format");
5512 cam_error_print(device, ccb, CAM_ESF_ALL,
5513 CAM_EPF_ALL, stderr);
5515 goto scsiformat_bailout;
5518 } else if (status != CAM_REQ_CMP) {
5519 warnx("Unexpected CAM status %#x", status);
5520 if (arglist & CAM_ARG_VERBOSE)
5521 cam_error_print(device, ccb, CAM_ESF_ALL,
5522 CAM_EPF_ALL, stderr);
5524 goto scsiformat_bailout;
5527 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5530 fprintf(stdout, "\nFormat Complete\n");
5540 scsireportluns(struct cam_device *device, int argc, char **argv,
5541 char *combinedopt, int retry_count, int timeout)
5544 int c, countonly, lunsonly;
5545 struct scsi_report_luns_data *lundata;
5547 uint8_t report_type;
5548 uint32_t list_len, i, j;
5553 report_type = RPL_REPORT_DEFAULT;
5554 ccb = cam_getccb(device);
5557 warnx("%s: error allocating ccb", __func__);
5561 bzero(&(&ccb->ccb_h)[1],
5562 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5567 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5576 if (strcasecmp(optarg, "default") == 0)
5577 report_type = RPL_REPORT_DEFAULT;
5578 else if (strcasecmp(optarg, "wellknown") == 0)
5579 report_type = RPL_REPORT_WELLKNOWN;
5580 else if (strcasecmp(optarg, "all") == 0)
5581 report_type = RPL_REPORT_ALL;
5583 warnx("%s: invalid report type \"%s\"",
5594 if ((countonly != 0)
5595 && (lunsonly != 0)) {
5596 warnx("%s: you can only specify one of -c or -l", __func__);
5601 * According to SPC-4, the allocation length must be at least 16
5602 * bytes -- enough for the header and one LUN.
5604 alloc_len = sizeof(*lundata) + 8;
5608 lundata = malloc(alloc_len);
5610 if (lundata == NULL) {
5611 warn("%s: error mallocing %d bytes", __func__, alloc_len);
5616 scsi_report_luns(&ccb->csio,
5617 /*retries*/ retry_count,
5619 /*tag_action*/ MSG_SIMPLE_Q_TAG,
5620 /*select_report*/ report_type,
5621 /*rpl_buf*/ lundata,
5622 /*alloc_len*/ alloc_len,
5623 /*sense_len*/ SSD_FULL_SIZE,
5624 /*timeout*/ timeout ? timeout : 5000);
5626 /* Disable freezing the device queue */
5627 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5629 if (arglist & CAM_ARG_ERR_RECOVER)
5630 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5632 if (cam_send_ccb(device, ccb) < 0) {
5633 warn("error sending REPORT LUNS command");
5635 if (arglist & CAM_ARG_VERBOSE)
5636 cam_error_print(device, ccb, CAM_ESF_ALL,
5637 CAM_EPF_ALL, stderr);
5643 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5644 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5650 list_len = scsi_4btoul(lundata->length);
5653 * If we need to list the LUNs, and our allocation
5654 * length was too short, reallocate and retry.
5656 if ((countonly == 0)
5657 && (list_len > (alloc_len - sizeof(*lundata)))) {
5658 alloc_len = list_len + sizeof(*lundata);
5664 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
5665 ((list_len / 8) > 1) ? "s" : "");
5670 for (i = 0; i < (list_len / 8); i++) {
5674 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
5676 fprintf(stdout, ",");
5677 switch (lundata->luns[i].lundata[j] &
5678 RPL_LUNDATA_ATYP_MASK) {
5679 case RPL_LUNDATA_ATYP_PERIPH:
5680 if ((lundata->luns[i].lundata[j] &
5681 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
5682 fprintf(stdout, "%d:",
5683 lundata->luns[i].lundata[j] &
5684 RPL_LUNDATA_PERIPH_BUS_MASK);
5686 && ((lundata->luns[i].lundata[j+2] &
5687 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
5690 fprintf(stdout, "%d",
5691 lundata->luns[i].lundata[j+1]);
5693 case RPL_LUNDATA_ATYP_FLAT: {
5695 tmplun[0] = lundata->luns[i].lundata[j] &
5696 RPL_LUNDATA_FLAT_LUN_MASK;
5697 tmplun[1] = lundata->luns[i].lundata[j+1];
5699 fprintf(stdout, "%d", scsi_2btoul(tmplun));
5703 case RPL_LUNDATA_ATYP_LUN:
5704 fprintf(stdout, "%d:%d:%d",
5705 (lundata->luns[i].lundata[j+1] &
5706 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
5707 lundata->luns[i].lundata[j] &
5708 RPL_LUNDATA_LUN_TARG_MASK,
5709 lundata->luns[i].lundata[j+1] &
5710 RPL_LUNDATA_LUN_LUN_MASK);
5712 case RPL_LUNDATA_ATYP_EXTLUN: {
5713 int field_len_code, eam_code;
5715 eam_code = lundata->luns[i].lundata[j] &
5716 RPL_LUNDATA_EXT_EAM_MASK;
5717 field_len_code = (lundata->luns[i].lundata[j] &
5718 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
5720 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
5721 && (field_len_code == 0x00)) {
5722 fprintf(stdout, "%d",
5723 lundata->luns[i].lundata[j+1]);
5724 } else if ((eam_code ==
5725 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
5726 && (field_len_code == 0x03)) {
5730 * This format takes up all 8 bytes.
5731 * If we aren't starting at offset 0,
5735 fprintf(stdout, "Invalid "
5738 "specified format", j);
5742 bzero(tmp_lun, sizeof(tmp_lun));
5743 bcopy(&lundata->luns[i].lundata[j+1],
5744 &tmp_lun[1], sizeof(tmp_lun) - 1);
5745 fprintf(stdout, "%#jx",
5746 (intmax_t)scsi_8btou64(tmp_lun));
5749 fprintf(stderr, "Unknown Extended LUN"
5750 "Address method %#x, length "
5751 "code %#x", eam_code,
5758 fprintf(stderr, "Unknown LUN address method "
5759 "%#x\n", lundata->luns[i].lundata[0] &
5760 RPL_LUNDATA_ATYP_MASK);
5764 * For the flat addressing method, there are no
5765 * other levels after it.
5770 fprintf(stdout, "\n");
5783 scsireadcapacity(struct cam_device *device, int argc, char **argv,
5784 char *combinedopt, int retry_count, int timeout)
5787 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
5788 struct scsi_read_capacity_data rcap;
5789 struct scsi_read_capacity_data_long rcaplong;
5803 ccb = cam_getccb(device);
5806 warnx("%s: error allocating ccb", __func__);
5810 bzero(&(&ccb->ccb_h)[1],
5811 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5813 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5840 if ((blocksizeonly != 0)
5841 && (numblocks != 0)) {
5842 warnx("%s: you can only specify one of -b or -N", __func__);
5847 if ((blocksizeonly != 0)
5848 && (sizeonly != 0)) {
5849 warnx("%s: you can only specify one of -b or -s", __func__);
5856 warnx("%s: you can only specify one of -h/-H or -q", __func__);
5862 && (blocksizeonly != 0)) {
5863 warnx("%s: you can only specify one of -h/-H or -b", __func__);
5868 scsi_read_capacity(&ccb->csio,
5869 /*retries*/ retry_count,
5871 /*tag_action*/ MSG_SIMPLE_Q_TAG,
5874 /*timeout*/ timeout ? timeout : 5000);
5876 /* Disable freezing the device queue */
5877 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5879 if (arglist & CAM_ARG_ERR_RECOVER)
5880 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5882 if (cam_send_ccb(device, ccb) < 0) {
5883 warn("error sending READ CAPACITY command");
5885 if (arglist & CAM_ARG_VERBOSE)
5886 cam_error_print(device, ccb, CAM_ESF_ALL,
5887 CAM_EPF_ALL, stderr);
5893 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5894 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5899 maxsector = scsi_4btoul(rcap.addr);
5900 block_len = scsi_4btoul(rcap.length);
5903 * A last block of 2^32-1 means that the true capacity is over 2TB,
5904 * and we need to issue the long READ CAPACITY to get the real
5905 * capacity. Otherwise, we're all set.
5907 if (maxsector != 0xffffffff)
5910 scsi_read_capacity_16(&ccb->csio,
5911 /*retries*/ retry_count,
5913 /*tag_action*/ MSG_SIMPLE_Q_TAG,
5918 /*sense_len*/ SSD_FULL_SIZE,
5919 /*timeout*/ timeout ? timeout : 5000);
5921 /* Disable freezing the device queue */
5922 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5924 if (arglist & CAM_ARG_ERR_RECOVER)
5925 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5927 if (cam_send_ccb(device, ccb) < 0) {
5928 warn("error sending READ CAPACITY (16) command");
5930 if (arglist & CAM_ARG_VERBOSE)
5931 cam_error_print(device, ccb, CAM_ESF_ALL,
5932 CAM_EPF_ALL, stderr);
5938 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5939 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5944 maxsector = scsi_8btou64(rcaplong.addr);
5945 block_len = scsi_4btoul(rcaplong.length);
5948 if (blocksizeonly == 0) {
5950 * Humanize implies !quiet, and also implies numblocks.
5952 if (humanize != 0) {
5957 tmpbytes = (maxsector + 1) * block_len;
5958 ret = humanize_number(tmpstr, sizeof(tmpstr),
5959 tmpbytes, "", HN_AUTOSCALE,
5962 HN_DIVISOR_1000 : 0));
5964 warnx("%s: humanize_number failed!", __func__);
5968 fprintf(stdout, "Device Size: %s%s", tmpstr,
5969 (sizeonly == 0) ? ", " : "\n");
5970 } else if (numblocks != 0) {
5971 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
5972 "Blocks: " : "", (uintmax_t)maxsector + 1,
5973 (sizeonly == 0) ? ", " : "\n");
5975 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
5976 "Last Block: " : "", (uintmax_t)maxsector,
5977 (sizeonly == 0) ? ", " : "\n");
5981 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
5982 "Block Length: " : "", block_len, (quiet == 0) ?
5991 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
5992 int retry_count, int timeout)
5996 uint8_t *smp_request = NULL, *smp_response = NULL;
5997 int request_size = 0, response_size = 0;
5998 int fd_request = 0, fd_response = 0;
5999 char *datastr = NULL;
6000 struct get_hook hook;
6005 * Note that at the moment we don't support sending SMP CCBs to
6006 * devices that aren't probed by CAM.
6008 ccb = cam_getccb(device);
6010 warnx("%s: error allocating CCB", __func__);
6014 bzero(&(&ccb->ccb_h)[1],
6015 sizeof(union ccb) - sizeof(struct ccb_hdr));
6017 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6020 arglist |= CAM_ARG_CMD_IN;
6021 response_size = strtol(optarg, NULL, 0);
6022 if (response_size <= 0) {
6023 warnx("invalid number of response bytes %d",
6026 goto smpcmd_bailout;
6028 hook.argc = argc - optind;
6029 hook.argv = argv + optind;
6032 datastr = cget(&hook, NULL);
6034 * If the user supplied "-" instead of a format, he
6035 * wants the data to be written to stdout.
6037 if ((datastr != NULL)
6038 && (datastr[0] == '-'))
6041 smp_response = (u_int8_t *)malloc(response_size);
6042 if (smp_response == NULL) {
6043 warn("can't malloc memory for SMP response");
6045 goto smpcmd_bailout;
6049 arglist |= CAM_ARG_CMD_OUT;
6050 request_size = strtol(optarg, NULL, 0);
6051 if (request_size <= 0) {
6052 warnx("invalid number of request bytes %d",
6055 goto smpcmd_bailout;
6057 hook.argc = argc - optind;
6058 hook.argv = argv + optind;
6060 datastr = cget(&hook, NULL);
6061 smp_request = (u_int8_t *)malloc(request_size);
6062 if (smp_request == NULL) {
6063 warn("can't malloc memory for SMP request");
6065 goto smpcmd_bailout;
6067 bzero(smp_request, request_size);
6069 * If the user supplied "-" instead of a format, he
6070 * wants the data to be read from stdin.
6072 if ((datastr != NULL)
6073 && (datastr[0] == '-'))
6076 buff_encode_visit(smp_request, request_size,
6087 * If fd_data is set, and we're writing to the device, we need to
6088 * read the data the user wants written from stdin.
6090 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
6092 int amt_to_read = request_size;
6093 u_int8_t *buf_ptr = smp_request;
6095 for (amt_read = 0; amt_to_read > 0;
6096 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
6097 if (amt_read == -1) {
6098 warn("error reading data from stdin");
6100 goto smpcmd_bailout;
6102 amt_to_read -= amt_read;
6103 buf_ptr += amt_read;
6107 if (((arglist & CAM_ARG_CMD_IN) == 0)
6108 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
6109 warnx("%s: need both the request (-r) and response (-R) "
6110 "arguments", __func__);
6112 goto smpcmd_bailout;
6115 flags |= CAM_DEV_QFRZDIS;
6117 cam_fill_smpio(&ccb->smpio,
6118 /*retries*/ retry_count,
6121 /*smp_request*/ smp_request,
6122 /*smp_request_len*/ request_size,
6123 /*smp_response*/ smp_response,
6124 /*smp_response_len*/ response_size,
6125 /*timeout*/ timeout ? timeout : 5000);
6127 ccb->smpio.flags = SMP_FLAG_NONE;
6129 if (((retval = cam_send_ccb(device, ccb)) < 0)
6130 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6131 const char warnstr[] = "error sending command";
6138 if (arglist & CAM_ARG_VERBOSE) {
6139 cam_error_print(device, ccb, CAM_ESF_ALL,
6140 CAM_EPF_ALL, stderr);
6144 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
6145 && (response_size > 0)) {
6146 if (fd_response == 0) {
6147 buff_decode_visit(smp_response, response_size,
6148 datastr, arg_put, NULL);
6149 fprintf(stdout, "\n");
6151 ssize_t amt_written;
6152 int amt_to_write = response_size;
6153 u_int8_t *buf_ptr = smp_response;
6155 for (amt_written = 0; (amt_to_write > 0) &&
6156 (amt_written = write(STDOUT_FILENO, buf_ptr,
6157 amt_to_write)) > 0;){
6158 amt_to_write -= amt_written;
6159 buf_ptr += amt_written;
6161 if (amt_written == -1) {
6162 warn("error writing data to stdout");
6164 goto smpcmd_bailout;
6165 } else if ((amt_written == 0)
6166 && (amt_to_write > 0)) {
6167 warnx("only wrote %u bytes out of %u",
6168 response_size - amt_to_write,
6177 if (smp_request != NULL)
6180 if (smp_response != NULL)
6187 smpreportgeneral(struct cam_device *device, int argc, char **argv,
6188 char *combinedopt, int retry_count, int timeout)
6191 struct smp_report_general_request *request = NULL;
6192 struct smp_report_general_response *response = NULL;
6193 struct sbuf *sb = NULL;
6195 int c, long_response = 0;
6199 * Note that at the moment we don't support sending SMP CCBs to
6200 * devices that aren't probed by CAM.
6202 ccb = cam_getccb(device);
6204 warnx("%s: error allocating CCB", __func__);
6208 bzero(&(&ccb->ccb_h)[1],
6209 sizeof(union ccb) - sizeof(struct ccb_hdr));
6211 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6220 request = malloc(sizeof(*request));
6221 if (request == NULL) {
6222 warn("%s: unable to allocate %zd bytes", __func__,
6228 response = malloc(sizeof(*response));
6229 if (response == NULL) {
6230 warn("%s: unable to allocate %zd bytes", __func__,
6237 smp_report_general(&ccb->smpio,
6241 /*request_len*/ sizeof(*request),
6242 (uint8_t *)response,
6243 /*response_len*/ sizeof(*response),
6244 /*long_response*/ long_response,
6247 if (((retval = cam_send_ccb(device, ccb)) < 0)
6248 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6249 const char warnstr[] = "error sending command";
6256 if (arglist & CAM_ARG_VERBOSE) {
6257 cam_error_print(device, ccb, CAM_ESF_ALL,
6258 CAM_EPF_ALL, stderr);
6265 * If the device supports the long response bit, try again and see
6266 * if we can get all of the data.
6268 if ((response->long_response & SMP_RG_LONG_RESPONSE)
6269 && (long_response == 0)) {
6270 ccb->ccb_h.status = CAM_REQ_INPROG;
6271 bzero(&(&ccb->ccb_h)[1],
6272 sizeof(union ccb) - sizeof(struct ccb_hdr));
6278 * XXX KDM detect and decode SMP errors here.
6280 sb = sbuf_new_auto();
6282 warnx("%s: error allocating sbuf", __func__);
6286 smp_report_general_sbuf(response, sizeof(*response), sb);
6288 if (sbuf_finish(sb) != 0) {
6289 warnx("%s: sbuf_finish", __func__);
6293 printf("%s", sbuf_data(sb));
6299 if (request != NULL)
6302 if (response != NULL)
6311 static struct camcontrol_opts phy_ops[] = {
6312 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
6313 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
6314 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
6315 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
6316 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
6317 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
6318 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
6319 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
6320 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
6325 smpphycontrol(struct cam_device *device, int argc, char **argv,
6326 char *combinedopt, int retry_count, int timeout)
6329 struct smp_phy_control_request *request = NULL;
6330 struct smp_phy_control_response *response = NULL;
6331 int long_response = 0;
6334 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
6336 uint64_t attached_dev_name = 0;
6337 int dev_name_set = 0;
6338 uint32_t min_plr = 0, max_plr = 0;
6339 uint32_t pp_timeout_val = 0;
6340 int slumber_partial = 0;
6341 int set_pp_timeout_val = 0;
6345 * Note that at the moment we don't support sending SMP CCBs to
6346 * devices that aren't probed by CAM.
6348 ccb = cam_getccb(device);
6350 warnx("%s: error allocating CCB", __func__);
6354 bzero(&(&ccb->ccb_h)[1],
6355 sizeof(union ccb) - sizeof(struct ccb_hdr));
6357 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6365 if (strcasecmp(optarg, "enable") == 0)
6367 else if (strcasecmp(optarg, "disable") == 0)
6370 warnx("%s: Invalid argument %s", __func__,
6377 slumber_partial |= enable <<
6378 SMP_PC_SAS_SLUMBER_SHIFT;
6381 slumber_partial |= enable <<
6382 SMP_PC_SAS_PARTIAL_SHIFT;
6385 slumber_partial |= enable <<
6386 SMP_PC_SATA_SLUMBER_SHIFT;
6389 slumber_partial |= enable <<
6390 SMP_PC_SATA_PARTIAL_SHIFT;
6393 warnx("%s: programmer error", __func__);
6396 break; /*NOTREACHED*/
6401 attached_dev_name = (uintmax_t)strtoumax(optarg,
6410 * We don't do extensive checking here, so this
6411 * will continue to work when new speeds come out.
6413 min_plr = strtoul(optarg, NULL, 0);
6415 || (min_plr > 0xf)) {
6416 warnx("%s: invalid link rate %x",
6424 * We don't do extensive checking here, so this
6425 * will continue to work when new speeds come out.
6427 max_plr = strtoul(optarg, NULL, 0);
6429 || (max_plr > 0xf)) {
6430 warnx("%s: invalid link rate %x",
6437 camcontrol_optret optreturn;
6438 cam_argmask argnums;
6441 if (phy_op_set != 0) {
6442 warnx("%s: only one phy operation argument "
6443 "(-o) allowed", __func__);
6451 * Allow the user to specify the phy operation
6452 * numerically, as well as with a name. This will
6453 * future-proof it a bit, so options that are added
6454 * in future specs can be used.
6456 if (isdigit(optarg[0])) {
6457 phy_operation = strtoul(optarg, NULL, 0);
6458 if ((phy_operation == 0)
6459 || (phy_operation > 0xff)) {
6460 warnx("%s: invalid phy operation %#x",
6461 __func__, phy_operation);
6467 optreturn = getoption(phy_ops, optarg, &phy_operation,
6470 if (optreturn == CC_OR_AMBIGUOUS) {
6471 warnx("%s: ambiguous option %s", __func__,
6476 } else if (optreturn == CC_OR_NOT_FOUND) {
6477 warnx("%s: option %s not found", __func__,
6489 pp_timeout_val = strtoul(optarg, NULL, 0);
6490 if (pp_timeout_val > 15) {
6491 warnx("%s: invalid partial pathway timeout "
6492 "value %u, need a value less than 16",
6493 __func__, pp_timeout_val);
6497 set_pp_timeout_val = 1;
6505 warnx("%s: a PHY (-p phy) argument is required",__func__);
6510 if (((dev_name_set != 0)
6511 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
6512 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
6513 && (dev_name_set == 0))) {
6514 warnx("%s: -d name and -o setdevname arguments both "
6515 "required to set device name", __func__);
6520 request = malloc(sizeof(*request));
6521 if (request == NULL) {
6522 warn("%s: unable to allocate %zd bytes", __func__,
6528 response = malloc(sizeof(*response));
6529 if (response == NULL) {
6530 warn("%s: unable to allocate %zd bytes", __func__,
6536 smp_phy_control(&ccb->smpio,
6541 (uint8_t *)response,
6544 /*expected_exp_change_count*/ 0,
6547 (set_pp_timeout_val != 0) ? 1 : 0,
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) {
6566 * Use CAM_EPF_NORMAL so we only get one line of
6567 * SMP command decoding.
6569 cam_error_print(device, ccb, CAM_ESF_ALL,
6570 CAM_EPF_NORMAL, stderr);
6576 /* XXX KDM print out something here for success? */
6581 if (request != NULL)
6584 if (response != NULL)
6591 smpmaninfo(struct cam_device *device, int argc, char **argv,
6592 char *combinedopt, int retry_count, int timeout)
6595 struct smp_report_manuf_info_request request;
6596 struct smp_report_manuf_info_response response;
6597 struct sbuf *sb = NULL;
6598 int long_response = 0;
6603 * Note that at the moment we don't support sending SMP CCBs to
6604 * devices that aren't probed by CAM.
6606 ccb = cam_getccb(device);
6608 warnx("%s: error allocating CCB", __func__);
6612 bzero(&(&ccb->ccb_h)[1],
6613 sizeof(union ccb) - sizeof(struct ccb_hdr));
6615 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6624 bzero(&request, sizeof(request));
6625 bzero(&response, sizeof(response));
6627 smp_report_manuf_info(&ccb->smpio,
6632 (uint8_t *)&response,
6637 if (((retval = cam_send_ccb(device, ccb)) < 0)
6638 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6639 const char warnstr[] = "error sending command";
6646 if (arglist & CAM_ARG_VERBOSE) {
6647 cam_error_print(device, ccb, CAM_ESF_ALL,
6648 CAM_EPF_ALL, stderr);
6654 sb = sbuf_new_auto();
6656 warnx("%s: error allocating sbuf", __func__);
6660 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
6662 if (sbuf_finish(sb) != 0) {
6663 warnx("%s: sbuf_finish", __func__);
6667 printf("%s", sbuf_data(sb));
6681 getdevid(struct cam_devitem *item)
6684 union ccb *ccb = NULL;
6686 struct cam_device *dev;
6688 dev = cam_open_btl(item->dev_match.path_id,
6689 item->dev_match.target_id,
6690 item->dev_match.target_lun, O_RDWR, NULL);
6693 warnx("%s", cam_errbuf);
6698 item->device_id_len = 0;
6700 ccb = cam_getccb(dev);
6702 warnx("%s: error allocating CCB", __func__);
6707 bzero(&(&ccb->ccb_h)[1],
6708 sizeof(union ccb) - sizeof(struct ccb_hdr));
6711 * On the first try, we just probe for the size of the data, and
6712 * then allocate that much memory and try again.
6715 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
6716 ccb->ccb_h.flags = CAM_DIR_IN;
6717 ccb->cdai.flags = 0;
6718 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
6719 ccb->cdai.bufsiz = item->device_id_len;
6720 if (item->device_id_len != 0)
6721 ccb->cdai.buf = (uint8_t *)item->device_id;
6723 if (cam_send_ccb(dev, ccb) < 0) {
6724 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
6729 if (ccb->ccb_h.status != CAM_REQ_CMP) {
6730 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
6735 if (item->device_id_len == 0) {
6737 * This is our first time through. Allocate the buffer,
6738 * and then go back to get the data.
6740 if (ccb->cdai.provsiz == 0) {
6741 warnx("%s: invalid .provsiz field returned with "
6742 "XPT_GDEV_ADVINFO CCB", __func__);
6746 item->device_id_len = ccb->cdai.provsiz;
6747 item->device_id = malloc(item->device_id_len);
6748 if (item->device_id == NULL) {
6749 warn("%s: unable to allocate %d bytes", __func__,
6750 item->device_id_len);
6754 ccb->ccb_h.status = CAM_REQ_INPROG;
6760 cam_close_device(dev);
6769 * XXX KDM merge this code with getdevtree()?
6772 buildbusdevlist(struct cam_devlist *devlist)
6775 int bufsize, fd = -1;
6776 struct dev_match_pattern *patterns;
6777 struct cam_devitem *item = NULL;
6778 int skip_device = 0;
6781 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
6782 warn("couldn't open %s", XPT_DEVICE);
6786 bzero(&ccb, sizeof(union ccb));
6788 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
6789 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
6790 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
6792 ccb.ccb_h.func_code = XPT_DEV_MATCH;
6793 bufsize = sizeof(struct dev_match_result) * 100;
6794 ccb.cdm.match_buf_len = bufsize;
6795 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
6796 if (ccb.cdm.matches == NULL) {
6797 warnx("can't malloc memory for matches");
6801 ccb.cdm.num_matches = 0;
6802 ccb.cdm.num_patterns = 2;
6803 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
6804 ccb.cdm.num_patterns;
6806 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
6807 if (patterns == NULL) {
6808 warnx("can't malloc memory for patterns");
6813 ccb.cdm.patterns = patterns;
6814 bzero(patterns, ccb.cdm.pattern_buf_len);
6816 patterns[0].type = DEV_MATCH_DEVICE;
6817 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
6818 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
6819 patterns[1].type = DEV_MATCH_PERIPH;
6820 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
6821 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
6824 * We do the ioctl multiple times if necessary, in case there are
6825 * more than 100 nodes in the EDT.
6830 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
6831 warn("error sending CAMIOCOMMAND ioctl");
6836 if ((ccb.ccb_h.status != CAM_REQ_CMP)
6837 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
6838 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
6839 warnx("got CAM error %#x, CDM error %d\n",
6840 ccb.ccb_h.status, ccb.cdm.status);
6845 for (i = 0; i < ccb.cdm.num_matches; i++) {
6846 switch (ccb.cdm.matches[i].type) {
6847 case DEV_MATCH_DEVICE: {
6848 struct device_match_result *dev_result;
6851 &ccb.cdm.matches[i].result.device_result;
6853 if (dev_result->flags &
6854 DEV_RESULT_UNCONFIGURED) {
6860 item = malloc(sizeof(*item));
6862 warn("%s: unable to allocate %zd bytes",
6863 __func__, sizeof(*item));
6867 bzero(item, sizeof(*item));
6868 bcopy(dev_result, &item->dev_match,
6869 sizeof(*dev_result));
6870 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
6873 if (getdevid(item) != 0) {
6879 case DEV_MATCH_PERIPH: {
6880 struct periph_match_result *periph_result;
6883 &ccb.cdm.matches[i].result.periph_result;
6885 if (skip_device != 0)
6887 item->num_periphs++;
6888 item->periph_matches = realloc(
6889 item->periph_matches,
6891 sizeof(struct periph_match_result));
6892 if (item->periph_matches == NULL) {
6893 warn("%s: error allocating periph "
6898 bcopy(periph_result, &item->periph_matches[
6899 item->num_periphs - 1],
6900 sizeof(*periph_result));
6904 fprintf(stderr, "%s: unexpected match "
6905 "type %d\n", __func__,
6906 ccb.cdm.matches[i].type);
6909 break; /*NOTREACHED*/
6912 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
6913 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
6921 free(ccb.cdm.matches);
6924 freebusdevlist(devlist);
6930 freebusdevlist(struct cam_devlist *devlist)
6932 struct cam_devitem *item, *item2;
6934 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
6935 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
6937 free(item->device_id);
6938 free(item->periph_matches);
6943 static struct cam_devitem *
6944 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
6946 struct cam_devitem *item;
6948 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
6949 struct scsi_vpd_id_descriptor *idd;
6952 * XXX KDM look for LUN IDs as well?
6954 idd = scsi_get_devid(item->device_id,
6955 item->device_id_len,
6956 scsi_devid_is_sas_target);
6960 if (scsi_8btou64(idd->identifier) == sasaddr)
6968 smpphylist(struct cam_device *device, int argc, char **argv,
6969 char *combinedopt, int retry_count, int timeout)
6971 struct smp_report_general_request *rgrequest = NULL;
6972 struct smp_report_general_response *rgresponse = NULL;
6973 struct smp_discover_request *disrequest = NULL;
6974 struct smp_discover_response *disresponse = NULL;
6975 struct cam_devlist devlist;
6977 int long_response = 0;
6984 * Note that at the moment we don't support sending SMP CCBs to
6985 * devices that aren't probed by CAM.
6987 ccb = cam_getccb(device);
6989 warnx("%s: error allocating CCB", __func__);
6993 bzero(&(&ccb->ccb_h)[1],
6994 sizeof(union ccb) - sizeof(struct ccb_hdr));
6995 STAILQ_INIT(&devlist.dev_queue);
6997 rgrequest = malloc(sizeof(*rgrequest));
6998 if (rgrequest == NULL) {
6999 warn("%s: unable to allocate %zd bytes", __func__,
7000 sizeof(*rgrequest));
7005 rgresponse = malloc(sizeof(*rgresponse));
7006 if (rgresponse == NULL) {
7007 warn("%s: unable to allocate %zd bytes", __func__,
7008 sizeof(*rgresponse));
7013 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7026 smp_report_general(&ccb->smpio,
7030 /*request_len*/ sizeof(*rgrequest),
7031 (uint8_t *)rgresponse,
7032 /*response_len*/ sizeof(*rgresponse),
7033 /*long_response*/ long_response,
7036 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7038 if (((retval = cam_send_ccb(device, ccb)) < 0)
7039 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7040 const char warnstr[] = "error sending command";
7047 if (arglist & CAM_ARG_VERBOSE) {
7048 cam_error_print(device, ccb, CAM_ESF_ALL,
7049 CAM_EPF_ALL, stderr);
7055 num_phys = rgresponse->num_phys;
7057 if (num_phys == 0) {
7059 fprintf(stdout, "%s: No Phys reported\n", __func__);
7064 devlist.path_id = device->path_id;
7066 retval = buildbusdevlist(&devlist);
7071 fprintf(stdout, "%d PHYs:\n", num_phys);
7072 fprintf(stdout, "PHY Attached SAS Address\n");
7075 disrequest = malloc(sizeof(*disrequest));
7076 if (disrequest == NULL) {
7077 warn("%s: unable to allocate %zd bytes", __func__,
7078 sizeof(*disrequest));
7083 disresponse = malloc(sizeof(*disresponse));
7084 if (disresponse == NULL) {
7085 warn("%s: unable to allocate %zd bytes", __func__,
7086 sizeof(*disresponse));
7091 for (i = 0; i < num_phys; i++) {
7092 struct cam_devitem *item;
7093 struct device_match_result *dev_match;
7094 char vendor[16], product[48], revision[16];
7098 bzero(&(&ccb->ccb_h)[1],
7099 sizeof(union ccb) - sizeof(struct ccb_hdr));
7101 ccb->ccb_h.status = CAM_REQ_INPROG;
7102 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7104 smp_discover(&ccb->smpio,
7108 sizeof(*disrequest),
7109 (uint8_t *)disresponse,
7110 sizeof(*disresponse),
7112 /*ignore_zone_group*/ 0,
7116 if (((retval = cam_send_ccb(device, ccb)) < 0)
7117 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
7118 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
7119 const char warnstr[] = "error sending command";
7126 if (arglist & CAM_ARG_VERBOSE) {
7127 cam_error_print(device, ccb, CAM_ESF_ALL,
7128 CAM_EPF_ALL, stderr);
7134 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
7136 fprintf(stdout, "%3d <vacant>\n", i);
7140 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
7143 item = findsasdevice(&devlist,
7144 scsi_8btou64(disresponse->attached_sas_address));
7148 || (item != NULL)) {
7149 fprintf(stdout, "%3d 0x%016jx", i,
7150 (uintmax_t)scsi_8btou64(
7151 disresponse->attached_sas_address));
7153 fprintf(stdout, "\n");
7156 } else if (quiet != 0)
7159 dev_match = &item->dev_match;
7161 if (dev_match->protocol == PROTO_SCSI) {
7162 cam_strvis(vendor, dev_match->inq_data.vendor,
7163 sizeof(dev_match->inq_data.vendor),
7165 cam_strvis(product, dev_match->inq_data.product,
7166 sizeof(dev_match->inq_data.product),
7168 cam_strvis(revision, dev_match->inq_data.revision,
7169 sizeof(dev_match->inq_data.revision),
7171 sprintf(tmpstr, "<%s %s %s>", vendor, product,
7173 } else if ((dev_match->protocol == PROTO_ATA)
7174 || (dev_match->protocol == PROTO_SATAPM)) {
7175 cam_strvis(product, dev_match->ident_data.model,
7176 sizeof(dev_match->ident_data.model),
7178 cam_strvis(revision, dev_match->ident_data.revision,
7179 sizeof(dev_match->ident_data.revision),
7181 sprintf(tmpstr, "<%s %s>", product, revision);
7183 sprintf(tmpstr, "<>");
7185 fprintf(stdout, " %-33s ", tmpstr);
7188 * If we have 0 periphs, that's a bug...
7190 if (item->num_periphs == 0) {
7191 fprintf(stdout, "\n");
7195 fprintf(stdout, "(");
7196 for (j = 0; j < item->num_periphs; j++) {
7198 fprintf(stdout, ",");
7200 fprintf(stdout, "%s%d",
7201 item->periph_matches[j].periph_name,
7202 item->periph_matches[j].unit_number);
7205 fprintf(stdout, ")\n");
7219 freebusdevlist(&devlist);
7225 atapm(struct cam_device *device, int argc, char **argv,
7226 char *combinedopt, int retry_count, int timeout)
7234 ccb = cam_getccb(device);
7237 warnx("%s: error allocating ccb", __func__);
7241 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7250 if (strcmp(argv[1], "idle") == 0) {
7252 cmd = ATA_IDLE_IMMEDIATE;
7255 } else if (strcmp(argv[1], "standby") == 0) {
7257 cmd = ATA_STANDBY_IMMEDIATE;
7259 cmd = ATA_STANDBY_CMD;
7267 else if (t <= (240 * 5))
7269 else if (t <= (252 * 5))
7270 /* special encoding for 21 minutes */
7272 else if (t <= (11 * 30 * 60))
7273 sc = (t - 1) / (30 * 60) + 241;
7277 cam_fill_ataio(&ccb->ataio,
7280 /*flags*/CAM_DIR_NONE,
7284 timeout ? timeout : 30 * 1000);
7285 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
7287 /* Disable freezing the device queue */
7288 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7290 if (arglist & CAM_ARG_ERR_RECOVER)
7291 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7293 if (cam_send_ccb(device, ccb) < 0) {
7294 warn("error sending command");
7296 if (arglist & CAM_ARG_VERBOSE)
7297 cam_error_print(device, ccb, CAM_ESF_ALL,
7298 CAM_EPF_ALL, stderr);
7304 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7305 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7314 #endif /* MINIMALISTIC */
7317 usage(int printlong)
7320 fprintf(printlong ? stdout : stderr,
7321 "usage: camcontrol <command> [device id][generic args][command args]\n"
7322 " camcontrol devlist [-v]\n"
7323 #ifndef MINIMALISTIC
7324 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
7325 " camcontrol tur [dev_id][generic args]\n"
7326 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
7327 " camcontrol identify [dev_id][generic args] [-v]\n"
7328 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
7329 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
7331 " camcontrol start [dev_id][generic args]\n"
7332 " camcontrol stop [dev_id][generic args]\n"
7333 " camcontrol load [dev_id][generic args]\n"
7334 " camcontrol eject [dev_id][generic args]\n"
7335 #endif /* MINIMALISTIC */
7336 " camcontrol rescan <all | bus[:target:lun]>\n"
7337 " camcontrol reset <all | bus[:target:lun]>\n"
7338 #ifndef MINIMALISTIC
7339 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
7340 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
7341 " [-P pagectl][-e | -b][-d]\n"
7342 " camcontrol cmd [dev_id][generic args]\n"
7343 " <-a cmd [args] | -c cmd [args]>\n"
7344 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
7345 " camcontrol smpcmd [dev_id][generic args]\n"
7346 " <-r len fmt [args]> <-R len fmt [args]>\n"
7347 " camcontrol smprg [dev_id][generic args][-l]\n"
7348 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
7349 " [-o operation][-d name][-m rate][-M rate]\n"
7350 " [-T pp_timeout][-a enable|disable]\n"
7351 " [-A enable|disable][-s enable|disable]\n"
7352 " [-S enable|disable]\n"
7353 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
7354 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
7355 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
7356 " <all|bus[:target[:lun]]|off>\n"
7357 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
7358 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
7359 " [-D <enable|disable>][-M mode][-O offset]\n"
7360 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
7361 " [-U][-W bus_width]\n"
7362 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
7363 " camcontrol idle [dev_id][generic args][-t time]\n"
7364 " camcontrol standby [dev_id][generic args][-t time]\n"
7365 " camcontrol sleep [dev_id][generic args]\n"
7366 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
7367 " camcontrol security [dev_id][generic args]\n"
7368 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
7369 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
7370 " [-U <user|master>] [-y]\n"
7371 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
7372 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
7373 #endif /* MINIMALISTIC */
7374 " camcontrol help\n");
7377 #ifndef MINIMALISTIC
7379 "Specify one of the following options:\n"
7380 "devlist list all CAM devices\n"
7381 "periphlist list all CAM peripheral drivers attached to a device\n"
7382 "tur send a test unit ready to the named device\n"
7383 "inquiry send a SCSI inquiry command to the named device\n"
7384 "identify send a ATA identify command to the named device\n"
7385 "reportluns send a SCSI report luns command to the device\n"
7386 "readcap send a SCSI read capacity command to the device\n"
7387 "start send a Start Unit command to the device\n"
7388 "stop send a Stop Unit command to the device\n"
7389 "load send a Start Unit command to the device with the load bit set\n"
7390 "eject send a Stop Unit command to the device with the eject bit set\n"
7391 "rescan rescan all busses, the given bus, or bus:target:lun\n"
7392 "reset reset all busses, the given bus, or bus:target:lun\n"
7393 "defects read the defect list of the specified device\n"
7394 "modepage display or edit (-e) the given mode page\n"
7395 "cmd send the given SCSI command, may need -i or -o as well\n"
7396 "smpcmd send the given SMP command, requires -o and -i\n"
7397 "smprg send the SMP Report General command\n"
7398 "smppc send the SMP PHY Control command, requires -p\n"
7399 "smpphylist display phys attached to a SAS expander\n"
7400 "smpmaninfo send the SMP Report Manufacturer Info command\n"
7401 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
7402 "tags report or set the number of transaction slots for a device\n"
7403 "negotiate report or set device negotiation parameters\n"
7404 "format send the SCSI FORMAT UNIT command to the named device\n"
7405 "idle send the ATA IDLE command to the named device\n"
7406 "standby send the ATA STANDBY command to the named device\n"
7407 "sleep send the ATA SLEEP command to the named device\n"
7408 "fwdownload program firmware of the named device with the given image"
7409 "security report or send ATA security commands to the named device\n"
7410 "help this message\n"
7411 "Device Identifiers:\n"
7412 "bus:target specify the bus and target, lun defaults to 0\n"
7413 "bus:target:lun specify the bus, target and lun\n"
7414 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
7415 "Generic arguments:\n"
7416 "-v be verbose, print out sense information\n"
7417 "-t timeout command timeout in seconds, overrides default timeout\n"
7418 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
7419 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
7420 "-E have the kernel attempt to perform SCSI error recovery\n"
7421 "-C count specify the SCSI command retry count (needs -E to work)\n"
7422 "modepage arguments:\n"
7423 "-l list all available mode pages\n"
7424 "-m page specify the mode page to view or edit\n"
7425 "-e edit the specified mode page\n"
7426 "-b force view to binary mode\n"
7427 "-d disable block descriptors for mode sense\n"
7428 "-P pgctl page control field 0-3\n"
7429 "defects arguments:\n"
7430 "-f format specify defect list format (block, bfi or phys)\n"
7431 "-G get the grown defect list\n"
7432 "-P get the permanent defect list\n"
7433 "inquiry arguments:\n"
7434 "-D get the standard inquiry data\n"
7435 "-S get the serial number\n"
7436 "-R get the transfer rate, etc.\n"
7437 "reportluns arguments:\n"
7438 "-c only report a count of available LUNs\n"
7439 "-l only print out luns, and not a count\n"
7440 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
7441 "readcap arguments\n"
7442 "-b only report the blocksize\n"
7443 "-h human readable device size, base 2\n"
7444 "-H human readable device size, base 10\n"
7445 "-N print the number of blocks instead of last block\n"
7446 "-q quiet, print numbers only\n"
7447 "-s only report the last block/device size\n"
7449 "-c cdb [args] specify the SCSI CDB\n"
7450 "-i len fmt specify input data and input data format\n"
7451 "-o len fmt [args] specify output data and output data fmt\n"
7452 "smpcmd arguments:\n"
7453 "-r len fmt [args] specify the SMP command to be sent\n"
7454 "-R len fmt [args] specify SMP response format\n"
7455 "smprg arguments:\n"
7456 "-l specify the long response format\n"
7457 "smppc arguments:\n"
7458 "-p phy specify the PHY to operate on\n"
7459 "-l specify the long request/response format\n"
7460 "-o operation specify the phy control operation\n"
7461 "-d name set the attached device name\n"
7462 "-m rate set the minimum physical link rate\n"
7463 "-M rate set the maximum physical link rate\n"
7464 "-T pp_timeout set the partial pathway timeout value\n"
7465 "-a enable|disable enable or disable SATA slumber\n"
7466 "-A enable|disable enable or disable SATA partial phy power\n"
7467 "-s enable|disable enable or disable SAS slumber\n"
7468 "-S enable|disable enable or disable SAS partial phy power\n"
7469 "smpphylist arguments:\n"
7470 "-l specify the long response format\n"
7471 "-q only print phys with attached devices\n"
7472 "smpmaninfo arguments:\n"
7473 "-l specify the long response format\n"
7474 "debug arguments:\n"
7475 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
7476 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
7477 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
7478 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
7480 "-N tags specify the number of tags to use for this device\n"
7481 "-q be quiet, don't report the number of tags\n"
7482 "-v report a number of tag-related parameters\n"
7483 "negotiate arguments:\n"
7484 "-a send a test unit ready after negotiation\n"
7485 "-c report/set current negotiation settings\n"
7486 "-D <arg> \"enable\" or \"disable\" disconnection\n"
7487 "-M mode set ATA mode\n"
7488 "-O offset set command delay offset\n"
7489 "-q be quiet, don't report anything\n"
7490 "-R syncrate synchronization rate in MHz\n"
7491 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
7492 "-U report/set user negotiation settings\n"
7493 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
7494 "-v also print a Path Inquiry CCB for the controller\n"
7495 "format arguments:\n"
7496 "-q be quiet, don't print status messages\n"
7497 "-r run in report only mode\n"
7498 "-w don't send immediate format command\n"
7499 "-y don't ask any questions\n"
7500 "idle/standby arguments:\n"
7501 "-t <arg> number of seconds before respective state.\n"
7502 "fwdownload arguments:\n"
7503 "-f fw_image path to firmware image file\n"
7504 "-y don't ask any questions\n"
7505 "-s run in simulation mode\n"
7506 "-v print info for every firmware segment sent to device\n"
7507 "security arguments:\n"
7508 "-d pwd disable security using the given password for the selected\n"
7510 "-e pwd erase the device using the given pwd for the selected user\n"
7511 "-f freeze the security configuration of the specified device\n"
7512 "-h pwd enhanced erase the device using the given pwd for the\n"
7514 "-k pwd unlock the device using the given pwd for the selected\n"
7516 "-l <high|maximum> specifies which security level to set: high or maximum\n"
7517 "-q be quiet, do not print any status messages\n"
7518 "-s pwd password the device (enable security) using the given\n"
7519 " pwd for the selected user\n"
7520 "-T timeout overrides the timeout (seconds) used for erase operation\n"
7521 "-U <user|master> specifies which user to set: user or master\n"
7522 "-y don't ask any questions\n"
7524 "-f freeze the HPA configuration of the device\n"
7525 "-l lock the HPA configuration of the device\n"
7526 "-P make the HPA max sectors persist\n"
7527 "-p pwd Set the HPA configuration password required for unlock\n"
7529 "-q be quiet, do not print any status messages\n"
7530 "-s sectors configures the maximum user accessible sectors of the\n"
7532 "-U pwd unlock the HPA configuration of the device\n"
7533 "-y don't ask any questions\n"
7535 #endif /* MINIMALISTIC */
7539 main(int argc, char **argv)
7542 char *device = NULL;
7544 struct cam_device *cam_dev = NULL;
7545 int timeout = 0, retry_count = 1;
7546 camcontrol_optret optreturn;
7548 const char *mainopt = "C:En:t:u:v";
7549 const char *subopt = NULL;
7550 char combinedopt[256];
7551 int error = 0, optstart = 2;
7553 #ifndef MINIMALISTIC
7554 int bus, target, lun;
7555 #endif /* MINIMALISTIC */
7557 cmdlist = CAM_CMD_NONE;
7558 arglist = CAM_ARG_NONE;
7566 * Get the base option.
7568 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
7570 if (optreturn == CC_OR_AMBIGUOUS) {
7571 warnx("ambiguous option %s", argv[1]);
7574 } else if (optreturn == CC_OR_NOT_FOUND) {
7575 warnx("option %s not found", argv[1]);
7581 * Ahh, getopt(3) is a pain.
7583 * This is a gross hack. There really aren't many other good
7584 * options (excuse the pun) for parsing options in a situation like
7585 * this. getopt is kinda braindead, so you end up having to run
7586 * through the options twice, and give each invocation of getopt
7587 * the option string for the other invocation.
7589 * You would think that you could just have two groups of options.
7590 * The first group would get parsed by the first invocation of
7591 * getopt, and the second group would get parsed by the second
7592 * invocation of getopt. It doesn't quite work out that way. When
7593 * the first invocation of getopt finishes, it leaves optind pointing
7594 * to the argument _after_ the first argument in the second group.
7595 * So when the second invocation of getopt comes around, it doesn't
7596 * recognize the first argument it gets and then bails out.
7598 * A nice alternative would be to have a flag for getopt that says
7599 * "just keep parsing arguments even when you encounter an unknown
7600 * argument", but there isn't one. So there's no real clean way to
7601 * easily parse two sets of arguments without having one invocation
7602 * of getopt know about the other.
7604 * Without this hack, the first invocation of getopt would work as
7605 * long as the generic arguments are first, but the second invocation
7606 * (in the subfunction) would fail in one of two ways. In the case
7607 * where you don't set optreset, it would fail because optind may be
7608 * pointing to the argument after the one it should be pointing at.
7609 * In the case where you do set optreset, and reset optind, it would
7610 * fail because getopt would run into the first set of options, which
7611 * it doesn't understand.
7613 * All of this would "sort of" work if you could somehow figure out
7614 * whether optind had been incremented one option too far. The
7615 * mechanics of that, however, are more daunting than just giving
7616 * both invocations all of the expect options for either invocation.
7618 * Needless to say, I wouldn't mind if someone invented a better
7619 * (non-GPL!) command line parsing interface than getopt. I
7620 * wouldn't mind if someone added more knobs to getopt to make it
7621 * work better. Who knows, I may talk myself into doing it someday,
7622 * if the standards weenies let me. As it is, it just leads to
7623 * hackery like this and causes people to avoid it in some cases.
7625 * KDM, September 8th, 1998
7628 sprintf(combinedopt, "%s%s", mainopt, subopt);
7630 sprintf(combinedopt, "%s", mainopt);
7633 * For these options we do not parse optional device arguments and
7634 * we do not open a passthrough device.
7636 if ((cmdlist == CAM_CMD_RESCAN)
7637 || (cmdlist == CAM_CMD_RESET)
7638 || (cmdlist == CAM_CMD_DEVTREE)
7639 || (cmdlist == CAM_CMD_USAGE)
7640 || (cmdlist == CAM_CMD_DEBUG))
7643 #ifndef MINIMALISTIC
7645 && (argc > 2 && argv[2][0] != '-')) {
7649 if (isdigit(argv[2][0])) {
7650 /* device specified as bus:target[:lun] */
7651 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
7653 errx(1, "numeric device specification must "
7654 "be either bus:target, or "
7656 /* default to 0 if lun was not specified */
7657 if ((arglist & CAM_ARG_LUN) == 0) {
7659 arglist |= CAM_ARG_LUN;
7663 if (cam_get_device(argv[2], name, sizeof name, &unit)
7665 errx(1, "%s", cam_errbuf);
7666 device = strdup(name);
7667 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
7671 #endif /* MINIMALISTIC */
7673 * Start getopt processing at argv[2/3], since we've already
7674 * accepted argv[1..2] as the command name, and as a possible
7680 * Now we run through the argument list looking for generic
7681 * options, and ignoring options that possibly belong to
7684 while ((c = getopt(argc, argv, combinedopt))!= -1){
7687 retry_count = strtol(optarg, NULL, 0);
7688 if (retry_count < 0)
7689 errx(1, "retry count %d is < 0",
7691 arglist |= CAM_ARG_RETRIES;
7694 arglist |= CAM_ARG_ERR_RECOVER;
7697 arglist |= CAM_ARG_DEVICE;
7699 while (isspace(*tstr) && (*tstr != '\0'))
7701 device = (char *)strdup(tstr);
7704 timeout = strtol(optarg, NULL, 0);
7706 errx(1, "invalid timeout %d", timeout);
7707 /* Convert the timeout from seconds to ms */
7709 arglist |= CAM_ARG_TIMEOUT;
7712 arglist |= CAM_ARG_UNIT;
7713 unit = strtol(optarg, NULL, 0);
7716 arglist |= CAM_ARG_VERBOSE;
7723 #ifndef MINIMALISTIC
7725 * For most commands we'll want to open the passthrough device
7726 * associated with the specified device. In the case of the rescan
7727 * commands, we don't use a passthrough device at all, just the
7728 * transport layer device.
7731 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
7732 && (((arglist & CAM_ARG_DEVICE) == 0)
7733 || ((arglist & CAM_ARG_UNIT) == 0))) {
7734 errx(1, "subcommand \"%s\" requires a valid device "
7735 "identifier", argv[1]);
7738 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
7739 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
7740 cam_open_spec_device(device,unit,O_RDWR,NULL)))
7742 errx(1,"%s", cam_errbuf);
7744 #endif /* MINIMALISTIC */
7747 * Reset optind to 2, and reset getopt, so these routines can parse
7748 * the arguments again.
7754 #ifndef MINIMALISTIC
7755 case CAM_CMD_DEVLIST:
7756 error = getdevlist(cam_dev);
7759 error = atahpa(cam_dev, retry_count, timeout,
7760 argc, argv, combinedopt);
7762 #endif /* MINIMALISTIC */
7763 case CAM_CMD_DEVTREE:
7764 error = getdevtree();
7766 #ifndef MINIMALISTIC
7768 error = testunitready(cam_dev, retry_count, timeout, 0);
7770 case CAM_CMD_INQUIRY:
7771 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
7772 retry_count, timeout);
7774 case CAM_CMD_IDENTIFY:
7775 error = ataidentify(cam_dev, retry_count, timeout);
7777 case CAM_CMD_STARTSTOP:
7778 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
7779 arglist & CAM_ARG_EJECT, retry_count,
7782 #endif /* MINIMALISTIC */
7783 case CAM_CMD_RESCAN:
7784 error = dorescan_or_reset(argc, argv, 1);
7787 error = dorescan_or_reset(argc, argv, 0);
7789 #ifndef MINIMALISTIC
7790 case CAM_CMD_READ_DEFECTS:
7791 error = readdefects(cam_dev, argc, argv, combinedopt,
7792 retry_count, timeout);
7794 case CAM_CMD_MODE_PAGE:
7795 modepage(cam_dev, argc, argv, combinedopt,
7796 retry_count, timeout);
7798 case CAM_CMD_SCSI_CMD:
7799 error = scsicmd(cam_dev, argc, argv, combinedopt,
7800 retry_count, timeout);
7802 case CAM_CMD_SMP_CMD:
7803 error = smpcmd(cam_dev, argc, argv, combinedopt,
7804 retry_count, timeout);
7806 case CAM_CMD_SMP_RG:
7807 error = smpreportgeneral(cam_dev, argc, argv,
7808 combinedopt, retry_count,
7811 case CAM_CMD_SMP_PC:
7812 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
7813 retry_count, timeout);
7815 case CAM_CMD_SMP_PHYLIST:
7816 error = smpphylist(cam_dev, argc, argv, combinedopt,
7817 retry_count, timeout);
7819 case CAM_CMD_SMP_MANINFO:
7820 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
7821 retry_count, timeout);
7824 error = camdebug(argc, argv, combinedopt);
7827 error = tagcontrol(cam_dev, argc, argv, combinedopt);
7830 error = ratecontrol(cam_dev, retry_count, timeout,
7831 argc, argv, combinedopt);
7833 case CAM_CMD_FORMAT:
7834 error = scsiformat(cam_dev, argc, argv,
7835 combinedopt, retry_count, timeout);
7837 case CAM_CMD_REPORTLUNS:
7838 error = scsireportluns(cam_dev, argc, argv,
7839 combinedopt, retry_count,
7842 case CAM_CMD_READCAP:
7843 error = scsireadcapacity(cam_dev, argc, argv,
7844 combinedopt, retry_count,
7848 case CAM_CMD_STANDBY:
7850 error = atapm(cam_dev, argc, argv,
7851 combinedopt, retry_count, timeout);
7853 case CAM_CMD_SECURITY:
7854 error = atasecurity(cam_dev, retry_count, timeout,
7855 argc, argv, combinedopt);
7857 case CAM_CMD_DOWNLOAD_FW:
7858 error = fwdownload(cam_dev, argc, argv, combinedopt,
7859 arglist & CAM_ARG_VERBOSE, retry_count, timeout,
7860 get_disk_type(cam_dev));
7862 #endif /* MINIMALISTIC */
7872 if (cam_dev != NULL)
7873 cam_close_device(cam_dev);