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>
51 #include <cam/cam_debug.h>
52 #include <cam/cam_ccb.h>
53 #include <cam/scsi/scsi_all.h>
54 #include <cam/scsi/scsi_da.h>
55 #include <cam/scsi/scsi_pass.h>
56 #include <cam/scsi/scsi_message.h>
57 #include <cam/ata/ata_all.h>
59 #include "camcontrol.h"
62 CAM_CMD_NONE = 0x00000000,
63 CAM_CMD_DEVLIST = 0x00000001,
64 CAM_CMD_TUR = 0x00000002,
65 CAM_CMD_INQUIRY = 0x00000003,
66 CAM_CMD_STARTSTOP = 0x00000004,
67 CAM_CMD_RESCAN = 0x00000005,
68 CAM_CMD_READ_DEFECTS = 0x00000006,
69 CAM_CMD_MODE_PAGE = 0x00000007,
70 CAM_CMD_SCSI_CMD = 0x00000008,
71 CAM_CMD_DEVTREE = 0x00000009,
72 CAM_CMD_USAGE = 0x0000000a,
73 CAM_CMD_DEBUG = 0x0000000b,
74 CAM_CMD_RESET = 0x0000000c,
75 CAM_CMD_FORMAT = 0x0000000d,
76 CAM_CMD_TAG = 0x0000000e,
77 CAM_CMD_RATE = 0x0000000f,
78 CAM_CMD_DETACH = 0x00000010,
79 CAM_CMD_REPORTLUNS = 0x00000011,
80 CAM_CMD_READCAP = 0x00000012,
81 CAM_CMD_IDENTIFY = 0x00000013,
82 CAM_CMD_IDLE = 0x00000014,
83 CAM_CMD_STANDBY = 0x00000015,
84 CAM_CMD_SLEEP = 0x00000016,
85 CAM_CMD_SECURITY = 0x00000017,
86 CAM_CMD_HPA = 0x00000018
90 CAM_ARG_NONE = 0x00000000,
91 CAM_ARG_VERBOSE = 0x00000001,
92 CAM_ARG_DEVICE = 0x00000002,
93 CAM_ARG_BUS = 0x00000004,
94 CAM_ARG_TARGET = 0x00000008,
95 CAM_ARG_LUN = 0x00000010,
96 CAM_ARG_EJECT = 0x00000020,
97 CAM_ARG_UNIT = 0x00000040,
98 CAM_ARG_FORMAT_BLOCK = 0x00000080,
99 CAM_ARG_FORMAT_BFI = 0x00000100,
100 CAM_ARG_FORMAT_PHYS = 0x00000200,
101 CAM_ARG_PLIST = 0x00000400,
102 CAM_ARG_GLIST = 0x00000800,
103 CAM_ARG_GET_SERIAL = 0x00001000,
104 CAM_ARG_GET_STDINQ = 0x00002000,
105 CAM_ARG_GET_XFERRATE = 0x00004000,
106 CAM_ARG_INQ_MASK = 0x00007000,
107 CAM_ARG_MODE_EDIT = 0x00008000,
108 CAM_ARG_PAGE_CNTL = 0x00010000,
109 CAM_ARG_TIMEOUT = 0x00020000,
110 CAM_ARG_CMD_IN = 0x00040000,
111 CAM_ARG_CMD_OUT = 0x00080000,
112 CAM_ARG_DBD = 0x00100000,
113 CAM_ARG_ERR_RECOVER = 0x00200000,
114 CAM_ARG_RETRIES = 0x00400000,
115 CAM_ARG_START_UNIT = 0x00800000,
116 CAM_ARG_DEBUG_INFO = 0x01000000,
117 CAM_ARG_DEBUG_TRACE = 0x02000000,
118 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
119 CAM_ARG_DEBUG_CDB = 0x08000000,
120 CAM_ARG_DEBUG_XPT = 0x10000000,
121 CAM_ARG_DEBUG_PERIPH = 0x20000000,
122 CAM_ARG_DEBUG_PROBE = 0x40000000,
125 struct camcontrol_opts {
133 struct ata_res_pass16 {
134 u_int16_t reserved[5];
137 u_int8_t sector_count_exp;
138 u_int8_t sector_count;
139 u_int8_t lba_low_exp;
141 u_int8_t lba_mid_exp;
143 u_int8_t lba_high_exp;
149 struct ata_set_max_pwd
152 u_int8_t password[32];
153 u_int16_t reserved2[239];
156 static const char scsicmd_opts[] = "a:c:dfi:o:r";
157 static const char readdefect_opts[] = "f:GP";
158 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
162 struct camcontrol_opts option_table[] = {
164 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
165 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
166 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
167 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
168 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
169 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
170 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
171 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
172 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
173 #endif /* MINIMALISTIC */
174 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
175 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
177 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
178 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
179 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
180 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
181 #endif /* MINIMALISTIC */
182 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL},
184 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
185 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
186 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
187 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
188 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
189 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
190 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
191 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
192 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
193 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
194 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
195 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
196 #endif /* MINIMALISTIC */
197 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
198 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
199 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
213 camcontrol_optret getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
214 const char **subopt);
216 static int getdevlist(struct cam_device *device);
217 #endif /* MINIMALISTIC */
218 static int getdevtree(void);
220 static int testunitready(struct cam_device *device, int retry_count,
221 int timeout, int quiet);
222 static int scsistart(struct cam_device *device, int startstop, int loadeject,
223 int retry_count, int timeout);
224 static int scsidoinquiry(struct cam_device *device, int argc, char **argv,
225 char *combinedopt, int retry_count, int timeout);
226 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
227 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
228 static int camxferrate(struct cam_device *device);
229 #endif /* MINIMALISTIC */
230 static int parse_btl(char *tstr, int *bus, int *target, int *lun,
231 cam_argmask *arglst);
232 static int dorescan_or_reset(int argc, char **argv, int rescan);
233 static int rescan_or_reset_bus(int bus, int rescan);
234 static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
236 static int readdefects(struct cam_device *device, int argc, char **argv,
237 char *combinedopt, int retry_count, int timeout);
238 static void modepage(struct cam_device *device, int argc, char **argv,
239 char *combinedopt, int retry_count, int timeout);
240 static int scsicmd(struct cam_device *device, int argc, char **argv,
241 char *combinedopt, int retry_count, int timeout);
242 static int tagcontrol(struct cam_device *device, int argc, char **argv,
244 static void cts_print(struct cam_device *device,
245 struct ccb_trans_settings *cts);
246 static void cpi_print(struct ccb_pathinq *cpi);
247 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
248 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
249 static int get_print_cts(struct cam_device *device, int user_settings,
250 int quiet, struct ccb_trans_settings *cts);
251 static int ratecontrol(struct cam_device *device, int retry_count,
252 int timeout, int argc, char **argv, char *combinedopt);
253 static int scsiformat(struct cam_device *device, int argc, char **argv,
254 char *combinedopt, int retry_count, int timeout);
255 static int scsireportluns(struct cam_device *device, int argc, char **argv,
256 char *combinedopt, int retry_count, int timeout);
257 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
258 char *combinedopt, int retry_count, int timeout);
259 static int atapm(struct cam_device *device, int argc, char **argv,
260 char *combinedopt, int retry_count, int timeout);
261 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
262 int argc, char **argv, char *combinedopt);
263 static int atahpa(struct cam_device *device, int retry_count, int timeout,
264 int argc, char **argv, char *combinedopt);
266 #endif /* MINIMALISTIC */
268 #define min(a,b) (((a)<(b))?(a):(b))
271 #define max(a,b) (((a)>(b))?(a):(b))
275 getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
278 struct camcontrol_opts *opts;
281 for (opts = option_table; (opts != NULL) && (opts->optname != NULL);
283 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
284 *cmdnum = opts->cmdnum;
285 *argnum = opts->argnum;
286 *subopt = opts->subopt;
287 if (++num_matches > 1)
288 return(CC_OR_AMBIGUOUS);
295 return(CC_OR_NOT_FOUND);
300 getdevlist(struct cam_device *device)
306 ccb = cam_getccb(device);
308 ccb->ccb_h.func_code = XPT_GDEVLIST;
309 ccb->ccb_h.flags = CAM_DIR_NONE;
310 ccb->ccb_h.retry_count = 1;
312 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
313 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
314 if (cam_send_ccb(device, ccb) < 0) {
315 perror("error getting device list");
322 switch (ccb->cgdl.status) {
323 case CAM_GDEVLIST_MORE_DEVS:
324 strcpy(status, "MORE");
326 case CAM_GDEVLIST_LAST_DEVICE:
327 strcpy(status, "LAST");
329 case CAM_GDEVLIST_LIST_CHANGED:
330 strcpy(status, "CHANGED");
332 case CAM_GDEVLIST_ERROR:
333 strcpy(status, "ERROR");
338 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
339 ccb->cgdl.periph_name,
340 ccb->cgdl.unit_number,
341 ccb->cgdl.generation,
346 * If the list has changed, we need to start over from the
349 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
357 #endif /* MINIMALISTIC */
369 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
370 warn("couldn't open %s", XPT_DEVICE);
374 bzero(&ccb, sizeof(union ccb));
376 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
377 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
378 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
380 ccb.ccb_h.func_code = XPT_DEV_MATCH;
381 bufsize = sizeof(struct dev_match_result) * 100;
382 ccb.cdm.match_buf_len = bufsize;
383 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
384 if (ccb.cdm.matches == NULL) {
385 warnx("can't malloc memory for matches");
389 ccb.cdm.num_matches = 0;
392 * We fetch all nodes, since we display most of them in the default
393 * case, and all in the verbose case.
395 ccb.cdm.num_patterns = 0;
396 ccb.cdm.pattern_buf_len = 0;
399 * We do the ioctl multiple times if necessary, in case there are
400 * more than 100 nodes in the EDT.
403 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
404 warn("error sending CAMIOCOMMAND ioctl");
409 if ((ccb.ccb_h.status != CAM_REQ_CMP)
410 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
411 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
412 warnx("got CAM error %#x, CDM error %d\n",
413 ccb.ccb_h.status, ccb.cdm.status);
418 for (i = 0; i < ccb.cdm.num_matches; i++) {
419 switch (ccb.cdm.matches[i].type) {
420 case DEV_MATCH_BUS: {
421 struct bus_match_result *bus_result;
424 * Only print the bus information if the
425 * user turns on the verbose flag.
427 if ((arglist & CAM_ARG_VERBOSE) == 0)
431 &ccb.cdm.matches[i].result.bus_result;
434 fprintf(stdout, ")\n");
438 fprintf(stdout, "scbus%d on %s%d bus %d:\n",
440 bus_result->dev_name,
441 bus_result->unit_number,
445 case DEV_MATCH_DEVICE: {
446 struct device_match_result *dev_result;
447 char vendor[16], product[48], revision[16];
451 &ccb.cdm.matches[i].result.device_result;
453 if ((dev_result->flags
454 & DEV_RESULT_UNCONFIGURED)
455 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
461 if (dev_result->protocol == PROTO_SCSI) {
462 cam_strvis(vendor, dev_result->inq_data.vendor,
463 sizeof(dev_result->inq_data.vendor),
466 dev_result->inq_data.product,
467 sizeof(dev_result->inq_data.product),
470 dev_result->inq_data.revision,
471 sizeof(dev_result->inq_data.revision),
473 sprintf(tmpstr, "<%s %s %s>", vendor, product,
475 } else if (dev_result->protocol == PROTO_ATA ||
476 dev_result->protocol == PROTO_SATAPM) {
478 dev_result->ident_data.model,
479 sizeof(dev_result->ident_data.model),
482 dev_result->ident_data.revision,
483 sizeof(dev_result->ident_data.revision),
485 sprintf(tmpstr, "<%s %s>", product,
488 sprintf(tmpstr, "<>");
491 fprintf(stdout, ")\n");
495 fprintf(stdout, "%-33s at scbus%d "
496 "target %d lun %d (",
499 dev_result->target_id,
500 dev_result->target_lun);
506 case DEV_MATCH_PERIPH: {
507 struct periph_match_result *periph_result;
510 &ccb.cdm.matches[i].result.periph_result;
512 if (skip_device != 0)
516 fprintf(stdout, ",");
518 fprintf(stdout, "%s%d",
519 periph_result->periph_name,
520 periph_result->unit_number);
526 fprintf(stdout, "unknown match type\n");
531 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
532 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
535 fprintf(stdout, ")\n");
544 testunitready(struct cam_device *device, int retry_count, int timeout,
550 ccb = cam_getccb(device);
552 scsi_test_unit_ready(&ccb->csio,
553 /* retries */ retry_count,
555 /* tag_action */ MSG_SIMPLE_Q_TAG,
556 /* sense_len */ SSD_FULL_SIZE,
557 /* timeout */ timeout ? timeout : 5000);
559 /* Disable freezing the device queue */
560 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
562 if (arglist & CAM_ARG_ERR_RECOVER)
563 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
565 if (cam_send_ccb(device, ccb) < 0) {
567 perror("error sending test unit ready");
569 if (arglist & CAM_ARG_VERBOSE) {
570 cam_error_print(device, ccb, CAM_ESF_ALL,
571 CAM_EPF_ALL, stderr);
578 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
580 fprintf(stdout, "Unit is ready\n");
583 fprintf(stdout, "Unit is not ready\n");
586 if (arglist & CAM_ARG_VERBOSE) {
587 cam_error_print(device, ccb, CAM_ESF_ALL,
588 CAM_EPF_ALL, stderr);
598 scsistart(struct cam_device *device, int startstop, int loadeject,
599 int retry_count, int timeout)
604 ccb = cam_getccb(device);
607 * If we're stopping, send an ordered tag so the drive in question
608 * will finish any previously queued writes before stopping. If
609 * the device isn't capable of tagged queueing, or if tagged
610 * queueing is turned off, the tag action is a no-op.
612 scsi_start_stop(&ccb->csio,
613 /* retries */ retry_count,
615 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
617 /* start/stop */ startstop,
618 /* load_eject */ loadeject,
620 /* sense_len */ SSD_FULL_SIZE,
621 /* timeout */ timeout ? timeout : 120000);
623 /* Disable freezing the device queue */
624 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
626 if (arglist & CAM_ARG_ERR_RECOVER)
627 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
629 if (cam_send_ccb(device, ccb) < 0) {
630 perror("error sending start unit");
632 if (arglist & CAM_ARG_VERBOSE) {
633 cam_error_print(device, ccb, CAM_ESF_ALL,
634 CAM_EPF_ALL, stderr);
641 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
643 fprintf(stdout, "Unit started successfully");
645 fprintf(stdout,", Media loaded\n");
647 fprintf(stdout,"\n");
649 fprintf(stdout, "Unit stopped successfully");
651 fprintf(stdout, ", Media ejected\n");
653 fprintf(stdout, "\n");
659 "Error received from start unit command\n");
662 "Error received from stop unit command\n");
664 if (arglist & CAM_ARG_VERBOSE) {
665 cam_error_print(device, ccb, CAM_ESF_ALL,
666 CAM_EPF_ALL, stderr);
676 scsidoinquiry(struct cam_device *device, int argc, char **argv,
677 char *combinedopt, int retry_count, int timeout)
682 while ((c = getopt(argc, argv, combinedopt)) != -1) {
685 arglist |= CAM_ARG_GET_STDINQ;
688 arglist |= CAM_ARG_GET_XFERRATE;
691 arglist |= CAM_ARG_GET_SERIAL;
699 * If the user didn't specify any inquiry options, he wants all of
702 if ((arglist & CAM_ARG_INQ_MASK) == 0)
703 arglist |= CAM_ARG_INQ_MASK;
705 if (arglist & CAM_ARG_GET_STDINQ)
706 error = scsiinquiry(device, retry_count, timeout);
711 if (arglist & CAM_ARG_GET_SERIAL)
712 scsiserial(device, retry_count, timeout);
717 if (arglist & CAM_ARG_GET_XFERRATE)
718 error = camxferrate(device);
724 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
727 struct scsi_inquiry_data *inq_buf;
730 ccb = cam_getccb(device);
733 warnx("couldn't allocate CCB");
737 /* cam_getccb cleans up the header, caller has to zero the payload */
738 bzero(&(&ccb->ccb_h)[1],
739 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
741 inq_buf = (struct scsi_inquiry_data *)malloc(
742 sizeof(struct scsi_inquiry_data));
744 if (inq_buf == NULL) {
746 warnx("can't malloc memory for inquiry\n");
749 bzero(inq_buf, sizeof(*inq_buf));
752 * Note that although the size of the inquiry buffer is the full
753 * 256 bytes specified in the SCSI spec, we only tell the device
754 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
755 * two reasons for this:
757 * - The SCSI spec says that when a length field is only 1 byte,
758 * a value of 0 will be interpreted as 256. Therefore
759 * scsi_inquiry() will convert an inq_len (which is passed in as
760 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
761 * to 0. Evidently, very few devices meet the spec in that
762 * regard. Some devices, like many Seagate disks, take the 0 as
763 * 0, and don't return any data. One Pioneer DVD-R drive
764 * returns more data than the command asked for.
766 * So, since there are numerous devices that just don't work
767 * right with the full inquiry size, we don't send the full size.
769 * - The second reason not to use the full inquiry data length is
770 * that we don't need it here. The only reason we issue a
771 * standard inquiry is to get the vendor name, device name,
772 * and revision so scsi_print_inquiry() can print them.
774 * If, at some point in the future, more inquiry data is needed for
775 * some reason, this code should use a procedure similar to the
776 * probe code. i.e., issue a short inquiry, and determine from
777 * the additional length passed back from the device how much
778 * inquiry data the device supports. Once the amount the device
779 * supports is determined, issue an inquiry for that amount and no
784 scsi_inquiry(&ccb->csio,
785 /* retries */ retry_count,
787 /* tag_action */ MSG_SIMPLE_Q_TAG,
788 /* inq_buf */ (u_int8_t *)inq_buf,
789 /* inq_len */ SHORT_INQUIRY_LENGTH,
792 /* sense_len */ SSD_FULL_SIZE,
793 /* timeout */ timeout ? timeout : 5000);
795 /* Disable freezing the device queue */
796 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
798 if (arglist & CAM_ARG_ERR_RECOVER)
799 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
801 if (cam_send_ccb(device, ccb) < 0) {
802 perror("error sending SCSI inquiry");
804 if (arglist & CAM_ARG_VERBOSE) {
805 cam_error_print(device, ccb, CAM_ESF_ALL,
806 CAM_EPF_ALL, stderr);
813 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
816 if (arglist & CAM_ARG_VERBOSE) {
817 cam_error_print(device, ccb, CAM_ESF_ALL,
818 CAM_EPF_ALL, stderr);
829 fprintf(stdout, "%s%d: ", device->device_name,
830 device->dev_unit_num);
831 scsi_print_inquiry(inq_buf);
839 scsiserial(struct cam_device *device, int retry_count, int timeout)
842 struct scsi_vpd_unit_serial_number *serial_buf;
843 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
846 ccb = cam_getccb(device);
849 warnx("couldn't allocate CCB");
853 /* cam_getccb cleans up the header, caller has to zero the payload */
854 bzero(&(&ccb->ccb_h)[1],
855 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
857 serial_buf = (struct scsi_vpd_unit_serial_number *)
858 malloc(sizeof(*serial_buf));
860 if (serial_buf == NULL) {
862 warnx("can't malloc memory for serial number");
866 scsi_inquiry(&ccb->csio,
867 /*retries*/ retry_count,
869 /* tag_action */ MSG_SIMPLE_Q_TAG,
870 /* inq_buf */ (u_int8_t *)serial_buf,
871 /* inq_len */ sizeof(*serial_buf),
873 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
874 /* sense_len */ SSD_FULL_SIZE,
875 /* timeout */ timeout ? timeout : 5000);
877 /* Disable freezing the device queue */
878 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
880 if (arglist & CAM_ARG_ERR_RECOVER)
881 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
883 if (cam_send_ccb(device, ccb) < 0) {
884 warn("error getting serial number");
886 if (arglist & CAM_ARG_VERBOSE) {
887 cam_error_print(device, ccb, CAM_ESF_ALL,
888 CAM_EPF_ALL, stderr);
896 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
899 if (arglist & CAM_ARG_VERBOSE) {
900 cam_error_print(device, ccb, CAM_ESF_ALL,
901 CAM_EPF_ALL, stderr);
912 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
913 serial_num[serial_buf->length] = '\0';
915 if ((arglist & CAM_ARG_GET_STDINQ)
916 || (arglist & CAM_ARG_GET_XFERRATE))
917 fprintf(stdout, "%s%d: Serial Number ",
918 device->device_name, device->dev_unit_num);
920 fprintf(stdout, "%.60s\n", serial_num);
928 camxferrate(struct cam_device *device)
930 struct ccb_pathinq cpi;
937 if ((retval = get_cpi(device, &cpi)) != 0)
940 ccb = cam_getccb(device);
943 warnx("couldn't allocate CCB");
947 bzero(&(&ccb->ccb_h)[1],
948 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
950 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
951 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
953 if (((retval = cam_send_ccb(device, ccb)) < 0)
954 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
955 const char error_string[] = "error getting transfer settings";
962 if (arglist & CAM_ARG_VERBOSE)
963 cam_error_print(device, ccb, CAM_ESF_ALL,
964 CAM_EPF_ALL, stderr);
968 goto xferrate_bailout;
972 speed = cpi.base_transfer_speed;
974 if (ccb->cts.transport == XPORT_SPI) {
975 struct ccb_trans_settings_spi *spi =
976 &ccb->cts.xport_specific.spi;
978 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
979 freq = scsi_calc_syncsrate(spi->sync_period);
982 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
983 speed *= (0x01 << spi->bus_width);
985 } else if (ccb->cts.transport == XPORT_FC) {
986 struct ccb_trans_settings_fc *fc =
987 &ccb->cts.xport_specific.fc;
989 if (fc->valid & CTS_FC_VALID_SPEED)
991 } else if (ccb->cts.transport == XPORT_SAS) {
992 struct ccb_trans_settings_sas *sas =
993 &ccb->cts.xport_specific.sas;
995 if (sas->valid & CTS_SAS_VALID_SPEED)
996 speed = sas->bitrate;
997 } else if (ccb->cts.transport == XPORT_ATA) {
998 struct ccb_trans_settings_pata *pata =
999 &ccb->cts.xport_specific.ata;
1001 if (pata->valid & CTS_ATA_VALID_MODE)
1002 speed = ata_mode2speed(pata->mode);
1003 } else if (ccb->cts.transport == XPORT_SATA) {
1004 struct ccb_trans_settings_sata *sata =
1005 &ccb->cts.xport_specific.sata;
1007 if (sata->valid & CTS_SATA_VALID_REVISION)
1008 speed = ata_revision2speed(sata->revision);
1013 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1014 device->device_name, device->dev_unit_num,
1017 fprintf(stdout, "%s%d: %dKB/s transfers",
1018 device->device_name, device->dev_unit_num,
1022 if (ccb->cts.transport == XPORT_SPI) {
1023 struct ccb_trans_settings_spi *spi =
1024 &ccb->cts.xport_specific.spi;
1026 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1027 && (spi->sync_offset != 0))
1028 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1029 freq % 1000, spi->sync_offset);
1031 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1032 && (spi->bus_width > 0)) {
1033 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1034 && (spi->sync_offset != 0)) {
1035 fprintf(stdout, ", ");
1037 fprintf(stdout, " (");
1039 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1040 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1041 && (spi->sync_offset != 0)) {
1042 fprintf(stdout, ")");
1044 } else if (ccb->cts.transport == XPORT_ATA) {
1045 struct ccb_trans_settings_pata *pata =
1046 &ccb->cts.xport_specific.ata;
1049 if (pata->valid & CTS_ATA_VALID_MODE)
1050 printf("%s, ", ata_mode2string(pata->mode));
1051 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1052 printf("ATAPI %dbytes, ", pata->atapi);
1053 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1054 printf("PIO %dbytes", pata->bytecount);
1056 } else if (ccb->cts.transport == XPORT_SATA) {
1057 struct ccb_trans_settings_sata *sata =
1058 &ccb->cts.xport_specific.sata;
1061 if (sata->valid & CTS_SATA_VALID_REVISION)
1062 printf("SATA %d.x, ", sata->revision);
1065 if (sata->valid & CTS_SATA_VALID_MODE)
1066 printf("%s, ", ata_mode2string(sata->mode));
1067 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1068 printf("ATAPI %dbytes, ", sata->atapi);
1069 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1070 printf("PIO %dbytes", sata->bytecount);
1074 if (ccb->cts.protocol == PROTO_SCSI) {
1075 struct ccb_trans_settings_scsi *scsi =
1076 &ccb->cts.proto_specific.scsi;
1077 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1078 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1079 fprintf(stdout, ", Command Queueing Enabled");
1084 fprintf(stdout, "\n");
1094 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1096 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1097 ((u_int32_t)parm->lba_size_2 << 16);
1099 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1100 ((u_int64_t)parm->lba_size48_2 << 16) |
1101 ((u_int64_t)parm->lba_size48_3 << 32) |
1102 ((u_int64_t)parm->lba_size48_4 << 48);
1106 "Support Enabled Value\n");
1109 printf("Host Protected Area (HPA) ");
1110 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1111 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1112 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1115 printf("HPA - Security ");
1116 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1126 atacapprint(struct ata_params *parm)
1128 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1129 ((u_int32_t)parm->lba_size_2 << 16);
1131 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1132 ((u_int64_t)parm->lba_size48_2 << 16) |
1133 ((u_int64_t)parm->lba_size48_3 << 32) |
1134 ((u_int64_t)parm->lba_size48_4 << 48);
1137 printf("protocol ");
1138 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1139 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1140 if (parm->satacapabilities & ATA_SATA_GEN3)
1141 printf(" SATA 3.x\n");
1142 else if (parm->satacapabilities & ATA_SATA_GEN2)
1143 printf(" SATA 2.x\n");
1144 else if (parm->satacapabilities & ATA_SATA_GEN1)
1145 printf(" SATA 1.x\n");
1151 printf("device model %.40s\n", parm->model);
1152 printf("firmware revision %.8s\n", parm->revision);
1153 printf("serial number %.20s\n", parm->serial);
1154 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1155 printf("WWN %04x%04x%04x%04x\n",
1156 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1158 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1159 printf("media serial number %.30s\n",
1160 parm->media_serial);
1163 printf("cylinders %d\n", parm->cylinders);
1164 printf("heads %d\n", parm->heads);
1165 printf("sectors/track %d\n", parm->sectors);
1166 printf("sector size logical %u, physical %lu, offset %lu\n",
1167 ata_logical_sector_size(parm),
1168 (unsigned long)ata_physical_sector_size(parm),
1169 (unsigned long)ata_logical_sector_offset(parm));
1171 if (parm->config == ATA_PROTO_CFA ||
1172 (parm->support.command2 & ATA_SUPPORT_CFA))
1173 printf("CFA supported\n");
1175 printf("LBA%ssupported ",
1176 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1178 printf("%d sectors\n", lbasize);
1182 printf("LBA48%ssupported ",
1183 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1185 printf("%ju sectors\n", (uintmax_t)lbasize48);
1189 printf("PIO supported PIO");
1190 switch (ata_max_pmode(parm)) {
1206 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1207 printf(" w/o IORDY");
1210 printf("DMA%ssupported ",
1211 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1212 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1213 if (parm->mwdmamodes & 0xff) {
1215 if (parm->mwdmamodes & 0x04)
1217 else if (parm->mwdmamodes & 0x02)
1219 else if (parm->mwdmamodes & 0x01)
1223 if ((parm->atavalid & ATA_FLAG_88) &&
1224 (parm->udmamodes & 0xff)) {
1226 if (parm->udmamodes & 0x40)
1228 else if (parm->udmamodes & 0x20)
1230 else if (parm->udmamodes & 0x10)
1232 else if (parm->udmamodes & 0x08)
1234 else if (parm->udmamodes & 0x04)
1236 else if (parm->udmamodes & 0x02)
1238 else if (parm->udmamodes & 0x01)
1245 if (parm->media_rotation_rate == 1) {
1246 printf("media RPM non-rotating\n");
1247 } else if (parm->media_rotation_rate >= 0x0401 &&
1248 parm->media_rotation_rate <= 0xFFFE) {
1249 printf("media RPM %d\n",
1250 parm->media_rotation_rate);
1254 "Support Enabled Value Vendor\n");
1255 printf("read ahead %s %s\n",
1256 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1257 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1258 printf("write cache %s %s\n",
1259 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1260 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1261 printf("flush cache %s %s\n",
1262 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1263 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1264 printf("overlap %s\n",
1265 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1266 printf("Tagged Command Queuing (TCQ) %s %s",
1267 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1268 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1269 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1270 printf(" %d tags\n",
1271 ATA_QUEUE_LEN(parm->queue) + 1);
1274 printf("Native Command Queuing (NCQ) ");
1275 if (parm->satacapabilities != 0xffff &&
1276 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1277 printf("yes %d tags\n",
1278 ATA_QUEUE_LEN(parm->queue) + 1);
1281 printf("SMART %s %s\n",
1282 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1283 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1284 printf("microcode download %s %s\n",
1285 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1286 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1287 printf("security %s %s\n",
1288 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1289 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1290 printf("power management %s %s\n",
1291 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1292 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1293 printf("advanced power management %s %s",
1294 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1295 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1296 if (parm->support.command2 & ATA_SUPPORT_APM) {
1297 printf(" %d/0x%02X\n",
1298 parm->apm_value, parm->apm_value);
1301 printf("automatic acoustic management %s %s",
1302 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1303 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1304 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1305 printf(" %d/0x%02X %d/0x%02X\n",
1306 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1307 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1308 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1309 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1312 printf("media status notification %s %s\n",
1313 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1314 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1315 printf("power-up in Standby %s %s\n",
1316 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1317 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1318 printf("write-read-verify %s %s",
1319 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1320 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1321 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1322 printf(" %d/0x%x\n",
1323 parm->wrv_mode, parm->wrv_mode);
1326 printf("unload %s %s\n",
1327 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1328 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1329 printf("free-fall %s %s\n",
1330 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1331 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1332 printf("Data Set Management (DSM/TRIM) ");
1333 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1335 printf("DSM - max 512byte blocks ");
1336 if (parm->max_dsm_blocks == 0x00)
1337 printf("yes not specified\n");
1340 parm->max_dsm_blocks);
1342 printf("DSM - deterministic read ");
1343 if (parm->support3 & ATA_SUPPORT_DRAT) {
1344 if (parm->support3 & ATA_SUPPORT_RZAT)
1345 printf("yes zeroed\n");
1347 printf("yes any value\n");
1357 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1359 struct ata_pass_16 *ata_pass_16;
1360 struct ata_cmd ata_cmd;
1362 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1363 ata_cmd.command = ata_pass_16->command;
1364 ata_cmd.control = ata_pass_16->control;
1365 ata_cmd.features = ata_pass_16->features;
1367 if (arglist & CAM_ARG_VERBOSE) {
1368 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1369 ata_op_string(&ata_cmd),
1370 ccb->csio.ccb_h.timeout);
1373 /* Disable freezing the device queue */
1374 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1376 if (arglist & CAM_ARG_ERR_RECOVER)
1377 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1379 if (cam_send_ccb(device, ccb) < 0) {
1380 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1381 warn("error sending ATA %s via pass_16",
1382 ata_op_string(&ata_cmd));
1385 if (arglist & CAM_ARG_VERBOSE) {
1386 cam_error_print(device, ccb, CAM_ESF_ALL,
1387 CAM_EPF_ALL, stderr);
1393 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1394 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1395 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1396 warnx("ATA %s via pass_16 failed",
1397 ata_op_string(&ata_cmd));
1399 if (arglist & CAM_ARG_VERBOSE) {
1400 cam_error_print(device, ccb, CAM_ESF_ALL,
1401 CAM_EPF_ALL, stderr);
1412 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1414 if (arglist & CAM_ARG_VERBOSE) {
1415 warnx("sending ATA %s with timeout of %u msecs",
1416 ata_op_string(&(ccb->ataio.cmd)),
1417 ccb->ataio.ccb_h.timeout);
1420 /* Disable freezing the device queue */
1421 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1423 if (arglist & CAM_ARG_ERR_RECOVER)
1424 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1426 if (cam_send_ccb(device, ccb) < 0) {
1427 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1428 warn("error sending ATA %s",
1429 ata_op_string(&(ccb->ataio.cmd)));
1432 if (arglist & CAM_ARG_VERBOSE) {
1433 cam_error_print(device, ccb, CAM_ESF_ALL,
1434 CAM_EPF_ALL, stderr);
1440 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1441 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1442 warnx("ATA %s failed: %d",
1443 ata_op_string(&(ccb->ataio.cmd)), quiet);
1446 if (arglist & CAM_ARG_VERBOSE) {
1447 cam_error_print(device, ccb, CAM_ESF_ALL,
1448 CAM_EPF_ALL, stderr);
1458 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1459 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1460 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1461 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1462 u_int16_t dxfer_len, int timeout, int quiet)
1464 if (data_ptr != NULL) {
1465 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1466 AP_FLAG_TLEN_SECT_CNT;
1467 if (flags & CAM_DIR_OUT)
1468 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1470 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1472 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1475 bzero(&(&ccb->ccb_h)[1],
1476 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1478 scsi_ata_pass_16(&ccb->csio,
1492 /*sense_len*/SSD_FULL_SIZE,
1495 return scsi_cam_pass_16_send(device, ccb, quiet);
1499 ata_try_pass_16(struct cam_device *device)
1501 struct ccb_pathinq cpi;
1503 if (get_cpi(device, &cpi) != 0) {
1504 warnx("couldn't get CPI");
1508 if (cpi.protocol == PROTO_SCSI) {
1509 /* possibly compatible with pass_16 */
1513 /* likely not compatible with pass_16 */
1518 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1519 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1520 u_int8_t command, u_int8_t features, u_int32_t lba,
1521 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1522 int timeout, int quiet)
1526 switch (ata_try_pass_16(device)) {
1530 /* Try using SCSI Passthrough */
1531 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1532 0, tag_action, command, features, lba,
1533 sector_count, data_ptr, dxfer_len,
1537 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1538 sizeof(struct ccb_hdr));
1539 cam_fill_ataio(&ccb->ataio,
1548 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1549 return ata_cam_send(device, ccb, quiet);
1553 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1554 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1555 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1556 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1557 u_int16_t dxfer_len, int timeout, int force48bit)
1561 retval = ata_try_pass_16(device);
1568 /* Try using SCSI Passthrough */
1569 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1570 ata_flags, tag_action, command, features,
1571 lba, sector_count, data_ptr, dxfer_len,
1574 if (ata_flags & AP_FLAG_CHK_COND) {
1575 /* Decode ata_res from sense data */
1576 struct ata_res_pass16 *res_pass16;
1577 struct ata_res *res;
1581 /* sense_data is 4 byte aligned */
1582 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1583 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1584 ptr[i] = le16toh(ptr[i]);
1586 /* sense_data is 4 byte aligned */
1587 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1588 &ccb->csio.sense_data;
1589 res = &ccb->ataio.res;
1590 res->flags = res_pass16->flags;
1591 res->status = res_pass16->status;
1592 res->error = res_pass16->error;
1593 res->lba_low = res_pass16->lba_low;
1594 res->lba_mid = res_pass16->lba_mid;
1595 res->lba_high = res_pass16->lba_high;
1596 res->device = res_pass16->device;
1597 res->lba_low_exp = res_pass16->lba_low_exp;
1598 res->lba_mid_exp = res_pass16->lba_mid_exp;
1599 res->lba_high_exp = res_pass16->lba_high_exp;
1600 res->sector_count = res_pass16->sector_count;
1601 res->sector_count_exp = res_pass16->sector_count_exp;
1607 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1608 sizeof(struct ccb_hdr));
1609 cam_fill_ataio(&ccb->ataio,
1618 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1619 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1621 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1623 if (ata_flags & AP_FLAG_CHK_COND)
1624 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1626 return ata_cam_send(device, ccb, 0);
1630 dump_data(uint16_t *ptr, uint32_t len)
1634 for (i = 0; i < len / 2; i++) {
1636 printf(" %3d: ", i);
1637 printf("%04hx ", ptr[i]);
1646 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1647 int is48bit, u_int64_t *hpasize)
1649 struct ata_res *res;
1651 res = &ccb->ataio.res;
1652 if (res->status & ATA_STATUS_ERROR) {
1653 if (arglist & CAM_ARG_VERBOSE) {
1654 cam_error_print(device, ccb, CAM_ESF_ALL,
1655 CAM_EPF_ALL, stderr);
1656 printf("error = 0x%02x, sector_count = 0x%04x, "
1657 "device = 0x%02x, status = 0x%02x\n",
1658 res->error, res->sector_count,
1659 res->device, res->status);
1662 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1663 warnx("Max address has already been set since "
1664 "last power-on or hardware reset");
1670 if (arglist & CAM_ARG_VERBOSE) {
1671 fprintf(stdout, "%s%d: Raw native max data:\n",
1672 device->device_name, device->dev_unit_num);
1673 /* res is 4 byte aligned */
1674 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1676 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1677 "status = 0x%02x\n", res->error, res->sector_count,
1678 res->device, res->status);
1681 if (hpasize != NULL) {
1683 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1684 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1685 ((res->lba_high << 16) | (res->lba_mid << 8) |
1688 *hpasize = (((res->device & 0x0f) << 24) |
1689 (res->lba_high << 16) | (res->lba_mid << 8) |
1698 ata_read_native_max(struct cam_device *device, int retry_count,
1699 u_int32_t timeout, union ccb *ccb,
1700 struct ata_params *parm, u_int64_t *hpasize)
1706 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1707 protocol = AP_PROTO_NON_DATA;
1710 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1711 protocol |= AP_EXTEND;
1713 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1716 error = ata_do_cmd(device,
1719 /*flags*/CAM_DIR_NONE,
1720 /*protocol*/protocol,
1721 /*ata_flags*/AP_FLAG_CHK_COND,
1722 /*tag_action*/MSG_SIMPLE_Q_TAG,
1729 timeout ? timeout : 1000,
1735 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1739 atahpa_set_max(struct cam_device *device, int retry_count,
1740 u_int32_t timeout, union ccb *ccb,
1741 int is48bit, u_int64_t maxsize, int persist)
1747 protocol = AP_PROTO_NON_DATA;
1750 cmd = ATA_SET_MAX_ADDRESS48;
1751 protocol |= AP_EXTEND;
1753 cmd = ATA_SET_MAX_ADDRESS;
1756 /* lba's are zero indexed so the max lba is requested max - 1 */
1760 error = ata_do_cmd(device,
1763 /*flags*/CAM_DIR_NONE,
1764 /*protocol*/protocol,
1765 /*ata_flags*/AP_FLAG_CHK_COND,
1766 /*tag_action*/MSG_SIMPLE_Q_TAG,
1768 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1770 /*sector_count*/persist,
1773 timeout ? timeout : 1000,
1779 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1783 atahpa_password(struct cam_device *device, int retry_count,
1784 u_int32_t timeout, union ccb *ccb,
1785 int is48bit, struct ata_set_max_pwd *pwd)
1791 protocol = AP_PROTO_PIO_OUT;
1792 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1794 error = ata_do_cmd(device,
1797 /*flags*/CAM_DIR_OUT,
1798 /*protocol*/protocol,
1799 /*ata_flags*/AP_FLAG_CHK_COND,
1800 /*tag_action*/MSG_SIMPLE_Q_TAG,
1802 /*features*/ATA_HPA_FEAT_SET_PWD,
1805 /*data_ptr*/(u_int8_t*)pwd,
1806 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1807 timeout ? timeout : 1000,
1813 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1817 atahpa_lock(struct cam_device *device, int retry_count,
1818 u_int32_t timeout, union ccb *ccb, int is48bit)
1824 protocol = AP_PROTO_NON_DATA;
1825 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1827 error = ata_do_cmd(device,
1830 /*flags*/CAM_DIR_NONE,
1831 /*protocol*/protocol,
1832 /*ata_flags*/AP_FLAG_CHK_COND,
1833 /*tag_action*/MSG_SIMPLE_Q_TAG,
1835 /*features*/ATA_HPA_FEAT_LOCK,
1840 timeout ? timeout : 1000,
1846 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1850 atahpa_unlock(struct cam_device *device, int retry_count,
1851 u_int32_t timeout, union ccb *ccb,
1852 int is48bit, struct ata_set_max_pwd *pwd)
1858 protocol = AP_PROTO_PIO_OUT;
1859 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1861 error = ata_do_cmd(device,
1864 /*flags*/CAM_DIR_OUT,
1865 /*protocol*/protocol,
1866 /*ata_flags*/AP_FLAG_CHK_COND,
1867 /*tag_action*/MSG_SIMPLE_Q_TAG,
1869 /*features*/ATA_HPA_FEAT_UNLOCK,
1872 /*data_ptr*/(u_int8_t*)pwd,
1873 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1874 timeout ? timeout : 1000,
1880 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1884 atahpa_freeze_lock(struct cam_device *device, int retry_count,
1885 u_int32_t timeout, union ccb *ccb, int is48bit)
1891 protocol = AP_PROTO_NON_DATA;
1892 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1894 error = ata_do_cmd(device,
1897 /*flags*/CAM_DIR_NONE,
1898 /*protocol*/protocol,
1899 /*ata_flags*/AP_FLAG_CHK_COND,
1900 /*tag_action*/MSG_SIMPLE_Q_TAG,
1902 /*features*/ATA_HPA_FEAT_FREEZE,
1907 timeout ? timeout : 1000,
1913 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1918 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
1919 union ccb *ccb, struct ata_params** ident_bufp)
1921 struct ata_params *ident_buf;
1922 struct ccb_pathinq cpi;
1923 struct ccb_getdev cgd;
1926 u_int8_t command, retry_command;
1928 if (get_cpi(device, &cpi) != 0) {
1929 warnx("couldn't get CPI");
1933 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
1934 if (cpi.protocol == PROTO_ATA) {
1935 if (get_cgd(device, &cgd) != 0) {
1936 warnx("couldn't get CGD");
1940 command = (cgd.protocol == PROTO_ATA) ?
1941 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
1944 /* We don't know which for sure so try both */
1945 command = ATA_ATA_IDENTIFY;
1946 retry_command = ATA_ATAPI_IDENTIFY;
1949 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
1951 warnx("can't calloc memory for identify\n");
1955 error = ata_do_28bit_cmd(device,
1957 /*retries*/retry_count,
1958 /*flags*/CAM_DIR_IN,
1959 /*protocol*/AP_PROTO_PIO_IN,
1960 /*tag_action*/MSG_SIMPLE_Q_TAG,
1964 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
1965 /*data_ptr*/(u_int8_t *)ptr,
1966 /*dxfer_len*/sizeof(struct ata_params),
1967 /*timeout*/timeout ? timeout : 30 * 1000,
1971 if (retry_command == 0) {
1975 error = ata_do_28bit_cmd(device,
1977 /*retries*/retry_count,
1978 /*flags*/CAM_DIR_IN,
1979 /*protocol*/AP_PROTO_PIO_IN,
1980 /*tag_action*/MSG_SIMPLE_Q_TAG,
1981 /*command*/retry_command,
1984 /*sector_count*/(u_int8_t)
1985 sizeof(struct ata_params),
1986 /*data_ptr*/(u_int8_t *)ptr,
1987 /*dxfer_len*/sizeof(struct ata_params),
1988 /*timeout*/timeout ? timeout : 30 * 1000,
1998 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
1999 ptr[i] = le16toh(ptr[i]);
2004 if (arglist & CAM_ARG_VERBOSE) {
2005 fprintf(stdout, "%s%d: Raw identify data:\n",
2006 device->device_name, device->dev_unit_num);
2007 dump_data(ptr, sizeof(struct ata_params));
2010 /* check for invalid (all zero) response */
2012 warnx("Invalid identify response detected");
2017 ident_buf = (struct ata_params *)ptr;
2018 if (strncmp(ident_buf->model, "FX", 2) &&
2019 strncmp(ident_buf->model, "NEC", 3) &&
2020 strncmp(ident_buf->model, "Pioneer", 7) &&
2021 strncmp(ident_buf->model, "SHARP", 5)) {
2022 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2023 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2024 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2025 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2027 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2028 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2029 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2030 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2031 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2032 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2033 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2034 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2035 sizeof(ident_buf->media_serial));
2037 *ident_bufp = ident_buf;
2044 ataidentify(struct cam_device *device, int retry_count, int timeout)
2047 struct ata_params *ident_buf;
2050 if ((ccb = cam_getccb(device)) == NULL) {
2051 warnx("couldn't allocate CCB");
2055 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2060 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2061 if (ata_read_native_max(device, retry_count, timeout, ccb,
2062 ident_buf, &hpasize) != 0) {
2070 printf("%s%d: ", device->device_name, device->dev_unit_num);
2071 ata_print_ident(ident_buf);
2072 camxferrate(device);
2073 atacapprint(ident_buf);
2074 atahpa_print(ident_buf, hpasize, 0);
2081 #endif /* MINIMALISTIC */
2084 #ifndef MINIMALISTIC
2086 ATA_SECURITY_ACTION_PRINT,
2087 ATA_SECURITY_ACTION_FREEZE,
2088 ATA_SECURITY_ACTION_UNLOCK,
2089 ATA_SECURITY_ACTION_DISABLE,
2090 ATA_SECURITY_ACTION_ERASE,
2091 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2092 ATA_SECURITY_ACTION_SET_PASSWORD
2093 } atasecurity_action;
2096 atasecurity_print_time(u_int16_t tw)
2100 printf("unspecified");
2102 printf("> 508 min");
2104 printf("%i min", 2 * tw);
2108 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2112 return 2 * 3600 * 1000; /* default: two hours */
2113 else if (timeout > 255)
2114 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2116 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2121 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2125 bzero(&cmd, sizeof(cmd));
2126 cmd.command = command;
2127 printf("Issuing %s", ata_op_string(&cmd));
2130 char pass[sizeof(pwd->password)+1];
2132 /* pwd->password may not be null terminated */
2133 pass[sizeof(pwd->password)] = '\0';
2134 strncpy(pass, pwd->password, sizeof(pwd->password));
2135 printf(" password='%s', user='%s'",
2137 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2140 if (command == ATA_SECURITY_SET_PASSWORD) {
2141 printf(", mode='%s'",
2142 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2143 "maximum" : "high");
2151 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2152 int retry_count, u_int32_t timeout, int quiet)
2156 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2158 return ata_do_28bit_cmd(device,
2161 /*flags*/CAM_DIR_NONE,
2162 /*protocol*/AP_PROTO_NON_DATA,
2163 /*tag_action*/MSG_SIMPLE_Q_TAG,
2164 /*command*/ATA_SECURITY_FREEZE_LOCK,
2175 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2176 int retry_count, u_int32_t timeout,
2177 struct ata_security_password *pwd, int quiet)
2181 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2183 return ata_do_28bit_cmd(device,
2186 /*flags*/CAM_DIR_OUT,
2187 /*protocol*/AP_PROTO_PIO_OUT,
2188 /*tag_action*/MSG_SIMPLE_Q_TAG,
2189 /*command*/ATA_SECURITY_UNLOCK,
2193 /*data_ptr*/(u_int8_t *)pwd,
2194 /*dxfer_len*/sizeof(*pwd),
2200 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2201 int retry_count, u_int32_t timeout,
2202 struct ata_security_password *pwd, int quiet)
2206 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2207 return ata_do_28bit_cmd(device,
2210 /*flags*/CAM_DIR_OUT,
2211 /*protocol*/AP_PROTO_PIO_OUT,
2212 /*tag_action*/MSG_SIMPLE_Q_TAG,
2213 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2217 /*data_ptr*/(u_int8_t *)pwd,
2218 /*dxfer_len*/sizeof(*pwd),
2225 atasecurity_erase_confirm(struct cam_device *device,
2226 struct ata_params* ident_buf)
2229 printf("\nYou are about to ERASE ALL DATA from the following"
2230 " device:\n%s%d,%s%d: ", device->device_name,
2231 device->dev_unit_num, device->given_dev_name,
2232 device->given_unit_number);
2233 ata_print_ident(ident_buf);
2237 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2239 if (fgets(str, sizeof(str), stdin) != NULL) {
2240 if (strncasecmp(str, "yes", 3) == 0) {
2242 } else if (strncasecmp(str, "no", 2) == 0) {
2245 printf("Please answer \"yes\" or "
2256 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2257 int retry_count, u_int32_t timeout,
2258 u_int32_t erase_timeout,
2259 struct ata_security_password *pwd, int quiet)
2264 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2266 error = ata_do_28bit_cmd(device,
2269 /*flags*/CAM_DIR_NONE,
2270 /*protocol*/AP_PROTO_NON_DATA,
2271 /*tag_action*/MSG_SIMPLE_Q_TAG,
2272 /*command*/ATA_SECURITY_ERASE_PREPARE,
2285 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2287 error = ata_do_28bit_cmd(device,
2290 /*flags*/CAM_DIR_OUT,
2291 /*protocol*/AP_PROTO_PIO_OUT,
2292 /*tag_action*/MSG_SIMPLE_Q_TAG,
2293 /*command*/ATA_SECURITY_ERASE_UNIT,
2297 /*data_ptr*/(u_int8_t *)pwd,
2298 /*dxfer_len*/sizeof(*pwd),
2299 /*timeout*/erase_timeout,
2302 if (error == 0 && quiet == 0)
2303 printf("\nErase Complete\n");
2309 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2310 int retry_count, u_int32_t timeout,
2311 struct ata_security_password *pwd, int quiet)
2315 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2317 return ata_do_28bit_cmd(device,
2320 /*flags*/CAM_DIR_OUT,
2321 /*protocol*/AP_PROTO_PIO_OUT,
2322 /*tag_action*/MSG_SIMPLE_Q_TAG,
2323 /*command*/ATA_SECURITY_SET_PASSWORD,
2327 /*data_ptr*/(u_int8_t *)pwd,
2328 /*dxfer_len*/sizeof(*pwd),
2334 atasecurity_print(struct ata_params *parm)
2337 printf("\nSecurity Option Value\n");
2338 if (arglist & CAM_ARG_VERBOSE) {
2339 printf("status %04x\n",
2340 parm->security_status);
2342 printf("supported %s\n",
2343 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2344 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2346 printf("enabled %s\n",
2347 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2348 printf("drive locked %s\n",
2349 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2350 printf("security config frozen %s\n",
2351 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2352 printf("count expired %s\n",
2353 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2354 printf("security level %s\n",
2355 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2356 printf("enhanced erase supported %s\n",
2357 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2358 printf("erase time ");
2359 atasecurity_print_time(parm->erase_time);
2361 printf("enhanced erase time ");
2362 atasecurity_print_time(parm->enhanced_erase_time);
2364 printf("master password rev %04x%s\n",
2365 parm->master_passwd_revision,
2366 parm->master_passwd_revision == 0x0000 ||
2367 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2371 * Validates and copies the password in optarg to the passed buffer.
2372 * If the password in optarg is the same length as the buffer then
2373 * the data will still be copied but no null termination will occur.
2376 ata_getpwd(u_int8_t *passwd, int max, char opt)
2380 len = strlen(optarg);
2382 warnx("-%c password is too long", opt);
2384 } else if (len == 0) {
2385 warnx("-%c password is missing", opt);
2387 } else if (optarg[0] == '-'){
2388 warnx("-%c password starts with '-' (generic arg?)", opt);
2390 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2391 warnx("-%c password conflicts with existing password from -%c",
2396 /* Callers pass in a buffer which does NOT need to be terminated */
2397 strncpy(passwd, optarg, max);
2404 ATA_HPA_ACTION_PRINT,
2405 ATA_HPA_ACTION_SET_MAX,
2406 ATA_HPA_ACTION_SET_PWD,
2407 ATA_HPA_ACTION_LOCK,
2408 ATA_HPA_ACTION_UNLOCK,
2409 ATA_HPA_ACTION_FREEZE_LOCK
2413 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2414 u_int64_t maxsize, int persist)
2416 printf("\nYou are about to configure HPA to limit the user accessible\n"
2417 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2418 persist ? "persistently" : "temporarily",
2419 device->device_name, device->dev_unit_num,
2420 device->given_dev_name, device->given_unit_number);
2421 ata_print_ident(ident_buf);
2425 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2427 if (NULL != fgets(str, sizeof(str), stdin)) {
2428 if (0 == strncasecmp(str, "yes", 3)) {
2430 } else if (0 == strncasecmp(str, "no", 2)) {
2433 printf("Please answer \"yes\" or "
2444 atahpa(struct cam_device *device, int retry_count, int timeout,
2445 int argc, char **argv, char *combinedopt)
2448 struct ata_params *ident_buf;
2449 struct ccb_getdev cgd;
2450 struct ata_set_max_pwd pwd;
2451 int error, confirm, quiet, c, action, actions, setpwd, persist;
2452 int security, is48bit, pwdsize;
2453 u_int64_t hpasize, maxsize;
2463 memset(&pwd, 0, sizeof(pwd));
2465 /* default action is to print hpa information */
2466 action = ATA_HPA_ACTION_PRINT;
2467 pwdsize = sizeof(pwd.password);
2469 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2472 action = ATA_HPA_ACTION_SET_MAX;
2473 maxsize = strtoumax(optarg, NULL, 0);
2478 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2480 action = ATA_HPA_ACTION_SET_PWD;
2486 action = ATA_HPA_ACTION_LOCK;
2492 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2494 action = ATA_HPA_ACTION_UNLOCK;
2500 action = ATA_HPA_ACTION_FREEZE_LOCK;
2520 warnx("too many hpa actions specified");
2524 if (get_cgd(device, &cgd) != 0) {
2525 warnx("couldn't get CGD");
2529 ccb = cam_getccb(device);
2531 warnx("couldn't allocate CCB");
2535 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2542 printf("%s%d: ", device->device_name, device->dev_unit_num);
2543 ata_print_ident(ident_buf);
2544 camxferrate(device);
2547 if (action == ATA_HPA_ACTION_PRINT) {
2548 error = ata_read_native_max(device, retry_count, timeout, ccb,
2549 ident_buf, &hpasize);
2551 atahpa_print(ident_buf, hpasize, 1);
2558 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2559 warnx("HPA is not supported by this device");
2565 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2566 warnx("HPA Security is not supported by this device");
2572 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2575 * The ATA spec requires:
2576 * 1. Read native max addr is called directly before set max addr
2577 * 2. Read native max addr is NOT called before any other set max call
2580 case ATA_HPA_ACTION_SET_MAX:
2582 atahpa_set_confirm(device, ident_buf, maxsize,
2589 error = ata_read_native_max(device, retry_count, timeout,
2590 ccb, ident_buf, &hpasize);
2592 error = atahpa_set_max(device, retry_count, timeout,
2593 ccb, is48bit, maxsize, persist);
2595 /* redo identify to get new lba values */
2596 error = ata_do_identify(device, retry_count,
2599 atahpa_print(ident_buf, hpasize, 1);
2604 case ATA_HPA_ACTION_SET_PWD:
2605 error = atahpa_password(device, retry_count, timeout,
2606 ccb, is48bit, &pwd);
2608 printf("HPA password has been set\n");
2611 case ATA_HPA_ACTION_LOCK:
2612 error = atahpa_lock(device, retry_count, timeout,
2615 printf("HPA has been locked\n");
2618 case ATA_HPA_ACTION_UNLOCK:
2619 error = atahpa_unlock(device, retry_count, timeout,
2620 ccb, is48bit, &pwd);
2622 printf("HPA has been unlocked\n");
2625 case ATA_HPA_ACTION_FREEZE_LOCK:
2626 error = atahpa_freeze_lock(device, retry_count, timeout,
2629 printf("HPA has been frozen\n");
2633 errx(1, "Option currently not supported");
2643 atasecurity(struct cam_device *device, int retry_count, int timeout,
2644 int argc, char **argv, char *combinedopt)
2647 struct ata_params *ident_buf;
2648 int error, confirm, quiet, c, action, actions, setpwd;
2649 int security_enabled, erase_timeout, pwdsize;
2650 struct ata_security_password pwd;
2658 memset(&pwd, 0, sizeof(pwd));
2660 /* default action is to print security information */
2661 action = ATA_SECURITY_ACTION_PRINT;
2663 /* user is master by default as its safer that way */
2664 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2665 pwdsize = sizeof(pwd.password);
2667 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2670 action = ATA_SECURITY_ACTION_FREEZE;
2675 if (strcasecmp(optarg, "user") == 0) {
2676 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2677 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2678 } else if (strcasecmp(optarg, "master") == 0) {
2679 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2680 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2682 warnx("-U argument '%s' is invalid (must be "
2683 "'user' or 'master')", optarg);
2689 if (strcasecmp(optarg, "high") == 0) {
2690 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2691 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2692 } else if (strcasecmp(optarg, "maximum") == 0) {
2693 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2694 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2696 warnx("-l argument '%s' is unknown (must be "
2697 "'high' or 'maximum')", optarg);
2703 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2705 action = ATA_SECURITY_ACTION_UNLOCK;
2710 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2712 action = ATA_SECURITY_ACTION_DISABLE;
2717 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2719 action = ATA_SECURITY_ACTION_ERASE;
2724 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2726 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2727 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2732 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2735 if (action == ATA_SECURITY_ACTION_PRINT)
2736 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2738 * Don't increment action as this can be combined
2739 * with other actions.
2752 erase_timeout = atoi(optarg) * 1000;
2758 warnx("too many security actions specified");
2762 if ((ccb = cam_getccb(device)) == NULL) {
2763 warnx("couldn't allocate CCB");
2767 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2774 printf("%s%d: ", device->device_name, device->dev_unit_num);
2775 ata_print_ident(ident_buf);
2776 camxferrate(device);
2779 if (action == ATA_SECURITY_ACTION_PRINT) {
2780 atasecurity_print(ident_buf);
2786 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2787 warnx("Security not supported");
2793 /* default timeout 15 seconds the same as linux hdparm */
2794 timeout = timeout ? timeout : 15 * 1000;
2796 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2798 /* first set the password if requested */
2800 /* confirm we can erase before setting the password if erasing */
2802 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2803 action == ATA_SECURITY_ACTION_ERASE) &&
2804 atasecurity_erase_confirm(device, ident_buf) == 0) {
2810 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2811 pwd.revision = ident_buf->master_passwd_revision;
2812 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2813 --pwd.revision == 0) {
2814 pwd.revision = 0xfffe;
2817 error = atasecurity_set_password(device, ccb, retry_count,
2818 timeout, &pwd, quiet);
2824 security_enabled = 1;
2828 case ATA_SECURITY_ACTION_FREEZE:
2829 error = atasecurity_freeze(device, ccb, retry_count,
2833 case ATA_SECURITY_ACTION_UNLOCK:
2834 if (security_enabled) {
2835 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2836 error = atasecurity_unlock(device, ccb,
2837 retry_count, timeout, &pwd, quiet);
2839 warnx("Can't unlock, drive is not locked");
2843 warnx("Can't unlock, security is disabled");
2848 case ATA_SECURITY_ACTION_DISABLE:
2849 if (security_enabled) {
2850 /* First unlock the drive if its locked */
2851 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2852 error = atasecurity_unlock(device, ccb,
2860 error = atasecurity_disable(device,
2868 warnx("Can't disable security (already disabled)");
2873 case ATA_SECURITY_ACTION_ERASE:
2874 if (security_enabled) {
2875 if (erase_timeout == 0) {
2876 erase_timeout = atasecurity_erase_timeout_msecs(
2877 ident_buf->erase_time);
2880 error = atasecurity_erase(device, ccb, retry_count,
2881 timeout, erase_timeout, &pwd,
2884 warnx("Can't secure erase (security is disabled)");
2889 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
2890 if (security_enabled) {
2891 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
2892 if (erase_timeout == 0) {
2894 atasecurity_erase_timeout_msecs(
2895 ident_buf->enhanced_erase_time);
2898 error = atasecurity_erase(device, ccb,
2899 retry_count, timeout,
2900 erase_timeout, &pwd,
2903 warnx("Enhanced erase is not supported");
2907 warnx("Can't secure erase (enhanced), "
2908 "(security is disabled)");
2919 #endif /* MINIMALISTIC */
2922 * Parse out a bus, or a bus, target and lun in the following
2928 * Returns the number of parsed components, or 0.
2931 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
2936 while (isspace(*tstr) && (*tstr != '\0'))
2939 tmpstr = (char *)strtok(tstr, ":");
2940 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
2941 *bus = strtol(tmpstr, NULL, 0);
2942 *arglst |= CAM_ARG_BUS;
2944 tmpstr = (char *)strtok(NULL, ":");
2945 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
2946 *target = strtol(tmpstr, NULL, 0);
2947 *arglst |= CAM_ARG_TARGET;
2949 tmpstr = (char *)strtok(NULL, ":");
2950 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
2951 *lun = strtol(tmpstr, NULL, 0);
2952 *arglst |= CAM_ARG_LUN;
2962 dorescan_or_reset(int argc, char **argv, int rescan)
2964 static const char must[] =
2965 "you must specify \"all\", a bus, or a bus:target:lun to %s";
2967 int bus = -1, target = -1, lun = -1;
2971 warnx(must, rescan? "rescan" : "reset");
2975 tstr = argv[optind];
2976 while (isspace(*tstr) && (*tstr != '\0'))
2978 if (strncasecmp(tstr, "all", strlen("all")) == 0)
2979 arglist |= CAM_ARG_BUS;
2981 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
2982 if (rv != 1 && rv != 3) {
2983 warnx(must, rescan? "rescan" : "reset");
2988 if ((arglist & CAM_ARG_BUS)
2989 && (arglist & CAM_ARG_TARGET)
2990 && (arglist & CAM_ARG_LUN))
2991 error = scanlun_or_reset_dev(bus, target, lun, rescan);
2993 error = rescan_or_reset_bus(bus, rescan);
2999 rescan_or_reset_bus(int bus, int rescan)
3001 union ccb ccb, matchccb;
3007 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3008 warnx("error opening transport layer device %s", XPT_DEVICE);
3009 warn("%s", XPT_DEVICE);
3014 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3015 ccb.ccb_h.path_id = bus;
3016 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3017 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3018 ccb.crcn.flags = CAM_FLAG_NONE;
3020 /* run this at a low priority */
3021 ccb.ccb_h.pinfo.priority = 5;
3023 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3024 warn("CAMIOCOMMAND ioctl failed");
3029 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3030 fprintf(stdout, "%s of bus %d was successful\n",
3031 rescan ? "Re-scan" : "Reset", bus);
3033 fprintf(stdout, "%s of bus %d returned error %#x\n",
3034 rescan ? "Re-scan" : "Reset", bus,
3035 ccb.ccb_h.status & CAM_STATUS_MASK);
3046 * The right way to handle this is to modify the xpt so that it can
3047 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3048 * that isn't implemented, so instead we enumerate the busses and
3049 * send the rescan or reset to those busses in the case where the
3050 * given bus is -1 (wildcard). We don't send a rescan or reset
3051 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3052 * no-op, sending a rescan to the xpt bus would result in a status of
3055 bzero(&(&matchccb.ccb_h)[1],
3056 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
3057 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
3058 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
3059 bufsize = sizeof(struct dev_match_result) * 20;
3060 matchccb.cdm.match_buf_len = bufsize;
3061 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
3062 if (matchccb.cdm.matches == NULL) {
3063 warnx("can't malloc memory for matches");
3067 matchccb.cdm.num_matches = 0;
3069 matchccb.cdm.num_patterns = 1;
3070 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3072 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
3073 matchccb.cdm.pattern_buf_len);
3074 if (matchccb.cdm.patterns == NULL) {
3075 warnx("can't malloc memory for patterns");
3079 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
3080 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3085 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
3086 warn("CAMIOCOMMAND ioctl failed");
3091 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
3092 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
3093 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
3094 warnx("got CAM error %#x, CDM error %d\n",
3095 matchccb.ccb_h.status, matchccb.cdm.status);
3100 for (i = 0; i < matchccb.cdm.num_matches; i++) {
3101 struct bus_match_result *bus_result;
3103 /* This shouldn't happen. */
3104 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
3107 bus_result = &matchccb.cdm.matches[i].result.bus_result;
3110 * We don't want to rescan or reset the xpt bus.
3113 if ((int)bus_result->path_id == -1)
3116 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3118 ccb.ccb_h.path_id = bus_result->path_id;
3119 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
3120 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
3121 ccb.crcn.flags = CAM_FLAG_NONE;
3123 /* run this at a low priority */
3124 ccb.ccb_h.pinfo.priority = 5;
3126 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3127 warn("CAMIOCOMMAND ioctl failed");
3132 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
3133 fprintf(stdout, "%s of bus %d was successful\n",
3134 rescan? "Re-scan" : "Reset",
3135 bus_result->path_id);
3138 * Don't bail out just yet, maybe the other
3139 * rescan or reset commands will complete
3142 fprintf(stderr, "%s of bus %d returned error "
3143 "%#x\n", rescan? "Re-scan" : "Reset",
3144 bus_result->path_id,
3145 ccb.ccb_h.status & CAM_STATUS_MASK);
3149 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
3150 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
3157 if (matchccb.cdm.patterns != NULL)
3158 free(matchccb.cdm.patterns);
3159 if (matchccb.cdm.matches != NULL)
3160 free(matchccb.cdm.matches);
3166 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
3169 struct cam_device *device;
3175 warnx("invalid bus number %d", bus);
3180 warnx("invalid target number %d", target);
3185 warnx("invalid lun number %d", lun);
3191 bzero(&ccb, sizeof(union ccb));
3194 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3195 warnx("error opening transport layer device %s\n",
3197 warn("%s", XPT_DEVICE);
3201 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3202 if (device == NULL) {
3203 warnx("%s", cam_errbuf);
3208 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3209 ccb.ccb_h.path_id = bus;
3210 ccb.ccb_h.target_id = target;
3211 ccb.ccb_h.target_lun = lun;
3212 ccb.ccb_h.timeout = 5000;
3213 ccb.crcn.flags = CAM_FLAG_NONE;
3215 /* run this at a low priority */
3216 ccb.ccb_h.pinfo.priority = 5;
3219 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3220 warn("CAMIOCOMMAND ioctl failed");
3225 if (cam_send_ccb(device, &ccb) < 0) {
3226 warn("error sending XPT_RESET_DEV CCB");
3227 cam_close_device(device);
3235 cam_close_device(device);
3238 * An error code of CAM_BDR_SENT is normal for a BDR request.
3240 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3242 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3243 fprintf(stdout, "%s of %d:%d:%d was successful\n",
3244 scan? "Re-scan" : "Reset", bus, target, lun);
3247 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
3248 scan? "Re-scan" : "Reset", bus, target, lun,
3249 ccb.ccb_h.status & CAM_STATUS_MASK);
3254 #ifndef MINIMALISTIC
3256 readdefects(struct cam_device *device, int argc, char **argv,
3257 char *combinedopt, int retry_count, int timeout)
3259 union ccb *ccb = NULL;
3260 struct scsi_read_defect_data_10 *rdd_cdb;
3261 u_int8_t *defect_list = NULL;
3262 u_int32_t dlist_length = 65000;
3263 u_int32_t returned_length = 0;
3264 u_int32_t num_returned = 0;
3265 u_int8_t returned_format;
3268 int lists_specified = 0;
3270 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3276 while (isspace(*tstr) && (*tstr != '\0'))
3278 if (strcmp(tstr, "block") == 0)
3279 arglist |= CAM_ARG_FORMAT_BLOCK;
3280 else if (strcmp(tstr, "bfi") == 0)
3281 arglist |= CAM_ARG_FORMAT_BFI;
3282 else if (strcmp(tstr, "phys") == 0)
3283 arglist |= CAM_ARG_FORMAT_PHYS;
3286 warnx("invalid defect format %s", tstr);
3287 goto defect_bailout;
3292 arglist |= CAM_ARG_GLIST;
3295 arglist |= CAM_ARG_PLIST;
3302 ccb = cam_getccb(device);
3305 * Hopefully 65000 bytes is enough to hold the defect list. If it
3306 * isn't, the disk is probably dead already. We'd have to go with
3307 * 12 byte command (i.e. alloc_length is 32 bits instead of 16)
3310 defect_list = malloc(dlist_length);
3311 if (defect_list == NULL) {
3312 warnx("can't malloc memory for defect list");
3314 goto defect_bailout;
3317 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
3320 * cam_getccb() zeros the CCB header only. So we need to zero the
3321 * payload portion of the ccb.
3323 bzero(&(&ccb->ccb_h)[1],
3324 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3326 cam_fill_csio(&ccb->csio,
3327 /*retries*/ retry_count,
3329 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
3330 CAM_PASS_ERR_RECOVER : 0),
3331 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3332 /*data_ptr*/ defect_list,
3333 /*dxfer_len*/ dlist_length,
3334 /*sense_len*/ SSD_FULL_SIZE,
3335 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
3336 /*timeout*/ timeout ? timeout : 5000);
3338 rdd_cdb->opcode = READ_DEFECT_DATA_10;
3339 if (arglist & CAM_ARG_FORMAT_BLOCK)
3340 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
3341 else if (arglist & CAM_ARG_FORMAT_BFI)
3342 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
3343 else if (arglist & CAM_ARG_FORMAT_PHYS)
3344 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
3347 warnx("no defect list format specified");
3348 goto defect_bailout;
3350 if (arglist & CAM_ARG_PLIST) {
3351 rdd_cdb->format |= SRDD10_PLIST;
3355 if (arglist & CAM_ARG_GLIST) {
3356 rdd_cdb->format |= SRDD10_GLIST;
3360 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
3362 /* Disable freezing the device queue */
3363 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3365 if (cam_send_ccb(device, ccb) < 0) {
3366 perror("error reading defect list");
3368 if (arglist & CAM_ARG_VERBOSE) {
3369 cam_error_print(device, ccb, CAM_ESF_ALL,
3370 CAM_EPF_ALL, stderr);
3374 goto defect_bailout;
3377 returned_length = scsi_2btoul(((struct
3378 scsi_read_defect_data_hdr_10 *)defect_list)->length);
3380 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
3381 defect_list)->format;
3383 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3384 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3385 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3386 struct scsi_sense_data *sense;
3387 int error_code, sense_key, asc, ascq;
3389 sense = &ccb->csio.sense_data;
3390 scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq);
3393 * According to the SCSI spec, if the disk doesn't support
3394 * the requested format, it will generally return a sense
3395 * key of RECOVERED ERROR, and an additional sense code
3396 * of "DEFECT LIST NOT FOUND". So, we check for that, and
3397 * also check to make sure that the returned length is
3398 * greater than 0, and then print out whatever format the
3401 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3402 && (asc == 0x1c) && (ascq == 0x00)
3403 && (returned_length > 0)) {
3404 warnx("requested defect format not available");
3405 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
3406 case SRDD10_BLOCK_FORMAT:
3407 warnx("Device returned block format");
3409 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3410 warnx("Device returned bytes from index"
3413 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3414 warnx("Device returned physical sector format");
3418 warnx("Device returned unknown defect"
3419 " data format %#x", returned_format);
3420 goto defect_bailout;
3421 break; /* NOTREACHED */
3425 warnx("Error returned from read defect data command");
3426 if (arglist & CAM_ARG_VERBOSE)
3427 cam_error_print(device, ccb, CAM_ESF_ALL,
3428 CAM_EPF_ALL, stderr);
3429 goto defect_bailout;
3431 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3433 warnx("Error returned from read defect data command");
3434 if (arglist & CAM_ARG_VERBOSE)
3435 cam_error_print(device, ccb, CAM_ESF_ALL,
3436 CAM_EPF_ALL, stderr);
3437 goto defect_bailout;
3441 * XXX KDM I should probably clean up the printout format for the
3444 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
3445 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
3447 struct scsi_defect_desc_phys_sector *dlist;
3449 dlist = (struct scsi_defect_desc_phys_sector *)
3451 sizeof(struct scsi_read_defect_data_hdr_10));
3453 num_returned = returned_length /
3454 sizeof(struct scsi_defect_desc_phys_sector);
3456 fprintf(stderr, "Got %d defect", num_returned);
3458 if ((lists_specified == 0) || (num_returned == 0)) {
3459 fprintf(stderr, "s.\n");
3461 } else if (num_returned == 1)
3462 fprintf(stderr, ":\n");
3464 fprintf(stderr, "s:\n");
3466 for (i = 0; i < num_returned; i++) {
3467 fprintf(stdout, "%d:%d:%d\n",
3468 scsi_3btoul(dlist[i].cylinder),
3470 scsi_4btoul(dlist[i].sector));
3474 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
3476 struct scsi_defect_desc_bytes_from_index *dlist;
3478 dlist = (struct scsi_defect_desc_bytes_from_index *)
3480 sizeof(struct scsi_read_defect_data_hdr_10));
3482 num_returned = returned_length /
3483 sizeof(struct scsi_defect_desc_bytes_from_index);
3485 fprintf(stderr, "Got %d defect", num_returned);
3487 if ((lists_specified == 0) || (num_returned == 0)) {
3488 fprintf(stderr, "s.\n");
3490 } else if (num_returned == 1)
3491 fprintf(stderr, ":\n");
3493 fprintf(stderr, "s:\n");
3495 for (i = 0; i < num_returned; i++) {
3496 fprintf(stdout, "%d:%d:%d\n",
3497 scsi_3btoul(dlist[i].cylinder),
3499 scsi_4btoul(dlist[i].bytes_from_index));
3503 case SRDDH10_BLOCK_FORMAT:
3505 struct scsi_defect_desc_block *dlist;
3507 dlist = (struct scsi_defect_desc_block *)(defect_list +
3508 sizeof(struct scsi_read_defect_data_hdr_10));
3510 num_returned = returned_length /
3511 sizeof(struct scsi_defect_desc_block);
3513 fprintf(stderr, "Got %d defect", num_returned);
3515 if ((lists_specified == 0) || (num_returned == 0)) {
3516 fprintf(stderr, "s.\n");
3518 } else if (num_returned == 1)
3519 fprintf(stderr, ":\n");
3521 fprintf(stderr, "s:\n");
3523 for (i = 0; i < num_returned; i++)
3524 fprintf(stdout, "%u\n",
3525 scsi_4btoul(dlist[i].address));
3529 fprintf(stderr, "Unknown defect format %d\n",
3530 returned_format & SRDDH10_DLIST_FORMAT_MASK);
3536 if (defect_list != NULL)
3544 #endif /* MINIMALISTIC */
3548 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3552 ccb = cam_getccb(device);
3558 #ifndef MINIMALISTIC
3560 mode_sense(struct cam_device *device, int mode_page, int page_control,
3561 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3566 ccb = cam_getccb(device);
3569 errx(1, "mode_sense: couldn't allocate CCB");
3571 bzero(&(&ccb->ccb_h)[1],
3572 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3574 scsi_mode_sense(&ccb->csio,
3575 /* retries */ retry_count,
3577 /* tag_action */ MSG_SIMPLE_Q_TAG,
3579 /* page_code */ page_control << 6,
3580 /* page */ mode_page,
3581 /* param_buf */ data,
3582 /* param_len */ datalen,
3583 /* sense_len */ SSD_FULL_SIZE,
3584 /* timeout */ timeout ? timeout : 5000);
3586 if (arglist & CAM_ARG_ERR_RECOVER)
3587 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3589 /* Disable freezing the device queue */
3590 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3592 if (((retval = cam_send_ccb(device, ccb)) < 0)
3593 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3594 if (arglist & CAM_ARG_VERBOSE) {
3595 cam_error_print(device, ccb, CAM_ESF_ALL,
3596 CAM_EPF_ALL, stderr);
3599 cam_close_device(device);
3601 err(1, "error sending mode sense command");
3603 errx(1, "error sending mode sense command");
3610 mode_select(struct cam_device *device, int save_pages, int retry_count,
3611 int timeout, u_int8_t *data, int datalen)
3616 ccb = cam_getccb(device);
3619 errx(1, "mode_select: couldn't allocate CCB");
3621 bzero(&(&ccb->ccb_h)[1],
3622 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3624 scsi_mode_select(&ccb->csio,
3625 /* retries */ retry_count,
3627 /* tag_action */ MSG_SIMPLE_Q_TAG,
3628 /* scsi_page_fmt */ 1,
3629 /* save_pages */ save_pages,
3630 /* param_buf */ data,
3631 /* param_len */ datalen,
3632 /* sense_len */ SSD_FULL_SIZE,
3633 /* timeout */ timeout ? timeout : 5000);
3635 if (arglist & CAM_ARG_ERR_RECOVER)
3636 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3638 /* Disable freezing the device queue */
3639 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3641 if (((retval = cam_send_ccb(device, ccb)) < 0)
3642 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3643 if (arglist & CAM_ARG_VERBOSE) {
3644 cam_error_print(device, ccb, CAM_ESF_ALL,
3645 CAM_EPF_ALL, stderr);
3648 cam_close_device(device);
3651 err(1, "error sending mode select command");
3653 errx(1, "error sending mode select command");
3661 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
3662 int retry_count, int timeout)
3664 int c, mode_page = -1, page_control = 0;
3665 int binary = 0, list = 0;
3667 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3673 arglist |= CAM_ARG_DBD;
3676 arglist |= CAM_ARG_MODE_EDIT;
3682 mode_page = strtol(optarg, NULL, 0);
3684 errx(1, "invalid mode page %d", mode_page);
3687 page_control = strtol(optarg, NULL, 0);
3688 if ((page_control < 0) || (page_control > 3))
3689 errx(1, "invalid page control field %d",
3691 arglist |= CAM_ARG_PAGE_CNTL;
3698 if (mode_page == -1 && list == 0)
3699 errx(1, "you must specify a mode page!");
3702 mode_list(device, page_control, arglist & CAM_ARG_DBD,
3703 retry_count, timeout);
3705 mode_edit(device, mode_page, page_control,
3706 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
3707 retry_count, timeout);
3712 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
3713 int retry_count, int timeout)
3716 u_int32_t flags = CAM_DIR_NONE;
3717 u_int8_t *data_ptr = NULL;
3719 u_int8_t atacmd[12];
3720 struct get_hook hook;
3721 int c, data_bytes = 0;
3727 char *datastr = NULL, *tstr, *resstr = NULL;
3729 int fd_data = 0, fd_res = 0;
3732 ccb = cam_getccb(device);
3735 warnx("scsicmd: error allocating ccb");
3739 bzero(&(&ccb->ccb_h)[1],
3740 sizeof(union ccb) - sizeof(struct ccb_hdr));
3742 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3746 while (isspace(*tstr) && (*tstr != '\0'))
3748 hook.argc = argc - optind;
3749 hook.argv = argv + optind;
3751 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
3754 * Increment optind by the number of arguments the
3755 * encoding routine processed. After each call to
3756 * getopt(3), optind points to the argument that
3757 * getopt should process _next_. In this case,
3758 * that means it points to the first command string
3759 * argument, if there is one. Once we increment
3760 * this, it should point to either the next command
3761 * line argument, or it should be past the end of
3768 while (isspace(*tstr) && (*tstr != '\0'))
3770 hook.argc = argc - optind;
3771 hook.argv = argv + optind;
3773 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
3776 * Increment optind by the number of arguments the
3777 * encoding routine processed. After each call to
3778 * getopt(3), optind points to the argument that
3779 * getopt should process _next_. In this case,
3780 * that means it points to the first command string
3781 * argument, if there is one. Once we increment
3782 * this, it should point to either the next command
3783 * line argument, or it should be past the end of
3795 if (arglist & CAM_ARG_CMD_OUT) {
3796 warnx("command must either be "
3797 "read or write, not both");
3799 goto scsicmd_bailout;
3801 arglist |= CAM_ARG_CMD_IN;
3803 data_bytes = strtol(optarg, NULL, 0);
3804 if (data_bytes <= 0) {
3805 warnx("invalid number of input bytes %d",
3808 goto scsicmd_bailout;
3810 hook.argc = argc - optind;
3811 hook.argv = argv + optind;
3814 datastr = cget(&hook, NULL);
3816 * If the user supplied "-" instead of a format, he
3817 * wants the data to be written to stdout.
3819 if ((datastr != NULL)
3820 && (datastr[0] == '-'))
3823 data_ptr = (u_int8_t *)malloc(data_bytes);
3824 if (data_ptr == NULL) {
3825 warnx("can't malloc memory for data_ptr");
3827 goto scsicmd_bailout;
3831 if (arglist & CAM_ARG_CMD_IN) {
3832 warnx("command must either be "
3833 "read or write, not both");
3835 goto scsicmd_bailout;
3837 arglist |= CAM_ARG_CMD_OUT;
3838 flags = CAM_DIR_OUT;
3839 data_bytes = strtol(optarg, NULL, 0);
3840 if (data_bytes <= 0) {
3841 warnx("invalid number of output bytes %d",
3844 goto scsicmd_bailout;
3846 hook.argc = argc - optind;
3847 hook.argv = argv + optind;
3849 datastr = cget(&hook, NULL);
3850 data_ptr = (u_int8_t *)malloc(data_bytes);
3851 if (data_ptr == NULL) {
3852 warnx("can't malloc memory for data_ptr");
3854 goto scsicmd_bailout;
3856 bzero(data_ptr, data_bytes);
3858 * If the user supplied "-" instead of a format, he
3859 * wants the data to be read from stdin.
3861 if ((datastr != NULL)
3862 && (datastr[0] == '-'))
3865 buff_encode_visit(data_ptr, data_bytes, datastr,
3871 hook.argc = argc - optind;
3872 hook.argv = argv + optind;
3874 resstr = cget(&hook, NULL);
3875 if ((resstr != NULL) && (resstr[0] == '-'))
3885 * If fd_data is set, and we're writing to the device, we need to
3886 * read the data the user wants written from stdin.
3888 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
3890 int amt_to_read = data_bytes;
3891 u_int8_t *buf_ptr = data_ptr;
3893 for (amt_read = 0; amt_to_read > 0;
3894 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
3895 if (amt_read == -1) {
3896 warn("error reading data from stdin");
3898 goto scsicmd_bailout;
3900 amt_to_read -= amt_read;
3901 buf_ptr += amt_read;
3905 if (arglist & CAM_ARG_ERR_RECOVER)
3906 flags |= CAM_PASS_ERR_RECOVER;
3908 /* Disable freezing the device queue */
3909 flags |= CAM_DEV_QFRZDIS;
3913 * This is taken from the SCSI-3 draft spec.
3914 * (T10/1157D revision 0.3)
3915 * The top 3 bits of an opcode are the group code.
3916 * The next 5 bits are the command code.
3917 * Group 0: six byte commands
3918 * Group 1: ten byte commands
3919 * Group 2: ten byte commands
3921 * Group 4: sixteen byte commands
3922 * Group 5: twelve byte commands
3923 * Group 6: vendor specific
3924 * Group 7: vendor specific
3926 switch((cdb[0] >> 5) & 0x7) {
3937 /* computed by buff_encode_visit */
3948 * We should probably use csio_build_visit or something like that
3949 * here, but it's easier to encode arguments as you go. The
3950 * alternative would be skipping the CDB argument and then encoding
3951 * it here, since we've got the data buffer argument by now.
3953 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
3955 cam_fill_csio(&ccb->csio,
3956 /*retries*/ retry_count,
3959 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3960 /*data_ptr*/ data_ptr,
3961 /*dxfer_len*/ data_bytes,
3962 /*sense_len*/ SSD_FULL_SIZE,
3963 /*cdb_len*/ cdb_len,
3964 /*timeout*/ timeout ? timeout : 5000);
3967 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
3969 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
3971 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
3973 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
3975 cam_fill_ataio(&ccb->ataio,
3976 /*retries*/ retry_count,
3980 /*data_ptr*/ data_ptr,
3981 /*dxfer_len*/ data_bytes,
3982 /*timeout*/ timeout ? timeout : 5000);
3985 if (((retval = cam_send_ccb(device, ccb)) < 0)
3986 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3988 warn("error sending command");
3990 warnx("error sending command");
3992 if (arglist & CAM_ARG_VERBOSE) {
3993 cam_error_print(device, ccb, CAM_ESF_ALL,
3994 CAM_EPF_ALL, stderr);
3998 goto scsicmd_bailout;
4001 if (atacmd_len && need_res) {
4003 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4005 fprintf(stdout, "\n");
4008 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4009 ccb->ataio.res.status,
4010 ccb->ataio.res.error,
4011 ccb->ataio.res.lba_low,
4012 ccb->ataio.res.lba_mid,
4013 ccb->ataio.res.lba_high,
4014 ccb->ataio.res.device,
4015 ccb->ataio.res.lba_low_exp,
4016 ccb->ataio.res.lba_mid_exp,
4017 ccb->ataio.res.lba_high_exp,
4018 ccb->ataio.res.sector_count,
4019 ccb->ataio.res.sector_count_exp);
4024 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4025 && (arglist & CAM_ARG_CMD_IN)
4026 && (data_bytes > 0)) {
4028 buff_decode_visit(data_ptr, data_bytes, datastr,
4030 fprintf(stdout, "\n");
4032 ssize_t amt_written;
4033 int amt_to_write = data_bytes;
4034 u_int8_t *buf_ptr = data_ptr;
4036 for (amt_written = 0; (amt_to_write > 0) &&
4037 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4038 amt_to_write -= amt_written;
4039 buf_ptr += amt_written;
4041 if (amt_written == -1) {
4042 warn("error writing data to stdout");
4044 goto scsicmd_bailout;
4045 } else if ((amt_written == 0)
4046 && (amt_to_write > 0)) {
4047 warnx("only wrote %u bytes out of %u",
4048 data_bytes - amt_to_write, data_bytes);
4055 if ((data_bytes > 0) && (data_ptr != NULL))
4064 camdebug(int argc, char **argv, char *combinedopt)
4067 int bus = -1, target = -1, lun = -1;
4068 char *tstr, *tmpstr = NULL;
4072 bzero(&ccb, sizeof(union ccb));
4074 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4077 arglist |= CAM_ARG_DEBUG_INFO;
4078 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4081 arglist |= CAM_ARG_DEBUG_PERIPH;
4082 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4085 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4086 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4089 arglist |= CAM_ARG_DEBUG_TRACE;
4090 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4093 arglist |= CAM_ARG_DEBUG_XPT;
4094 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4097 arglist |= CAM_ARG_DEBUG_CDB;
4098 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4101 arglist |= CAM_ARG_DEBUG_PROBE;
4102 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4109 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4110 warnx("error opening transport layer device %s", XPT_DEVICE);
4111 warn("%s", XPT_DEVICE);
4118 warnx("you must specify \"off\", \"all\" or a bus,");
4119 warnx("bus:target, or bus:target:lun");
4126 while (isspace(*tstr) && (*tstr != '\0'))
4129 if (strncmp(tstr, "off", 3) == 0) {
4130 ccb.cdbg.flags = CAM_DEBUG_NONE;
4131 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4132 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4133 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4134 } else if (strncmp(tstr, "all", 3) != 0) {
4135 tmpstr = (char *)strtok(tstr, ":");
4136 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4137 bus = strtol(tmpstr, NULL, 0);
4138 arglist |= CAM_ARG_BUS;
4139 tmpstr = (char *)strtok(NULL, ":");
4140 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4141 target = strtol(tmpstr, NULL, 0);
4142 arglist |= CAM_ARG_TARGET;
4143 tmpstr = (char *)strtok(NULL, ":");
4144 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4145 lun = strtol(tmpstr, NULL, 0);
4146 arglist |= CAM_ARG_LUN;
4151 warnx("you must specify \"all\", \"off\", or a bus,");
4152 warnx("bus:target, or bus:target:lun to debug");
4158 ccb.ccb_h.func_code = XPT_DEBUG;
4159 ccb.ccb_h.path_id = bus;
4160 ccb.ccb_h.target_id = target;
4161 ccb.ccb_h.target_lun = lun;
4163 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4164 warn("CAMIOCOMMAND ioctl failed");
4169 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4170 CAM_FUNC_NOTAVAIL) {
4171 warnx("CAM debugging not available");
4172 warnx("you need to put options CAMDEBUG in"
4173 " your kernel config file!");
4175 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4177 warnx("XPT_DEBUG CCB failed with status %#x",
4181 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4183 "Debugging turned off\n");
4186 "Debugging enabled for "
4199 tagcontrol(struct cam_device *device, int argc, char **argv,
4209 ccb = cam_getccb(device);
4212 warnx("tagcontrol: error allocating ccb");
4216 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4219 numtags = strtol(optarg, NULL, 0);
4221 warnx("tag count %d is < 0", numtags);
4223 goto tagcontrol_bailout;
4234 cam_path_string(device, pathstr, sizeof(pathstr));
4237 bzero(&(&ccb->ccb_h)[1],
4238 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
4239 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4240 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4241 ccb->crs.openings = numtags;
4244 if (cam_send_ccb(device, ccb) < 0) {
4245 perror("error sending XPT_REL_SIMQ CCB");
4247 goto tagcontrol_bailout;
4250 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4251 warnx("XPT_REL_SIMQ CCB failed");
4252 cam_error_print(device, ccb, CAM_ESF_ALL,
4253 CAM_EPF_ALL, stderr);
4255 goto tagcontrol_bailout;
4260 fprintf(stdout, "%stagged openings now %d\n",
4261 pathstr, ccb->crs.openings);
4264 bzero(&(&ccb->ccb_h)[1],
4265 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
4267 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4269 if (cam_send_ccb(device, ccb) < 0) {
4270 perror("error sending XPT_GDEV_STATS CCB");
4272 goto tagcontrol_bailout;
4275 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4276 warnx("XPT_GDEV_STATS CCB failed");
4277 cam_error_print(device, ccb, CAM_ESF_ALL,
4278 CAM_EPF_ALL, stderr);
4280 goto tagcontrol_bailout;
4283 if (arglist & CAM_ARG_VERBOSE) {
4284 fprintf(stdout, "%s", pathstr);
4285 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4286 fprintf(stdout, "%s", pathstr);
4287 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4288 fprintf(stdout, "%s", pathstr);
4289 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
4290 fprintf(stdout, "%s", pathstr);
4291 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
4292 fprintf(stdout, "%s", pathstr);
4293 fprintf(stdout, "held %d\n", ccb->cgds.held);
4294 fprintf(stdout, "%s", pathstr);
4295 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4296 fprintf(stdout, "%s", pathstr);
4297 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4300 fprintf(stdout, "%s", pathstr);
4301 fprintf(stdout, "device openings: ");
4303 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4304 ccb->cgds.dev_active);
4314 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4318 cam_path_string(device, pathstr, sizeof(pathstr));
4320 if (cts->transport == XPORT_SPI) {
4321 struct ccb_trans_settings_spi *spi =
4322 &cts->xport_specific.spi;
4324 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4326 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4329 if (spi->sync_offset != 0) {
4332 freq = scsi_calc_syncsrate(spi->sync_period);
4333 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4334 pathstr, freq / 1000, freq % 1000);
4338 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4339 fprintf(stdout, "%soffset: %d\n", pathstr,
4343 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4344 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4345 (0x01 << spi->bus_width) * 8);
4348 if (spi->valid & CTS_SPI_VALID_DISC) {
4349 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4350 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4351 "enabled" : "disabled");
4354 if (cts->transport == XPORT_FC) {
4355 struct ccb_trans_settings_fc *fc =
4356 &cts->xport_specific.fc;
4358 if (fc->valid & CTS_FC_VALID_WWNN)
4359 fprintf(stdout, "%sWWNN: 0x%llx", pathstr,
4360 (long long) fc->wwnn);
4361 if (fc->valid & CTS_FC_VALID_WWPN)
4362 fprintf(stdout, "%sWWPN: 0x%llx", pathstr,
4363 (long long) fc->wwpn);
4364 if (fc->valid & CTS_FC_VALID_PORT)
4365 fprintf(stdout, "%sPortID: 0x%x", pathstr, fc->port);
4366 if (fc->valid & CTS_FC_VALID_SPEED)
4367 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4368 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4370 if (cts->transport == XPORT_SAS) {
4371 struct ccb_trans_settings_sas *sas =
4372 &cts->xport_specific.sas;
4374 if (sas->valid & CTS_SAS_VALID_SPEED)
4375 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4376 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4378 if (cts->transport == XPORT_ATA) {
4379 struct ccb_trans_settings_pata *pata =
4380 &cts->xport_specific.ata;
4382 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4383 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4384 ata_mode2string(pata->mode));
4386 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4387 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4390 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4391 fprintf(stdout, "%sPIO transaction length: %d\n",
4392 pathstr, pata->bytecount);
4395 if (cts->transport == XPORT_SATA) {
4396 struct ccb_trans_settings_sata *sata =
4397 &cts->xport_specific.sata;
4399 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4400 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4403 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4404 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4405 ata_mode2string(sata->mode));
4407 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4408 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4411 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4412 fprintf(stdout, "%sPIO transaction length: %d\n",
4413 pathstr, sata->bytecount);
4415 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4416 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4419 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4420 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4423 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4424 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4428 if (cts->protocol == PROTO_ATA) {
4429 struct ccb_trans_settings_ata *ata=
4430 &cts->proto_specific.ata;
4432 if (ata->valid & CTS_ATA_VALID_TQ) {
4433 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4434 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4435 "enabled" : "disabled");
4438 if (cts->protocol == PROTO_SCSI) {
4439 struct ccb_trans_settings_scsi *scsi=
4440 &cts->proto_specific.scsi;
4442 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4443 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4444 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4445 "enabled" : "disabled");
4452 * Get a path inquiry CCB for the specified device.
4455 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4460 ccb = cam_getccb(device);
4462 warnx("get_cpi: couldn't allocate CCB");
4465 bzero(&(&ccb->ccb_h)[1],
4466 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4467 ccb->ccb_h.func_code = XPT_PATH_INQ;
4468 if (cam_send_ccb(device, ccb) < 0) {
4469 warn("get_cpi: error sending Path Inquiry CCB");
4470 if (arglist & CAM_ARG_VERBOSE)
4471 cam_error_print(device, ccb, CAM_ESF_ALL,
4472 CAM_EPF_ALL, stderr);
4474 goto get_cpi_bailout;
4476 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4477 if (arglist & CAM_ARG_VERBOSE)
4478 cam_error_print(device, ccb, CAM_ESF_ALL,
4479 CAM_EPF_ALL, stderr);
4481 goto get_cpi_bailout;
4483 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4491 * Get a get device CCB for the specified device.
4494 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4499 ccb = cam_getccb(device);
4501 warnx("get_cgd: couldn't allocate CCB");
4504 bzero(&(&ccb->ccb_h)[1],
4505 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4506 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4507 if (cam_send_ccb(device, ccb) < 0) {
4508 warn("get_cgd: error sending Path Inquiry CCB");
4509 if (arglist & CAM_ARG_VERBOSE)
4510 cam_error_print(device, ccb, CAM_ESF_ALL,
4511 CAM_EPF_ALL, stderr);
4513 goto get_cgd_bailout;
4515 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4516 if (arglist & CAM_ARG_VERBOSE)
4517 cam_error_print(device, ccb, CAM_ESF_ALL,
4518 CAM_EPF_ALL, stderr);
4520 goto get_cgd_bailout;
4522 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4530 cpi_print(struct ccb_pathinq *cpi)
4532 char adapter_str[1024];
4535 snprintf(adapter_str, sizeof(adapter_str),
4536 "%s%d:", cpi->dev_name, cpi->unit_number);
4538 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
4541 for (i = 1; i < 0xff; i = i << 1) {
4544 if ((i & cpi->hba_inquiry) == 0)
4547 fprintf(stdout, "%s supports ", adapter_str);
4551 str = "MDP message";
4554 str = "32 bit wide SCSI";
4557 str = "16 bit wide SCSI";
4560 str = "SDTR message";
4563 str = "linked CDBs";
4566 str = "tag queue messages";
4569 str = "soft reset alternative";
4572 str = "SATA Port Multiplier";
4575 str = "unknown PI bit set";
4578 fprintf(stdout, "%s\n", str);
4581 for (i = 1; i < 0xff; i = i << 1) {
4584 if ((i & cpi->hba_misc) == 0)
4587 fprintf(stdout, "%s ", adapter_str);
4591 str = "bus scans from high ID to low ID";
4594 str = "removable devices not included in scan";
4596 case PIM_NOINITIATOR:
4597 str = "initiator role not supported";
4599 case PIM_NOBUSRESET:
4600 str = "user has disabled initial BUS RESET or"
4601 " controller is in target/mixed mode";
4604 str = "do not send 6-byte commands";
4607 str = "scan bus sequentially";
4610 str = "unknown PIM bit set";
4613 fprintf(stdout, "%s\n", str);
4616 for (i = 1; i < 0xff; i = i << 1) {
4619 if ((i & cpi->target_sprt) == 0)
4622 fprintf(stdout, "%s supports ", adapter_str);
4625 str = "target mode processor mode";
4628 str = "target mode phase cog. mode";
4630 case PIT_DISCONNECT:
4631 str = "disconnects in target mode";
4634 str = "terminate I/O message in target mode";
4637 str = "group 6 commands in target mode";
4640 str = "group 7 commands in target mode";
4643 str = "unknown PIT bit set";
4647 fprintf(stdout, "%s\n", str);
4649 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
4651 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
4653 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
4655 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
4656 adapter_str, cpi->hpath_id);
4657 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
4659 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
4660 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
4661 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
4662 fprintf(stdout, "%s base transfer speed: ", adapter_str);
4663 if (cpi->base_transfer_speed > 1000)
4664 fprintf(stdout, "%d.%03dMB/sec\n",
4665 cpi->base_transfer_speed / 1000,
4666 cpi->base_transfer_speed % 1000);
4668 fprintf(stdout, "%dKB/sec\n",
4669 (cpi->base_transfer_speed % 1000) * 1000);
4673 get_print_cts(struct cam_device *device, int user_settings, int quiet,
4674 struct ccb_trans_settings *cts)
4680 ccb = cam_getccb(device);
4683 warnx("get_print_cts: error allocating ccb");
4687 bzero(&(&ccb->ccb_h)[1],
4688 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4690 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
4692 if (user_settings == 0)
4693 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
4695 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
4697 if (cam_send_ccb(device, ccb) < 0) {
4698 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
4699 if (arglist & CAM_ARG_VERBOSE)
4700 cam_error_print(device, ccb, CAM_ESF_ALL,
4701 CAM_EPF_ALL, stderr);
4703 goto get_print_cts_bailout;
4706 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4707 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
4708 if (arglist & CAM_ARG_VERBOSE)
4709 cam_error_print(device, ccb, CAM_ESF_ALL,
4710 CAM_EPF_ALL, stderr);
4712 goto get_print_cts_bailout;
4716 cts_print(device, &ccb->cts);
4719 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
4721 get_print_cts_bailout:
4729 ratecontrol(struct cam_device *device, int retry_count, int timeout,
4730 int argc, char **argv, char *combinedopt)
4734 int user_settings = 0;
4736 int disc_enable = -1, tag_enable = -1;
4739 double syncrate = -1;
4742 int change_settings = 0, send_tur = 0;
4743 struct ccb_pathinq cpi;
4745 ccb = cam_getccb(device);
4747 warnx("ratecontrol: error allocating ccb");
4750 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4759 if (strncasecmp(optarg, "enable", 6) == 0)
4761 else if (strncasecmp(optarg, "disable", 7) == 0)
4764 warnx("-D argument \"%s\" is unknown", optarg);
4766 goto ratecontrol_bailout;
4768 change_settings = 1;
4771 mode = ata_string2mode(optarg);
4773 warnx("unknown mode '%s'", optarg);
4775 goto ratecontrol_bailout;
4777 change_settings = 1;
4780 offset = strtol(optarg, NULL, 0);
4782 warnx("offset value %d is < 0", offset);
4784 goto ratecontrol_bailout;
4786 change_settings = 1;
4792 syncrate = atof(optarg);
4794 warnx("sync rate %f is < 0", syncrate);
4796 goto ratecontrol_bailout;
4798 change_settings = 1;
4801 if (strncasecmp(optarg, "enable", 6) == 0)
4803 else if (strncasecmp(optarg, "disable", 7) == 0)
4806 warnx("-T argument \"%s\" is unknown", optarg);
4808 goto ratecontrol_bailout;
4810 change_settings = 1;
4816 bus_width = strtol(optarg, NULL, 0);
4817 if (bus_width < 0) {
4818 warnx("bus width %d is < 0", bus_width);
4820 goto ratecontrol_bailout;
4822 change_settings = 1;
4828 bzero(&(&ccb->ccb_h)[1],
4829 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4831 * Grab path inquiry information, so we can determine whether
4832 * or not the initiator is capable of the things that the user
4835 ccb->ccb_h.func_code = XPT_PATH_INQ;
4836 if (cam_send_ccb(device, ccb) < 0) {
4837 perror("error sending XPT_PATH_INQ CCB");
4838 if (arglist & CAM_ARG_VERBOSE) {
4839 cam_error_print(device, ccb, CAM_ESF_ALL,
4840 CAM_EPF_ALL, stderr);
4843 goto ratecontrol_bailout;
4845 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4846 warnx("XPT_PATH_INQ CCB failed");
4847 if (arglist & CAM_ARG_VERBOSE) {
4848 cam_error_print(device, ccb, CAM_ESF_ALL,
4849 CAM_EPF_ALL, stderr);
4852 goto ratecontrol_bailout;
4854 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
4855 bzero(&(&ccb->ccb_h)[1],
4856 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4858 fprintf(stdout, "%s parameters:\n",
4859 user_settings ? "User" : "Current");
4861 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
4863 goto ratecontrol_bailout;
4865 if (arglist & CAM_ARG_VERBOSE)
4868 if (change_settings) {
4869 int didsettings = 0;
4870 struct ccb_trans_settings_spi *spi = NULL;
4871 struct ccb_trans_settings_pata *pata = NULL;
4872 struct ccb_trans_settings_sata *sata = NULL;
4873 struct ccb_trans_settings_ata *ata = NULL;
4874 struct ccb_trans_settings_scsi *scsi = NULL;
4876 if (ccb->cts.transport == XPORT_SPI)
4877 spi = &ccb->cts.xport_specific.spi;
4878 if (ccb->cts.transport == XPORT_ATA)
4879 pata = &ccb->cts.xport_specific.ata;
4880 if (ccb->cts.transport == XPORT_SATA)
4881 sata = &ccb->cts.xport_specific.sata;
4882 if (ccb->cts.protocol == PROTO_ATA)
4883 ata = &ccb->cts.proto_specific.ata;
4884 if (ccb->cts.protocol == PROTO_SCSI)
4885 scsi = &ccb->cts.proto_specific.scsi;
4886 ccb->cts.xport_specific.valid = 0;
4887 ccb->cts.proto_specific.valid = 0;
4888 if (spi && disc_enable != -1) {
4889 spi->valid |= CTS_SPI_VALID_DISC;
4890 if (disc_enable == 0)
4891 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
4893 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
4896 if (tag_enable != -1) {
4897 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
4898 warnx("HBA does not support tagged queueing, "
4899 "so you cannot modify tag settings");
4901 goto ratecontrol_bailout;
4904 ata->valid |= CTS_SCSI_VALID_TQ;
4905 if (tag_enable == 0)
4906 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
4908 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
4911 scsi->valid |= CTS_SCSI_VALID_TQ;
4912 if (tag_enable == 0)
4913 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
4915 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
4919 if (spi && offset != -1) {
4920 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4921 warnx("HBA is not capable of changing offset");
4923 goto ratecontrol_bailout;
4925 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
4926 spi->sync_offset = offset;
4929 if (spi && syncrate != -1) {
4930 int prelim_sync_period;
4933 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4934 warnx("HBA is not capable of changing "
4937 goto ratecontrol_bailout;
4939 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
4941 * The sync rate the user gives us is in MHz.
4942 * We need to translate it into KHz for this
4947 * Next, we calculate a "preliminary" sync period
4948 * in tenths of a nanosecond.
4951 prelim_sync_period = 0;
4953 prelim_sync_period = 10000000 / syncrate;
4955 scsi_calc_syncparam(prelim_sync_period);
4956 freq = scsi_calc_syncsrate(spi->sync_period);
4959 if (sata && syncrate != -1) {
4960 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4961 warnx("HBA is not capable of changing "
4964 goto ratecontrol_bailout;
4966 if (!user_settings) {
4967 warnx("You can modify only user rate "
4968 "settings for SATA");
4970 goto ratecontrol_bailout;
4972 sata->revision = ata_speed2revision(syncrate * 100);
4973 if (sata->revision < 0) {
4974 warnx("Invalid rate %f", syncrate);
4976 goto ratecontrol_bailout;
4978 sata->valid |= CTS_SATA_VALID_REVISION;
4981 if ((pata || sata) && mode != -1) {
4982 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4983 warnx("HBA is not capable of changing "
4986 goto ratecontrol_bailout;
4988 if (!user_settings) {
4989 warnx("You can modify only user mode "
4990 "settings for ATA/SATA");
4992 goto ratecontrol_bailout;
4996 pata->valid |= CTS_ATA_VALID_MODE;
4999 sata->valid |= CTS_SATA_VALID_MODE;
5004 * The bus_width argument goes like this:
5008 * Therefore, if you shift the number of bits given on the
5009 * command line right by 4, you should get the correct
5012 if (spi && bus_width != -1) {
5014 * We might as well validate things here with a
5015 * decipherable error message, rather than what
5016 * will probably be an indecipherable error message
5017 * by the time it gets back to us.
5019 if ((bus_width == 16)
5020 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5021 warnx("HBA does not support 16 bit bus width");
5023 goto ratecontrol_bailout;
5024 } else if ((bus_width == 32)
5025 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5026 warnx("HBA does not support 32 bit bus width");
5028 goto ratecontrol_bailout;
5029 } else if ((bus_width != 8)
5030 && (bus_width != 16)
5031 && (bus_width != 32)) {
5032 warnx("Invalid bus width %d", bus_width);
5034 goto ratecontrol_bailout;
5036 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5037 spi->bus_width = bus_width >> 4;
5040 if (didsettings == 0) {
5041 goto ratecontrol_bailout;
5043 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5044 if (cam_send_ccb(device, ccb) < 0) {
5045 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5046 if (arglist & CAM_ARG_VERBOSE) {
5047 cam_error_print(device, ccb, CAM_ESF_ALL,
5048 CAM_EPF_ALL, stderr);
5051 goto ratecontrol_bailout;
5053 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5054 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5055 if (arglist & CAM_ARG_VERBOSE) {
5056 cam_error_print(device, ccb, CAM_ESF_ALL,
5057 CAM_EPF_ALL, stderr);
5060 goto ratecontrol_bailout;
5064 retval = testunitready(device, retry_count, timeout,
5065 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5067 * If the TUR didn't succeed, just bail.
5071 fprintf(stderr, "Test Unit Ready failed\n");
5072 goto ratecontrol_bailout;
5075 if ((change_settings || send_tur) && !quiet &&
5076 (ccb->cts.transport == XPORT_ATA ||
5077 ccb->cts.transport == XPORT_SATA || send_tur)) {
5078 fprintf(stdout, "New parameters:\n");
5079 retval = get_print_cts(device, user_settings, 0, NULL);
5082 ratecontrol_bailout:
5088 scsiformat(struct cam_device *device, int argc, char **argv,
5089 char *combinedopt, int retry_count, int timeout)
5093 int ycount = 0, quiet = 0;
5094 int error = 0, response = 0, retval = 0;
5095 int use_timeout = 10800 * 1000;
5097 struct format_defect_list_header fh;
5098 u_int8_t *data_ptr = NULL;
5099 u_int32_t dxfer_len = 0;
5101 int num_warnings = 0;
5104 ccb = cam_getccb(device);
5107 warnx("scsiformat: error allocating ccb");
5111 bzero(&(&ccb->ccb_h)[1],
5112 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5114 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5135 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5136 "following device:\n");
5138 error = scsidoinquiry(device, argc, argv, combinedopt,
5139 retry_count, timeout);
5142 warnx("scsiformat: error sending inquiry");
5143 goto scsiformat_bailout;
5152 fprintf(stdout, "Are you SURE you want to do "
5155 if (fgets(str, sizeof(str), stdin) != NULL) {
5157 if (strncasecmp(str, "yes", 3) == 0)
5159 else if (strncasecmp(str, "no", 2) == 0)
5162 fprintf(stdout, "Please answer"
5163 " \"yes\" or \"no\"\n");
5166 } while (response == 0);
5168 if (response == -1) {
5170 goto scsiformat_bailout;
5175 use_timeout = timeout;
5178 fprintf(stdout, "Current format timeout is %d seconds\n",
5179 use_timeout / 1000);
5183 * If the user hasn't disabled questions and didn't specify a
5184 * timeout on the command line, ask them if they want the current
5188 && (timeout == 0)) {
5190 int new_timeout = 0;
5192 fprintf(stdout, "Enter new timeout in seconds or press\n"
5193 "return to keep the current timeout [%d] ",
5194 use_timeout / 1000);
5196 if (fgets(str, sizeof(str), stdin) != NULL) {
5198 new_timeout = atoi(str);
5201 if (new_timeout != 0) {
5202 use_timeout = new_timeout * 1000;
5203 fprintf(stdout, "Using new timeout value %d\n",
5204 use_timeout / 1000);
5209 * Keep this outside the if block below to silence any unused
5210 * variable warnings.
5212 bzero(&fh, sizeof(fh));
5215 * If we're in immediate mode, we've got to include the format
5218 if (immediate != 0) {
5219 fh.byte2 = FU_DLH_IMMED;
5220 data_ptr = (u_int8_t *)&fh;
5221 dxfer_len = sizeof(fh);
5222 byte2 = FU_FMT_DATA;
5223 } else if (quiet == 0) {
5224 fprintf(stdout, "Formatting...");
5228 scsi_format_unit(&ccb->csio,
5229 /* retries */ retry_count,
5231 /* tag_action */ MSG_SIMPLE_Q_TAG,
5234 /* data_ptr */ data_ptr,
5235 /* dxfer_len */ dxfer_len,
5236 /* sense_len */ SSD_FULL_SIZE,
5237 /* timeout */ use_timeout);
5239 /* Disable freezing the device queue */
5240 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5242 if (arglist & CAM_ARG_ERR_RECOVER)
5243 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5245 if (((retval = cam_send_ccb(device, ccb)) < 0)
5246 || ((immediate == 0)
5247 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5248 const char errstr[] = "error sending format command";
5255 if (arglist & CAM_ARG_VERBOSE) {
5256 cam_error_print(device, ccb, CAM_ESF_ALL,
5257 CAM_EPF_ALL, stderr);
5260 goto scsiformat_bailout;
5264 * If we ran in non-immediate mode, we already checked for errors
5265 * above and printed out any necessary information. If we're in
5266 * immediate mode, we need to loop through and get status
5267 * information periodically.
5269 if (immediate == 0) {
5271 fprintf(stdout, "Format Complete\n");
5273 goto scsiformat_bailout;
5280 bzero(&(&ccb->ccb_h)[1],
5281 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5284 * There's really no need to do error recovery or
5285 * retries here, since we're just going to sit in a
5286 * loop and wait for the device to finish formatting.
5288 scsi_test_unit_ready(&ccb->csio,
5291 /* tag_action */ MSG_SIMPLE_Q_TAG,
5292 /* sense_len */ SSD_FULL_SIZE,
5293 /* timeout */ 5000);
5295 /* Disable freezing the device queue */
5296 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5298 retval = cam_send_ccb(device, ccb);
5301 * If we get an error from the ioctl, bail out. SCSI
5302 * errors are expected.
5305 warn("error sending CAMIOCOMMAND ioctl");
5306 if (arglist & CAM_ARG_VERBOSE) {
5307 cam_error_print(device, ccb, CAM_ESF_ALL,
5308 CAM_EPF_ALL, stderr);
5311 goto scsiformat_bailout;
5314 status = ccb->ccb_h.status & CAM_STATUS_MASK;
5316 if ((status != CAM_REQ_CMP)
5317 && (status == CAM_SCSI_STATUS_ERROR)
5318 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
5319 struct scsi_sense_data *sense;
5320 int error_code, sense_key, asc, ascq;
5322 sense = &ccb->csio.sense_data;
5323 scsi_extract_sense(sense, &error_code, &sense_key,
5327 * According to the SCSI-2 and SCSI-3 specs, a
5328 * drive that is in the middle of a format should
5329 * return NOT READY with an ASC of "logical unit
5330 * not ready, format in progress". The sense key
5331 * specific bytes will then be a progress indicator.
5333 if ((sense_key == SSD_KEY_NOT_READY)
5334 && (asc == 0x04) && (ascq == 0x04)) {
5335 if ((sense->extra_len >= 10)
5336 && ((sense->sense_key_spec[0] &
5337 SSD_SCS_VALID) != 0)
5340 u_int64_t percentage;
5343 &sense->sense_key_spec[1]);
5344 percentage = 10000 * val;
5347 "\rFormatting: %ju.%02u %% "
5349 (uintmax_t)(percentage /
5351 (unsigned)((percentage /
5355 } else if ((quiet == 0)
5356 && (++num_warnings <= 1)) {
5357 warnx("Unexpected SCSI Sense Key "
5358 "Specific value returned "
5360 scsi_sense_print(device, &ccb->csio,
5362 warnx("Unable to print status "
5363 "information, but format will "
5365 warnx("will exit when format is "
5370 warnx("Unexpected SCSI error during format");
5371 cam_error_print(device, ccb, CAM_ESF_ALL,
5372 CAM_EPF_ALL, stderr);
5374 goto scsiformat_bailout;
5377 } else if (status != CAM_REQ_CMP) {
5378 warnx("Unexpected CAM status %#x", status);
5379 if (arglist & CAM_ARG_VERBOSE)
5380 cam_error_print(device, ccb, CAM_ESF_ALL,
5381 CAM_EPF_ALL, stderr);
5383 goto scsiformat_bailout;
5386 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
5389 fprintf(stdout, "\nFormat Complete\n");
5399 scsireportluns(struct cam_device *device, int argc, char **argv,
5400 char *combinedopt, int retry_count, int timeout)
5403 int c, countonly, lunsonly;
5404 struct scsi_report_luns_data *lundata;
5406 uint8_t report_type;
5407 uint32_t list_len, i, j;
5412 report_type = RPL_REPORT_DEFAULT;
5413 ccb = cam_getccb(device);
5416 warnx("%s: error allocating ccb", __func__);
5420 bzero(&(&ccb->ccb_h)[1],
5421 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5426 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5435 if (strcasecmp(optarg, "default") == 0)
5436 report_type = RPL_REPORT_DEFAULT;
5437 else if (strcasecmp(optarg, "wellknown") == 0)
5438 report_type = RPL_REPORT_WELLKNOWN;
5439 else if (strcasecmp(optarg, "all") == 0)
5440 report_type = RPL_REPORT_ALL;
5442 warnx("%s: invalid report type \"%s\"",
5453 if ((countonly != 0)
5454 && (lunsonly != 0)) {
5455 warnx("%s: you can only specify one of -c or -l", __func__);
5460 * According to SPC-4, the allocation length must be at least 16
5461 * bytes -- enough for the header and one LUN.
5463 alloc_len = sizeof(*lundata) + 8;
5467 lundata = malloc(alloc_len);
5469 if (lundata == NULL) {
5470 warn("%s: error mallocing %d bytes", __func__, alloc_len);
5475 scsi_report_luns(&ccb->csio,
5476 /*retries*/ retry_count,
5478 /*tag_action*/ MSG_SIMPLE_Q_TAG,
5479 /*select_report*/ report_type,
5480 /*rpl_buf*/ lundata,
5481 /*alloc_len*/ alloc_len,
5482 /*sense_len*/ SSD_FULL_SIZE,
5483 /*timeout*/ timeout ? timeout : 5000);
5485 /* Disable freezing the device queue */
5486 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5488 if (arglist & CAM_ARG_ERR_RECOVER)
5489 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5491 if (cam_send_ccb(device, ccb) < 0) {
5492 warn("error sending REPORT LUNS command");
5494 if (arglist & CAM_ARG_VERBOSE)
5495 cam_error_print(device, ccb, CAM_ESF_ALL,
5496 CAM_EPF_ALL, stderr);
5502 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5503 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5509 list_len = scsi_4btoul(lundata->length);
5512 * If we need to list the LUNs, and our allocation
5513 * length was too short, reallocate and retry.
5515 if ((countonly == 0)
5516 && (list_len > (alloc_len - sizeof(*lundata)))) {
5517 alloc_len = list_len + sizeof(*lundata);
5523 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
5524 ((list_len / 8) > 1) ? "s" : "");
5529 for (i = 0; i < (list_len / 8); i++) {
5533 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
5535 fprintf(stdout, ",");
5536 switch (lundata->luns[i].lundata[j] &
5537 RPL_LUNDATA_ATYP_MASK) {
5538 case RPL_LUNDATA_ATYP_PERIPH:
5539 if ((lundata->luns[i].lundata[j] &
5540 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
5541 fprintf(stdout, "%d:",
5542 lundata->luns[i].lundata[j] &
5543 RPL_LUNDATA_PERIPH_BUS_MASK);
5545 && ((lundata->luns[i].lundata[j+2] &
5546 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
5549 fprintf(stdout, "%d",
5550 lundata->luns[i].lundata[j+1]);
5552 case RPL_LUNDATA_ATYP_FLAT: {
5554 tmplun[0] = lundata->luns[i].lundata[j] &
5555 RPL_LUNDATA_FLAT_LUN_MASK;
5556 tmplun[1] = lundata->luns[i].lundata[j+1];
5558 fprintf(stdout, "%d", scsi_2btoul(tmplun));
5562 case RPL_LUNDATA_ATYP_LUN:
5563 fprintf(stdout, "%d:%d:%d",
5564 (lundata->luns[i].lundata[j+1] &
5565 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
5566 lundata->luns[i].lundata[j] &
5567 RPL_LUNDATA_LUN_TARG_MASK,
5568 lundata->luns[i].lundata[j+1] &
5569 RPL_LUNDATA_LUN_LUN_MASK);
5571 case RPL_LUNDATA_ATYP_EXTLUN: {
5572 int field_len, field_len_code, eam_code;
5574 eam_code = lundata->luns[i].lundata[j] &
5575 RPL_LUNDATA_EXT_EAM_MASK;
5576 field_len_code = (lundata->luns[i].lundata[j] &
5577 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
5578 field_len = field_len_code * 2;
5580 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
5581 && (field_len_code == 0x00)) {
5582 fprintf(stdout, "%d",
5583 lundata->luns[i].lundata[j+1]);
5584 } else if ((eam_code ==
5585 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
5586 && (field_len_code == 0x03)) {
5590 * This format takes up all 8 bytes.
5591 * If we aren't starting at offset 0,
5595 fprintf(stdout, "Invalid "
5598 "specified format", j);
5602 bzero(tmp_lun, sizeof(tmp_lun));
5603 bcopy(&lundata->luns[i].lundata[j+1],
5604 &tmp_lun[1], sizeof(tmp_lun) - 1);
5605 fprintf(stdout, "%#jx",
5606 (intmax_t)scsi_8btou64(tmp_lun));
5609 fprintf(stderr, "Unknown Extended LUN"
5610 "Address method %#x, length "
5611 "code %#x", eam_code,
5618 fprintf(stderr, "Unknown LUN address method "
5619 "%#x\n", lundata->luns[i].lundata[0] &
5620 RPL_LUNDATA_ATYP_MASK);
5624 * For the flat addressing method, there are no
5625 * other levels after it.
5630 fprintf(stdout, "\n");
5643 scsireadcapacity(struct cam_device *device, int argc, char **argv,
5644 char *combinedopt, int retry_count, int timeout)
5647 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
5648 struct scsi_read_capacity_data rcap;
5649 struct scsi_read_capacity_data_long rcaplong;
5663 ccb = cam_getccb(device);
5666 warnx("%s: error allocating ccb", __func__);
5670 bzero(&(&ccb->ccb_h)[1],
5671 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5673 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5700 if ((blocksizeonly != 0)
5701 && (numblocks != 0)) {
5702 warnx("%s: you can only specify one of -b or -N", __func__);
5707 if ((blocksizeonly != 0)
5708 && (sizeonly != 0)) {
5709 warnx("%s: you can only specify one of -b or -s", __func__);
5716 warnx("%s: you can only specify one of -h/-H or -q", __func__);
5722 && (blocksizeonly != 0)) {
5723 warnx("%s: you can only specify one of -h/-H or -b", __func__);
5728 scsi_read_capacity(&ccb->csio,
5729 /*retries*/ retry_count,
5731 /*tag_action*/ MSG_SIMPLE_Q_TAG,
5734 /*timeout*/ timeout ? timeout : 5000);
5736 /* Disable freezing the device queue */
5737 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5739 if (arglist & CAM_ARG_ERR_RECOVER)
5740 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5742 if (cam_send_ccb(device, ccb) < 0) {
5743 warn("error sending READ CAPACITY command");
5745 if (arglist & CAM_ARG_VERBOSE)
5746 cam_error_print(device, ccb, CAM_ESF_ALL,
5747 CAM_EPF_ALL, stderr);
5753 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5754 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5759 maxsector = scsi_4btoul(rcap.addr);
5760 block_len = scsi_4btoul(rcap.length);
5763 * A last block of 2^32-1 means that the true capacity is over 2TB,
5764 * and we need to issue the long READ CAPACITY to get the real
5765 * capacity. Otherwise, we're all set.
5767 if (maxsector != 0xffffffff)
5770 scsi_read_capacity_16(&ccb->csio,
5771 /*retries*/ retry_count,
5773 /*tag_action*/ MSG_SIMPLE_Q_TAG,
5778 /*sense_len*/ SSD_FULL_SIZE,
5779 /*timeout*/ timeout ? timeout : 5000);
5781 /* Disable freezing the device queue */
5782 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5784 if (arglist & CAM_ARG_ERR_RECOVER)
5785 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5787 if (cam_send_ccb(device, ccb) < 0) {
5788 warn("error sending READ CAPACITY (16) command");
5790 if (arglist & CAM_ARG_VERBOSE)
5791 cam_error_print(device, ccb, CAM_ESF_ALL,
5792 CAM_EPF_ALL, stderr);
5798 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5799 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5804 maxsector = scsi_8btou64(rcaplong.addr);
5805 block_len = scsi_4btoul(rcaplong.length);
5808 if (blocksizeonly == 0) {
5810 * Humanize implies !quiet, and also implies numblocks.
5812 if (humanize != 0) {
5817 tmpbytes = (maxsector + 1) * block_len;
5818 ret = humanize_number(tmpstr, sizeof(tmpstr),
5819 tmpbytes, "", HN_AUTOSCALE,
5822 HN_DIVISOR_1000 : 0));
5824 warnx("%s: humanize_number failed!", __func__);
5828 fprintf(stdout, "Device Size: %s%s", tmpstr,
5829 (sizeonly == 0) ? ", " : "\n");
5830 } else if (numblocks != 0) {
5831 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
5832 "Blocks: " : "", (uintmax_t)maxsector + 1,
5833 (sizeonly == 0) ? ", " : "\n");
5835 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
5836 "Last Block: " : "", (uintmax_t)maxsector,
5837 (sizeonly == 0) ? ", " : "\n");
5841 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
5842 "Block Length: " : "", block_len, (quiet == 0) ?
5851 atapm(struct cam_device *device, int argc, char **argv,
5852 char *combinedopt, int retry_count, int timeout)
5860 ccb = cam_getccb(device);
5863 warnx("%s: error allocating ccb", __func__);
5867 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5876 if (strcmp(argv[1], "idle") == 0) {
5878 cmd = ATA_IDLE_IMMEDIATE;
5881 } else if (strcmp(argv[1], "standby") == 0) {
5883 cmd = ATA_STANDBY_IMMEDIATE;
5885 cmd = ATA_STANDBY_CMD;
5893 else if (t <= (240 * 5))
5895 else if (t <= (252 * 5))
5896 /* special encoding for 21 minutes */
5898 else if (t <= (11 * 30 * 60))
5899 sc = (t - 1) / (30 * 60) + 241;
5903 cam_fill_ataio(&ccb->ataio,
5906 /*flags*/CAM_DIR_NONE,
5910 timeout ? timeout : 30 * 1000);
5911 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
5913 /* Disable freezing the device queue */
5914 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5916 if (arglist & CAM_ARG_ERR_RECOVER)
5917 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5919 if (cam_send_ccb(device, ccb) < 0) {
5920 warn("error sending command");
5922 if (arglist & CAM_ARG_VERBOSE)
5923 cam_error_print(device, ccb, CAM_ESF_ALL,
5924 CAM_EPF_ALL, stderr);
5930 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5931 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5940 #endif /* MINIMALISTIC */
5945 fprintf(verbose ? stdout : stderr,
5946 "usage: camcontrol <command> [device id][generic args][command args]\n"
5947 " camcontrol devlist [-v]\n"
5948 #ifndef MINIMALISTIC
5949 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
5950 " camcontrol tur [dev_id][generic args]\n"
5951 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
5952 " camcontrol identify [dev_id][generic args] [-v]\n"
5953 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
5954 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
5956 " camcontrol start [dev_id][generic args]\n"
5957 " camcontrol stop [dev_id][generic args]\n"
5958 " camcontrol load [dev_id][generic args]\n"
5959 " camcontrol eject [dev_id][generic args]\n"
5960 #endif /* MINIMALISTIC */
5961 " camcontrol rescan <all | bus[:target:lun]>\n"
5962 " camcontrol reset <all | bus[:target:lun]>\n"
5963 #ifndef MINIMALISTIC
5964 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
5965 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
5966 " [-P pagectl][-e | -b][-d]\n"
5967 " camcontrol cmd [dev_id][generic args]\n"
5968 " <-a cmd [args] | -c cmd [args]>\n"
5969 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
5970 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
5971 " <all|bus[:target[:lun]]|off>\n"
5972 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
5973 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
5974 " [-D <enable|disable>][-M mode][-O offset]\n"
5975 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
5976 " [-U][-W bus_width]\n"
5977 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
5978 " camcontrol idle [dev_id][generic args][-t time]\n"
5979 " camcontrol standby [dev_id][generic args][-t time]\n"
5980 " camcontrol sleep [dev_id][generic args]\n"
5981 " camcontrol security [dev_id][generic args]\n"
5982 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
5983 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
5984 " [-U <user|master>] [-y]\n"
5985 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
5986 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
5987 #endif /* MINIMALISTIC */
5988 " camcontrol help\n");
5991 #ifndef MINIMALISTIC
5993 "Specify one of the following options:\n"
5994 "devlist list all CAM devices\n"
5995 "periphlist list all CAM peripheral drivers attached to a device\n"
5996 "tur send a test unit ready to the named device\n"
5997 "inquiry send a SCSI inquiry command to the named device\n"
5998 "identify send a ATA identify command to the named device\n"
5999 "reportluns send a SCSI report luns command to the device\n"
6000 "readcap send a SCSI read capacity command to the device\n"
6001 "start send a Start Unit command to the device\n"
6002 "stop send a Stop Unit command to the device\n"
6003 "load send a Start Unit command to the device with the load bit set\n"
6004 "eject send a Stop Unit command to the device with the eject bit set\n"
6005 "rescan rescan all busses, the given bus, or bus:target:lun\n"
6006 "reset reset all busses, the given bus, or bus:target:lun\n"
6007 "defects read the defect list of the specified device\n"
6008 "modepage display or edit (-e) the given mode page\n"
6009 "cmd send the given scsi command, may need -i or -o as well\n"
6010 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
6011 "tags report or set the number of transaction slots for a device\n"
6012 "negotiate report or set device negotiation parameters\n"
6013 "format send the SCSI FORMAT UNIT command to the named device\n"
6014 "idle send the ATA IDLE command to the named device\n"
6015 "standby send the ATA STANDBY command to the named device\n"
6016 "sleep send the ATA SLEEP command to the named device\n"
6017 "security report or send ATA security commands to the named device\n"
6018 "help this message\n"
6019 "Device Identifiers:\n"
6020 "bus:target specify the bus and target, lun defaults to 0\n"
6021 "bus:target:lun specify the bus, target and lun\n"
6022 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
6023 "Generic arguments:\n"
6024 "-v be verbose, print out sense information\n"
6025 "-t timeout command timeout in seconds, overrides default timeout\n"
6026 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
6027 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
6028 "-E have the kernel attempt to perform SCSI error recovery\n"
6029 "-C count specify the SCSI command retry count (needs -E to work)\n"
6030 "modepage arguments:\n"
6031 "-l list all available mode pages\n"
6032 "-m page specify the mode page to view or edit\n"
6033 "-e edit the specified mode page\n"
6034 "-b force view to binary mode\n"
6035 "-d disable block descriptors for mode sense\n"
6036 "-P pgctl page control field 0-3\n"
6037 "defects arguments:\n"
6038 "-f format specify defect list format (block, bfi or phys)\n"
6039 "-G get the grown defect list\n"
6040 "-P get the permanant defect list\n"
6041 "inquiry arguments:\n"
6042 "-D get the standard inquiry data\n"
6043 "-S get the serial number\n"
6044 "-R get the transfer rate, etc.\n"
6045 "reportluns arguments:\n"
6046 "-c only report a count of available LUNs\n"
6047 "-l only print out luns, and not a count\n"
6048 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
6049 "readcap arguments\n"
6050 "-b only report the blocksize\n"
6051 "-h human readable device size, base 2\n"
6052 "-H human readable device size, base 10\n"
6053 "-N print the number of blocks instead of last block\n"
6054 "-q quiet, print numbers only\n"
6055 "-s only report the last block/device size\n"
6057 "-c cdb [args] specify the SCSI CDB\n"
6058 "-i len fmt specify input data and input data format\n"
6059 "-o len fmt [args] specify output data and output data fmt\n"
6060 "debug arguments:\n"
6061 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
6062 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
6063 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
6064 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
6066 "-N tags specify the number of tags to use for this device\n"
6067 "-q be quiet, don't report the number of tags\n"
6068 "-v report a number of tag-related parameters\n"
6069 "negotiate arguments:\n"
6070 "-a send a test unit ready after negotiation\n"
6071 "-c report/set current negotiation settings\n"
6072 "-D <arg> \"enable\" or \"disable\" disconnection\n"
6073 "-M mode set ATA mode\n"
6074 "-O offset set command delay offset\n"
6075 "-q be quiet, don't report anything\n"
6076 "-R syncrate synchronization rate in MHz\n"
6077 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
6078 "-U report/set user negotiation settings\n"
6079 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
6080 "-v also print a Path Inquiry CCB for the controller\n"
6081 "format arguments:\n"
6082 "-q be quiet, don't print status messages\n"
6083 "-r run in report only mode\n"
6084 "-w don't send immediate format command\n"
6085 "-y don't ask any questions\n"
6086 "idle/standby arguments:\n"
6087 "-t <arg> number of seconds before respective state.\n"
6088 "security arguments:\n"
6089 "-d pwd disable security using the given password for the selected\n"
6091 "-e pwd erase the device using the given pwd for the selected user\n"
6092 "-f freeze the security configuration of the specified device\n"
6093 "-h pwd enhanced erase the device using the given pwd for the\n"
6095 "-k pwd unlock the device using the given pwd for the selected\n"
6097 "-l <high|maximum> specifies which security level to set: high or maximum\n"
6098 "-q be quiet, do not print any status messages\n"
6099 "-s pwd password the device (enable security) using the given\n"
6100 " pwd for the selected user\n"
6101 "-T timeout overrides the timeout (seconds) used for erase operation\n"
6102 "-U <user|master> specifies which user to set: user or master\n"
6103 "-y don't ask any questions\n"
6105 "-f freeze the HPA configuration of the device\n"
6106 "-l lock the HPA configuration of the device\n"
6107 "-P make the HPA max sectors persist\n"
6108 "-p pwd Set the HPA configuration password required for unlock\n"
6110 "-q be quiet, do not print any status messages\n"
6111 "-s sectors configures the maximum user accessible sectors of the\n"
6113 "-U pwd unlock the HPA configuration of the device\n"
6114 "-y don't ask any questions\n"
6116 #endif /* MINIMALISTIC */
6120 main(int argc, char **argv)
6123 char *device = NULL;
6125 struct cam_device *cam_dev = NULL;
6126 int timeout = 0, retry_count = 1;
6127 camcontrol_optret optreturn;
6129 const char *mainopt = "C:En:t:u:v";
6130 const char *subopt = NULL;
6131 char combinedopt[256];
6132 int error = 0, optstart = 2;
6134 #ifndef MINIMALISTIC
6135 int bus, target, lun;
6136 #endif /* MINIMALISTIC */
6138 cmdlist = CAM_CMD_NONE;
6139 arglist = CAM_ARG_NONE;
6147 * Get the base option.
6149 optreturn = getoption(argv[1], &cmdlist, &arglist, &subopt);
6151 if (optreturn == CC_OR_AMBIGUOUS) {
6152 warnx("ambiguous option %s", argv[1]);
6155 } else if (optreturn == CC_OR_NOT_FOUND) {
6156 warnx("option %s not found", argv[1]);
6162 * Ahh, getopt(3) is a pain.
6164 * This is a gross hack. There really aren't many other good
6165 * options (excuse the pun) for parsing options in a situation like
6166 * this. getopt is kinda braindead, so you end up having to run
6167 * through the options twice, and give each invocation of getopt
6168 * the option string for the other invocation.
6170 * You would think that you could just have two groups of options.
6171 * The first group would get parsed by the first invocation of
6172 * getopt, and the second group would get parsed by the second
6173 * invocation of getopt. It doesn't quite work out that way. When
6174 * the first invocation of getopt finishes, it leaves optind pointing
6175 * to the argument _after_ the first argument in the second group.
6176 * So when the second invocation of getopt comes around, it doesn't
6177 * recognize the first argument it gets and then bails out.
6179 * A nice alternative would be to have a flag for getopt that says
6180 * "just keep parsing arguments even when you encounter an unknown
6181 * argument", but there isn't one. So there's no real clean way to
6182 * easily parse two sets of arguments without having one invocation
6183 * of getopt know about the other.
6185 * Without this hack, the first invocation of getopt would work as
6186 * long as the generic arguments are first, but the second invocation
6187 * (in the subfunction) would fail in one of two ways. In the case
6188 * where you don't set optreset, it would fail because optind may be
6189 * pointing to the argument after the one it should be pointing at.
6190 * In the case where you do set optreset, and reset optind, it would
6191 * fail because getopt would run into the first set of options, which
6192 * it doesn't understand.
6194 * All of this would "sort of" work if you could somehow figure out
6195 * whether optind had been incremented one option too far. The
6196 * mechanics of that, however, are more daunting than just giving
6197 * both invocations all of the expect options for either invocation.
6199 * Needless to say, I wouldn't mind if someone invented a better
6200 * (non-GPL!) command line parsing interface than getopt. I
6201 * wouldn't mind if someone added more knobs to getopt to make it
6202 * work better. Who knows, I may talk myself into doing it someday,
6203 * if the standards weenies let me. As it is, it just leads to
6204 * hackery like this and causes people to avoid it in some cases.
6206 * KDM, September 8th, 1998
6209 sprintf(combinedopt, "%s%s", mainopt, subopt);
6211 sprintf(combinedopt, "%s", mainopt);
6214 * For these options we do not parse optional device arguments and
6215 * we do not open a passthrough device.
6217 if ((cmdlist == CAM_CMD_RESCAN)
6218 || (cmdlist == CAM_CMD_RESET)
6219 || (cmdlist == CAM_CMD_DEVTREE)
6220 || (cmdlist == CAM_CMD_USAGE)
6221 || (cmdlist == CAM_CMD_DEBUG))
6224 #ifndef MINIMALISTIC
6226 && (argc > 2 && argv[2][0] != '-')) {
6230 if (isdigit(argv[2][0])) {
6231 /* device specified as bus:target[:lun] */
6232 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
6234 errx(1, "numeric device specification must "
6235 "be either bus:target, or "
6237 /* default to 0 if lun was not specified */
6238 if ((arglist & CAM_ARG_LUN) == 0) {
6240 arglist |= CAM_ARG_LUN;
6244 if (cam_get_device(argv[2], name, sizeof name, &unit)
6246 errx(1, "%s", cam_errbuf);
6247 device = strdup(name);
6248 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
6252 #endif /* MINIMALISTIC */
6254 * Start getopt processing at argv[2/3], since we've already
6255 * accepted argv[1..2] as the command name, and as a possible
6261 * Now we run through the argument list looking for generic
6262 * options, and ignoring options that possibly belong to
6265 while ((c = getopt(argc, argv, combinedopt))!= -1){
6268 retry_count = strtol(optarg, NULL, 0);
6269 if (retry_count < 0)
6270 errx(1, "retry count %d is < 0",
6272 arglist |= CAM_ARG_RETRIES;
6275 arglist |= CAM_ARG_ERR_RECOVER;
6278 arglist |= CAM_ARG_DEVICE;
6280 while (isspace(*tstr) && (*tstr != '\0'))
6282 device = (char *)strdup(tstr);
6285 timeout = strtol(optarg, NULL, 0);
6287 errx(1, "invalid timeout %d", timeout);
6288 /* Convert the timeout from seconds to ms */
6290 arglist |= CAM_ARG_TIMEOUT;
6293 arglist |= CAM_ARG_UNIT;
6294 unit = strtol(optarg, NULL, 0);
6297 arglist |= CAM_ARG_VERBOSE;
6304 #ifndef MINIMALISTIC
6306 * For most commands we'll want to open the passthrough device
6307 * associated with the specified device. In the case of the rescan
6308 * commands, we don't use a passthrough device at all, just the
6309 * transport layer device.
6312 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
6313 && (((arglist & CAM_ARG_DEVICE) == 0)
6314 || ((arglist & CAM_ARG_UNIT) == 0))) {
6315 errx(1, "subcommand \"%s\" requires a valid device "
6316 "identifier", argv[1]);
6319 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
6320 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
6321 cam_open_spec_device(device,unit,O_RDWR,NULL)))
6323 errx(1,"%s", cam_errbuf);
6325 #endif /* MINIMALISTIC */
6328 * Reset optind to 2, and reset getopt, so these routines can parse
6329 * the arguments again.
6335 #ifndef MINIMALISTIC
6336 case CAM_CMD_DEVLIST:
6337 error = getdevlist(cam_dev);
6340 error = atahpa(cam_dev, retry_count, timeout,
6341 argc, argv, combinedopt);
6343 #endif /* MINIMALISTIC */
6344 case CAM_CMD_DEVTREE:
6345 error = getdevtree();
6347 #ifndef MINIMALISTIC
6349 error = testunitready(cam_dev, retry_count, timeout, 0);
6351 case CAM_CMD_INQUIRY:
6352 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
6353 retry_count, timeout);
6355 case CAM_CMD_IDENTIFY:
6356 error = ataidentify(cam_dev, retry_count, timeout);
6358 case CAM_CMD_STARTSTOP:
6359 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
6360 arglist & CAM_ARG_EJECT, retry_count,
6363 #endif /* MINIMALISTIC */
6364 case CAM_CMD_RESCAN:
6365 error = dorescan_or_reset(argc, argv, 1);
6368 error = dorescan_or_reset(argc, argv, 0);
6370 #ifndef MINIMALISTIC
6371 case CAM_CMD_READ_DEFECTS:
6372 error = readdefects(cam_dev, argc, argv, combinedopt,
6373 retry_count, timeout);
6375 case CAM_CMD_MODE_PAGE:
6376 modepage(cam_dev, argc, argv, combinedopt,
6377 retry_count, timeout);
6379 case CAM_CMD_SCSI_CMD:
6380 error = scsicmd(cam_dev, argc, argv, combinedopt,
6381 retry_count, timeout);
6384 error = camdebug(argc, argv, combinedopt);
6387 error = tagcontrol(cam_dev, argc, argv, combinedopt);
6390 error = ratecontrol(cam_dev, retry_count, timeout,
6391 argc, argv, combinedopt);
6393 case CAM_CMD_FORMAT:
6394 error = scsiformat(cam_dev, argc, argv,
6395 combinedopt, retry_count, timeout);
6397 case CAM_CMD_REPORTLUNS:
6398 error = scsireportluns(cam_dev, argc, argv,
6399 combinedopt, retry_count,
6402 case CAM_CMD_READCAP:
6403 error = scsireadcapacity(cam_dev, argc, argv,
6404 combinedopt, retry_count,
6408 case CAM_CMD_STANDBY:
6410 error = atapm(cam_dev, argc, argv,
6411 combinedopt, retry_count, timeout);
6413 case CAM_CMD_SECURITY:
6414 error = atasecurity(cam_dev, retry_count, timeout,
6415 argc, argv, combinedopt);
6417 #endif /* MINIMALISTIC */
6427 if (cam_dev != NULL)
6428 cam_close_device(cam_dev);