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 #include <sys/ioctl.h>
31 #include <sys/stdint.h>
32 #include <sys/types.h>
34 #include <sys/endian.h>
52 #include <cam/cam_debug.h>
53 #include <cam/cam_ccb.h>
54 #include <cam/scsi/scsi_all.h>
55 #include <cam/scsi/scsi_da.h>
56 #include <cam/scsi/scsi_pass.h>
57 #include <cam/scsi/scsi_message.h>
58 #include <cam/scsi/smp_all.h>
59 #include <cam/ata/ata_all.h>
60 #include <cam/mmc/mmc_all.h>
62 #include "camcontrol.h"
64 #include "nvmecontrol_ext.h"
117 CAM_ARG_NONE = 0x00000000,
118 CAM_ARG_VERBOSE = 0x00000001,
119 CAM_ARG_DEVICE = 0x00000002,
120 CAM_ARG_BUS = 0x00000004,
121 CAM_ARG_TARGET = 0x00000008,
122 CAM_ARG_LUN = 0x00000010,
123 CAM_ARG_EJECT = 0x00000020,
124 CAM_ARG_UNIT = 0x00000040,
125 /* unused 0x00000080 */
126 /* unused 0x00000100 */
127 /* unused 0x00000200 */
128 /* unused 0x00000400 */
129 /* unused 0x00000800 */
130 CAM_ARG_GET_SERIAL = 0x00001000,
131 CAM_ARG_GET_STDINQ = 0x00002000,
132 CAM_ARG_GET_XFERRATE = 0x00004000,
133 CAM_ARG_INQ_MASK = 0x00007000,
134 /* unused 0x00008000 */
135 /* unused 0x00010000 */
136 CAM_ARG_TIMEOUT = 0x00020000,
137 CAM_ARG_CMD_IN = 0x00040000,
138 CAM_ARG_CMD_OUT = 0x00080000,
139 /* unused 0x00100000 */
140 CAM_ARG_ERR_RECOVER = 0x00200000,
141 CAM_ARG_RETRIES = 0x00400000,
142 CAM_ARG_START_UNIT = 0x00800000,
143 CAM_ARG_DEBUG_INFO = 0x01000000,
144 CAM_ARG_DEBUG_TRACE = 0x02000000,
145 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
146 CAM_ARG_DEBUG_CDB = 0x08000000,
147 CAM_ARG_DEBUG_XPT = 0x10000000,
148 CAM_ARG_DEBUG_PERIPH = 0x20000000,
149 CAM_ARG_DEBUG_PROBE = 0x40000000,
150 /* unused 0x80000000 */
153 struct camcontrol_opts {
160 struct ata_set_max_pwd
163 uint8_t password[32];
164 uint16_t reserved2[239];
167 static struct scsi_nv task_attrs[] = {
168 { "simple", MSG_SIMPLE_Q_TAG },
169 { "head", MSG_HEAD_OF_Q_TAG },
170 { "ordered", MSG_ORDERED_Q_TAG },
171 { "iwr", MSG_IGN_WIDE_RESIDUE },
172 { "aca", MSG_ACA_TASK }
175 static const char scsicmd_opts[] = "a:c:dfi:o:r";
176 static const char readdefect_opts[] = "f:GPqsS:X";
177 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
178 static const char smprg_opts[] = "l";
179 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
180 static const char smpphylist_opts[] = "lq";
183 static struct camcontrol_opts option_table[] = {
184 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
185 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
186 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
187 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
188 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
189 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
190 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
191 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
192 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
193 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
194 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
195 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
196 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
197 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:F:f:Wb:l:41S:I"},
198 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
199 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
200 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
201 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
202 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
203 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
204 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
205 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
206 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
207 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
208 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
209 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
210 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
211 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
212 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm:DLP:"},
213 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
214 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
215 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
216 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
217 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
218 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
219 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
220 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
221 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
222 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
223 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
224 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
225 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
226 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
227 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
228 {"ama", CAM_CMD_AMA, CAM_ARG_NONE, "fqs:"},
229 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
230 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
231 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
232 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
233 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
234 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
235 {"depop", CAM_CMD_DEPOP, CAM_ARG_NONE, "ac:de:ls"},
236 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
237 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
238 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
243 struct device_match_result dev_match;
245 struct periph_match_result *periph_matches;
246 struct scsi_vpd_device_id *device_id;
248 STAILQ_ENTRY(cam_devitem) links;
252 STAILQ_HEAD(, cam_devitem) dev_queue;
256 static cam_argmask arglist;
258 static const char *devtype_names[] = {
268 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
269 uint32_t *cmdnum, cam_argmask *argnum,
270 const char **subopt);
271 static int getdevlist(struct cam_device *device);
272 static int getdevtree(int argc, char **argv, char *combinedopt);
273 static int getdevtype(struct cam_device *device);
274 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
275 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
276 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
277 static int print_dev_mmcsd(struct device_match_result *dev_result,
280 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
282 static int testunitready(struct cam_device *device, int task_attr,
283 int retry_count, int timeout, int quiet);
284 static int scsistart(struct cam_device *device, int startstop, int loadeject,
285 int task_attr, int retry_count, int timeout);
286 static int scsiinquiry(struct cam_device *device, int task_attr,
287 int retry_count, int timeout);
288 static int scsiserial(struct cam_device *device, int task_attr,
289 int retry_count, int timeout);
290 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
291 lun_id_t *lun, cam_argmask *arglst);
292 static int reprobe(struct cam_device *device);
293 static int dorescan_or_reset(int argc, char **argv, int rescan);
294 static int rescan_or_reset_bus(path_id_t bus, int rescan);
295 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
296 lun_id_t lun, int scan);
297 static int readdefects(struct cam_device *device, int argc, char **argv,
298 char *combinedopt, int task_attr, int retry_count,
300 static void modepage(struct cam_device *device, int argc, char **argv,
301 char *combinedopt, int task_attr, int retry_count,
303 static int scsicmd(struct cam_device *device, int argc, char **argv,
304 char *combinedopt, int task_attr, int retry_count,
306 static int smpcmd(struct cam_device *device, int argc, char **argv,
307 char *combinedopt, int retry_count, int timeout);
308 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int retry_count, int timeout);
310 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
311 char *combinedopt, int retry_count, int timeout);
312 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
313 char *combinedopt, int retry_count, int timeout);
314 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int retry_count, int timeout);
316 static int getdevid(struct cam_devitem *item);
317 static int buildbusdevlist(struct cam_devlist *devlist);
318 static void freebusdevlist(struct cam_devlist *devlist);
319 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
321 static int smpphylist(struct cam_device *device, int argc, char **argv,
322 char *combinedopt, int retry_count, int timeout);
323 static int tagcontrol(struct cam_device *device, int argc, char **argv,
325 static void cts_print(struct cam_device *device,
326 struct ccb_trans_settings *cts);
327 static void cpi_print(struct ccb_pathinq *cpi);
328 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
329 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
330 static int get_print_cts(struct cam_device *device, int user_settings,
331 int quiet, struct ccb_trans_settings *cts);
332 static int ratecontrol(struct cam_device *device, int task_attr,
333 int retry_count, int timeout, int argc, char **argv,
335 static int scsiformat(struct cam_device *device, int argc, char **argv,
336 char *combinedopt, int task_attr, int retry_count,
338 static int sanitize(struct cam_device *device, int argc, char **argv,
339 char *combinedopt, int task_attr, int retry_count,
341 static int scsireportluns(struct cam_device *device, int argc, char **argv,
342 char *combinedopt, int task_attr, int retry_count,
344 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
345 char *combinedopt, int task_attr, int retry_count,
347 static int atapm(struct cam_device *device, int argc, char **argv,
348 char *combinedopt, int retry_count, int timeout);
349 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
350 int argc, char **argv, char *combinedopt);
351 static int atahpa(struct cam_device *device, int retry_count, int timeout,
352 int argc, char **argv, char *combinedopt);
353 static int ataama(struct cam_device *device, int retry_count, int timeout,
354 int argc, char **argv, char *combinedopt);
355 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
356 int sa_set, int req_sa, uint8_t *buf,
358 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
360 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
361 char *combinedopt, int task_attr, int retry_count,
362 int timeout, int verbose);
365 #define min(a,b) (((a)<(b))?(a):(b))
368 #define max(a,b) (((a)>(b))?(a):(b))
372 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
373 cam_argmask *argnum, const char **subopt)
375 struct camcontrol_opts *opts;
378 for (opts = table; (opts != NULL) && (opts->optname != NULL);
380 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
381 *cmdnum = opts->cmdnum;
382 *argnum = opts->argnum;
383 *subopt = opts->subopt;
384 if (++num_matches > 1)
385 return (CC_OR_AMBIGUOUS);
390 return (CC_OR_FOUND);
392 return (CC_OR_NOT_FOUND);
396 getdevlist(struct cam_device *device)
402 ccb = cam_getccb(device);
404 ccb->ccb_h.func_code = XPT_GDEVLIST;
405 ccb->ccb_h.flags = CAM_DIR_NONE;
406 ccb->ccb_h.retry_count = 1;
408 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
409 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
410 if (cam_send_ccb(device, ccb) < 0) {
411 warn("error getting device list");
418 switch (ccb->cgdl.status) {
419 case CAM_GDEVLIST_MORE_DEVS:
420 strcpy(status, "MORE");
422 case CAM_GDEVLIST_LAST_DEVICE:
423 strcpy(status, "LAST");
425 case CAM_GDEVLIST_LIST_CHANGED:
426 strcpy(status, "CHANGED");
428 case CAM_GDEVLIST_ERROR:
429 strcpy(status, "ERROR");
434 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
435 ccb->cgdl.periph_name,
436 ccb->cgdl.unit_number,
437 ccb->cgdl.generation,
442 * If the list has changed, we need to start over from the
445 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
455 getdevtree(int argc, char **argv, char *combinedopt)
466 while ((c = getopt(argc, argv, combinedopt)) != -1) {
469 if ((arglist & CAM_ARG_VERBOSE) == 0)
477 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
478 warn("couldn't open %s", XPT_DEVICE);
482 bzero(&ccb, sizeof(union ccb));
484 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
485 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
486 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
488 ccb.ccb_h.func_code = XPT_DEV_MATCH;
489 bufsize = sizeof(struct dev_match_result) * 100;
490 ccb.cdm.match_buf_len = bufsize;
491 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
492 if (ccb.cdm.matches == NULL) {
493 warnx("can't malloc memory for matches");
497 ccb.cdm.num_matches = 0;
500 * We fetch all nodes, since we display most of them in the default
501 * case, and all in the verbose case.
503 ccb.cdm.num_patterns = 0;
504 ccb.cdm.pattern_buf_len = 0;
507 * We do the ioctl multiple times if necessary, in case there are
508 * more than 100 nodes in the EDT.
511 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
512 warn("error sending CAMIOCOMMAND ioctl");
517 if ((ccb.ccb_h.status != CAM_REQ_CMP)
518 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
519 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
520 warnx("got CAM error %#x, CDM error %d\n",
521 ccb.ccb_h.status, ccb.cdm.status);
526 for (i = 0; i < ccb.cdm.num_matches; i++) {
527 switch (ccb.cdm.matches[i].type) {
528 case DEV_MATCH_BUS: {
529 struct bus_match_result *bus_result;
532 * Only print the bus information if the
533 * user turns on the verbose flag.
535 if ((busonly == 0) &&
536 (arglist & CAM_ARG_VERBOSE) == 0)
540 &ccb.cdm.matches[i].result.bus_result;
543 fprintf(stdout, ")\n");
547 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
549 bus_result->dev_name,
550 bus_result->unit_number,
552 (busonly ? "" : ":"));
555 case DEV_MATCH_DEVICE: {
556 struct device_match_result *dev_result;
563 &ccb.cdm.matches[i].result.device_result;
565 if ((dev_result->flags
566 & DEV_RESULT_UNCONFIGURED)
567 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
573 if (dev_result->protocol == PROTO_SCSI) {
574 if (print_dev_scsi(dev_result,
579 } else if (dev_result->protocol == PROTO_ATA ||
580 dev_result->protocol == PROTO_SATAPM) {
581 if (print_dev_ata(dev_result,
586 } else if (dev_result->protocol == PROTO_MMCSD){
587 if (print_dev_mmcsd(dev_result,
592 } else if (dev_result->protocol == PROTO_SEMB) {
593 if (print_dev_semb(dev_result,
599 } else if (dev_result->protocol == PROTO_NVME) {
600 if (print_dev_nvme(dev_result,
607 sprintf(tmpstr, "<>");
610 fprintf(stdout, ")\n");
614 fprintf(stdout, "%-33s at scbus%d "
615 "target %d lun %jx (",
618 dev_result->target_id,
619 (uintmax_t)dev_result->target_lun);
625 case DEV_MATCH_PERIPH: {
626 struct periph_match_result *periph_result;
629 &ccb.cdm.matches[i].result.periph_result;
631 if (busonly || skip_device != 0)
635 fprintf(stdout, ",");
637 fprintf(stdout, "%s%d",
638 periph_result->periph_name,
639 periph_result->unit_number);
645 fprintf(stdout, "unknown match type\n");
650 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
651 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
654 fprintf(stdout, ")\n");
662 getdevtype(struct cam_device *cam_dev)
664 camcontrol_devtype dt;
668 * Get the device type and report it, request no I/O be done to do this.
670 error = get_device_type(cam_dev, -1, 0, 0, &dt);
671 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
672 fprintf(stdout, "illegal\n");
675 fprintf(stdout, "%s\n", devtype_names[dt]);
680 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
682 char vendor[16], product[48], revision[16];
684 cam_strvis(vendor, dev_result->inq_data.vendor,
685 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
686 cam_strvis(product, dev_result->inq_data.product,
687 sizeof(dev_result->inq_data.product), sizeof(product));
688 cam_strvis(revision, dev_result->inq_data.revision,
689 sizeof(dev_result->inq_data.revision), sizeof(revision));
690 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
696 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
698 char product[48], revision[16];
700 cam_strvis(product, dev_result->ident_data.model,
701 sizeof(dev_result->ident_data.model), sizeof(product));
702 cam_strvis(revision, dev_result->ident_data.revision,
703 sizeof(dev_result->ident_data.revision), sizeof(revision));
704 sprintf(tmpstr, "<%s %s>", product, revision);
710 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
712 struct sep_identify_data *sid;
713 char vendor[16], product[48], revision[16], fw[5];
715 sid = (struct sep_identify_data *)&dev_result->ident_data;
716 cam_strvis(vendor, sid->vendor_id,
717 sizeof(sid->vendor_id), sizeof(vendor));
718 cam_strvis(product, sid->product_id,
719 sizeof(sid->product_id), sizeof(product));
720 cam_strvis(revision, sid->product_rev,
721 sizeof(sid->product_rev), sizeof(revision));
722 cam_strvis(fw, sid->firmware_rev,
723 sizeof(sid->firmware_rev), sizeof(fw));
724 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
730 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
733 struct ccb_dev_advinfo *advi;
734 struct cam_device *dev;
735 struct mmc_params mmc_ident_data;
737 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
738 dev_result->target_lun, O_RDWR, NULL);
740 warnx("%s", cam_errbuf);
744 ccb = cam_getccb(dev);
746 warnx("couldn't allocate CCB");
747 cam_close_device(dev);
752 advi->ccb_h.flags = CAM_DIR_IN;
753 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
754 advi->flags = CDAI_FLAG_NONE;
755 advi->buftype = CDAI_TYPE_MMC_PARAMS;
756 advi->bufsiz = sizeof(struct mmc_params);
757 advi->buf = (uint8_t *)&mmc_ident_data;
759 if (cam_send_ccb(dev, ccb) < 0) {
760 warn("error sending XPT_DEV_ADVINFO CCB");
762 cam_close_device(dev);
766 if (strlen(mmc_ident_data.model) > 0) {
767 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
769 sprintf(tmpstr, "<%s card>",
770 mmc_ident_data.card_features &
771 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
775 cam_close_device(dev);
781 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
784 struct ccb_dev_advinfo *advi;
786 ccb = cam_getccb(dev);
788 warnx("couldn't allocate CCB");
789 cam_close_device(dev);
794 advi->ccb_h.flags = CAM_DIR_IN;
795 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
796 advi->flags = CDAI_FLAG_NONE;
797 advi->buftype = CDAI_TYPE_NVME_CNTRL;
798 advi->bufsiz = sizeof(struct nvme_controller_data);
799 advi->buf = (uint8_t *)cdata;
801 if (cam_send_ccb(dev, ccb) < 0) {
802 warn("error sending XPT_DEV_ADVINFO CCB");
804 cam_close_device(dev);
807 if (advi->ccb_h.status != CAM_REQ_CMP) {
808 warnx("got CAM error %#x", advi->ccb_h.status);
810 cam_close_device(dev);
818 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
820 struct cam_device *dev;
821 struct nvme_controller_data cdata;
822 char vendor[64], product[64];
824 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
825 dev_result->target_lun, O_RDWR, NULL);
827 warnx("%s", cam_errbuf);
831 if (nvme_get_cdata(dev, &cdata))
834 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
835 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
836 sprintf(tmpstr, "<%s %s>", vendor, product);
838 cam_close_device(dev);
844 testunitready(struct cam_device *device, int task_attr, int retry_count,
845 int timeout, int quiet)
850 ccb = cam_getccb(device);
852 scsi_test_unit_ready(&ccb->csio,
853 /* retries */ retry_count,
855 /* tag_action */ task_attr,
856 /* sense_len */ SSD_FULL_SIZE,
857 /* timeout */ timeout ? timeout : 5000);
859 /* Disable freezing the device queue */
860 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
862 if (arglist & CAM_ARG_ERR_RECOVER)
863 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
865 if (cam_send_ccb(device, ccb) < 0) {
867 warn("error sending TEST UNIT READY command");
872 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
874 fprintf(stdout, "Unit is ready\n");
877 fprintf(stdout, "Unit is not ready\n");
880 if (arglist & CAM_ARG_VERBOSE) {
881 cam_error_print(device, ccb, CAM_ESF_ALL,
882 CAM_EPF_ALL, stderr);
892 scsistart(struct cam_device *device, int startstop, int loadeject,
893 int task_attr, int retry_count, int timeout)
898 ccb = cam_getccb(device);
901 * If we're stopping, send an ordered tag so the drive in question
902 * will finish any previously queued writes before stopping. If
903 * the device isn't capable of tagged queueing, or if tagged
904 * queueing is turned off, the tag action is a no-op. We override
905 * the default simple tag, although this also has the effect of
906 * overriding the user's wishes if he wanted to specify a simple
910 && (task_attr == MSG_SIMPLE_Q_TAG))
911 task_attr = MSG_ORDERED_Q_TAG;
913 scsi_start_stop(&ccb->csio,
914 /* retries */ retry_count,
916 /* tag_action */ task_attr,
917 /* start/stop */ startstop,
918 /* load_eject */ loadeject,
920 /* sense_len */ SSD_FULL_SIZE,
921 /* timeout */ timeout ? timeout : 120000);
923 /* Disable freezing the device queue */
924 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
926 if (arglist & CAM_ARG_ERR_RECOVER)
927 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
929 if (cam_send_ccb(device, ccb) < 0) {
930 warn("error sending START STOP UNIT command");
935 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
937 fprintf(stdout, "Unit started successfully");
939 fprintf(stdout,", Media loaded\n");
941 fprintf(stdout,"\n");
943 fprintf(stdout, "Unit stopped successfully");
945 fprintf(stdout, ", Media ejected\n");
947 fprintf(stdout, "\n");
953 "Error received from start unit command\n");
956 "Error received from stop unit command\n");
958 if (arglist & CAM_ARG_VERBOSE) {
959 cam_error_print(device, ccb, CAM_ESF_ALL,
960 CAM_EPF_ALL, stderr);
970 scsidoinquiry(struct cam_device *device, int argc, char **argv,
971 char *combinedopt, int task_attr, int retry_count, int timeout)
976 while ((c = getopt(argc, argv, combinedopt)) != -1) {
979 arglist |= CAM_ARG_GET_STDINQ;
982 arglist |= CAM_ARG_GET_XFERRATE;
985 arglist |= CAM_ARG_GET_SERIAL;
993 * If the user didn't specify any inquiry options, he wants all of
996 if ((arglist & CAM_ARG_INQ_MASK) == 0)
997 arglist |= CAM_ARG_INQ_MASK;
999 if (arglist & CAM_ARG_GET_STDINQ)
1000 error = scsiinquiry(device, task_attr, retry_count, timeout);
1005 if (arglist & CAM_ARG_GET_SERIAL)
1006 scsiserial(device, task_attr, retry_count, timeout);
1008 if (arglist & CAM_ARG_GET_XFERRATE)
1009 error = camxferrate(device);
1015 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1019 struct scsi_inquiry_data *inq_buf;
1022 ccb = cam_getccb(device);
1025 warnx("couldn't allocate CCB");
1029 inq_buf = (struct scsi_inquiry_data *)malloc(
1030 sizeof(struct scsi_inquiry_data));
1032 if (inq_buf == NULL) {
1034 warnx("can't malloc memory for inquiry\n");
1037 bzero(inq_buf, sizeof(*inq_buf));
1040 * Note that although the size of the inquiry buffer is the full
1041 * 256 bytes specified in the SCSI spec, we only tell the device
1042 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1043 * two reasons for this:
1045 * - The SCSI spec says that when a length field is only 1 byte,
1046 * a value of 0 will be interpreted as 256. Therefore
1047 * scsi_inquiry() will convert an inq_len (which is passed in as
1048 * a uint32_t, but the field in the CDB is only 1 byte) of 256
1049 * to 0. Evidently, very few devices meet the spec in that
1050 * regard. Some devices, like many Seagate disks, take the 0 as
1051 * 0, and don't return any data. One Pioneer DVD-R drive
1052 * returns more data than the command asked for.
1054 * So, since there are numerous devices that just don't work
1055 * right with the full inquiry size, we don't send the full size.
1057 * - The second reason not to use the full inquiry data length is
1058 * that we don't need it here. The only reason we issue a
1059 * standard inquiry is to get the vendor name, device name,
1060 * and revision so scsi_print_inquiry() can print them.
1062 * If, at some point in the future, more inquiry data is needed for
1063 * some reason, this code should use a procedure similar to the
1064 * probe code. i.e., issue a short inquiry, and determine from
1065 * the additional length passed back from the device how much
1066 * inquiry data the device supports. Once the amount the device
1067 * supports is determined, issue an inquiry for that amount and no
1072 scsi_inquiry(&ccb->csio,
1073 /* retries */ retry_count,
1075 /* tag_action */ task_attr,
1076 /* inq_buf */ (uint8_t *)inq_buf,
1077 /* inq_len */ SHORT_INQUIRY_LENGTH,
1080 /* sense_len */ SSD_FULL_SIZE,
1081 /* timeout */ timeout ? timeout : 5000);
1083 /* Disable freezing the device queue */
1084 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1086 if (arglist & CAM_ARG_ERR_RECOVER)
1087 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1089 if (cam_send_ccb(device, ccb) < 0) {
1090 warn("error sending INQUIRY command");
1095 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1098 if (arglist & CAM_ARG_VERBOSE) {
1099 cam_error_print(device, ccb, CAM_ESF_ALL,
1100 CAM_EPF_ALL, stderr);
1111 fprintf(stdout, "%s%d: ", device->device_name,
1112 device->dev_unit_num);
1113 scsi_print_inquiry(inq_buf);
1121 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1125 struct scsi_vpd_unit_serial_number *serial_buf;
1126 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1129 ccb = cam_getccb(device);
1132 warnx("couldn't allocate CCB");
1136 serial_buf = (struct scsi_vpd_unit_serial_number *)
1137 malloc(sizeof(*serial_buf));
1139 if (serial_buf == NULL) {
1141 warnx("can't malloc memory for serial number");
1145 scsi_inquiry(&ccb->csio,
1146 /*retries*/ retry_count,
1148 /* tag_action */ task_attr,
1149 /* inq_buf */ (uint8_t *)serial_buf,
1150 /* inq_len */ sizeof(*serial_buf),
1152 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1153 /* sense_len */ SSD_FULL_SIZE,
1154 /* timeout */ timeout ? timeout : 5000);
1156 /* Disable freezing the device queue */
1157 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1159 if (arglist & CAM_ARG_ERR_RECOVER)
1160 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1162 if (cam_send_ccb(device, ccb) < 0) {
1163 warn("error sending INQUIRY command");
1169 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1172 if (arglist & CAM_ARG_VERBOSE) {
1173 cam_error_print(device, ccb, CAM_ESF_ALL,
1174 CAM_EPF_ALL, stderr);
1185 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1186 serial_num[serial_buf->length] = '\0';
1188 if ((arglist & CAM_ARG_GET_STDINQ)
1189 || (arglist & CAM_ARG_GET_XFERRATE))
1190 fprintf(stdout, "%s%d: Serial Number ",
1191 device->device_name, device->dev_unit_num);
1193 fprintf(stdout, "%.60s\n", serial_num);
1201 camxferrate(struct cam_device *device)
1203 struct ccb_pathinq cpi;
1210 if ((retval = get_cpi(device, &cpi)) != 0)
1213 ccb = cam_getccb(device);
1216 warnx("couldn't allocate CCB");
1220 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1221 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1223 if (((retval = cam_send_ccb(device, ccb)) < 0)
1224 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1225 const char error_string[] = "error getting transfer settings";
1230 warnx(error_string);
1232 if (arglist & CAM_ARG_VERBOSE)
1233 cam_error_print(device, ccb, CAM_ESF_ALL,
1234 CAM_EPF_ALL, stderr);
1238 goto xferrate_bailout;
1242 speed = cpi.base_transfer_speed;
1244 if (ccb->cts.transport == XPORT_SPI) {
1245 struct ccb_trans_settings_spi *spi =
1246 &ccb->cts.xport_specific.spi;
1248 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1249 freq = scsi_calc_syncsrate(spi->sync_period);
1252 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1253 speed *= (0x01 << spi->bus_width);
1255 } else if (ccb->cts.transport == XPORT_FC) {
1256 struct ccb_trans_settings_fc *fc =
1257 &ccb->cts.xport_specific.fc;
1259 if (fc->valid & CTS_FC_VALID_SPEED)
1260 speed = fc->bitrate;
1261 } else if (ccb->cts.transport == XPORT_SAS) {
1262 struct ccb_trans_settings_sas *sas =
1263 &ccb->cts.xport_specific.sas;
1265 if (sas->valid & CTS_SAS_VALID_SPEED)
1266 speed = sas->bitrate;
1267 } else if (ccb->cts.transport == XPORT_ATA) {
1268 struct ccb_trans_settings_pata *pata =
1269 &ccb->cts.xport_specific.ata;
1271 if (pata->valid & CTS_ATA_VALID_MODE)
1272 speed = ata_mode2speed(pata->mode);
1273 } else if (ccb->cts.transport == XPORT_SATA) {
1274 struct ccb_trans_settings_sata *sata =
1275 &ccb->cts.xport_specific.sata;
1277 if (sata->valid & CTS_SATA_VALID_REVISION)
1278 speed = ata_revision2speed(sata->revision);
1283 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1284 device->device_name, device->dev_unit_num,
1287 fprintf(stdout, "%s%d: %dKB/s transfers",
1288 device->device_name, device->dev_unit_num,
1292 if (ccb->cts.transport == XPORT_SPI) {
1293 struct ccb_trans_settings_spi *spi =
1294 &ccb->cts.xport_specific.spi;
1296 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1297 && (spi->sync_offset != 0))
1298 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1299 freq % 1000, spi->sync_offset);
1301 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1302 && (spi->bus_width > 0)) {
1303 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1304 && (spi->sync_offset != 0)) {
1305 fprintf(stdout, ", ");
1307 fprintf(stdout, " (");
1309 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1310 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1311 && (spi->sync_offset != 0)) {
1312 fprintf(stdout, ")");
1314 } else if (ccb->cts.transport == XPORT_ATA) {
1315 struct ccb_trans_settings_pata *pata =
1316 &ccb->cts.xport_specific.ata;
1319 if (pata->valid & CTS_ATA_VALID_MODE)
1320 printf("%s, ", ata_mode2string(pata->mode));
1321 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1322 printf("ATAPI %dbytes, ", pata->atapi);
1323 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1324 printf("PIO %dbytes", pata->bytecount);
1326 } else if (ccb->cts.transport == XPORT_SATA) {
1327 struct ccb_trans_settings_sata *sata =
1328 &ccb->cts.xport_specific.sata;
1331 if (sata->valid & CTS_SATA_VALID_REVISION)
1332 printf("SATA %d.x, ", sata->revision);
1335 if (sata->valid & CTS_SATA_VALID_MODE)
1336 printf("%s, ", ata_mode2string(sata->mode));
1337 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1338 printf("ATAPI %dbytes, ", sata->atapi);
1339 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1340 printf("PIO %dbytes", sata->bytecount);
1344 if (ccb->cts.protocol == PROTO_SCSI) {
1345 struct ccb_trans_settings_scsi *scsi =
1346 &ccb->cts.proto_specific.scsi;
1347 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1348 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1349 fprintf(stdout, ", Command Queueing Enabled");
1354 fprintf(stdout, "\n");
1364 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1366 uint32_t lbasize = (uint32_t)parm->lba_size_1 |
1367 ((uint32_t)parm->lba_size_2 << 16);
1369 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1370 ((u_int64_t)parm->lba_size48_2 << 16) |
1371 ((u_int64_t)parm->lba_size48_3 << 32) |
1372 ((u_int64_t)parm->lba_size48_4 << 48);
1376 "Support Enabled Value\n");
1379 printf("Host Protected Area (HPA) ");
1380 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1381 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1382 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1385 printf("HPA - Security ");
1386 if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY)
1387 printf("yes %s\n", (parm->enabled.command2 &
1388 ATA_SUPPORT_MAXSECURITY) ? "yes" : "no ");
1397 ataama_print(struct ata_params *parm, u_int64_t nativesize, int header)
1399 uint32_t lbasize = (uint32_t)parm->lba_size_1 |
1400 ((uint32_t)parm->lba_size_2 << 16);
1402 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1403 ((u_int64_t)parm->lba_size48_2 << 16) |
1404 ((u_int64_t)parm->lba_size48_3 << 32) |
1405 ((u_int64_t)parm->lba_size48_4 << 48);
1409 "Support Enabled Value\n");
1412 printf("Accessible Max Address Config ");
1413 if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) {
1414 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1415 printf("yes %s %ju/%ju\n",
1416 (nativesize > lba) ? "yes" : "no ", lba, nativesize);
1423 atasata(struct ata_params *parm)
1427 if (parm->satacapabilities != 0xffff &&
1428 parm->satacapabilities != 0x0000)
1435 atacapprint(struct ata_params *parm)
1438 uint32_t lbasize = (uint32_t)parm->lba_size_1 |
1439 ((uint32_t)parm->lba_size_2 << 16);
1441 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1442 ((u_int64_t)parm->lba_size48_2 << 16) |
1443 ((u_int64_t)parm->lba_size48_3 << 32) |
1444 ((u_int64_t)parm->lba_size48_4 << 48);
1447 printf("protocol ");
1448 proto = (parm->config == ATA_PROTO_CFA) ? "CFA" :
1449 (parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
1450 if (ata_version(parm->version_major) == 0) {
1451 printf("%s", proto);
1452 } else if (ata_version(parm->version_major) <= 7) {
1453 printf("%s-%d", proto,
1454 ata_version(parm->version_major));
1455 } else if (ata_version(parm->version_major) == 8) {
1456 printf("%s8-ACS", proto);
1459 ata_version(parm->version_major) - 7, proto);
1461 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1462 if (parm->satacapabilities & ATA_SATA_GEN3)
1463 printf(" SATA 3.x\n");
1464 else if (parm->satacapabilities & ATA_SATA_GEN2)
1465 printf(" SATA 2.x\n");
1466 else if (parm->satacapabilities & ATA_SATA_GEN1)
1467 printf(" SATA 1.x\n");
1473 printf("device model %.40s\n", parm->model);
1474 printf("firmware revision %.8s\n", parm->revision);
1475 printf("serial number %.20s\n", parm->serial);
1476 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1477 printf("WWN %04x%04x%04x%04x\n",
1478 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1480 printf("additional product id %.8s\n", parm->product_id);
1481 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1482 printf("media serial number %.30s\n",
1483 parm->media_serial);
1486 printf("cylinders %d\n", parm->cylinders);
1487 printf("heads %d\n", parm->heads);
1488 printf("sectors/track %d\n", parm->sectors);
1489 printf("sector size logical %u, physical %lu, offset %lu\n",
1490 ata_logical_sector_size(parm),
1491 (unsigned long)ata_physical_sector_size(parm),
1492 (unsigned long)ata_logical_sector_offset(parm));
1494 if (parm->config == ATA_PROTO_CFA ||
1495 (parm->support.command2 & ATA_SUPPORT_CFA))
1496 printf("CFA supported\n");
1498 printf("LBA%ssupported ",
1499 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1501 printf("%d sectors\n", lbasize);
1505 printf("LBA48%ssupported ",
1506 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1508 printf("%ju sectors\n", (uintmax_t)lbasize48);
1512 printf("PIO supported PIO");
1513 switch (ata_max_pmode(parm)) {
1529 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1530 printf(" w/o IORDY");
1533 printf("DMA%ssupported ",
1534 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1535 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1536 if (parm->mwdmamodes & 0xff) {
1538 if (parm->mwdmamodes & 0x04)
1540 else if (parm->mwdmamodes & 0x02)
1542 else if (parm->mwdmamodes & 0x01)
1546 if ((parm->atavalid & ATA_FLAG_88) &&
1547 (parm->udmamodes & 0xff)) {
1549 if (parm->udmamodes & 0x40)
1551 else if (parm->udmamodes & 0x20)
1553 else if (parm->udmamodes & 0x10)
1555 else if (parm->udmamodes & 0x08)
1557 else if (parm->udmamodes & 0x04)
1559 else if (parm->udmamodes & 0x02)
1561 else if (parm->udmamodes & 0x01)
1568 if (parm->media_rotation_rate == 1) {
1569 printf("media RPM non-rotating\n");
1570 } else if (parm->media_rotation_rate >= 0x0401 &&
1571 parm->media_rotation_rate <= 0xFFFE) {
1572 printf("media RPM %d\n",
1573 parm->media_rotation_rate);
1576 printf("Zoned-Device Commands ");
1577 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1578 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1579 printf("device managed\n");
1581 case ATA_SUPPORT_ZONE_HOST_AWARE:
1582 printf("host aware\n");
1589 "Support Enabled Value Vendor\n");
1590 printf("read ahead %s %s\n",
1591 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1592 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1593 printf("write cache %s %s\n",
1594 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1595 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1596 printf("flush cache %s %s\n",
1597 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1598 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1599 printf("Native Command Queuing (NCQ) ");
1600 if (atasata(parm) && (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1601 printf("yes %d tags\n",
1602 ATA_QUEUE_LEN(parm->queue) + 1);
1603 printf("NCQ Priority Information %s\n",
1604 parm->satacapabilities & ATA_SUPPORT_NCQ_PRIO ?
1606 printf("NCQ Non-Data Command %s\n",
1607 parm->satacapabilities2 & ATA_SUPPORT_NCQ_NON_DATA ?
1609 printf("NCQ Streaming %s\n",
1610 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1612 printf("Receive & Send FPDMA Queued %s\n",
1613 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1615 printf("NCQ Autosense %s\n",
1616 parm->satasupport & ATA_SUPPORT_NCQ_AUTOSENSE ?
1621 printf("SMART %s %s\n",
1622 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1623 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1624 printf("security %s %s\n",
1625 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1626 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1627 printf("power management %s %s\n",
1628 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1629 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1630 printf("microcode download %s %s\n",
1631 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1632 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1633 printf("advanced power management %s %s",
1634 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1635 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1636 if (parm->support.command2 & ATA_SUPPORT_APM) {
1637 printf(" %d/0x%02X\n",
1638 parm->apm_value & 0xff, parm->apm_value & 0xff);
1641 printf("automatic acoustic management %s %s",
1642 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1643 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1644 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1645 printf(" %d/0x%02X %d/0x%02X\n",
1646 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1647 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1648 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1649 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1652 printf("media status notification %s %s\n",
1653 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1654 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1655 printf("power-up in Standby %s %s\n",
1656 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1657 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1658 printf("write-read-verify %s %s",
1659 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1660 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1661 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1662 printf(" %d/0x%x\n",
1663 parm->wrv_mode, parm->wrv_mode);
1666 printf("unload %s %s\n",
1667 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1668 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1669 printf("general purpose logging %s %s\n",
1670 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1671 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1672 printf("free-fall %s %s\n",
1673 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1674 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1675 printf("sense data reporting %s %s\n",
1676 parm->support2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no",
1677 parm->enabled2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no");
1678 printf("extended power conditions %s %s\n",
1679 parm->support2 & ATA_SUPPORT_EPC ? "yes" : "no",
1680 parm->enabled2 & ATA_SUPPORT_EPC ? "yes" : "no");
1681 printf("device statistics notification %s %s\n",
1682 parm->support2 & ATA_SUPPORT_DSN ? "yes" : "no",
1683 parm->enabled2 & ATA_SUPPORT_DSN ? "yes" : "no");
1684 printf("Data Set Management (DSM/TRIM) ");
1685 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1687 printf("DSM - max 512byte blocks ");
1688 if (parm->max_dsm_blocks == 0x00)
1689 printf("yes not specified\n");
1692 parm->max_dsm_blocks);
1694 printf("DSM - deterministic read ");
1695 if (parm->support3 & ATA_SUPPORT_DRAT) {
1696 if (parm->support3 & ATA_SUPPORT_RZAT)
1697 printf("yes zeroed\n");
1699 printf("yes any value\n");
1706 printf("Trusted Computing %s\n",
1707 ((parm->tcg & 0xc000) == 0x4000) && (parm->tcg & ATA_SUPPORT_TCG) ?
1709 printf("encrypts all user data %s\n",
1710 parm->support3 & ATA_ENCRYPTS_ALL_USER_DATA ? "yes" : "no");
1711 printf("Sanitize ");
1712 if (parm->multi & ATA_SUPPORT_SANITIZE) {
1713 printf("yes\t\t%s%s%s\n",
1714 parm->multi & ATA_SUPPORT_BLOCK_ERASE_EXT ? "block, " : "",
1715 parm->multi & ATA_SUPPORT_OVERWRITE_EXT ? "overwrite, " : "",
1716 parm->multi & ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT ? "crypto" : "");
1717 printf("Sanitize - commands allowed %s\n",
1718 parm->multi & ATA_SUPPORT_SANITIZE_ALLOWED ? "yes" : "no");
1719 printf("Sanitize - antifreeze lock %s\n",
1720 parm->multi & ATA_SUPPORT_ANTIFREEZE_LOCK_EXT ? "yes" : "no");
1727 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb)
1729 struct ata_pass_16 *ata_pass_16;
1730 struct ata_cmd ata_cmd;
1732 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1733 ata_cmd.command = ata_pass_16->command;
1734 ata_cmd.control = ata_pass_16->control;
1735 ata_cmd.features = ata_pass_16->features;
1737 if (arglist & CAM_ARG_VERBOSE) {
1738 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1739 ata_op_string(&ata_cmd),
1740 ccb->csio.ccb_h.timeout);
1743 /* Disable freezing the device queue */
1744 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1746 if (arglist & CAM_ARG_ERR_RECOVER)
1747 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1749 if (cam_send_ccb(device, ccb) < 0) {
1750 warn("error sending ATA %s via pass_16", ata_op_string(&ata_cmd));
1755 * Consider any non-CAM_REQ_CMP status as error and report it here,
1756 * unless caller set AP_FLAG_CHK_COND, in which case it is responsible.
1758 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1759 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1760 warnx("ATA %s via pass_16 failed", ata_op_string(&ata_cmd));
1761 if (arglist & CAM_ARG_VERBOSE) {
1762 cam_error_print(device, ccb, CAM_ESF_ALL,
1763 CAM_EPF_ALL, stderr);
1773 ata_cam_send(struct cam_device *device, union ccb *ccb)
1775 if (arglist & CAM_ARG_VERBOSE) {
1776 warnx("sending ATA %s with timeout of %u msecs",
1777 ata_op_string(&(ccb->ataio.cmd)),
1778 ccb->ataio.ccb_h.timeout);
1781 /* Disable freezing the device queue */
1782 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1784 if (arglist & CAM_ARG_ERR_RECOVER)
1785 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1787 if (cam_send_ccb(device, ccb) < 0) {
1788 warn("error sending ATA %s", ata_op_string(&(ccb->ataio.cmd)));
1793 * Consider any non-CAM_REQ_CMP status as error and report it here,
1794 * unless caller set AP_FLAG_CHK_COND, in which case it is responsible.
1796 if (!(ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT) &&
1797 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1798 warnx("ATA %s failed", ata_op_string(&(ccb->ataio.cmd)));
1799 if (arglist & CAM_ARG_VERBOSE) {
1800 cam_error_print(device, ccb, CAM_ESF_ALL,
1801 CAM_EPF_ALL, stderr);
1810 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1811 uint32_t flags, uint8_t protocol, uint8_t ata_flags,
1812 uint8_t tag_action, uint8_t command, uint16_t features,
1813 u_int64_t lba, uint16_t sector_count, uint8_t *data_ptr,
1814 uint16_t dxfer_len, int timeout)
1816 if (data_ptr != NULL) {
1817 if (flags & CAM_DIR_OUT)
1818 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1820 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1822 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1825 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1827 scsi_ata_pass_16(&ccb->csio,
1841 /*sense_len*/SSD_FULL_SIZE,
1844 return scsi_cam_pass_16_send(device, ccb);
1848 ata_try_pass_16(struct cam_device *device)
1850 struct ccb_pathinq cpi;
1852 if (get_cpi(device, &cpi) != 0) {
1853 warnx("couldn't get CPI");
1857 if (cpi.protocol == PROTO_SCSI) {
1858 /* possibly compatible with pass_16 */
1862 /* likely not compatible with pass_16 */
1867 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1868 uint32_t flags, uint8_t protocol, uint8_t ata_flags,
1869 uint8_t tag_action, uint8_t command, uint16_t features,
1870 u_int64_t lba, uint16_t sector_count, uint8_t *data_ptr,
1871 uint16_t dxfer_len, int timeout, int force48bit)
1875 retval = ata_try_pass_16(device);
1880 return (ata_do_pass_16(device, ccb, retries, flags, protocol,
1881 ata_flags, tag_action, command, features,
1882 lba, sector_count, data_ptr, dxfer_len,
1886 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1887 cam_fill_ataio(&ccb->ataio,
1896 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1897 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1899 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1901 if (ata_flags & AP_FLAG_CHK_COND)
1902 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1904 return ata_cam_send(device, ccb);
1908 dump_data(uint16_t *ptr, uint32_t len)
1912 for (i = 0; i < len / 2; i++) {
1914 printf(" %3d: ", i);
1915 printf("%04hx ", ptr[i]);
1924 atahpa_proc_resp(struct cam_device *device, union ccb *ccb, u_int64_t *hpasize)
1926 uint8_t error = 0, ata_device = 0, status = 0;
1931 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
1934 if (arglist & CAM_ARG_VERBOSE) {
1935 cam_error_print(device, ccb, CAM_ESF_ALL,
1936 CAM_EPF_ALL, stderr);
1938 warnx("Can't get ATA command status");
1942 if (status & ATA_STATUS_ERROR) {
1943 if (arglist & CAM_ARG_VERBOSE) {
1944 cam_error_print(device, ccb, CAM_ESF_ALL,
1945 CAM_EPF_ALL, stderr);
1948 if (error & ATA_ERROR_ID_NOT_FOUND) {
1949 warnx("Max address has already been set since "
1950 "last power-on or hardware reset");
1951 } else if (hpasize == NULL)
1952 warnx("Command failed with ATA error");
1957 if (hpasize != NULL) {
1958 if (retval == 2 || retval == 6)
1967 ata_read_native_max(struct cam_device *device, int retry_count,
1968 uint32_t timeout, union ccb *ccb,
1969 struct ata_params *parm, u_int64_t *hpasize)
1975 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1976 protocol = AP_PROTO_NON_DATA;
1979 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1980 protocol |= AP_EXTEND;
1982 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1985 error = ata_do_cmd(device,
1988 /*flags*/CAM_DIR_NONE,
1989 /*protocol*/protocol,
1990 /*ata_flags*/AP_FLAG_CHK_COND,
1991 /*tag_action*/MSG_SIMPLE_Q_TAG,
1998 timeout ? timeout : 5000,
2004 return atahpa_proc_resp(device, ccb, hpasize);
2008 atahpa_set_max(struct cam_device *device, int retry_count,
2009 uint32_t timeout, union ccb *ccb,
2010 int is48bit, u_int64_t maxsize, int persist)
2016 protocol = AP_PROTO_NON_DATA;
2019 cmd = ATA_SET_MAX_ADDRESS48;
2020 protocol |= AP_EXTEND;
2022 cmd = ATA_SET_MAX_ADDRESS;
2025 /* lba's are zero indexed so the max lba is requested max - 1 */
2029 error = ata_do_cmd(device,
2032 /*flags*/CAM_DIR_NONE,
2033 /*protocol*/protocol,
2034 /*ata_flags*/AP_FLAG_CHK_COND,
2035 /*tag_action*/MSG_SIMPLE_Q_TAG,
2037 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2039 /*sector_count*/persist,
2042 timeout ? timeout : 1000,
2048 return atahpa_proc_resp(device, ccb, NULL);
2052 atahpa_password(struct cam_device *device, int retry_count,
2053 uint32_t timeout, union ccb *ccb,
2054 int is48bit, struct ata_set_max_pwd *pwd)
2059 protocol = AP_PROTO_PIO_OUT;
2060 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2062 return (ata_do_cmd(device,
2065 /*flags*/CAM_DIR_OUT,
2066 /*protocol*/protocol,
2067 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2068 AP_FLAG_TLEN_SECT_CNT,
2069 /*tag_action*/MSG_SIMPLE_Q_TAG,
2071 /*features*/ATA_HPA_FEAT_SET_PWD,
2073 /*sector_count*/sizeof(*pwd) / 512,
2074 /*data_ptr*/(uint8_t*)pwd,
2075 /*dxfer_len*/sizeof(*pwd),
2076 timeout ? timeout : 1000,
2081 atahpa_lock(struct cam_device *device, int retry_count,
2082 uint32_t timeout, union ccb *ccb, int is48bit)
2087 protocol = AP_PROTO_NON_DATA;
2088 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2090 return (ata_do_cmd(device,
2093 /*flags*/CAM_DIR_NONE,
2094 /*protocol*/protocol,
2096 /*tag_action*/MSG_SIMPLE_Q_TAG,
2098 /*features*/ATA_HPA_FEAT_LOCK,
2103 timeout ? timeout : 1000,
2108 atahpa_unlock(struct cam_device *device, int retry_count,
2109 uint32_t timeout, union ccb *ccb,
2110 int is48bit, struct ata_set_max_pwd *pwd)
2115 protocol = AP_PROTO_PIO_OUT;
2116 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2118 return (ata_do_cmd(device,
2121 /*flags*/CAM_DIR_OUT,
2122 /*protocol*/protocol,
2123 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2124 AP_FLAG_TLEN_SECT_CNT,
2125 /*tag_action*/MSG_SIMPLE_Q_TAG,
2127 /*features*/ATA_HPA_FEAT_UNLOCK,
2129 /*sector_count*/sizeof(*pwd) / 512,
2130 /*data_ptr*/(uint8_t*)pwd,
2131 /*dxfer_len*/sizeof(*pwd),
2132 timeout ? timeout : 1000,
2137 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2138 uint32_t timeout, union ccb *ccb, int is48bit)
2143 protocol = AP_PROTO_NON_DATA;
2144 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2146 return (ata_do_cmd(device,
2149 /*flags*/CAM_DIR_NONE,
2150 /*protocol*/protocol,
2152 /*tag_action*/MSG_SIMPLE_Q_TAG,
2154 /*features*/ATA_HPA_FEAT_FREEZE,
2159 timeout ? timeout : 1000,
2164 ata_get_native_max(struct cam_device *device, int retry_count,
2165 uint32_t timeout, union ccb *ccb,
2166 u_int64_t *nativesize)
2170 error = ata_do_cmd(device,
2173 /*flags*/CAM_DIR_NONE,
2174 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2175 /*ata_flags*/AP_FLAG_CHK_COND,
2176 /*tag_action*/MSG_SIMPLE_Q_TAG,
2177 /*command*/ATA_AMAX_ADDR,
2178 /*features*/ATA_AMAX_ADDR_GET,
2183 timeout ? timeout : 30 * 1000,
2189 return atahpa_proc_resp(device, ccb, nativesize);
2193 ataama_set(struct cam_device *device, int retry_count,
2194 uint32_t timeout, union ccb *ccb, u_int64_t maxsize)
2198 /* lba's are zero indexed so the max lba is requested max - 1 */
2202 error = ata_do_cmd(device,
2205 /*flags*/CAM_DIR_NONE,
2206 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2207 /*ata_flags*/AP_FLAG_CHK_COND,
2208 /*tag_action*/MSG_SIMPLE_Q_TAG,
2209 /*command*/ATA_AMAX_ADDR,
2210 /*features*/ATA_AMAX_ADDR_SET,
2215 timeout ? timeout : 30 * 1000,
2221 return atahpa_proc_resp(device, ccb, NULL);
2225 ataama_freeze(struct cam_device *device, int retry_count,
2226 uint32_t timeout, union ccb *ccb)
2229 return (ata_do_cmd(device,
2232 /*flags*/CAM_DIR_NONE,
2233 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2235 /*tag_action*/MSG_SIMPLE_Q_TAG,
2236 /*command*/ATA_AMAX_ADDR,
2237 /*features*/ATA_AMAX_ADDR_FREEZE,
2242 timeout ? timeout : 30 * 1000,
2247 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2248 union ccb *ccb, struct ata_params** ident_bufp)
2250 struct ata_params *ident_buf;
2251 struct ccb_pathinq cpi;
2252 struct ccb_getdev cgd;
2255 uint8_t command, retry_command;
2257 if (get_cpi(device, &cpi) != 0) {
2258 warnx("couldn't get CPI");
2262 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2263 if (cpi.protocol == PROTO_ATA) {
2264 if (get_cgd(device, &cgd) != 0) {
2265 warnx("couldn't get CGD");
2269 command = (cgd.protocol == PROTO_ATA) ?
2270 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2273 /* We don't know which for sure so try both */
2274 command = ATA_ATA_IDENTIFY;
2275 retry_command = ATA_ATAPI_IDENTIFY;
2278 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2280 warnx("can't calloc memory for identify\n");
2285 error = ata_do_cmd(device,
2287 /*retries*/retry_count,
2288 /*flags*/CAM_DIR_IN,
2289 /*protocol*/AP_PROTO_PIO_IN,
2290 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2291 AP_FLAG_TLEN_SECT_CNT,
2292 /*tag_action*/MSG_SIMPLE_Q_TAG,
2296 /*sector_count*/sizeof(struct ata_params) / 512,
2297 /*data_ptr*/(uint8_t *)ptr,
2298 /*dxfer_len*/sizeof(struct ata_params),
2299 /*timeout*/timeout ? timeout : 30 * 1000,
2303 if (retry_command != 0) {
2304 command = retry_command;
2312 ident_buf = (struct ata_params *)ptr;
2313 ata_param_fixup(ident_buf);
2316 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2321 /* check for invalid (all zero) response */
2323 warnx("Invalid identify response detected");
2328 *ident_bufp = ident_buf;
2335 ataidentify(struct cam_device *device, int retry_count, int timeout)
2338 struct ata_params *ident_buf;
2339 u_int64_t hpasize = 0, nativesize = 0;
2341 if ((ccb = cam_getccb(device)) == NULL) {
2342 warnx("couldn't allocate CCB");
2346 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2351 if (arglist & CAM_ARG_VERBOSE) {
2352 printf("%s%d: Raw identify data:\n",
2353 device->device_name, device->dev_unit_num);
2354 dump_data((uint16_t *)ident_buf, sizeof(struct ata_params));
2357 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2358 ata_read_native_max(device, retry_count, timeout, ccb,
2359 ident_buf, &hpasize);
2361 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2362 ata_get_native_max(device, retry_count, timeout, ccb,
2366 printf("%s%d: ", device->device_name, device->dev_unit_num);
2367 ata_print_ident(ident_buf);
2368 camxferrate(device);
2369 atacapprint(ident_buf);
2370 atahpa_print(ident_buf, hpasize, 0);
2371 ataama_print(ident_buf, nativesize, 0);
2381 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2383 struct nvme_controller_data cdata;
2385 if (nvme_get_cdata(device, &cdata))
2387 nvme_print_controller(&cdata);
2394 identify(struct cam_device *device, int retry_count, int timeout)
2397 struct ccb_pathinq cpi;
2399 if (get_cpi(device, &cpi) != 0) {
2400 warnx("couldn't get CPI");
2404 if (cpi.protocol == PROTO_NVME) {
2405 return (nvmeidentify(device, retry_count, timeout));
2408 return (ataidentify(device, retry_count, timeout));
2413 ATA_SECURITY_ACTION_PRINT,
2414 ATA_SECURITY_ACTION_FREEZE,
2415 ATA_SECURITY_ACTION_UNLOCK,
2416 ATA_SECURITY_ACTION_DISABLE,
2417 ATA_SECURITY_ACTION_ERASE,
2418 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2419 ATA_SECURITY_ACTION_SET_PASSWORD
2423 atasecurity_print_time(uint16_t tw)
2427 printf("unspecified");
2429 printf("> 508 min");
2431 printf("%i min", 2 * tw);
2435 atasecurity_erase_timeout_msecs(uint16_t timeout)
2439 return 2 * 3600 * 1000; /* default: two hours */
2440 else if (timeout > 255)
2441 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2443 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2448 atasecurity_notify(uint8_t command, struct ata_security_password *pwd)
2452 bzero(&cmd, sizeof(cmd));
2453 cmd.command = command;
2454 printf("Issuing %s", ata_op_string(&cmd));
2457 /* pwd->password may not be null terminated */
2458 char pass[sizeof(pwd->password)+1];
2460 strlcpy(pass, pwd->password, sizeof(pass));
2461 printf(" password='%s', user='%s'",
2463 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2466 if (command == ATA_SECURITY_SET_PASSWORD) {
2467 printf(", mode='%s'",
2468 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2469 "maximum" : "high");
2477 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2478 int retry_count, uint32_t timeout, int quiet)
2482 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2484 return ata_do_cmd(device,
2487 /*flags*/CAM_DIR_NONE,
2488 /*protocol*/AP_PROTO_NON_DATA,
2490 /*tag_action*/MSG_SIMPLE_Q_TAG,
2491 /*command*/ATA_SECURITY_FREEZE_LOCK,
2502 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2503 int retry_count, uint32_t timeout,
2504 struct ata_security_password *pwd, int quiet)
2508 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2510 return ata_do_cmd(device,
2513 /*flags*/CAM_DIR_OUT,
2514 /*protocol*/AP_PROTO_PIO_OUT,
2515 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2516 AP_FLAG_TLEN_SECT_CNT,
2517 /*tag_action*/MSG_SIMPLE_Q_TAG,
2518 /*command*/ATA_SECURITY_UNLOCK,
2521 /*sector_count*/sizeof(*pwd) / 512,
2522 /*data_ptr*/(uint8_t *)pwd,
2523 /*dxfer_len*/sizeof(*pwd),
2529 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2530 int retry_count, uint32_t timeout,
2531 struct ata_security_password *pwd, int quiet)
2535 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2536 return ata_do_cmd(device,
2539 /*flags*/CAM_DIR_OUT,
2540 /*protocol*/AP_PROTO_PIO_OUT,
2541 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2542 AP_FLAG_TLEN_SECT_CNT,
2543 /*tag_action*/MSG_SIMPLE_Q_TAG,
2544 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2547 /*sector_count*/sizeof(*pwd) / 512,
2548 /*data_ptr*/(uint8_t *)pwd,
2549 /*dxfer_len*/sizeof(*pwd),
2556 atasecurity_erase_confirm(struct cam_device *device,
2557 struct ata_params* ident_buf)
2560 printf("\nYou are about to ERASE ALL DATA from the following"
2561 " device:\n%s%d,%s%d: ", device->device_name,
2562 device->dev_unit_num, device->given_dev_name,
2563 device->given_unit_number);
2564 ata_print_ident(ident_buf);
2568 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2570 if (fgets(str, sizeof(str), stdin) != NULL) {
2571 if (strncasecmp(str, "yes", 3) == 0) {
2573 } else if (strncasecmp(str, "no", 2) == 0) {
2576 printf("Please answer \"yes\" or "
2587 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2588 int retry_count, uint32_t timeout,
2589 uint32_t erase_timeout,
2590 struct ata_security_password *pwd, int quiet)
2595 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2597 error = ata_do_cmd(device,
2600 /*flags*/CAM_DIR_NONE,
2601 /*protocol*/AP_PROTO_NON_DATA,
2603 /*tag_action*/MSG_SIMPLE_Q_TAG,
2604 /*command*/ATA_SECURITY_ERASE_PREPARE,
2617 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2619 error = ata_do_cmd(device,
2622 /*flags*/CAM_DIR_OUT,
2623 /*protocol*/AP_PROTO_PIO_OUT,
2624 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2625 AP_FLAG_TLEN_SECT_CNT,
2626 /*tag_action*/MSG_SIMPLE_Q_TAG,
2627 /*command*/ATA_SECURITY_ERASE_UNIT,
2630 /*sector_count*/sizeof(*pwd) / 512,
2631 /*data_ptr*/(uint8_t *)pwd,
2632 /*dxfer_len*/sizeof(*pwd),
2633 /*timeout*/erase_timeout,
2636 if (error == 0 && quiet == 0)
2637 printf("\nErase Complete\n");
2643 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2644 int retry_count, uint32_t timeout,
2645 struct ata_security_password *pwd, int quiet)
2649 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2651 return ata_do_cmd(device,
2654 /*flags*/CAM_DIR_OUT,
2655 /*protocol*/AP_PROTO_PIO_OUT,
2656 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2657 AP_FLAG_TLEN_SECT_CNT,
2658 /*tag_action*/MSG_SIMPLE_Q_TAG,
2659 /*command*/ATA_SECURITY_SET_PASSWORD,
2662 /*sector_count*/sizeof(*pwd) / 512,
2663 /*data_ptr*/(uint8_t *)pwd,
2664 /*dxfer_len*/sizeof(*pwd),
2670 atasecurity_print(struct ata_params *parm)
2673 printf("\nSecurity Option Value\n");
2674 if (arglist & CAM_ARG_VERBOSE) {
2675 printf("status %04x\n",
2676 parm->security_status);
2678 printf("supported %s\n",
2679 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2680 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2682 printf("enabled %s\n",
2683 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2684 printf("drive locked %s\n",
2685 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2686 printf("security config frozen %s\n",
2687 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2688 printf("count expired %s\n",
2689 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2690 printf("security level %s\n",
2691 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2692 printf("enhanced erase supported %s\n",
2693 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2694 printf("erase time ");
2695 atasecurity_print_time(parm->erase_time);
2697 printf("enhanced erase time ");
2698 atasecurity_print_time(parm->enhanced_erase_time);
2700 printf("master password rev %04x%s\n",
2701 parm->master_passwd_revision,
2702 parm->master_passwd_revision == 0x0000 ||
2703 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2707 * Validates and copies the password in optarg to the passed buffer.
2708 * If the password in optarg is the same length as the buffer then
2709 * the data will still be copied but no null termination will occur.
2712 ata_getpwd(uint8_t *passwd, int max, char opt)
2716 len = strlen(optarg);
2718 warnx("-%c password is too long", opt);
2720 } else if (len == 0) {
2721 warnx("-%c password is missing", opt);
2723 } else if (optarg[0] == '-'){
2724 warnx("-%c password starts with '-' (generic arg?)", opt);
2726 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2727 warnx("-%c password conflicts with existing password from -%c",
2732 /* Callers pass in a buffer which does NOT need to be terminated */
2733 strncpy(passwd, optarg, max);
2740 ATA_HPA_ACTION_PRINT,
2741 ATA_HPA_ACTION_SET_MAX,
2742 ATA_HPA_ACTION_SET_PWD,
2743 ATA_HPA_ACTION_LOCK,
2744 ATA_HPA_ACTION_UNLOCK,
2745 ATA_HPA_ACTION_FREEZE_LOCK
2749 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2750 u_int64_t maxsize, int persist)
2752 printf("\nYou are about to configure HPA to limit the user accessible\n"
2753 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2754 persist ? "persistently" : "temporarily",
2755 device->device_name, device->dev_unit_num,
2756 device->given_dev_name, device->given_unit_number);
2757 ata_print_ident(ident_buf);
2761 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2763 if (NULL != fgets(str, sizeof(str), stdin)) {
2764 if (0 == strncasecmp(str, "yes", 3)) {
2766 } else if (0 == strncasecmp(str, "no", 2)) {
2769 printf("Please answer \"yes\" or "
2780 atahpa(struct cam_device *device, int retry_count, int timeout,
2781 int argc, char **argv, char *combinedopt)
2784 struct ata_params *ident_buf;
2785 struct ccb_getdev cgd;
2786 struct ata_set_max_pwd pwd;
2787 int error, confirm, quiet, c, action, actions, persist;
2788 int security, is48bit, pwdsize;
2789 u_int64_t hpasize, maxsize;
2798 memset(&pwd, 0, sizeof(pwd));
2800 /* default action is to print hpa information */
2801 action = ATA_HPA_ACTION_PRINT;
2802 pwdsize = sizeof(pwd.password);
2804 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2807 action = ATA_HPA_ACTION_SET_MAX;
2808 maxsize = strtoumax(optarg, NULL, 0);
2813 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2815 action = ATA_HPA_ACTION_SET_PWD;
2821 action = ATA_HPA_ACTION_LOCK;
2827 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2829 action = ATA_HPA_ACTION_UNLOCK;
2835 action = ATA_HPA_ACTION_FREEZE_LOCK;
2855 warnx("too many hpa actions specified");
2859 if (get_cgd(device, &cgd) != 0) {
2860 warnx("couldn't get CGD");
2864 ccb = cam_getccb(device);
2866 warnx("couldn't allocate CCB");
2870 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2877 printf("%s%d: ", device->device_name, device->dev_unit_num);
2878 ata_print_ident(ident_buf);
2879 camxferrate(device);
2882 if (action == ATA_HPA_ACTION_PRINT) {
2884 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2885 ata_read_native_max(device, retry_count, timeout, ccb,
2886 ident_buf, &hpasize);
2887 atahpa_print(ident_buf, hpasize, 1);
2894 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2895 warnx("HPA is not supported by this device");
2901 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
2902 warnx("HPA Security is not supported by this device");
2908 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2911 * The ATA spec requires:
2912 * 1. Read native max addr is called directly before set max addr
2913 * 2. Read native max addr is NOT called before any other set max call
2916 case ATA_HPA_ACTION_SET_MAX:
2918 atahpa_set_confirm(device, ident_buf, maxsize,
2925 error = ata_read_native_max(device, retry_count, timeout,
2926 ccb, ident_buf, &hpasize);
2928 error = atahpa_set_max(device, retry_count, timeout,
2929 ccb, is48bit, maxsize, persist);
2932 /* redo identify to get new values */
2933 error = ata_do_identify(device,
2934 retry_count, timeout, ccb,
2936 atahpa_print(ident_buf, hpasize, 1);
2938 /* Hint CAM to reprobe the device. */
2944 case ATA_HPA_ACTION_SET_PWD:
2945 error = atahpa_password(device, retry_count, timeout,
2946 ccb, is48bit, &pwd);
2947 if (error == 0 && quiet == 0)
2948 printf("HPA password has been set\n");
2951 case ATA_HPA_ACTION_LOCK:
2952 error = atahpa_lock(device, retry_count, timeout,
2954 if (error == 0 && quiet == 0)
2955 printf("HPA has been locked\n");
2958 case ATA_HPA_ACTION_UNLOCK:
2959 error = atahpa_unlock(device, retry_count, timeout,
2960 ccb, is48bit, &pwd);
2961 if (error == 0 && quiet == 0)
2962 printf("HPA has been unlocked\n");
2965 case ATA_HPA_ACTION_FREEZE_LOCK:
2966 error = atahpa_freeze_lock(device, retry_count, timeout,
2968 if (error == 0 && quiet == 0)
2969 printf("HPA has been frozen\n");
2973 errx(1, "Option currently not supported");
2983 ATA_AMA_ACTION_PRINT,
2984 ATA_AMA_ACTION_SET_MAX,
2985 ATA_AMA_ACTION_FREEZE_LOCK
2989 ataama(struct cam_device *device, int retry_count, int timeout,
2990 int argc, char **argv, char *combinedopt)
2993 struct ata_params *ident_buf;
2994 struct ccb_getdev cgd;
2995 int error, quiet, c, action, actions;
2996 u_int64_t nativesize, maxsize;
3002 /* default action is to print AMA information */
3003 action = ATA_AMA_ACTION_PRINT;
3005 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3008 action = ATA_AMA_ACTION_SET_MAX;
3009 maxsize = strtoumax(optarg, NULL, 0);
3014 action = ATA_AMA_ACTION_FREEZE_LOCK;
3025 warnx("too many AMA actions specified");
3029 if (get_cgd(device, &cgd) != 0) {
3030 warnx("couldn't get CGD");
3034 ccb = cam_getccb(device);
3036 warnx("couldn't allocate CCB");
3040 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3047 printf("%s%d: ", device->device_name, device->dev_unit_num);
3048 ata_print_ident(ident_buf);
3049 camxferrate(device);
3052 if (action == ATA_AMA_ACTION_PRINT) {
3054 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3055 ata_get_native_max(device, retry_count, timeout, ccb,
3057 ataama_print(ident_buf, nativesize, 1);
3064 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3065 warnx("Accessible Max Address is not supported by this device");
3072 case ATA_AMA_ACTION_SET_MAX:
3073 error = ata_get_native_max(device, retry_count, timeout, ccb,
3076 error = ataama_set(device, retry_count, timeout,
3080 /* redo identify to get new values */
3081 error = ata_do_identify(device,
3082 retry_count, timeout, ccb,
3084 ataama_print(ident_buf, nativesize, 1);
3086 /* Hint CAM to reprobe the device. */
3092 case ATA_AMA_ACTION_FREEZE_LOCK:
3093 error = ataama_freeze(device, retry_count, timeout,
3095 if (error == 0 && quiet == 0)
3096 printf("Accessible Max Address has been frozen\n");
3100 errx(1, "Option currently not supported");
3110 atasecurity(struct cam_device *device, int retry_count, int timeout,
3111 int argc, char **argv, char *combinedopt)
3114 struct ata_params *ident_buf;
3115 int error, confirm, quiet, c, action, actions, setpwd;
3116 int security_enabled, erase_timeout, pwdsize;
3117 struct ata_security_password pwd;
3125 memset(&pwd, 0, sizeof(pwd));
3127 /* default action is to print security information */
3128 action = ATA_SECURITY_ACTION_PRINT;
3130 /* user is master by default as its safer that way */
3131 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3132 pwdsize = sizeof(pwd.password);
3134 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3137 action = ATA_SECURITY_ACTION_FREEZE;
3142 if (strcasecmp(optarg, "user") == 0) {
3143 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3144 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3145 } else if (strcasecmp(optarg, "master") == 0) {
3146 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3147 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3149 warnx("-U argument '%s' is invalid (must be "
3150 "'user' or 'master')", optarg);
3156 if (strcasecmp(optarg, "high") == 0) {
3157 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3158 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3159 } else if (strcasecmp(optarg, "maximum") == 0) {
3160 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3161 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3163 warnx("-l argument '%s' is unknown (must be "
3164 "'high' or 'maximum')", optarg);
3170 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3172 action = ATA_SECURITY_ACTION_UNLOCK;
3177 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3179 action = ATA_SECURITY_ACTION_DISABLE;
3184 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3186 action = ATA_SECURITY_ACTION_ERASE;
3191 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3193 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3194 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3199 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3202 if (action == ATA_SECURITY_ACTION_PRINT)
3203 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3205 * Don't increment action as this can be combined
3206 * with other actions.
3219 erase_timeout = atoi(optarg) * 1000;
3225 warnx("too many security actions specified");
3229 if ((ccb = cam_getccb(device)) == NULL) {
3230 warnx("couldn't allocate CCB");
3234 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3241 printf("%s%d: ", device->device_name, device->dev_unit_num);
3242 ata_print_ident(ident_buf);
3243 camxferrate(device);
3246 if (action == ATA_SECURITY_ACTION_PRINT) {
3247 atasecurity_print(ident_buf);
3253 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3254 warnx("Security not supported");
3260 /* default timeout 15 seconds the same as linux hdparm */
3261 timeout = timeout ? timeout : 15 * 1000;
3263 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3265 /* first set the password if requested */
3267 /* confirm we can erase before setting the password if erasing */
3269 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3270 action == ATA_SECURITY_ACTION_ERASE) &&
3271 atasecurity_erase_confirm(device, ident_buf) == 0) {
3277 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3278 pwd.revision = ident_buf->master_passwd_revision;
3279 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3280 --pwd.revision == 0) {
3281 pwd.revision = 0xfffe;
3284 error = atasecurity_set_password(device, ccb, retry_count,
3285 timeout, &pwd, quiet);
3291 security_enabled = 1;
3295 case ATA_SECURITY_ACTION_FREEZE:
3296 error = atasecurity_freeze(device, ccb, retry_count,
3300 case ATA_SECURITY_ACTION_UNLOCK:
3301 if (security_enabled) {
3302 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3303 error = atasecurity_unlock(device, ccb,
3304 retry_count, timeout, &pwd, quiet);
3306 warnx("Can't unlock, drive is not locked");
3310 warnx("Can't unlock, security is disabled");
3315 case ATA_SECURITY_ACTION_DISABLE:
3316 if (security_enabled) {
3317 /* First unlock the drive if its locked */
3318 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3319 error = atasecurity_unlock(device, ccb,
3327 error = atasecurity_disable(device,
3335 warnx("Can't disable security (already disabled)");
3340 case ATA_SECURITY_ACTION_ERASE:
3341 if (security_enabled) {
3342 if (erase_timeout == 0) {
3343 erase_timeout = atasecurity_erase_timeout_msecs(
3344 ident_buf->erase_time);
3347 error = atasecurity_erase(device, ccb, retry_count,
3348 timeout, erase_timeout, &pwd, quiet);
3350 warnx("Can't secure erase (security is disabled)");
3355 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3356 if (security_enabled) {
3357 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3358 if (erase_timeout == 0) {
3360 atasecurity_erase_timeout_msecs(
3361 ident_buf->enhanced_erase_time);
3364 error = atasecurity_erase(device, ccb,
3365 retry_count, timeout,
3366 erase_timeout, &pwd,
3369 warnx("Enhanced erase is not supported");
3373 warnx("Can't secure erase (enhanced), "
3374 "(security is disabled)");
3387 * Convert periph name into a bus, target and lun.
3389 * Returns the number of parsed components, or 0.
3392 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3393 cam_argmask *arglst)
3398 bzero(&ccb, sizeof(ccb));
3399 ccb.ccb_h.func_code = XPT_GDEVLIST;
3400 if (cam_get_device(tstr, ccb.cgdl.periph_name,
3401 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3402 warnx("%s", cam_errbuf);
3407 * Attempt to get the passthrough device. This ioctl will
3408 * fail if the device name is null, if the device doesn't
3409 * exist, or if the passthrough driver isn't in the kernel.
3411 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3412 warn("Unable to open %s", XPT_DEVICE);
3415 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3416 warn("Unable to find bus:target:lun for device %s%d",
3417 ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3422 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3423 const struct cam_status_entry *entry;
3425 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3426 warnx("Unable to find bus:target_lun for device %s%d, "
3427 "CAM status: %s (%#x)",
3428 ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3429 entry ? entry->status_text : "Unknown",
3435 * The kernel fills in the bus/target/lun. We don't
3436 * need the passthrough device name and unit number since
3437 * we aren't going to open it.
3439 *bus = ccb.ccb_h.path_id;
3440 *target = ccb.ccb_h.target_id;
3441 *lun = ccb.ccb_h.target_lun;
3442 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3447 * Parse out a bus, or a bus, target and lun in the following
3453 * Returns the number of parsed components, or 0.
3456 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3457 cam_argmask *arglst)
3462 *bus = CAM_BUS_WILDCARD;
3463 *target = CAM_TARGET_WILDCARD;
3464 *lun = CAM_LUN_WILDCARD;
3466 while (isspace(*tstr) && (*tstr != '\0'))
3469 if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3470 arglist |= CAM_ARG_BUS;
3474 if (!isdigit(*tstr))
3475 return (parse_btl_name(tstr, bus, target, lun, arglst));
3477 tmpstr = strsep(&tstr, ":");
3478 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3479 *bus = strtol(tmpstr, &end, 0);
3482 *arglst |= CAM_ARG_BUS;
3484 tmpstr = strsep(&tstr, ":");
3485 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3486 *target = strtol(tmpstr, &end, 0);
3489 *arglst |= CAM_ARG_TARGET;
3491 tmpstr = strsep(&tstr, ":");
3492 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3493 *lun = strtoll(tmpstr, &end, 0);
3496 *arglst |= CAM_ARG_LUN;
3506 dorescan_or_reset(int argc, char **argv, int rescan)
3508 static const char must[] =
3509 "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3511 path_id_t bus = CAM_BUS_WILDCARD;
3512 target_id_t target = CAM_TARGET_WILDCARD;
3513 lun_id_t lun = CAM_LUN_WILDCARD;
3517 warnx(must, rescan? "rescan" : "reset");
3521 tstr = argv[optind];
3522 while (isspace(*tstr) && (*tstr != '\0'))
3524 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3525 arglist |= CAM_ARG_BUS;
3527 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3528 if (rv != 1 && rv != 3) {
3529 warnx(must, rescan ? "rescan" : "reset");
3534 if (arglist & CAM_ARG_LUN)
3535 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3537 error = rescan_or_reset_bus(bus, rescan);
3543 rescan_or_reset_bus(path_id_t bus, int rescan)
3545 union ccb *ccb = NULL, *matchccb = NULL;
3546 int fd = -1, retval;
3551 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3552 warnx("error opening transport layer device %s", XPT_DEVICE);
3553 warn("%s", XPT_DEVICE);
3557 ccb = malloc(sizeof(*ccb));
3559 warn("failed to allocate CCB");
3563 bzero(ccb, sizeof(*ccb));
3565 if (bus != CAM_BUS_WILDCARD) {
3566 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3567 ccb->ccb_h.path_id = bus;
3568 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3569 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3570 ccb->crcn.flags = CAM_FLAG_NONE;
3572 /* run this at a low priority */
3573 ccb->ccb_h.pinfo.priority = 5;
3575 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3576 warn("CAMIOCOMMAND ioctl failed");
3581 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3582 fprintf(stdout, "%s of bus %d was successful\n",
3583 rescan ? "Re-scan" : "Reset", bus);
3585 fprintf(stdout, "%s of bus %d returned error %#x\n",
3586 rescan ? "Re-scan" : "Reset", bus,
3587 ccb->ccb_h.status & CAM_STATUS_MASK);
3596 * The right way to handle this is to modify the xpt so that it can
3597 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3598 * that isn't implemented, so instead we enumerate the buses and
3599 * send the rescan or reset to those buses in the case where the
3600 * given bus is -1 (wildcard). We don't send a rescan or reset
3601 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3602 * no-op, sending a rescan to the xpt bus would result in a status of
3605 matchccb = malloc(sizeof(*matchccb));
3606 if (matchccb == NULL) {
3607 warn("failed to allocate CCB");
3611 bzero(matchccb, sizeof(*matchccb));
3612 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3613 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3614 bufsize = sizeof(struct dev_match_result) * 20;
3615 matchccb->cdm.match_buf_len = bufsize;
3616 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3617 if (matchccb->cdm.matches == NULL) {
3618 warnx("can't malloc memory for matches");
3622 matchccb->cdm.num_matches = 0;
3624 matchccb->cdm.num_patterns = 1;
3625 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3627 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3628 matchccb->cdm.pattern_buf_len);
3629 if (matchccb->cdm.patterns == NULL) {
3630 warnx("can't malloc memory for patterns");
3634 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3635 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3640 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3641 warn("CAMIOCOMMAND ioctl failed");
3646 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3647 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3648 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3649 warnx("got CAM error %#x, CDM error %d\n",
3650 matchccb->ccb_h.status, matchccb->cdm.status);
3655 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3656 struct bus_match_result *bus_result;
3658 /* This shouldn't happen. */
3659 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3662 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3665 * We don't want to rescan or reset the xpt bus.
3668 if (bus_result->path_id == CAM_XPT_PATH_ID)
3671 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3673 ccb->ccb_h.path_id = bus_result->path_id;
3674 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3675 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3676 ccb->crcn.flags = CAM_FLAG_NONE;
3678 /* run this at a low priority */
3679 ccb->ccb_h.pinfo.priority = 5;
3681 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3682 warn("CAMIOCOMMAND ioctl failed");
3687 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3688 fprintf(stdout, "%s of bus %d was successful\n",
3689 rescan? "Re-scan" : "Reset",
3690 bus_result->path_id);
3693 * Don't bail out just yet, maybe the other
3694 * rescan or reset commands will complete
3697 fprintf(stderr, "%s of bus %d returned error "
3698 "%#x\n", rescan? "Re-scan" : "Reset",
3699 bus_result->path_id,
3700 ccb->ccb_h.status & CAM_STATUS_MASK);
3704 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3705 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3712 if (matchccb != NULL) {
3713 free(matchccb->cdm.patterns);
3714 free(matchccb->cdm.matches);
3723 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3726 struct cam_device *device;
3731 if (bus == CAM_BUS_WILDCARD) {
3732 warnx("invalid bus number %d", bus);
3736 if (target == CAM_TARGET_WILDCARD) {
3737 warnx("invalid target number %d", target);
3741 if (lun == CAM_LUN_WILDCARD) {
3742 warnx("invalid lun number %jx", (uintmax_t)lun);
3748 bzero(&ccb, sizeof(union ccb));
3751 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3752 warnx("error opening transport layer device %s\n",
3754 warn("%s", XPT_DEVICE);
3758 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3759 if (device == NULL) {
3760 warnx("%s", cam_errbuf);
3765 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3766 ccb.ccb_h.path_id = bus;
3767 ccb.ccb_h.target_id = target;
3768 ccb.ccb_h.target_lun = lun;
3769 ccb.ccb_h.timeout = 5000;
3770 ccb.crcn.flags = CAM_FLAG_NONE;
3772 /* run this at a low priority */
3773 ccb.ccb_h.pinfo.priority = 5;
3776 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3777 warn("CAMIOCOMMAND ioctl failed");
3782 if (cam_send_ccb(device, &ccb) < 0) {
3783 warn("error sending XPT_RESET_DEV CCB");
3784 cam_close_device(device);
3792 cam_close_device(device);
3795 * An error code of CAM_BDR_SENT is normal for a BDR request.
3797 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3799 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3800 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3801 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3804 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3805 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3806 ccb.ccb_h.status & CAM_STATUS_MASK);
3812 static struct scsi_nv defect_list_type_map[] = {
3813 { "block", SRDD10_BLOCK_FORMAT },
3814 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3815 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3816 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3817 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3818 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3822 readdefects(struct cam_device *device, int argc, char **argv,
3823 char *combinedopt, int task_attr, int retry_count, int timeout)
3825 union ccb *ccb = NULL;
3826 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3827 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3828 size_t hdr_size = 0, entry_size = 0;
3829 uint8_t *defect_list = NULL;
3830 uint8_t list_format = 0;
3831 uint32_t dlist_length = 0;
3832 uint32_t returned_length = 0, valid_len = 0;
3833 uint32_t num_returned = 0, num_valid = 0;
3834 uint32_t max_possible_size = 0, hdr_max = 0;
3835 uint32_t starting_offset = 0;
3836 uint8_t returned_format, returned_type;
3840 bool summary = false, quiet = false, list_type_set = false;
3841 bool get_length = true, use_12byte = false, first_pass = true;
3842 bool hex_format = false;
3844 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3848 scsi_nv_status status;
3851 if (list_type_set) {
3852 warnx("%s: -f specified twice", __func__);
3854 goto defect_bailout;
3857 status = scsi_get_nv(defect_list_type_map,
3858 sizeof(defect_list_type_map) /
3859 sizeof(defect_list_type_map[0]), optarg,
3860 &entry_num, SCSI_NV_FLAG_IG_CASE);
3862 if (status == SCSI_NV_FOUND) {
3863 list_format |= defect_list_type_map[
3865 list_type_set = true;
3867 warnx("%s: %s %s option %s", __func__,
3868 (status == SCSI_NV_AMBIGUOUS) ?
3869 "ambiguous" : "invalid", "defect list type",
3872 goto defect_bailout;
3877 list_format |= SRDD10_GLIST;
3880 list_format |= SRDD10_PLIST;
3891 starting_offset = strtoul(optarg, &endptr, 0);
3892 if (*endptr != '\0') {
3894 warnx("invalid starting offset %s", optarg);
3895 goto defect_bailout;
3908 if (!list_type_set) {
3910 warnx("no defect list format specified");
3911 goto defect_bailout;
3915 * This implies a summary, and was the previous behavior.
3917 if ((list_format & ~SRDD10_DLIST_FORMAT_MASK) == 0)
3920 ccb = cam_getccb(device);
3923 * We start off asking for just the header to determine how much defect
3924 * data is available. Some Hitachi drives return an error if you ask
3925 * for more data than the drive has. Once we know the length, we retry
3926 * the command with the returned length. When we're retrying the with
3927 * 12-byte command, we're always changing to the 12-byte command and
3928 * need to get the length. Simplify the logic below by always setting
3929 * use_12byte in this case with this slightly more complex logic here.
3932 dlist_length = sizeof(*hdr10);
3937 dlist_length = sizeof(*hdr12);
3941 if (defect_list != NULL) {
3945 defect_list = malloc(dlist_length);
3946 if (defect_list == NULL) {
3947 warnx("can't malloc memory for defect list");
3949 goto defect_bailout;
3953 bzero(defect_list, dlist_length);
3956 * cam_getccb() zeros the CCB header only. So we need to zero the
3957 * payload portion of the ccb.
3959 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3961 scsi_read_defects(&ccb->csio,
3962 /*retries*/ retry_count,
3964 /*tag_action*/ task_attr,
3965 /*list_format*/ list_format,
3966 /*addr_desc_index*/ starting_offset,
3967 /*data_ptr*/ defect_list,
3968 /*dxfer_len*/ dlist_length,
3969 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3970 /*sense_len*/ SSD_FULL_SIZE,
3971 /*timeout*/ timeout ? timeout : 5000);
3973 /* Disable freezing the device queue */
3974 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3976 if (cam_send_ccb(device, ccb) < 0) {
3977 warn("error sending READ DEFECT DATA command");
3979 goto defect_bailout;
3982 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3985 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3986 hdr_size = sizeof(*hdr10);
3987 hdr_max = SRDDH10_MAX_LENGTH;
3989 if (valid_len >= hdr_size) {
3990 returned_length = scsi_2btoul(hdr10->length);
3991 returned_format = hdr10->format;
3993 returned_length = 0;
3994 returned_format = 0;
3997 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3998 hdr_size = sizeof(*hdr12);
3999 hdr_max = SRDDH12_MAX_LENGTH;
4001 if (valid_len >= hdr_size) {
4002 returned_length = scsi_4btoul(hdr12->length);
4003 returned_format = hdr12->format;
4005 returned_length = 0;
4006 returned_format = 0;
4010 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4011 switch (returned_type) {
4012 case SRDD10_BLOCK_FORMAT:
4013 entry_size = sizeof(struct scsi_defect_desc_block);
4015 case SRDD10_LONG_BLOCK_FORMAT:
4016 entry_size = sizeof(struct scsi_defect_desc_long_block);
4018 case SRDD10_EXT_PHYS_FORMAT:
4019 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4020 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4022 case SRDD10_EXT_BFI_FORMAT:
4023 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4024 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4027 warnx("Unknown defect format 0x%x\n", returned_type);
4029 goto defect_bailout;
4033 max_possible_size = (hdr_max / entry_size) * entry_size;
4034 num_returned = returned_length / entry_size;
4035 num_valid = min(returned_length, valid_len - hdr_size);
4036 num_valid /= entry_size;
4041 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4042 CAM_SCSI_STATUS_ERROR) {
4043 struct scsi_sense_data *sense;
4044 int error_code, sense_key, asc, ascq;
4046 sense = &ccb->csio.sense_data;
4047 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4048 ccb->csio.sense_resid, &error_code, &sense_key,
4049 &asc, &ascq, /*show_errors*/ 1);
4052 * If the drive is reporting that it just doesn't
4053 * support the defect list format, go ahead and use
4054 * the length it reported. Otherwise, the length
4055 * may not be valid, so use the maximum.
4057 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4058 && (asc == 0x1c) && (ascq == 0x00)
4059 && (returned_length > 0)) {
4061 && (returned_length >= max_possible_size)) {
4064 dlist_length = returned_length + hdr_size;
4065 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4066 && (asc == 0x1f) && (ascq == 0x00)
4067 && (returned_length > 0)) {
4068 /* Partial defect list transfer */
4070 * Hitachi drives return this error
4071 * along with a partial defect list if they
4072 * have more defects than the 10 byte
4073 * command can support. Retry with the 12
4079 dlist_length = returned_length + hdr_size;
4080 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4081 && (asc == 0x24) && (ascq == 0x00)) {
4082 /* Invalid field in CDB */
4084 * SBC-3 says that if the drive has more
4085 * defects than can be reported with the
4086 * 10 byte command, it should return this
4087 * error and no data. Retry with the 12
4093 dlist_length = returned_length + hdr_size;
4096 * If we got a SCSI error and no valid length,
4097 * just use the 10 byte maximum. The 12
4098 * byte maximum is too large.
4100 if (returned_length == 0)
4101 dlist_length = SRDD10_MAX_LENGTH;
4104 && (returned_length >=
4105 max_possible_size)) {
4108 dlist_length = returned_length +
4112 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4115 warnx("Error reading defect header");
4116 if (arglist & CAM_ARG_VERBOSE)
4117 cam_error_print(device, ccb, CAM_ESF_ALL,
4118 CAM_EPF_ALL, stderr);
4119 goto defect_bailout;
4122 && (returned_length >= max_possible_size)) {
4125 dlist_length = returned_length + hdr_size;
4128 fprintf(stdout, "%u", num_returned);
4130 fprintf(stdout, " defect%s",
4131 (num_returned != 1) ? "s" : "");
4133 fprintf(stdout, "\n");
4135 goto defect_bailout;
4139 * We always limit the list length to the 10-byte maximum
4140 * length (0xffff). The reason is that some controllers
4141 * can't handle larger I/Os, and we can transfer the entire
4142 * 10 byte list in one shot. For drives that support the 12
4143 * byte read defects command, we'll step through the list
4144 * by specifying a starting offset. For drives that don't
4145 * support the 12 byte command's starting offset, we'll
4146 * just display the first 64K.
4148 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4154 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4155 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4156 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4157 struct scsi_sense_data *sense;
4158 int error_code, sense_key, asc, ascq;
4160 sense = &ccb->csio.sense_data;
4161 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4162 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4163 &ascq, /*show_errors*/ 1);
4166 * According to the SCSI spec, if the disk doesn't support
4167 * the requested format, it will generally return a sense
4168 * key of RECOVERED ERROR, and an additional sense code
4169 * of "DEFECT LIST NOT FOUND". HGST drives also return
4170 * Primary/Grown defect list not found errors. So just
4171 * check for an ASC of 0x1c.
4173 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4175 const char *format_str;
4177 format_str = scsi_nv_to_str(defect_list_type_map,
4178 sizeof(defect_list_type_map) /
4179 sizeof(defect_list_type_map[0]),
4180 list_format & SRDD10_DLIST_FORMAT_MASK);
4181 warnx("requested defect format %s not available",
4182 format_str ? format_str : "unknown");
4184 format_str = scsi_nv_to_str(defect_list_type_map,
4185 sizeof(defect_list_type_map) /
4186 sizeof(defect_list_type_map[0]), returned_type);
4187 if (format_str != NULL) {
4188 warnx("Device returned %s format",
4192 warnx("Device returned unknown defect"
4193 " data format %#x", returned_type);
4194 goto defect_bailout;
4198 warnx("Error returned from read defect data command");
4199 if (arglist & CAM_ARG_VERBOSE)
4200 cam_error_print(device, ccb, CAM_ESF_ALL,
4201 CAM_EPF_ALL, stderr);
4202 goto defect_bailout;
4204 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4206 warnx("Error returned from read defect data command");
4207 if (arglist & CAM_ARG_VERBOSE)
4208 cam_error_print(device, ccb, CAM_ESF_ALL,
4209 CAM_EPF_ALL, stderr);
4210 goto defect_bailout;
4214 fprintf(stderr, "Got %d defect", num_returned);
4216 if (!summary || (num_returned == 0)) {
4217 fprintf(stderr, "s.\n");
4218 goto defect_bailout;
4219 } else if (num_returned == 1)
4220 fprintf(stderr, ":\n");
4222 fprintf(stderr, "s:\n");
4228 * XXX KDM I should probably clean up the printout format for the
4231 switch (returned_type) {
4232 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4233 case SRDD10_EXT_PHYS_FORMAT:
4235 struct scsi_defect_desc_phys_sector *dlist;
4237 dlist = (struct scsi_defect_desc_phys_sector *)
4238 (defect_list + hdr_size);
4240 for (i = 0; i < num_valid; i++) {
4243 sector = scsi_4btoul(dlist[i].sector);
4244 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4245 mads = (sector & SDD_EXT_PHYS_MADS) ?
4247 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4250 fprintf(stdout, "%d:%d:%d%s",
4251 scsi_3btoul(dlist[i].cylinder),
4253 scsi_4btoul(dlist[i].sector),
4254 mads ? " - " : "\n");
4256 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4257 scsi_3btoul(dlist[i].cylinder),
4259 scsi_4btoul(dlist[i].sector),
4260 mads ? " - " : "\n");
4263 if (num_valid < num_returned) {
4264 starting_offset += num_valid;
4269 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4270 case SRDD10_EXT_BFI_FORMAT:
4272 struct scsi_defect_desc_bytes_from_index *dlist;
4274 dlist = (struct scsi_defect_desc_bytes_from_index *)
4275 (defect_list + hdr_size);
4277 for (i = 0; i < num_valid; i++) {
4280 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4281 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4282 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4283 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4286 fprintf(stdout, "%d:%d:%d%s",
4287 scsi_3btoul(dlist[i].cylinder),
4289 scsi_4btoul(dlist[i].bytes_from_index),
4290 mads ? " - " : "\n");
4292 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4293 scsi_3btoul(dlist[i].cylinder),
4295 scsi_4btoul(dlist[i].bytes_from_index),
4296 mads ? " - " : "\n");
4300 if (num_valid < num_returned) {
4301 starting_offset += num_valid;
4306 case SRDDH10_BLOCK_FORMAT:
4308 struct scsi_defect_desc_block *dlist;
4310 dlist = (struct scsi_defect_desc_block *)
4311 (defect_list + hdr_size);
4313 for (i = 0; i < num_valid; i++) {
4315 fprintf(stdout, "%u\n",
4316 scsi_4btoul(dlist[i].address));
4318 fprintf(stdout, "0x%x\n",
4319 scsi_4btoul(dlist[i].address));
4322 if (num_valid < num_returned) {
4323 starting_offset += num_valid;
4329 case SRDD10_LONG_BLOCK_FORMAT:
4331 struct scsi_defect_desc_long_block *dlist;
4333 dlist = (struct scsi_defect_desc_long_block *)
4334 (defect_list + hdr_size);
4336 for (i = 0; i < num_valid; i++) {
4338 fprintf(stdout, "%ju\n",
4339 (uintmax_t)scsi_8btou64(
4342 fprintf(stdout, "0x%jx\n",
4343 (uintmax_t)scsi_8btou64(
4347 if (num_valid < num_returned) {
4348 starting_offset += num_valid;
4354 fprintf(stderr, "Unknown defect format 0x%x\n",
4361 if (defect_list != NULL)
4372 reassignblocks(struct cam_device *device, uint32_t *blocks, int num_blocks)
4376 ccb = cam_getccb(device);
4383 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4384 int page, int subpage, int task_attr, int retry_count, int timeout,
4385 uint8_t *data, int datalen)
4388 int error_code, sense_key, asc, ascq;
4390 ccb = cam_getccb(device);
4392 errx(1, "mode_sense: couldn't allocate CCB");
4396 * MODE SENSE(6) can't handle more then 255 bytes. If there are more,
4397 * device must return error, so we should not get truncated data.
4399 if (*cdb_len == 6 && datalen > 255)
4402 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4404 scsi_mode_sense_subpage(&ccb->csio,
4405 /* retries */ retry_count,
4407 /* tag_action */ task_attr,
4411 /* subpage */ subpage,
4412 /* param_buf */ data,
4413 /* param_len */ datalen,
4414 /* minimum_cmd_size */ *cdb_len,
4415 /* sense_len */ SSD_FULL_SIZE,
4416 /* timeout */ timeout ? timeout : 5000);
4417 if (llbaa && ccb->csio.cdb_len == 10) {
4418 struct scsi_mode_sense_10 *cdb =
4419 (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4420 cdb->byte2 |= SMS10_LLBAA;
4423 /* Record what CDB size the above function really set. */
4424 *cdb_len = ccb->csio.cdb_len;
4426 if (arglist & CAM_ARG_ERR_RECOVER)
4427 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4429 /* Disable freezing the device queue */
4430 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4432 if (cam_send_ccb(device, ccb) < 0)
4433 err(1, "error sending mode sense command");
4435 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4436 if (*cdb_len != 6 &&
4437 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4438 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4439 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4444 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4445 if (arglist & CAM_ARG_VERBOSE) {
4446 cam_error_print(device, ccb, CAM_ESF_ALL,
4447 CAM_EPF_ALL, stderr);
4450 cam_close_device(device);
4451 errx(1, "mode sense command returned error");
4458 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4459 int task_attr, int retry_count, int timeout, uint8_t *data, int datalen)
4464 ccb = cam_getccb(device);
4467 errx(1, "mode_select: couldn't allocate CCB");
4469 scsi_mode_select_len(&ccb->csio,
4470 /* retries */ retry_count,
4472 /* tag_action */ task_attr,
4473 /* scsi_page_fmt */ 1,
4474 /* save_pages */ save_pages,
4475 /* param_buf */ data,
4476 /* param_len */ datalen,
4477 /* minimum_cmd_size */ cdb_len,
4478 /* sense_len */ SSD_FULL_SIZE,
4479 /* timeout */ timeout ? timeout : 5000);
4481 if (arglist & CAM_ARG_ERR_RECOVER)
4482 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4484 /* Disable freezing the device queue */
4485 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4487 if (((retval = cam_send_ccb(device, ccb)) < 0)
4488 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4489 if (arglist & CAM_ARG_VERBOSE) {
4490 cam_error_print(device, ccb, CAM_ESF_ALL,
4491 CAM_EPF_ALL, stderr);
4494 cam_close_device(device);
4497 err(1, "error sending mode select command");
4499 errx(1, "error sending mode select command");
4507 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4508 int task_attr, int retry_count, int timeout)
4511 int c, page = -1, subpage = 0, pc = 0, llbaa = 0;
4512 int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4514 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4532 str_subpage = optarg;
4533 strsep(&str_subpage, ",");
4534 page = strtol(optarg, NULL, 0);
4536 subpage = strtol(str_subpage, NULL, 0);
4537 if (page < 0 || page > 0x3f)
4538 errx(1, "invalid mode page %d", page);
4539 if (subpage < 0 || subpage > 0xff)
4540 errx(1, "invalid mode subpage %d", subpage);
4549 pc = strtol(optarg, NULL, 0);
4550 if ((pc < 0) || (pc > 3))
4551 errx(1, "invalid page control field %d", pc);
4558 if (desc && page == -1)
4559 page = SMS_ALL_PAGES_PAGE;
4561 if (page == -1 && list == 0)
4562 errx(1, "you must specify a mode page!");
4565 errx(1, "-d and -D are incompatible!");
4567 if (llbaa && cdb_len != 10)
4568 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4571 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4572 retry_count, timeout);
4574 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4575 edit, binary, task_attr, retry_count, timeout);
4580 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4581 int task_attr, int retry_count, int timeout)
4584 uint32_t flags = CAM_DIR_NONE;
4585 uint8_t *data_ptr = NULL;
4588 struct get_hook hook;
4589 int c, data_bytes = 0, valid_bytes;
4595 char *datastr = NULL, *tstr, *resstr = NULL;
4597 int fd_data = 0, fd_res = 0;
4600 ccb = cam_getccb(device);
4603 warnx("scsicmd: error allocating ccb");
4607 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4611 while (isspace(*tstr) && (*tstr != '\0'))
4613 hook.argc = argc - optind;
4614 hook.argv = argv + optind;
4616 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4619 * Increment optind by the number of arguments the
4620 * encoding routine processed. After each call to
4621 * getopt(3), optind points to the argument that
4622 * getopt should process _next_. In this case,
4623 * that means it points to the first command string
4624 * argument, if there is one. Once we increment
4625 * this, it should point to either the next command
4626 * line argument, or it should be past the end of
4633 while (isspace(*tstr) && (*tstr != '\0'))
4635 hook.argc = argc - optind;
4636 hook.argv = argv + optind;
4638 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4641 * Increment optind by the number of arguments the
4642 * encoding routine processed. After each call to
4643 * getopt(3), optind points to the argument that
4644 * getopt should process _next_. In this case,
4645 * that means it points to the first command string
4646 * argument, if there is one. Once we increment
4647 * this, it should point to either the next command
4648 * line argument, or it should be past the end of
4660 if (arglist & CAM_ARG_CMD_OUT) {
4661 warnx("command must either be "
4662 "read or write, not both");
4664 goto scsicmd_bailout;
4666 arglist |= CAM_ARG_CMD_IN;
4668 data_bytes = strtol(optarg, NULL, 0);
4669 if (data_bytes <= 0) {
4670 warnx("invalid number of input bytes %d",
4673 goto scsicmd_bailout;
4675 hook.argc = argc - optind;
4676 hook.argv = argv + optind;
4679 datastr = cget(&hook, NULL);
4681 * If the user supplied "-" instead of a format, he
4682 * wants the data to be written to stdout.
4684 if ((datastr != NULL)
4685 && (datastr[0] == '-'))
4688 data_ptr = (uint8_t *)malloc(data_bytes);
4689 if (data_ptr == NULL) {
4690 warnx("can't malloc memory for data_ptr");
4692 goto scsicmd_bailout;
4696 if (arglist & CAM_ARG_CMD_IN) {
4697 warnx("command must either be "
4698 "read or write, not both");
4700 goto scsicmd_bailout;
4702 arglist |= CAM_ARG_CMD_OUT;
4703 flags = CAM_DIR_OUT;
4704 data_bytes = strtol(optarg, NULL, 0);
4705 if (data_bytes <= 0) {
4706 warnx("invalid number of output bytes %d",
4709 goto scsicmd_bailout;
4711 hook.argc = argc - optind;
4712 hook.argv = argv + optind;
4714 datastr = cget(&hook, NULL);
4715 data_ptr = (uint8_t *)malloc(data_bytes);
4716 if (data_ptr == NULL) {
4717 warnx("can't malloc memory for data_ptr");
4719 goto scsicmd_bailout;
4721 bzero(data_ptr, data_bytes);
4723 * If the user supplied "-" instead of a format, he
4724 * wants the data to be read from stdin.
4726 if ((datastr != NULL)
4727 && (datastr[0] == '-'))
4730 buff_encode_visit(data_ptr, data_bytes, datastr,
4736 hook.argc = argc - optind;
4737 hook.argv = argv + optind;
4739 resstr = cget(&hook, NULL);
4740 if ((resstr != NULL) && (resstr[0] == '-'))
4750 * If fd_data is set, and we're writing to the device, we need to
4751 * read the data the user wants written from stdin.
4753 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4755 int amt_to_read = data_bytes;
4756 uint8_t *buf_ptr = data_ptr;
4758 for (amt_read = 0; amt_to_read > 0;
4759 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4760 if (amt_read == -1) {
4761 warn("error reading data from stdin");
4763 goto scsicmd_bailout;
4765 amt_to_read -= amt_read;
4766 buf_ptr += amt_read;
4770 if (arglist & CAM_ARG_ERR_RECOVER)
4771 flags |= CAM_PASS_ERR_RECOVER;
4773 /* Disable freezing the device queue */
4774 flags |= CAM_DEV_QFRZDIS;
4778 * This is taken from the SCSI-3 draft spec.
4779 * (T10/1157D revision 0.3)
4780 * The top 3 bits of an opcode are the group code.
4781 * The next 5 bits are the command code.
4782 * Group 0: six byte commands
4783 * Group 1: ten byte commands
4784 * Group 2: ten byte commands
4786 * Group 4: sixteen byte commands
4787 * Group 5: twelve byte commands
4788 * Group 6: vendor specific
4789 * Group 7: vendor specific
4791 switch((cdb[0] >> 5) & 0x7) {
4802 /* computed by buff_encode_visit */
4813 * We should probably use csio_build_visit or something like that
4814 * here, but it's easier to encode arguments as you go. The
4815 * alternative would be skipping the CDB argument and then encoding
4816 * it here, since we've got the data buffer argument by now.
4818 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4820 cam_fill_csio(&ccb->csio,
4821 /*retries*/ retry_count,
4824 /*tag_action*/ task_attr,
4825 /*data_ptr*/ data_ptr,
4826 /*dxfer_len*/ data_bytes,
4827 /*sense_len*/ SSD_FULL_SIZE,
4828 /*cdb_len*/ cdb_len,
4829 /*timeout*/ timeout ? timeout : 5000);
4832 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4834 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4836 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4838 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4840 cam_fill_ataio(&ccb->ataio,
4841 /*retries*/ retry_count,
4845 /*data_ptr*/ data_ptr,
4846 /*dxfer_len*/ data_bytes,
4847 /*timeout*/ timeout ? timeout : 5000);
4850 if (((retval = cam_send_ccb(device, ccb)) < 0)
4851 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4852 const char warnstr[] = "error sending command";
4859 if (arglist & CAM_ARG_VERBOSE) {
4860 cam_error_print(device, ccb, CAM_ESF_ALL,
4861 CAM_EPF_ALL, stderr);
4865 goto scsicmd_bailout;
4868 if (atacmd_len && need_res) {
4870 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4872 fprintf(stdout, "\n");
4875 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4876 ccb->ataio.res.status,
4877 ccb->ataio.res.error,
4878 ccb->ataio.res.lba_low,
4879 ccb->ataio.res.lba_mid,
4880 ccb->ataio.res.lba_high,
4881 ccb->ataio.res.device,
4882 ccb->ataio.res.lba_low_exp,
4883 ccb->ataio.res.lba_mid_exp,
4884 ccb->ataio.res.lba_high_exp,
4885 ccb->ataio.res.sector_count,
4886 ccb->ataio.res.sector_count_exp);
4892 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4894 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4895 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4896 && (arglist & CAM_ARG_CMD_IN)
4897 && (valid_bytes > 0)) {
4899 buff_decode_visit(data_ptr, valid_bytes, datastr,
4901 fprintf(stdout, "\n");
4903 ssize_t amt_written;
4904 int amt_to_write = valid_bytes;
4905 uint8_t *buf_ptr = data_ptr;
4907 for (amt_written = 0; (amt_to_write > 0) &&
4908 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4909 amt_to_write -= amt_written;
4910 buf_ptr += amt_written;
4912 if (amt_written == -1) {
4913 warn("error writing data to stdout");
4915 goto scsicmd_bailout;
4916 } else if ((amt_written == 0)
4917 && (amt_to_write > 0)) {
4918 warnx("only wrote %u bytes out of %u",
4919 valid_bytes - amt_to_write, valid_bytes);
4926 if ((data_bytes > 0) && (data_ptr != NULL))
4935 camdebug(int argc, char **argv, char *combinedopt)
4938 path_id_t bus = CAM_BUS_WILDCARD;
4939 target_id_t target = CAM_TARGET_WILDCARD;
4940 lun_id_t lun = CAM_LUN_WILDCARD;
4945 bzero(&ccb, sizeof(union ccb));
4947 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4950 arglist |= CAM_ARG_DEBUG_INFO;
4951 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4954 arglist |= CAM_ARG_DEBUG_PERIPH;
4955 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4958 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4959 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4962 arglist |= CAM_ARG_DEBUG_TRACE;
4963 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4966 arglist |= CAM_ARG_DEBUG_XPT;
4967 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4970 arglist |= CAM_ARG_DEBUG_CDB;
4971 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4974 arglist |= CAM_ARG_DEBUG_PROBE;
4975 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4986 warnx("you must specify \"off\", \"all\" or a bus,");
4987 warnx("bus:target, bus:target:lun or periph");
4992 while (isspace(*tstr) && (*tstr != '\0'))
4995 if (strncmp(tstr, "off", 3) == 0) {
4996 ccb.cdbg.flags = CAM_DEBUG_NONE;
4997 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4998 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4999 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5001 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5003 warnx("you must specify \"all\", \"off\", or a bus,");
5004 warnx("bus:target, bus:target:lun or periph to debug");
5009 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5010 warnx("error opening transport layer device %s", XPT_DEVICE);
5011 warn("%s", XPT_DEVICE);
5015 ccb.ccb_h.func_code = XPT_DEBUG;
5016 ccb.ccb_h.path_id = bus;
5017 ccb.ccb_h.target_id = target;
5018 ccb.ccb_h.target_lun = lun;
5020 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5021 warn("CAMIOCOMMAND ioctl failed");
5024 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5025 CAM_FUNC_NOTAVAIL) {
5026 warnx("CAM debugging not available");
5027 warnx("you need to put options CAMDEBUG in"
5028 " your kernel config file!");
5030 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5032 warnx("XPT_DEBUG CCB failed with status %#x",
5036 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5038 "Debugging turned off\n");
5041 "Debugging enabled for "
5043 bus, target, (uintmax_t)lun);
5053 tagcontrol(struct cam_device *device, int argc, char **argv,
5063 ccb = cam_getccb(device);
5066 warnx("tagcontrol: error allocating ccb");
5070 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5073 numtags = strtol(optarg, NULL, 0);
5075 warnx("tag count %d is < 0", numtags);
5077 goto tagcontrol_bailout;
5088 cam_path_string(device, pathstr, sizeof(pathstr));
5091 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5092 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5093 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5094 ccb->crs.openings = numtags;
5097 if (cam_send_ccb(device, ccb) < 0) {
5098 warn("error sending XPT_REL_SIMQ CCB");
5100 goto tagcontrol_bailout;
5103 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5104 warnx("XPT_REL_SIMQ CCB failed");
5105 cam_error_print(device, ccb, CAM_ESF_ALL,
5106 CAM_EPF_ALL, stderr);
5108 goto tagcontrol_bailout;
5113 fprintf(stdout, "%stagged openings now %d\n",
5114 pathstr, ccb->crs.openings);
5117 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5119 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5121 if (cam_send_ccb(device, ccb) < 0) {
5122 warn("error sending XPT_GDEV_STATS CCB");
5124 goto tagcontrol_bailout;
5127 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5128 warnx("XPT_GDEV_STATS CCB failed");
5129 cam_error_print(device, ccb, CAM_ESF_ALL,
5130 CAM_EPF_ALL, stderr);
5132 goto tagcontrol_bailout;
5135 if (arglist & CAM_ARG_VERBOSE) {
5136 fprintf(stdout, "%s", pathstr);
5137 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5138 fprintf(stdout, "%s", pathstr);
5139 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5140 fprintf(stdout, "%s", pathstr);
5141 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5142 fprintf(stdout, "%s", pathstr);
5143 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5144 fprintf(stdout, "%s", pathstr);
5145 fprintf(stdout, "held %d\n", ccb->cgds.held);
5146 fprintf(stdout, "%s", pathstr);
5147 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5148 fprintf(stdout, "%s", pathstr);
5149 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5152 fprintf(stdout, "%s", pathstr);
5153 fprintf(stdout, "device openings: ");
5155 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5156 ccb->cgds.dev_active);
5166 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5170 cam_path_string(device, pathstr, sizeof(pathstr));
5172 if (cts->transport == XPORT_SPI) {
5173 struct ccb_trans_settings_spi *spi =
5174 &cts->xport_specific.spi;
5176 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5178 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5181 if (spi->sync_offset != 0) {
5184 freq = scsi_calc_syncsrate(spi->sync_period);
5185 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5186 pathstr, freq / 1000, freq % 1000);
5190 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5191 fprintf(stdout, "%soffset: %d\n", pathstr,
5195 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5196 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5197 (0x01 << spi->bus_width) * 8);
5200 if (spi->valid & CTS_SPI_VALID_DISC) {
5201 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5202 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5203 "enabled" : "disabled");
5206 if (cts->transport == XPORT_FC) {
5207 struct ccb_trans_settings_fc *fc =
5208 &cts->xport_specific.fc;
5210 if (fc->valid & CTS_FC_VALID_WWNN)
5211 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5212 (long long) fc->wwnn);
5213 if (fc->valid & CTS_FC_VALID_WWPN)
5214 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5215 (long long) fc->wwpn);
5216 if (fc->valid & CTS_FC_VALID_PORT)
5217 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5218 if (fc->valid & CTS_FC_VALID_SPEED)
5219 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5220 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5222 if (cts->transport == XPORT_SAS) {
5223 struct ccb_trans_settings_sas *sas =
5224 &cts->xport_specific.sas;
5226 if (sas->valid & CTS_SAS_VALID_SPEED)
5227 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5228 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5230 if (cts->transport == XPORT_ATA) {
5231 struct ccb_trans_settings_pata *pata =
5232 &cts->xport_specific.ata;
5234 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5235 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5236 ata_mode2string(pata->mode));
5238 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5239 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5242 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5243 fprintf(stdout, "%sPIO transaction length: %d\n",
5244 pathstr, pata->bytecount);
5247 if (cts->transport == XPORT_SATA) {
5248 struct ccb_trans_settings_sata *sata =
5249 &cts->xport_specific.sata;
5251 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5252 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5255 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5256 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5257 ata_mode2string(sata->mode));
5259 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5260 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5263 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5264 fprintf(stdout, "%sPIO transaction length: %d\n",
5265 pathstr, sata->bytecount);
5267 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5268 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5271 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5272 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5275 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5276 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5280 if (cts->protocol == PROTO_ATA) {
5281 struct ccb_trans_settings_ata *ata=
5282 &cts->proto_specific.ata;
5284 if (ata->valid & CTS_ATA_VALID_TQ) {
5285 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5286 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5287 "enabled" : "disabled");
5290 if (cts->protocol == PROTO_SCSI) {
5291 struct ccb_trans_settings_scsi *scsi=
5292 &cts->proto_specific.scsi;
5294 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5295 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5296 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5297 "enabled" : "disabled");
5301 if (cts->protocol == PROTO_NVME) {
5302 struct ccb_trans_settings_nvme *nvmex =
5303 &cts->xport_specific.nvme;
5305 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5306 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5307 NVME_MAJOR(nvmex->spec),
5308 NVME_MINOR(nvmex->spec));
5310 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5311 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5312 nvmex->lanes, nvmex->max_lanes);
5313 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5314 nvmex->speed, nvmex->max_speed);
5321 * Get a path inquiry CCB for the specified device.
5324 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5329 ccb = cam_getccb(device);
5331 warnx("get_cpi: couldn't allocate CCB");
5334 ccb->ccb_h.func_code = XPT_PATH_INQ;
5335 if (cam_send_ccb(device, ccb) < 0) {
5336 warn("get_cpi: error sending Path Inquiry CCB");
5338 goto get_cpi_bailout;
5340 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5341 if (arglist & CAM_ARG_VERBOSE)
5342 cam_error_print(device, ccb, CAM_ESF_ALL,
5343 CAM_EPF_ALL, stderr);
5345 goto get_cpi_bailout;
5347 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5355 * Get a get device CCB for the specified device.
5358 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5363 ccb = cam_getccb(device);
5365 warnx("get_cgd: couldn't allocate CCB");
5368 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5369 if (cam_send_ccb(device, ccb) < 0) {
5370 warn("get_cgd: error sending Get type information CCB");
5372 goto get_cgd_bailout;
5374 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5375 if (arglist & CAM_ARG_VERBOSE)
5376 cam_error_print(device, ccb, CAM_ESF_ALL,
5377 CAM_EPF_ALL, stderr);
5379 goto get_cgd_bailout;
5381 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5389 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5393 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5394 int timeout, int verbosemode)
5396 union ccb *ccb = NULL;
5397 struct scsi_vpd_supported_page_list sup_pages;
5401 ccb = cam_getccb(dev);
5403 warn("Unable to allocate CCB");
5408 bzero(&sup_pages, sizeof(sup_pages));
5410 scsi_inquiry(&ccb->csio,
5411 /*retries*/ retry_count,
5413 /* tag_action */ MSG_SIMPLE_Q_TAG,
5414 /* inq_buf */ (uint8_t *)&sup_pages,
5415 /* inq_len */ sizeof(sup_pages),
5417 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5418 /* sense_len */ SSD_FULL_SIZE,
5419 /* timeout */ timeout ? timeout : 5000);
5421 /* Disable freezing the device queue */
5422 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5424 if (retry_count != 0)
5425 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5427 if (cam_send_ccb(dev, ccb) < 0) {
5434 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5435 if (verbosemode != 0)
5436 cam_error_print(dev, ccb, CAM_ESF_ALL,
5437 CAM_EPF_ALL, stderr);
5442 for (i = 0; i < sup_pages.length; i++) {
5443 if (sup_pages.list[i] == page_id) {
5456 * devtype is filled in with the type of device.
5457 * Returns 0 for success, non-zero for failure.
5460 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5461 int verbosemode, camcontrol_devtype *devtype)
5463 struct ccb_getdev cgd;
5466 retval = get_cgd(dev, &cgd);
5470 switch (cgd.protocol) {
5476 *devtype = CC_DT_ATA;
5478 break; /*NOTREACHED*/
5480 *devtype = CC_DT_NVME;
5482 break; /*NOTREACHED*/
5484 *devtype = CC_DT_MMCSD;
5486 break; /*NOTREACHED*/
5488 *devtype = CC_DT_UNKNOWN;
5490 break; /*NOTREACHED*/
5493 if (retry_count == -1) {
5495 * For a retry count of -1, used only the cached data to avoid
5496 * I/O to the drive. Sending the identify command to the drive
5497 * can cause issues for SATL attachaed drives since identify is
5498 * not an NCQ command. We check for the strings that windows
5499 * displays since those will not be NULs (they are supposed
5500 * to be space padded). We could check other bits, but anything
5501 * non-zero implies SATL.
5503 if (cgd.ident_data.serial[0] != 0 ||
5504 cgd.ident_data.revision[0] != 0 ||
5505 cgd.ident_data.model[0] != 0)
5506 *devtype = CC_DT_SATL;
5508 *devtype = CC_DT_SCSI;
5511 * Check for the ATA Information VPD page (0x89). If this is an
5512 * ATA device behind a SCSI to ATA translation layer (SATL),
5513 * this VPD page should be present.
5515 * If that VPD page isn't present, or we get an error back from
5516 * the INQUIRY command, we'll just treat it as a normal SCSI
5519 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5520 timeout, verbosemode);
5522 *devtype = CC_DT_SATL;
5524 *devtype = CC_DT_SCSI;
5533 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5534 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5535 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5536 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5537 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5538 int is48bit, camcontrol_devtype devtype)
5542 if (devtype == CC_DT_ATA) {
5543 cam_fill_ataio(&ccb->ataio,
5544 /*retries*/ retry_count,
5547 /*tag_action*/ tag_action,
5548 /*data_ptr*/ data_ptr,
5549 /*dxfer_len*/ dxfer_len,
5550 /*timeout*/ timeout);
5551 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5552 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5555 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5558 if (auxiliary != 0) {
5559 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5560 ccb->ataio.aux = auxiliary;
5563 if (ata_flags & AP_FLAG_CHK_COND)
5564 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5566 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5567 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5568 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5569 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5571 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5572 protocol |= AP_EXTEND;
5574 retval = scsi_ata_pass(&ccb->csio,
5575 /*retries*/ retry_count,
5578 /*tag_action*/ tag_action,
5579 /*protocol*/ protocol,
5580 /*ata_flags*/ ata_flags,
5581 /*features*/ features,
5582 /*sector_count*/ sector_count,
5584 /*command*/ command,
5587 /*auxiliary*/ auxiliary,
5589 /*data_ptr*/ data_ptr,
5590 /*dxfer_len*/ dxfer_len,
5591 /*cdb_storage*/ cdb_storage,
5592 /*cdb_storage_len*/ cdb_storage_len,
5593 /*minimum_cmd_size*/ 0,
5594 /*sense_len*/ sense_len,
5595 /*timeout*/ timeout);
5602 * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5603 * 4 -- count truncated, 6 -- lba and count truncated.
5606 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5607 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5611 switch (ccb->ccb_h.func_code) {
5614 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5618 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5619 * or 16 byte, and need to see what
5621 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5622 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5624 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5625 if ((opcode != ATA_PASS_12)
5626 && (opcode != ATA_PASS_16)) {
5627 warnx("%s: unsupported opcode %02x", __func__, opcode);
5631 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5633 /* Note: the _ccb() variant returns 0 for an error */
5637 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5638 switch (error_code) {
5639 case SSD_DESC_CURRENT_ERROR:
5640 case SSD_DESC_DEFERRED_ERROR: {
5641 struct scsi_sense_data_desc *sense;
5642 struct scsi_sense_ata_ret_desc *desc;
5645 sense = (struct scsi_sense_data_desc *)
5646 &ccb->csio.sense_data;
5648 desc_ptr = scsi_find_desc(sense, sense_len,
5650 if (desc_ptr == NULL) {
5651 cam_error_print(dev, ccb, CAM_ESF_ALL,
5652 CAM_EPF_ALL, stderr);
5655 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5657 *error = desc->error;
5658 *count = (desc->count_15_8 << 8) |
5660 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5661 ((uint64_t)desc->lba_39_32 << 32) |
5662 ((uint64_t)desc->lba_31_24 << 24) |
5663 (desc->lba_23_16 << 16) |
5664 (desc->lba_15_8 << 8) |
5666 *device = desc->device;
5667 *status = desc->status;
5670 * If the extend bit isn't set, the result is for a
5671 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5672 * command without the extend bit set. This means
5673 * that the device is supposed to return 28-bit
5674 * status. The count field is only 8 bits, and the
5675 * LBA field is only 8 bits.
5677 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5683 case SSD_CURRENT_ERROR:
5684 case SSD_DEFERRED_ERROR: {
5688 * In my understanding of SAT-5 specification, saying:
5689 * "without interpreting the contents of the STATUS",
5690 * this should not happen if CK_COND was set, but it
5691 * does at least for some devices, so try to revert.
5693 if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5694 (asc == 0) && (ascq == 0)) {
5695 *status = ATA_STATUS_ERROR;
5696 *error = ATA_ERROR_ABORT;
5703 if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5704 (asc != 0x00) || (ascq != 0x1d))
5708 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5709 SSD_DESC_INFO, &val, NULL);
5710 *error = (val >> 24) & 0xff;
5711 *status = (val >> 16) & 0xff;
5712 *device = (val >> 8) & 0xff;
5713 *count = val & 0xff;
5716 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5717 SSD_DESC_COMMAND, &val, NULL);
5718 *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5719 ((val & 0xff) << 16);
5721 /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5722 return ((val >> 28) & 0x06);
5731 struct ata_res *res;
5733 /* Only some statuses return ATA result register set. */
5734 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5735 cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5738 res = &ccb->ataio.res;
5739 *error = res->error;
5740 *status = res->status;
5741 *device = res->device;
5742 *count = res->sector_count;
5743 *lba = (res->lba_high << 16) |
5744 (res->lba_mid << 8) |
5746 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5747 *count |= (res->sector_count_exp << 8);
5748 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5749 ((uint64_t)res->lba_mid_exp << 32) |
5750 ((uint64_t)res->lba_high_exp << 40);
5752 *lba |= (res->device & 0xf) << 24;
5763 cpi_print(struct ccb_pathinq *cpi)
5765 char adapter_str[1024];
5768 snprintf(adapter_str, sizeof(adapter_str),
5769 "%s%d:", cpi->dev_name, cpi->unit_number);
5771 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5774 for (i = 1; i < UINT8_MAX; i = i << 1) {
5777 if ((i & cpi->hba_inquiry) == 0)
5780 fprintf(stdout, "%s supports ", adapter_str);
5784 str = "MDP message";
5787 str = "32 bit wide SCSI";
5790 str = "16 bit wide SCSI";
5793 str = "SDTR message";
5796 str = "linked CDBs";
5799 str = "tag queue messages";
5802 str = "soft reset alternative";
5805 str = "SATA Port Multiplier";
5808 str = "unknown PI bit set";
5811 fprintf(stdout, "%s\n", str);
5814 for (i = 1; i < UINT32_MAX; i = i << 1) {
5817 if ((i & cpi->hba_misc) == 0)
5820 fprintf(stdout, "%s ", adapter_str);
5824 str = "can understand ata_ext requests";
5827 str = "64bit extended LUNs supported";
5830 str = "bus scans from high ID to low ID";
5833 str = "removable devices not included in scan";
5835 case PIM_NOINITIATOR:
5836 str = "initiator role not supported";
5838 case PIM_NOBUSRESET:
5839 str = "user has disabled initial BUS RESET or"
5840 " controller is in target/mixed mode";
5843 str = "do not send 6-byte commands";
5846 str = "scan bus sequentially";
5849 str = "unmapped I/O supported";
5852 str = "does its own scanning";
5855 str = "unknown PIM bit set";
5858 fprintf(stdout, "%s\n", str);
5861 for (i = 1; i < UINT16_MAX; i = i << 1) {
5864 if ((i & cpi->target_sprt) == 0)
5867 fprintf(stdout, "%s supports ", adapter_str);
5870 str = "target mode processor mode";
5873 str = "target mode phase cog. mode";
5875 case PIT_DISCONNECT:
5876 str = "disconnects in target mode";
5879 str = "terminate I/O message in target mode";
5882 str = "group 6 commands in target mode";
5885 str = "group 7 commands in target mode";
5888 str = "unknown PIT bit set";
5892 fprintf(stdout, "%s\n", str);
5894 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5896 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5898 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5900 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5901 adapter_str, cpi->hpath_id);
5902 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5904 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5905 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5906 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5907 adapter_str, cpi->hba_vendor);
5908 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5909 adapter_str, cpi->hba_device);
5910 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5911 adapter_str, cpi->hba_subvendor);
5912 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5913 adapter_str, cpi->hba_subdevice);
5914 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5915 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5916 if (cpi->base_transfer_speed > 1000)
5917 fprintf(stdout, "%d.%03dMB/sec\n",
5918 cpi->base_transfer_speed / 1000,
5919 cpi->base_transfer_speed % 1000);
5921 fprintf(stdout, "%dKB/sec\n",
5922 (cpi->base_transfer_speed % 1000) * 1000);
5923 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5924 adapter_str, cpi->maxio);
5928 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5929 struct ccb_trans_settings *cts)
5935 ccb = cam_getccb(device);
5938 warnx("get_print_cts: error allocating ccb");
5942 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5944 if (user_settings == 0)
5945 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5947 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5949 if (cam_send_ccb(device, ccb) < 0) {
5950 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
5952 goto get_print_cts_bailout;
5955 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5956 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5957 if (arglist & CAM_ARG_VERBOSE)
5958 cam_error_print(device, ccb, CAM_ESF_ALL,
5959 CAM_EPF_ALL, stderr);
5961 goto get_print_cts_bailout;
5965 cts_print(device, &ccb->cts);
5968 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5970 get_print_cts_bailout:
5978 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5979 int timeout, int argc, char **argv, char *combinedopt)
5983 int user_settings = 0;
5985 int disc_enable = -1, tag_enable = -1;
5988 double syncrate = -1;
5991 int change_settings = 0, send_tur = 0;
5992 struct ccb_pathinq cpi;
5994 ccb = cam_getccb(device);
5996 warnx("ratecontrol: error allocating ccb");
5999 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6008 if (strncasecmp(optarg, "enable", 6) == 0)
6010 else if (strncasecmp(optarg, "disable", 7) == 0)
6013 warnx("-D argument \"%s\" is unknown", optarg);
6015 goto ratecontrol_bailout;
6017 change_settings = 1;
6020 mode = ata_string2mode(optarg);
6022 warnx("unknown mode '%s'", optarg);
6024 goto ratecontrol_bailout;
6026 change_settings = 1;
6029 offset = strtol(optarg, NULL, 0);
6031 warnx("offset value %d is < 0", offset);
6033 goto ratecontrol_bailout;
6035 change_settings = 1;
6041 syncrate = atof(optarg);
6043 warnx("sync rate %f is < 0", syncrate);
6045 goto ratecontrol_bailout;
6047 change_settings = 1;
6050 if (strncasecmp(optarg, "enable", 6) == 0)
6052 else if (strncasecmp(optarg, "disable", 7) == 0)
6055 warnx("-T argument \"%s\" is unknown", optarg);
6057 goto ratecontrol_bailout;
6059 change_settings = 1;
6065 bus_width = strtol(optarg, NULL, 0);
6066 if (bus_width < 0) {
6067 warnx("bus width %d is < 0", bus_width);
6069 goto ratecontrol_bailout;
6071 change_settings = 1;
6078 * Grab path inquiry information, so we can determine whether
6079 * or not the initiator is capable of the things that the user
6082 if ((retval = get_cpi(device, &cpi)) != 0)
6083 goto ratecontrol_bailout;
6085 fprintf(stdout, "%s parameters:\n",
6086 user_settings ? "User" : "Current");
6088 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6090 goto ratecontrol_bailout;
6092 if (arglist & CAM_ARG_VERBOSE)
6095 if (change_settings) {
6096 int didsettings = 0;
6097 struct ccb_trans_settings_spi *spi = NULL;
6098 struct ccb_trans_settings_pata *pata = NULL;
6099 struct ccb_trans_settings_sata *sata = NULL;
6100 struct ccb_trans_settings_ata *ata = NULL;
6101 struct ccb_trans_settings_scsi *scsi = NULL;
6103 if (ccb->cts.transport == XPORT_SPI)
6104 spi = &ccb->cts.xport_specific.spi;
6105 if (ccb->cts.transport == XPORT_ATA)
6106 pata = &ccb->cts.xport_specific.ata;
6107 if (ccb->cts.transport == XPORT_SATA)
6108 sata = &ccb->cts.xport_specific.sata;
6109 if (ccb->cts.protocol == PROTO_ATA)
6110 ata = &ccb->cts.proto_specific.ata;
6111 if (ccb->cts.protocol == PROTO_SCSI)
6112 scsi = &ccb->cts.proto_specific.scsi;
6113 ccb->cts.xport_specific.valid = 0;
6114 ccb->cts.proto_specific.valid = 0;
6115 if (spi && disc_enable != -1) {
6116 spi->valid |= CTS_SPI_VALID_DISC;
6117 if (disc_enable == 0)
6118 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6120 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6123 if (tag_enable != -1) {
6124 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6125 warnx("HBA does not support tagged queueing, "
6126 "so you cannot modify tag settings");
6128 goto ratecontrol_bailout;
6131 ata->valid |= CTS_SCSI_VALID_TQ;
6132 if (tag_enable == 0)
6133 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6135 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6138 scsi->valid |= CTS_SCSI_VALID_TQ;
6139 if (tag_enable == 0)
6140 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6142 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6146 if (spi && offset != -1) {
6147 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6148 warnx("HBA is not capable of changing offset");
6150 goto ratecontrol_bailout;
6152 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6153 spi->sync_offset = offset;
6156 if (spi && syncrate != -1) {
6157 int prelim_sync_period;
6159 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6160 warnx("HBA is not capable of changing "
6163 goto ratecontrol_bailout;
6165 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6167 * The sync rate the user gives us is in MHz.
6168 * We need to translate it into KHz for this
6173 * Next, we calculate a "preliminary" sync period
6174 * in tenths of a nanosecond.
6177 prelim_sync_period = 0;
6179 prelim_sync_period = 10000000 / syncrate;
6181 scsi_calc_syncparam(prelim_sync_period);
6184 if (sata && syncrate != -1) {
6185 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6186 warnx("HBA is not capable of changing "
6189 goto ratecontrol_bailout;
6191 if (!user_settings) {
6192 warnx("You can modify only user rate "
6193 "settings for SATA");
6195 goto ratecontrol_bailout;
6197 sata->revision = ata_speed2revision(syncrate * 100);
6198 if (sata->revision < 0) {
6199 warnx("Invalid rate %f", syncrate);
6201 goto ratecontrol_bailout;
6203 sata->valid |= CTS_SATA_VALID_REVISION;
6206 if ((pata || sata) && mode != -1) {
6207 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6208 warnx("HBA is not capable of changing "
6211 goto ratecontrol_bailout;
6213 if (!user_settings) {
6214 warnx("You can modify only user mode "
6215 "settings for ATA/SATA");
6217 goto ratecontrol_bailout;
6221 pata->valid |= CTS_ATA_VALID_MODE;
6224 sata->valid |= CTS_SATA_VALID_MODE;
6229 * The bus_width argument goes like this:
6233 * Therefore, if you shift the number of bits given on the
6234 * command line right by 4, you should get the correct
6237 if (spi && bus_width != -1) {
6239 * We might as well validate things here with a
6240 * decipherable error message, rather than what
6241 * will probably be an indecipherable error message
6242 * by the time it gets back to us.
6244 if ((bus_width == 16)
6245 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6246 warnx("HBA does not support 16 bit bus width");
6248 goto ratecontrol_bailout;
6249 } else if ((bus_width == 32)
6250 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6251 warnx("HBA does not support 32 bit bus width");
6253 goto ratecontrol_bailout;
6254 } else if ((bus_width != 8)
6255 && (bus_width != 16)
6256 && (bus_width != 32)) {
6257 warnx("Invalid bus width %d", bus_width);
6259 goto ratecontrol_bailout;
6261 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6262 spi->bus_width = bus_width >> 4;
6265 if (didsettings == 0) {
6266 goto ratecontrol_bailout;
6268 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6269 if (cam_send_ccb(device, ccb) < 0) {
6270 warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6272 goto ratecontrol_bailout;
6274 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6275 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6276 if (arglist & CAM_ARG_VERBOSE) {
6277 cam_error_print(device, ccb, CAM_ESF_ALL,
6278 CAM_EPF_ALL, stderr);
6281 goto ratecontrol_bailout;
6285 retval = testunitready(device, task_attr, retry_count, timeout,
6286 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6288 * If the TUR didn't succeed, just bail.
6292 fprintf(stderr, "Test Unit Ready failed\n");
6293 goto ratecontrol_bailout;
6296 if ((change_settings || send_tur) && !quiet &&
6297 (ccb->cts.transport == XPORT_ATA ||
6298 ccb->cts.transport == XPORT_SATA || send_tur)) {
6299 fprintf(stdout, "New parameters:\n");
6300 retval = get_print_cts(device, user_settings, 0, NULL);
6303 ratecontrol_bailout:
6309 scsiformat(struct cam_device *device, int argc, char **argv,
6310 char *combinedopt, int task_attr, int retry_count, int timeout)
6314 int ycount = 0, quiet = 0;
6315 int error = 0, retval = 0;
6316 int use_timeout = 10800 * 1000;
6318 struct format_defect_list_header fh;
6319 uint8_t *data_ptr = NULL;
6320 uint32_t dxfer_len = 0;
6322 int num_warnings = 0;
6325 ccb = cam_getccb(device);
6328 warnx("scsiformat: error allocating ccb");
6332 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6352 if (quiet == 0 && ycount == 0) {
6353 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6354 "following device:\n");
6356 error = scsidoinquiry(device, argc, argv, combinedopt,
6357 task_attr, retry_count, timeout);
6360 warnx("scsiformat: error sending inquiry");
6361 goto scsiformat_bailout;
6366 if (!get_confirmation()) {
6368 goto scsiformat_bailout;
6373 use_timeout = timeout;
6376 fprintf(stdout, "Current format timeout is %d seconds\n",
6377 use_timeout / 1000);
6381 * If the user hasn't disabled questions and didn't specify a
6382 * timeout on the command line, ask them if they want the current
6386 && (timeout == 0)) {
6388 int new_timeout = 0;
6390 fprintf(stdout, "Enter new timeout in seconds or press\n"
6391 "return to keep the current timeout [%d] ",
6392 use_timeout / 1000);
6394 if (fgets(str, sizeof(str), stdin) != NULL) {
6396 new_timeout = atoi(str);
6399 if (new_timeout != 0) {
6400 use_timeout = new_timeout * 1000;
6401 fprintf(stdout, "Using new timeout value %d\n",
6402 use_timeout / 1000);
6407 * Keep this outside the if block below to silence any unused
6408 * variable warnings.
6410 bzero(&fh, sizeof(fh));
6413 * If we're in immediate mode, we've got to include the format
6416 if (immediate != 0) {
6417 fh.byte2 = FU_DLH_IMMED;
6418 data_ptr = (uint8_t *)&fh;
6419 dxfer_len = sizeof(fh);
6420 byte2 = FU_FMT_DATA;
6421 } else if (quiet == 0) {
6422 fprintf(stdout, "Formatting...");
6426 scsi_format_unit(&ccb->csio,
6427 /* retries */ retry_count,
6429 /* tag_action */ task_attr,
6432 /* data_ptr */ data_ptr,
6433 /* dxfer_len */ dxfer_len,
6434 /* sense_len */ SSD_FULL_SIZE,
6435 /* timeout */ use_timeout);
6437 /* Disable freezing the device queue */
6438 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6440 if (arglist & CAM_ARG_ERR_RECOVER)
6441 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6443 if (((retval = cam_send_ccb(device, ccb)) < 0)
6444 || ((immediate == 0)
6445 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6446 const char errstr[] = "error sending format command";
6453 if (arglist & CAM_ARG_VERBOSE) {
6454 cam_error_print(device, ccb, CAM_ESF_ALL,
6455 CAM_EPF_ALL, stderr);
6458 goto scsiformat_bailout;
6462 * If we ran in non-immediate mode, we already checked for errors
6463 * above and printed out any necessary information. If we're in
6464 * immediate mode, we need to loop through and get status
6465 * information periodically.
6467 if (immediate == 0) {
6469 fprintf(stdout, "Format Complete\n");
6471 goto scsiformat_bailout;
6478 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6481 * There's really no need to do error recovery or
6482 * retries here, since we're just going to sit in a
6483 * loop and wait for the device to finish formatting.
6485 scsi_test_unit_ready(&ccb->csio,
6488 /* tag_action */ task_attr,
6489 /* sense_len */ SSD_FULL_SIZE,
6490 /* timeout */ 5000);
6492 /* Disable freezing the device queue */
6493 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6495 retval = cam_send_ccb(device, ccb);
6498 * If we get an error from the ioctl, bail out. SCSI
6499 * errors are expected.
6502 warn("error sending TEST UNIT READY command");
6504 goto scsiformat_bailout;
6507 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6509 if ((status != CAM_REQ_CMP)
6510 && (status == CAM_SCSI_STATUS_ERROR)
6511 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6512 struct scsi_sense_data *sense;
6513 int error_code, sense_key, asc, ascq;
6515 sense = &ccb->csio.sense_data;
6516 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6517 ccb->csio.sense_resid, &error_code, &sense_key,
6518 &asc, &ascq, /*show_errors*/ 1);
6521 * According to the SCSI-2 and SCSI-3 specs, a
6522 * drive that is in the middle of a format should
6523 * return NOT READY with an ASC of "logical unit
6524 * not ready, format in progress". The sense key
6525 * specific bytes will then be a progress indicator.
6527 if ((sense_key == SSD_KEY_NOT_READY)
6528 && (asc == 0x04) && (ascq == 0x04)) {
6531 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6532 ccb->csio.sense_resid, sks) == 0)
6535 u_int64_t percentage;
6537 val = scsi_2btoul(&sks[1]);
6538 percentage = 10000ull * val;
6541 "\rFormatting: %ju.%02u %% "
6543 (uintmax_t)(percentage /
6545 (unsigned)((percentage /
6549 } else if ((quiet == 0)
6550 && (++num_warnings <= 1)) {
6551 warnx("Unexpected SCSI Sense Key "
6552 "Specific value returned "
6554 scsi_sense_print(device, &ccb->csio,
6556 warnx("Unable to print status "
6557 "information, but format will "
6559 warnx("will exit when format is "
6564 warnx("Unexpected SCSI error during format");
6565 cam_error_print(device, ccb, CAM_ESF_ALL,
6566 CAM_EPF_ALL, stderr);
6568 goto scsiformat_bailout;
6571 } else if (status != CAM_REQ_CMP) {
6572 warnx("Unexpected CAM status %#x", status);
6573 if (arglist & CAM_ARG_VERBOSE)
6574 cam_error_print(device, ccb, CAM_ESF_ALL,
6575 CAM_EPF_ALL, stderr);
6577 goto scsiformat_bailout;
6580 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6583 fprintf(stdout, "\nFormat Complete\n");
6593 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6594 camcontrol_devtype devtype)
6597 uint8_t error = 0, ata_device = 0, status = 0;
6603 retval = build_ata_cmd(ccb,
6605 /*flags*/ CAM_DIR_NONE,
6606 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6607 /*protocol*/ AP_PROTO_NON_DATA,
6608 /*ata_flags*/ AP_FLAG_CHK_COND,
6609 /*features*/ 0x00, /* SANITIZE STATUS EXT */
6612 /*command*/ ATA_SANITIZE,
6616 /*cdb_storage*/ NULL,
6617 /*cdb_storage_len*/ 0,
6618 /*sense_len*/ SSD_FULL_SIZE,
6621 /*devtype*/ devtype);
6623 warnx("%s: build_ata_cmd() failed, likely "
6624 "programmer error", __func__);
6628 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6629 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6630 retval = cam_send_ccb(device, ccb);
6632 warn("error sending SANITIZE STATUS EXT command");
6636 retval = get_ata_status(device, ccb, &error, &count, &lba,
6637 &ata_device, &status);
6639 warnx("Can't get SANITIZE STATUS EXT status, "
6640 "sanitize may still run.");
6643 if (status & ATA_STATUS_ERROR) {
6644 if (error & ATA_ERROR_ABORT) {
6645 switch (lba & 0xff) {
6647 warnx("Reason not reported or sanitize failed.");
6650 warnx("Sanitize command unsuccessful. ");
6653 warnx("Unsupported sanitize device command. ");
6656 warnx("Device is in sanitize frozen state. ");
6659 warnx("Sanitize antifreeze lock is enabled. ");
6663 warnx("SANITIZE STATUS EXT failed, "
6664 "sanitize may still run.");
6667 if (count & 0x4000) {
6672 "Sanitizing: %u.%02u%% (%d/%d)\r",
6673 (perc / (0x10000 * 100)),
6674 ((perc / 0x10000) % 100),
6686 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6688 int warnings = 0, retval;
6693 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6696 * There's really no need to do error recovery or
6697 * retries here, since we're just going to sit in a
6698 * loop and wait for the device to finish sanitizing.
6700 scsi_test_unit_ready(&ccb->csio,
6703 /* tag_action */ task_attr,
6704 /* sense_len */ SSD_FULL_SIZE,
6705 /* timeout */ 5000);
6707 /* Disable freezing the device queue */
6708 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6710 retval = cam_send_ccb(device, ccb);
6713 * If we get an error from the ioctl, bail out. SCSI
6714 * errors are expected.
6717 warn("error sending TEST UNIT READY command");
6721 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6722 if ((status == CAM_SCSI_STATUS_ERROR) &&
6723 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6724 struct scsi_sense_data *sense;
6725 int error_code, sense_key, asc, ascq;
6727 sense = &ccb->csio.sense_data;
6728 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6729 ccb->csio.sense_resid, &error_code, &sense_key,
6730 &asc, &ascq, /*show_errors*/ 1);
6733 * According to the SCSI-3 spec, a drive that is in the
6734 * middle of a sanitize should return NOT READY with an
6735 * ASC of "logical unit not ready, sanitize in
6736 * progress". The sense key specific bytes will then
6737 * be a progress indicator.
6739 if ((sense_key == SSD_KEY_NOT_READY)
6740 && (asc == 0x04) && (ascq == 0x1b)) {
6743 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6744 ccb->csio.sense_resid, sks) == 0)
6746 val = scsi_2btoul(&sks[1]);
6749 "Sanitizing: %u.%02u%% (%d/%d)\r",
6750 (perc / (0x10000 * 100)),
6751 ((perc / 0x10000) % 100),
6754 } else if ((quiet == 0) && (++warnings <= 1)) {
6755 warnx("Unexpected SCSI Sense Key "
6756 "Specific value returned "
6757 "during sanitize:");
6758 scsi_sense_print(device, &ccb->csio,
6760 warnx("Unable to print status "
6761 "information, but sanitze will "
6763 warnx("will exit when sanitize is "
6768 warnx("Unexpected SCSI error during sanitize");
6769 cam_error_print(device, ccb, CAM_ESF_ALL,
6770 CAM_EPF_ALL, stderr);
6774 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6775 warnx("Unexpected CAM status %#x", status);
6776 if (arglist & CAM_ARG_VERBOSE)
6777 cam_error_print(device, ccb, CAM_ESF_ALL,
6778 CAM_EPF_ALL, stderr);
6781 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6786 sanitize(struct cam_device *device, int argc, char **argv,
6787 char *combinedopt, int task_attr, int retry_count, int timeout)
6792 int ycount = 0, quiet = 0;
6800 const char *pattern = NULL;
6801 uint8_t *data_ptr = NULL;
6802 uint32_t dxfer_len = 0;
6804 uint16_t feature, count;
6807 camcontrol_devtype dt;
6810 * Get the device type, request no I/O be done to do this.
6812 error = get_device_type(device, -1, 0, 0, &dt);
6813 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6814 warnx("sanitize: can't get device type");
6818 ccb = cam_getccb(device);
6821 warnx("sanitize: error allocating ccb");
6825 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6828 if (strcasecmp(optarg, "overwrite") == 0)
6829 action = SSZ_SERVICE_ACTION_OVERWRITE;
6830 else if (strcasecmp(optarg, "block") == 0)
6831 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6832 else if (strcasecmp(optarg, "crypto") == 0)
6833 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6834 else if (strcasecmp(optarg, "exitfailure") == 0)
6835 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6837 warnx("invalid service operation \"%s\"",
6840 goto sanitize_bailout;
6844 passes = strtol(optarg, NULL, 0);
6845 if (passes < 1 || passes > 31) {
6846 warnx("invalid passes value %d", passes);
6848 goto sanitize_bailout;
6867 /* ATA supports only immediate commands. */
6868 if (dt == CC_DT_SCSI)
6881 warnx("an action is required");
6883 goto sanitize_bailout;
6884 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6885 struct scsi_sanitize_parameter_list *pl;
6889 if (pattern == NULL) {
6890 warnx("overwrite action requires -P argument");
6892 goto sanitize_bailout;
6894 fd = open(pattern, O_RDONLY);
6896 warn("cannot open pattern file %s", pattern);
6898 goto sanitize_bailout;
6900 if (fstat(fd, &sb) < 0) {
6901 warn("cannot stat pattern file %s", pattern);
6903 goto sanitize_bailout;
6906 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6907 warnx("pattern file size exceeds maximum value %d",
6908 SSZPL_MAX_PATTERN_LENGTH);
6910 goto sanitize_bailout;
6912 dxfer_len = sizeof(*pl) + sz;
6913 data_ptr = calloc(1, dxfer_len);
6914 if (data_ptr == NULL) {
6915 warnx("cannot allocate parameter list buffer");
6917 goto sanitize_bailout;
6920 amt = read(fd, data_ptr + sizeof(*pl), sz);
6922 warn("cannot read pattern file");
6924 goto sanitize_bailout;
6925 } else if (amt != sz) {
6926 warnx("short pattern file read");
6928 goto sanitize_bailout;
6931 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6937 pl->byte1 |= SSZPL_INVERT;
6938 scsi_ulto2b(sz, pl->length);
6944 else if (invert != 0)
6946 else if (pattern != NULL)
6951 warnx("%s argument only valid with overwrite "
6954 goto sanitize_bailout;
6958 if (quiet == 0 && ycount == 0) {
6959 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6960 "following device:\n");
6962 if (dt == CC_DT_SCSI) {
6963 error = scsidoinquiry(device, argc, argv, combinedopt,
6964 task_attr, retry_count, timeout);
6965 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
6966 struct ata_params *ident_buf;
6967 error = ata_do_identify(device, retry_count, timeout,
6970 printf("%s%d: ", device->device_name,
6971 device->dev_unit_num);
6972 ata_print_ident(ident_buf);
6979 warnx("sanitize: error sending inquiry");
6980 goto sanitize_bailout;
6985 if (!get_confirmation()) {
6987 goto sanitize_bailout;
6992 use_timeout = timeout;
6994 use_timeout = (immediate ? 10 : 10800) * 1000;
6996 if (immediate == 0 && quiet == 0) {
6997 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6998 use_timeout / 1000);
7002 * If the user hasn't disabled questions and didn't specify a
7003 * timeout on the command line, ask them if they want the current
7006 if (immediate == 0 && ycount == 0 && timeout == 0) {
7008 int new_timeout = 0;
7010 fprintf(stdout, "Enter new timeout in seconds or press\n"
7011 "return to keep the current timeout [%d] ",
7012 use_timeout / 1000);
7014 if (fgets(str, sizeof(str), stdin) != NULL) {
7016 new_timeout = atoi(str);
7019 if (new_timeout != 0) {
7020 use_timeout = new_timeout * 1000;
7021 fprintf(stdout, "Using new timeout value %d\n",
7022 use_timeout / 1000);
7026 if (dt == CC_DT_SCSI) {
7029 byte2 |= SSZ_UNRESTRICTED_EXIT;
7032 scsi_sanitize(&ccb->csio,
7033 /* retries */ retry_count,
7035 /* tag_action */ task_attr,
7038 /* data_ptr */ data_ptr,
7039 /* dxfer_len */ dxfer_len,
7040 /* sense_len */ SSD_FULL_SIZE,
7041 /* timeout */ use_timeout);
7043 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7044 if (arglist & CAM_ARG_ERR_RECOVER)
7045 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7046 if (cam_send_ccb(device, ccb) < 0) {
7047 warn("error sending sanitize command");
7049 goto sanitize_bailout;
7051 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7052 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7053 feature = 0x14; /* OVERWRITE EXT */
7054 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7055 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7057 count |= 0x80; /* INVERT PATTERN */
7059 count |= 0x10; /* FAILURE MODE */
7060 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7061 feature = 0x12; /* BLOCK ERASE EXT */
7062 lba = 0x0000426B4572;
7065 count |= 0x10; /* FAILURE MODE */
7066 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7067 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7068 lba = 0x000043727970;
7071 count |= 0x10; /* FAILURE MODE */
7072 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7073 feature = 0x00; /* SANITIZE STATUS EXT */
7075 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7078 goto sanitize_bailout;
7081 error = ata_do_cmd(device,
7084 /*flags*/CAM_DIR_NONE,
7085 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7087 /*tag_action*/MSG_SIMPLE_Q_TAG,
7088 /*command*/ATA_SANITIZE,
7089 /*features*/feature,
7091 /*sector_count*/count,
7094 /*timeout*/ use_timeout,
7098 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7099 struct scsi_sense_data *sense;
7100 int error_code, sense_key, asc, ascq;
7102 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7103 CAM_SCSI_STATUS_ERROR) {
7104 sense = &ccb->csio.sense_data;
7105 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7106 ccb->csio.sense_resid, &error_code, &sense_key,
7107 &asc, &ascq, /*show_errors*/ 1);
7109 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7110 asc == 0x20 && ascq == 0x00)
7111 warnx("sanitize is not supported by "
7114 warnx("error sanitizing this device");
7116 warnx("error sanitizing this device");
7118 if (arglist & CAM_ARG_VERBOSE) {
7119 cam_error_print(device, ccb, CAM_ESF_ALL,
7120 CAM_EPF_ALL, stderr);
7123 goto sanitize_bailout;
7127 * If we ran in non-immediate mode, we already checked for errors
7128 * above and printed out any necessary information. If we're in
7129 * immediate mode, we need to loop through and get status
7130 * information periodically.
7132 if (immediate == 0) {
7134 fprintf(stdout, "Sanitize Complete\n");
7136 goto sanitize_bailout;
7140 if (dt == CC_DT_SCSI) {
7141 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7142 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7143 error = sanitize_wait_ata(device, ccb, quiet, dt);
7146 if (error == 0 && quiet == 0)
7147 fprintf(stdout, "Sanitize Complete \n");
7152 if (data_ptr != NULL)
7160 scsireportluns(struct cam_device *device, int argc, char **argv,
7161 char *combinedopt, int task_attr, int retry_count, int timeout)
7164 int c, countonly, lunsonly;
7165 struct scsi_report_luns_data *lundata;
7167 uint8_t report_type;
7168 uint32_t list_len, i, j;
7173 report_type = RPL_REPORT_DEFAULT;
7174 ccb = cam_getccb(device);
7177 warnx("%s: error allocating ccb", __func__);
7184 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7193 if (strcasecmp(optarg, "default") == 0)
7194 report_type = RPL_REPORT_DEFAULT;
7195 else if (strcasecmp(optarg, "wellknown") == 0)
7196 report_type = RPL_REPORT_WELLKNOWN;
7197 else if (strcasecmp(optarg, "all") == 0)
7198 report_type = RPL_REPORT_ALL;
7200 warnx("%s: invalid report type \"%s\"",
7211 if ((countonly != 0)
7212 && (lunsonly != 0)) {
7213 warnx("%s: you can only specify one of -c or -l", __func__);
7218 * According to SPC-4, the allocation length must be at least 16
7219 * bytes -- enough for the header and one LUN.
7221 alloc_len = sizeof(*lundata) + 8;
7225 lundata = malloc(alloc_len);
7227 if (lundata == NULL) {
7228 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7233 scsi_report_luns(&ccb->csio,
7234 /*retries*/ retry_count,
7236 /*tag_action*/ task_attr,
7237 /*select_report*/ report_type,
7238 /*rpl_buf*/ lundata,
7239 /*alloc_len*/ alloc_len,
7240 /*sense_len*/ SSD_FULL_SIZE,
7241 /*timeout*/ timeout ? timeout : 5000);
7243 /* Disable freezing the device queue */
7244 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7246 if (arglist & CAM_ARG_ERR_RECOVER)
7247 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7249 if (cam_send_ccb(device, ccb) < 0) {
7250 warn("error sending REPORT LUNS command");
7255 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7256 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7262 list_len = scsi_4btoul(lundata->length);
7265 * If we need to list the LUNs, and our allocation
7266 * length was too short, reallocate and retry.
7268 if ((countonly == 0)
7269 && (list_len > (alloc_len - sizeof(*lundata)))) {
7270 alloc_len = list_len + sizeof(*lundata);
7276 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7277 ((list_len / 8) > 1) ? "s" : "");
7282 for (i = 0; i < (list_len / 8); i++) {
7286 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7288 fprintf(stdout, ",");
7289 switch (lundata->luns[i].lundata[j] &
7290 RPL_LUNDATA_ATYP_MASK) {
7291 case RPL_LUNDATA_ATYP_PERIPH:
7292 if ((lundata->luns[i].lundata[j] &
7293 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7294 fprintf(stdout, "%d:",
7295 lundata->luns[i].lundata[j] &
7296 RPL_LUNDATA_PERIPH_BUS_MASK);
7298 && ((lundata->luns[i].lundata[j+2] &
7299 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7302 fprintf(stdout, "%d",
7303 lundata->luns[i].lundata[j+1]);
7305 case RPL_LUNDATA_ATYP_FLAT: {
7307 tmplun[0] = lundata->luns[i].lundata[j] &
7308 RPL_LUNDATA_FLAT_LUN_MASK;
7309 tmplun[1] = lundata->luns[i].lundata[j+1];
7311 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7315 case RPL_LUNDATA_ATYP_LUN:
7316 fprintf(stdout, "%d:%d:%d",
7317 (lundata->luns[i].lundata[j+1] &
7318 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7319 lundata->luns[i].lundata[j] &
7320 RPL_LUNDATA_LUN_TARG_MASK,
7321 lundata->luns[i].lundata[j+1] &
7322 RPL_LUNDATA_LUN_LUN_MASK);
7324 case RPL_LUNDATA_ATYP_EXTLUN: {
7325 int field_len_code, eam_code;
7327 eam_code = lundata->luns[i].lundata[j] &
7328 RPL_LUNDATA_EXT_EAM_MASK;
7329 field_len_code = (lundata->luns[i].lundata[j] &
7330 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7332 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7333 && (field_len_code == 0x00)) {
7334 fprintf(stdout, "%d",
7335 lundata->luns[i].lundata[j+1]);
7336 } else if ((eam_code ==
7337 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7338 && (field_len_code == 0x03)) {
7342 * This format takes up all 8 bytes.
7343 * If we aren't starting at offset 0,
7347 fprintf(stdout, "Invalid "
7350 "specified format", j);
7354 bzero(tmp_lun, sizeof(tmp_lun));
7355 bcopy(&lundata->luns[i].lundata[j+1],
7356 &tmp_lun[1], sizeof(tmp_lun) - 1);
7357 fprintf(stdout, "%#jx",
7358 (intmax_t)scsi_8btou64(tmp_lun));
7361 fprintf(stderr, "Unknown Extended LUN"
7362 "Address method %#x, length "
7363 "code %#x", eam_code,
7370 fprintf(stderr, "Unknown LUN address method "
7371 "%#x\n", lundata->luns[i].lundata[0] &
7372 RPL_LUNDATA_ATYP_MASK);
7376 * For the flat addressing method, there are no
7377 * other levels after it.
7382 fprintf(stdout, "\n");
7395 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7396 char *combinedopt, int task_attr, int retry_count, int timeout)
7399 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7400 struct scsi_read_capacity_data rcap;
7401 struct scsi_read_capacity_data_long rcaplong;
7416 ccb = cam_getccb(device);
7419 warnx("%s: error allocating ccb", __func__);
7423 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7453 if ((blocksizeonly != 0)
7454 && (numblocks != 0)) {
7455 warnx("%s: you can only specify one of -b or -N", __func__);
7460 if ((blocksizeonly != 0)
7461 && (sizeonly != 0)) {
7462 warnx("%s: you can only specify one of -b or -s", __func__);
7469 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7475 && (blocksizeonly != 0)) {
7476 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7484 scsi_read_capacity(&ccb->csio,
7485 /*retries*/ retry_count,
7487 /*tag_action*/ task_attr,
7490 /*timeout*/ timeout ? timeout : 5000);
7492 /* Disable freezing the device queue */
7493 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7495 if (arglist & CAM_ARG_ERR_RECOVER)
7496 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7498 if (cam_send_ccb(device, ccb) < 0) {
7499 warn("error sending READ CAPACITY command");
7504 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7505 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7510 maxsector = scsi_4btoul(rcap.addr);
7511 block_len = scsi_4btoul(rcap.length);
7514 * A last block of 2^32-1 means that the true capacity is over 2TB,
7515 * and we need to issue the long READ CAPACITY to get the real
7516 * capacity. Otherwise, we're all set.
7518 if (maxsector != 0xffffffff)
7522 scsi_read_capacity_16(&ccb->csio,
7523 /*retries*/ retry_count,
7525 /*tag_action*/ task_attr,
7529 /*rcap_buf*/ (uint8_t *)&rcaplong,
7530 /*rcap_buf_len*/ sizeof(rcaplong),
7531 /*sense_len*/ SSD_FULL_SIZE,
7532 /*timeout*/ timeout ? timeout : 5000);
7534 /* Disable freezing the device queue */
7535 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7537 if (arglist & CAM_ARG_ERR_RECOVER)
7538 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7540 if (cam_send_ccb(device, ccb) < 0) {
7541 warn("error sending READ CAPACITY (16) command");
7546 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7547 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7552 maxsector = scsi_8btou64(rcaplong.addr);
7553 block_len = scsi_4btoul(rcaplong.length);
7556 if (blocksizeonly == 0) {
7558 * Humanize implies !quiet, and also implies numblocks.
7560 if (humanize != 0) {
7565 tmpbytes = (maxsector + 1) * block_len;
7566 ret = humanize_number(tmpstr, sizeof(tmpstr),
7567 tmpbytes, "", HN_AUTOSCALE,
7570 HN_DIVISOR_1000 : 0));
7572 warnx("%s: humanize_number failed!", __func__);
7576 fprintf(stdout, "Device Size: %s%s", tmpstr,
7577 (sizeonly == 0) ? ", " : "\n");
7578 } else if (numblocks != 0) {
7579 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7580 "Blocks: " : "", (uintmax_t)maxsector + 1,
7581 (sizeonly == 0) ? ", " : "\n");
7583 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7584 "Last Block: " : "", (uintmax_t)maxsector,
7585 (sizeonly == 0) ? ", " : "\n");
7589 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7590 "Block Length: " : "", block_len, (quiet == 0) ?
7599 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7600 int retry_count, int timeout)
7604 uint8_t *smp_request = NULL, *smp_response = NULL;
7605 int request_size = 0, response_size = 0;
7606 int fd_request = 0, fd_response = 0;
7607 char *datastr = NULL;
7608 struct get_hook hook;
7613 * Note that at the moment we don't support sending SMP CCBs to
7614 * devices that aren't probed by CAM.
7616 ccb = cam_getccb(device);
7618 warnx("%s: error allocating CCB", __func__);
7622 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7625 arglist |= CAM_ARG_CMD_IN;
7626 response_size = strtol(optarg, NULL, 0);
7627 if (response_size <= 0) {
7628 warnx("invalid number of response bytes %d",
7631 goto smpcmd_bailout;
7633 hook.argc = argc - optind;
7634 hook.argv = argv + optind;
7637 datastr = cget(&hook, NULL);
7639 * If the user supplied "-" instead of a format, he
7640 * wants the data to be written to stdout.
7642 if ((datastr != NULL)
7643 && (datastr[0] == '-'))
7646 smp_response = (uint8_t *)malloc(response_size);
7647 if (smp_response == NULL) {
7648 warn("can't malloc memory for SMP response");
7650 goto smpcmd_bailout;
7654 arglist |= CAM_ARG_CMD_OUT;
7655 request_size = strtol(optarg, NULL, 0);
7656 if (request_size <= 0) {
7657 warnx("invalid number of request bytes %d",
7660 goto smpcmd_bailout;
7662 hook.argc = argc - optind;
7663 hook.argv = argv + optind;
7665 datastr = cget(&hook, NULL);
7666 smp_request = (uint8_t *)malloc(request_size);
7667 if (smp_request == NULL) {
7668 warn("can't malloc memory for SMP request");
7670 goto smpcmd_bailout;
7672 bzero(smp_request, request_size);
7674 * If the user supplied "-" instead of a format, he
7675 * wants the data to be read from stdin.
7677 if ((datastr != NULL)
7678 && (datastr[0] == '-'))
7681 buff_encode_visit(smp_request, request_size,
7692 * If fd_data is set, and we're writing to the device, we need to
7693 * read the data the user wants written from stdin.
7695 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7697 int amt_to_read = request_size;
7698 uint8_t *buf_ptr = smp_request;
7700 for (amt_read = 0; amt_to_read > 0;
7701 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7702 if (amt_read == -1) {
7703 warn("error reading data from stdin");
7705 goto smpcmd_bailout;
7707 amt_to_read -= amt_read;
7708 buf_ptr += amt_read;
7712 if (((arglist & CAM_ARG_CMD_IN) == 0)
7713 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7714 warnx("%s: need both the request (-r) and response (-R) "
7715 "arguments", __func__);
7717 goto smpcmd_bailout;
7720 flags |= CAM_DEV_QFRZDIS;
7722 cam_fill_smpio(&ccb->smpio,
7723 /*retries*/ retry_count,
7726 /*smp_request*/ smp_request,
7727 /*smp_request_len*/ request_size,
7728 /*smp_response*/ smp_response,
7729 /*smp_response_len*/ response_size,
7730 /*timeout*/ timeout ? timeout : 5000);
7732 ccb->smpio.flags = SMP_FLAG_NONE;
7734 if (((retval = cam_send_ccb(device, ccb)) < 0)
7735 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7736 const char warnstr[] = "error sending command";
7743 if (arglist & CAM_ARG_VERBOSE) {
7744 cam_error_print(device, ccb, CAM_ESF_ALL,
7745 CAM_EPF_ALL, stderr);
7749 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7750 && (response_size > 0)) {
7751 if (fd_response == 0) {
7752 buff_decode_visit(smp_response, response_size,
7753 datastr, arg_put, NULL);
7754 fprintf(stdout, "\n");
7756 ssize_t amt_written;
7757 int amt_to_write = response_size;
7758 uint8_t *buf_ptr = smp_response;
7760 for (amt_written = 0; (amt_to_write > 0) &&
7761 (amt_written = write(STDOUT_FILENO, buf_ptr,
7762 amt_to_write)) > 0;){
7763 amt_to_write -= amt_written;
7764 buf_ptr += amt_written;
7766 if (amt_written == -1) {
7767 warn("error writing data to stdout");
7769 goto smpcmd_bailout;
7770 } else if ((amt_written == 0)
7771 && (amt_to_write > 0)) {
7772 warnx("only wrote %u bytes out of %u",
7773 response_size - amt_to_write,
7782 if (smp_request != NULL)
7785 if (smp_response != NULL)
7792 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7793 int retry_count, int timeout)
7797 int32_t mmc_opcode = 0, mmc_arg = 0;
7798 int32_t mmc_flags = -1;
7801 int is_bw_4 = 0, is_bw_1 = 0;
7802 int is_frequency = 0;
7803 int is_highspeed = 0, is_stdspeed = 0;
7804 int is_info_request = 0;
7806 uint8_t mmc_data_byte = 0;
7807 uint32_t mmc_frequency = 0;
7809 /* For IO_RW_EXTENDED command */
7810 uint8_t *mmc_data = NULL;
7811 struct mmc_data mmc_d;
7812 int mmc_data_len = 0;
7815 * Note that at the moment we don't support sending SMP CCBs to
7816 * devices that aren't probed by CAM.
7818 ccb = cam_getccb(device);
7820 warnx("%s: error allocating CCB", __func__);
7824 bzero(&(&ccb->ccb_h)[1],
7825 sizeof(union ccb) - sizeof(struct ccb_hdr));
7827 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7836 if (!strcmp(optarg, "high"))
7842 is_info_request = 1;
7846 mmc_frequency = strtol(optarg, NULL, 0);
7849 mmc_opcode = strtol(optarg, NULL, 0);
7850 if (mmc_opcode < 0) {
7851 warnx("invalid MMC opcode %d",
7854 goto mmccmd_bailout;
7858 mmc_arg = strtol(optarg, NULL, 0);
7860 warnx("invalid MMC arg %d",
7863 goto mmccmd_bailout;
7867 mmc_flags = strtol(optarg, NULL, 0);
7868 if (mmc_flags < 0) {
7869 warnx("invalid MMC flags %d",
7872 goto mmccmd_bailout;
7876 mmc_data_len = strtol(optarg, NULL, 0);
7877 if (mmc_data_len <= 0) {
7878 warnx("invalid MMC data len %d",
7881 goto mmccmd_bailout;
7888 mmc_data_byte = strtol(optarg, NULL, 0);
7894 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7896 /* If flags are left default, supply the right flags */
7898 switch (mmc_opcode) {
7899 case MMC_GO_IDLE_STATE:
7900 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7902 case IO_SEND_OP_COND:
7903 mmc_flags = MMC_RSP_R4;
7905 case SD_SEND_RELATIVE_ADDR:
7906 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7908 case MMC_SELECT_CARD:
7909 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7910 mmc_arg = mmc_arg << 16;
7912 case SD_IO_RW_DIRECT:
7913 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7914 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7916 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7918 case SD_IO_RW_EXTENDED:
7919 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7920 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7921 int len_arg = mmc_data_len;
7922 if (mmc_data_len == 512)
7926 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7928 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7931 mmc_flags = MMC_RSP_R1;
7935 // Switch bus width instead of sending IO command
7936 if (is_bw_4 || is_bw_1) {
7937 struct ccb_trans_settings_mmc *cts;
7938 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7939 ccb->ccb_h.flags = 0;
7940 cts = &ccb->cts.proto_specific.mmc;
7941 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7942 cts->ios_valid = MMC_BW;
7943 if (((retval = cam_send_ccb(device, ccb)) < 0)
7944 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7945 warn("Error sending command");
7947 printf("Parameters set OK\n");
7954 struct ccb_trans_settings_mmc *cts;
7955 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7956 ccb->ccb_h.flags = 0;
7957 cts = &ccb->cts.proto_specific.mmc;
7958 cts->ios.clock = mmc_frequency;
7959 cts->ios_valid = MMC_CLK;
7960 if (((retval = cam_send_ccb(device, ccb)) < 0)
7961 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7962 warn("Error sending command");
7964 printf("Parameters set OK\n");
7970 // Switch bus speed instead of sending IO command
7971 if (is_stdspeed || is_highspeed) {
7972 struct ccb_trans_settings_mmc *cts;
7973 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7974 ccb->ccb_h.flags = 0;
7975 cts = &ccb->cts.proto_specific.mmc;
7976 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7977 cts->ios_valid = MMC_BT;
7978 if (((retval = cam_send_ccb(device, ccb)) < 0)
7979 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7980 warn("Error sending command");
7982 printf("Speed set OK (HS: %d)\n", is_highspeed);
7988 // Get information about controller and its settings
7989 if (is_info_request) {
7990 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7991 ccb->ccb_h.flags = 0;
7992 struct ccb_trans_settings_mmc *cts;
7993 cts = &ccb->cts.proto_specific.mmc;
7994 if (((retval = cam_send_ccb(device, ccb)) < 0)
7995 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7996 warn("Error sending command");
7999 printf("Host controller information\n");
8000 printf("Host OCR: 0x%x\n", cts->host_ocr);
8001 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8002 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8003 printf("Supported bus width:\n");
8004 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8006 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8009 printf("Supported operating modes:\n");
8010 if (cts->host_caps & MMC_CAP_HSPEED)
8011 printf(" Can do High Speed transfers\n");
8012 if (cts->host_caps & MMC_CAP_UHS_SDR12)
8013 printf(" Can do UHS SDR12\n");
8014 if (cts->host_caps & MMC_CAP_UHS_SDR25)
8015 printf(" Can do UHS SDR25\n");
8016 if (cts->host_caps & MMC_CAP_UHS_SDR50)
8017 printf(" Can do UHS SDR50\n");
8018 if (cts->host_caps & MMC_CAP_UHS_SDR104)
8019 printf(" Can do UHS SDR104\n");
8020 if (cts->host_caps & MMC_CAP_UHS_DDR50)
8021 printf(" Can do UHS DDR50\n");
8022 if (cts->host_caps & MMC_CAP_MMC_DDR52_120)
8023 printf(" Can do eMMC DDR52 at 1.2V\n");
8024 if (cts->host_caps & MMC_CAP_MMC_DDR52_180)
8025 printf(" Can do eMMC DDR52 at 1.8V\n");
8026 if (cts->host_caps & MMC_CAP_MMC_HS200_120)
8027 printf(" Can do eMMC HS200 at 1.2V\n");
8028 if (cts->host_caps & MMC_CAP_MMC_HS200_180)
8029 printf(" Can do eMMC HS200 at 1.8V\n");
8030 if (cts->host_caps & MMC_CAP_MMC_HS400_120)
8031 printf(" Can do eMMC HS400 at 1.2V\n");
8032 if (cts->host_caps & MMC_CAP_MMC_HS400_180)
8033 printf(" Can do eMMC HS400 at 1.8V\n");
8035 printf("Supported VCCQ voltages:\n");
8036 if (cts->host_caps & MMC_CAP_SIGNALING_120)
8038 if (cts->host_caps & MMC_CAP_SIGNALING_180)
8040 if (cts->host_caps & MMC_CAP_SIGNALING_330)
8043 printf("Current settings:\n");
8044 printf(" Bus width: ");
8045 switch (cts->ios.bus_width) {
8056 printf(" Freq: %d.%03d MHz%s\n",
8057 cts->ios.clock / 1000000,
8058 (cts->ios.clock / 1000) % 1000,
8059 cts->ios.timing == bus_timing_hs ? " (high-speed timing)" : "");
8062 switch (cts->ios.vccq) {
8076 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8078 if (mmc_data_len > 0) {
8079 flags |= CAM_DIR_IN;
8080 mmc_data = malloc(mmc_data_len);
8081 memset(mmc_data, 0, mmc_data_len);
8082 memset(&mmc_d, 0, sizeof(mmc_d));
8083 mmc_d.len = mmc_data_len;
8084 mmc_d.data = mmc_data;
8085 mmc_d.flags = MMC_DATA_READ;
8086 } else flags |= CAM_DIR_NONE;
8088 cam_fill_mmcio(&ccb->mmcio,
8089 /*retries*/ retry_count,
8092 /*mmc_opcode*/ mmc_opcode,
8093 /*mmc_arg*/ mmc_arg,
8094 /*mmc_flags*/ mmc_flags,
8095 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8096 /*timeout*/ timeout ? timeout : 5000);
8098 if (((retval = cam_send_ccb(device, ccb)) < 0)
8099 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8100 const char warnstr[] = "error sending command";
8107 if (arglist & CAM_ARG_VERBOSE) {
8108 cam_error_print(device, ccb, CAM_ESF_ALL,
8109 CAM_EPF_ALL, stderr);
8113 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8114 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8115 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8116 ccb->mmcio.cmd.resp[1],
8117 ccb->mmcio.cmd.resp[2],
8118 ccb->mmcio.cmd.resp[3]);
8120 switch (mmc_opcode) {
8121 case SD_IO_RW_DIRECT:
8122 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8123 SD_R5_DATA(ccb->mmcio.cmd.resp),
8124 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8126 case SD_IO_RW_EXTENDED:
8127 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8128 hexdump(mmc_data, mmc_data_len, NULL, 0);
8130 case SD_SEND_RELATIVE_ADDR:
8131 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8134 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8135 if (mmc_data_len > 0)
8136 hexdump(mmc_data, mmc_data_len, NULL, 0);
8143 if (mmc_data_len > 0 && mmc_data != NULL)
8150 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8151 char *combinedopt, int retry_count, int timeout)
8154 struct smp_report_general_request *request = NULL;
8155 struct smp_report_general_response *response = NULL;
8156 struct sbuf *sb = NULL;
8158 int c, long_response = 0;
8162 * Note that at the moment we don't support sending SMP CCBs to
8163 * devices that aren't probed by CAM.
8165 ccb = cam_getccb(device);
8167 warnx("%s: error allocating CCB", __func__);
8171 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8180 request = malloc(sizeof(*request));
8181 if (request == NULL) {
8182 warn("%s: unable to allocate %zd bytes", __func__,
8188 response = malloc(sizeof(*response));
8189 if (response == NULL) {
8190 warn("%s: unable to allocate %zd bytes", __func__,
8197 smp_report_general(&ccb->smpio,
8201 /*request_len*/ sizeof(*request),
8202 (uint8_t *)response,
8203 /*response_len*/ sizeof(*response),
8204 /*long_response*/ long_response,
8207 if (((retval = cam_send_ccb(device, ccb)) < 0)
8208 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8209 const char warnstr[] = "error sending command";
8216 if (arglist & CAM_ARG_VERBOSE) {
8217 cam_error_print(device, ccb, CAM_ESF_ALL,
8218 CAM_EPF_ALL, stderr);
8225 * If the device supports the long response bit, try again and see
8226 * if we can get all of the data.
8228 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8229 && (long_response == 0)) {
8230 ccb->ccb_h.status = CAM_REQ_INPROG;
8231 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8237 * XXX KDM detect and decode SMP errors here.
8239 sb = sbuf_new_auto();
8241 warnx("%s: error allocating sbuf", __func__);
8245 smp_report_general_sbuf(response, sizeof(*response), sb);
8247 if (sbuf_finish(sb) != 0) {
8248 warnx("%s: sbuf_finish", __func__);
8252 printf("%s", sbuf_data(sb));
8258 if (request != NULL)
8261 if (response != NULL)
8270 static struct camcontrol_opts phy_ops[] = {
8271 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8272 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8273 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8274 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8275 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8276 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8277 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8278 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8279 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8284 smpphycontrol(struct cam_device *device, int argc, char **argv,
8285 char *combinedopt, int retry_count, int timeout)
8288 struct smp_phy_control_request *request = NULL;
8289 struct smp_phy_control_response *response = NULL;
8290 int long_response = 0;
8293 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8295 uint64_t attached_dev_name = 0;
8296 int dev_name_set = 0;
8297 uint32_t min_plr = 0, max_plr = 0;
8298 uint32_t pp_timeout_val = 0;
8299 int slumber_partial = 0;
8300 int set_pp_timeout_val = 0;
8304 * Note that at the moment we don't support sending SMP CCBs to
8305 * devices that aren't probed by CAM.
8307 ccb = cam_getccb(device);
8309 warnx("%s: error allocating CCB", __func__);
8313 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8321 if (strcasecmp(optarg, "enable") == 0)
8323 else if (strcasecmp(optarg, "disable") == 0)
8326 warnx("%s: Invalid argument %s", __func__,
8333 slumber_partial |= enable <<
8334 SMP_PC_SAS_SLUMBER_SHIFT;
8337 slumber_partial |= enable <<
8338 SMP_PC_SAS_PARTIAL_SHIFT;
8341 slumber_partial |= enable <<
8342 SMP_PC_SATA_SLUMBER_SHIFT;
8345 slumber_partial |= enable <<
8346 SMP_PC_SATA_PARTIAL_SHIFT;
8349 warnx("%s: programmer error", __func__);
8352 break; /*NOTREACHED*/
8357 attached_dev_name = (uintmax_t)strtoumax(optarg,
8366 * We don't do extensive checking here, so this
8367 * will continue to work when new speeds come out.
8369 min_plr = strtoul(optarg, NULL, 0);
8371 || (min_plr > 0xf)) {
8372 warnx("%s: invalid link rate %x",
8380 * We don't do extensive checking here, so this
8381 * will continue to work when new speeds come out.
8383 max_plr = strtoul(optarg, NULL, 0);
8385 || (max_plr > 0xf)) {
8386 warnx("%s: invalid link rate %x",
8393 camcontrol_optret optreturn;
8394 cam_argmask argnums;
8397 if (phy_op_set != 0) {
8398 warnx("%s: only one phy operation argument "
8399 "(-o) allowed", __func__);
8407 * Allow the user to specify the phy operation
8408 * numerically, as well as with a name. This will
8409 * future-proof it a bit, so options that are added
8410 * in future specs can be used.
8412 if (isdigit(optarg[0])) {
8413 phy_operation = strtoul(optarg, NULL, 0);
8414 if ((phy_operation == 0)
8415 || (phy_operation > 0xff)) {
8416 warnx("%s: invalid phy operation %#x",
8417 __func__, phy_operation);
8423 optreturn = getoption(phy_ops, optarg, &phy_operation,
8426 if (optreturn == CC_OR_AMBIGUOUS) {
8427 warnx("%s: ambiguous option %s", __func__,
8432 } else if (optreturn == CC_OR_NOT_FOUND) {
8433 warnx("%s: option %s not found", __func__,
8445 pp_timeout_val = strtoul(optarg, NULL, 0);
8446 if (pp_timeout_val > 15) {
8447 warnx("%s: invalid partial pathway timeout "
8448 "value %u, need a value less than 16",
8449 __func__, pp_timeout_val);
8453 set_pp_timeout_val = 1;
8461 warnx("%s: a PHY (-p phy) argument is required",__func__);
8466 if (((dev_name_set != 0)
8467 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8468 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8469 && (dev_name_set == 0))) {
8470 warnx("%s: -d name and -o setdevname arguments both "
8471 "required to set device name", __func__);
8476 request = malloc(sizeof(*request));
8477 if (request == NULL) {
8478 warn("%s: unable to allocate %zd bytes", __func__,
8484 response = malloc(sizeof(*response));
8485 if (response == NULL) {
8486 warn("%s: unable to allocate %zd bytes", __func__,
8492 smp_phy_control(&ccb->smpio,
8497 (uint8_t *)response,
8500 /*expected_exp_change_count*/ 0,
8503 (set_pp_timeout_val != 0) ? 1 : 0,
8511 if (((retval = cam_send_ccb(device, ccb)) < 0)
8512 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8513 const char warnstr[] = "error sending command";
8520 if (arglist & CAM_ARG_VERBOSE) {
8522 * Use CAM_EPF_NORMAL so we only get one line of
8523 * SMP command decoding.
8525 cam_error_print(device, ccb, CAM_ESF_ALL,
8526 CAM_EPF_NORMAL, stderr);
8532 /* XXX KDM print out something here for success? */
8537 if (request != NULL)
8540 if (response != NULL)
8547 smpmaninfo(struct cam_device *device, int argc, char **argv,
8548 char *combinedopt, int retry_count, int timeout)
8551 struct smp_report_manuf_info_request request;
8552 struct smp_report_manuf_info_response response;
8553 struct sbuf *sb = NULL;
8554 int long_response = 0;
8559 * Note that at the moment we don't support sending SMP CCBs to
8560 * devices that aren't probed by CAM.
8562 ccb = cam_getccb(device);
8564 warnx("%s: error allocating CCB", __func__);
8568 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8577 bzero(&request, sizeof(request));
8578 bzero(&response, sizeof(response));
8580 smp_report_manuf_info(&ccb->smpio,
8585 (uint8_t *)&response,
8590 if (((retval = cam_send_ccb(device, ccb)) < 0)
8591 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8592 const char warnstr[] = "error sending command";
8599 if (arglist & CAM_ARG_VERBOSE) {
8600 cam_error_print(device, ccb, CAM_ESF_ALL,
8601 CAM_EPF_ALL, stderr);
8607 sb = sbuf_new_auto();
8609 warnx("%s: error allocating sbuf", __func__);
8613 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8615 if (sbuf_finish(sb) != 0) {
8616 warnx("%s: sbuf_finish", __func__);
8620 printf("%s", sbuf_data(sb));
8634 getdevid(struct cam_devitem *item)
8637 union ccb *ccb = NULL;
8639 struct cam_device *dev;
8641 dev = cam_open_btl(item->dev_match.path_id,
8642 item->dev_match.target_id,
8643 item->dev_match.target_lun, O_RDWR, NULL);
8646 warnx("%s", cam_errbuf);
8651 item->device_id_len = 0;
8653 ccb = cam_getccb(dev);
8655 warnx("%s: error allocating CCB", __func__);
8661 * On the first try, we just probe for the size of the data, and
8662 * then allocate that much memory and try again.
8665 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8666 ccb->ccb_h.flags = CAM_DIR_IN;
8667 ccb->cdai.flags = CDAI_FLAG_NONE;
8668 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8669 ccb->cdai.bufsiz = item->device_id_len;
8670 if (item->device_id_len != 0)
8671 ccb->cdai.buf = (uint8_t *)item->device_id;
8673 if (cam_send_ccb(dev, ccb) < 0) {
8674 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8679 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8680 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8685 if (item->device_id_len == 0) {
8687 * This is our first time through. Allocate the buffer,
8688 * and then go back to get the data.
8690 if (ccb->cdai.provsiz == 0) {
8691 warnx("%s: invalid .provsiz field returned with "
8692 "XPT_GDEV_ADVINFO CCB", __func__);
8696 item->device_id_len = ccb->cdai.provsiz;
8697 item->device_id = malloc(item->device_id_len);
8698 if (item->device_id == NULL) {
8699 warn("%s: unable to allocate %d bytes", __func__,
8700 item->device_id_len);
8704 ccb->ccb_h.status = CAM_REQ_INPROG;
8710 cam_close_device(dev);
8719 * XXX KDM merge this code with getdevtree()?
8722 buildbusdevlist(struct cam_devlist *devlist)
8725 int bufsize, fd = -1;
8726 struct dev_match_pattern *patterns;
8727 struct cam_devitem *item = NULL;
8728 int skip_device = 0;
8731 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8732 warn("couldn't open %s", XPT_DEVICE);
8736 bzero(&ccb, sizeof(union ccb));
8738 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8739 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8740 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8742 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8743 bufsize = sizeof(struct dev_match_result) * 100;
8744 ccb.cdm.match_buf_len = bufsize;
8745 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8746 if (ccb.cdm.matches == NULL) {
8747 warnx("can't malloc memory for matches");
8751 ccb.cdm.num_matches = 0;
8752 ccb.cdm.num_patterns = 2;
8753 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8754 ccb.cdm.num_patterns;
8756 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8757 if (patterns == NULL) {
8758 warnx("can't malloc memory for patterns");
8763 ccb.cdm.patterns = patterns;
8764 bzero(patterns, ccb.cdm.pattern_buf_len);
8766 patterns[0].type = DEV_MATCH_DEVICE;
8767 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8768 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8769 patterns[1].type = DEV_MATCH_PERIPH;
8770 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8771 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8774 * We do the ioctl multiple times if necessary, in case there are
8775 * more than 100 nodes in the EDT.
8780 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8781 warn("error sending CAMIOCOMMAND ioctl");
8786 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8787 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8788 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8789 warnx("got CAM error %#x, CDM error %d\n",
8790 ccb.ccb_h.status, ccb.cdm.status);
8795 for (i = 0; i < ccb.cdm.num_matches; i++) {
8796 switch (ccb.cdm.matches[i].type) {
8797 case DEV_MATCH_DEVICE: {
8798 struct device_match_result *dev_result;
8801 &ccb.cdm.matches[i].result.device_result;
8803 if (dev_result->flags &
8804 DEV_RESULT_UNCONFIGURED) {
8810 item = malloc(sizeof(*item));
8812 warn("%s: unable to allocate %zd bytes",
8813 __func__, sizeof(*item));
8817 bzero(item, sizeof(*item));
8818 bcopy(dev_result, &item->dev_match,
8819 sizeof(*dev_result));
8820 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8823 if (getdevid(item) != 0) {
8829 case DEV_MATCH_PERIPH: {
8830 struct periph_match_result *periph_result;
8833 &ccb.cdm.matches[i].result.periph_result;
8835 if (skip_device != 0)
8837 item->num_periphs++;
8838 item->periph_matches = realloc(
8839 item->periph_matches,
8841 sizeof(struct periph_match_result));
8842 if (item->periph_matches == NULL) {
8843 warn("%s: error allocating periph "
8848 bcopy(periph_result, &item->periph_matches[
8849 item->num_periphs - 1],
8850 sizeof(*periph_result));
8854 fprintf(stderr, "%s: unexpected match "
8855 "type %d\n", __func__,
8856 ccb.cdm.matches[i].type);
8859 break; /*NOTREACHED*/
8862 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8863 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8871 free(ccb.cdm.matches);
8874 freebusdevlist(devlist);
8880 freebusdevlist(struct cam_devlist *devlist)
8882 struct cam_devitem *item, *item2;
8884 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8885 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8887 free(item->device_id);
8888 free(item->periph_matches);
8893 static struct cam_devitem *
8894 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8896 struct cam_devitem *item;
8898 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8899 struct scsi_vpd_id_descriptor *idd;
8902 * XXX KDM look for LUN IDs as well?
8904 idd = scsi_get_devid(item->device_id,
8905 item->device_id_len,
8906 scsi_devid_is_sas_target);
8910 if (scsi_8btou64(idd->identifier) == sasaddr)
8918 smpphylist(struct cam_device *device, int argc, char **argv,
8919 char *combinedopt, int retry_count, int timeout)
8921 struct smp_report_general_request *rgrequest = NULL;
8922 struct smp_report_general_response *rgresponse = NULL;
8923 struct smp_discover_request *disrequest = NULL;
8924 struct smp_discover_response *disresponse = NULL;
8925 struct cam_devlist devlist;
8927 int long_response = 0;
8934 * Note that at the moment we don't support sending SMP CCBs to
8935 * devices that aren't probed by CAM.
8937 ccb = cam_getccb(device);
8939 warnx("%s: error allocating CCB", __func__);
8943 STAILQ_INIT(&devlist.dev_queue);
8945 rgrequest = malloc(sizeof(*rgrequest));
8946 if (rgrequest == NULL) {
8947 warn("%s: unable to allocate %zd bytes", __func__,
8948 sizeof(*rgrequest));
8953 rgresponse = malloc(sizeof(*rgresponse));
8954 if (rgresponse == NULL) {
8955 warn("%s: unable to allocate %zd bytes", __func__,
8956 sizeof(*rgresponse));
8961 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8974 smp_report_general(&ccb->smpio,
8978 /*request_len*/ sizeof(*rgrequest),
8979 (uint8_t *)rgresponse,
8980 /*response_len*/ sizeof(*rgresponse),
8981 /*long_response*/ long_response,
8984 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8986 if (((retval = cam_send_ccb(device, ccb)) < 0)
8987 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8988 const char warnstr[] = "error sending command";
8995 if (arglist & CAM_ARG_VERBOSE) {
8996 cam_error_print(device, ccb, CAM_ESF_ALL,
8997 CAM_EPF_ALL, stderr);
9003 num_phys = rgresponse->num_phys;
9005 if (num_phys == 0) {
9007 fprintf(stdout, "%s: No Phys reported\n", __func__);
9012 devlist.path_id = device->path_id;
9014 retval = buildbusdevlist(&devlist);
9019 fprintf(stdout, "%d PHYs:\n", num_phys);
9020 fprintf(stdout, "PHY Attached SAS Address\n");
9023 disrequest = malloc(sizeof(*disrequest));
9024 if (disrequest == NULL) {
9025 warn("%s: unable to allocate %zd bytes", __func__,
9026 sizeof(*disrequest));
9031 disresponse = malloc(sizeof(*disresponse));
9032 if (disresponse == NULL) {
9033 warn("%s: unable to allocate %zd bytes", __func__,
9034 sizeof(*disresponse));
9039 for (i = 0; i < num_phys; i++) {
9040 struct cam_devitem *item;
9041 struct device_match_result *dev_match;
9042 char vendor[16], product[48], revision[16];
9046 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9048 ccb->ccb_h.status = CAM_REQ_INPROG;
9049 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9051 smp_discover(&ccb->smpio,
9055 sizeof(*disrequest),
9056 (uint8_t *)disresponse,
9057 sizeof(*disresponse),
9059 /*ignore_zone_group*/ 0,
9063 if (((retval = cam_send_ccb(device, ccb)) < 0)
9064 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9065 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9066 const char warnstr[] = "error sending command";
9073 if (arglist & CAM_ARG_VERBOSE) {
9074 cam_error_print(device, ccb, CAM_ESF_ALL,
9075 CAM_EPF_ALL, stderr);
9081 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9083 fprintf(stdout, "%3d <vacant>\n", i);
9087 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9090 item = findsasdevice(&devlist,
9091 scsi_8btou64(disresponse->attached_sas_address));
9095 || (item != NULL)) {
9096 fprintf(stdout, "%3d 0x%016jx", i,
9097 (uintmax_t)scsi_8btou64(
9098 disresponse->attached_sas_address));
9100 fprintf(stdout, "\n");
9103 } else if (quiet != 0)
9106 dev_match = &item->dev_match;
9108 if (dev_match->protocol == PROTO_SCSI) {
9109 cam_strvis(vendor, dev_match->inq_data.vendor,
9110 sizeof(dev_match->inq_data.vendor),
9112 cam_strvis(product, dev_match->inq_data.product,
9113 sizeof(dev_match->inq_data.product),
9115 cam_strvis(revision, dev_match->inq_data.revision,
9116 sizeof(dev_match->inq_data.revision),
9118 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9120 } else if ((dev_match->protocol == PROTO_ATA)
9121 || (dev_match->protocol == PROTO_SATAPM)) {
9122 cam_strvis(product, dev_match->ident_data.model,
9123 sizeof(dev_match->ident_data.model),
9125 cam_strvis(revision, dev_match->ident_data.revision,
9126 sizeof(dev_match->ident_data.revision),
9128 sprintf(tmpstr, "<%s %s>", product, revision);
9130 sprintf(tmpstr, "<>");
9132 fprintf(stdout, " %-33s ", tmpstr);
9135 * If we have 0 periphs, that's a bug...
9137 if (item->num_periphs == 0) {
9138 fprintf(stdout, "\n");
9142 fprintf(stdout, "(");
9143 for (j = 0; j < item->num_periphs; j++) {
9145 fprintf(stdout, ",");
9147 fprintf(stdout, "%s%d",
9148 item->periph_matches[j].periph_name,
9149 item->periph_matches[j].unit_number);
9152 fprintf(stdout, ")\n");
9166 freebusdevlist(&devlist);
9172 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9174 uint8_t error = 0, ata_device = 0, status = 0;
9179 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9182 if (arglist & CAM_ARG_VERBOSE) {
9183 cam_error_print(device, ccb, CAM_ESF_ALL,
9184 CAM_EPF_ALL, stderr);
9186 warnx("Can't get ATA command status");
9190 if (status & ATA_STATUS_ERROR) {
9191 cam_error_print(device, ccb, CAM_ESF_ALL,
9192 CAM_EPF_ALL, stderr);
9196 printf("%s%d: ", device->device_name, device->dev_unit_num);
9198 case ATA_PM_STANDBY:
9199 printf("Standby mode\n");
9201 case ATA_PM_STANDBY_Y:
9202 printf("Standby_y mode\n");
9204 case 0x40: /* obsolete since ACS-3 */
9205 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9207 case 0x41: /* obsolete since ACS-3 */
9208 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9211 printf("Idle mode\n");
9214 printf("Idle_a mode\n");
9217 printf("Idle_b mode\n");
9220 printf("Idle_c mode\n");
9222 case ATA_PM_ACTIVE_IDLE:
9223 printf("Active or Idle mode\n");
9226 printf("Unknown mode 0x%02x\n", count);
9234 atapm(struct cam_device *device, int argc, char **argv,
9235 char *combinedopt, int retry_count, int timeout)
9241 uint8_t ata_flags = 0;
9244 ccb = cam_getccb(device);
9247 warnx("%s: error allocating ccb", __func__);
9251 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9260 if (strcmp(argv[1], "idle") == 0) {
9262 cmd = ATA_IDLE_IMMEDIATE;
9265 } else if (strcmp(argv[1], "standby") == 0) {
9267 cmd = ATA_STANDBY_IMMEDIATE;
9269 cmd = ATA_STANDBY_CMD;
9270 } else if (strcmp(argv[1], "powermode") == 0) {
9271 cmd = ATA_CHECK_POWER_MODE;
9272 ata_flags = AP_FLAG_CHK_COND;
9281 else if (t <= (240 * 5))
9283 else if (t <= (252 * 5))
9284 /* special encoding for 21 minutes */
9286 else if (t <= (11 * 30 * 60))
9287 sc = (t - 1) / (30 * 60) + 241;
9291 retval = ata_do_cmd(device,
9293 /*retries*/retry_count,
9294 /*flags*/CAM_DIR_NONE,
9295 /*protocol*/AP_PROTO_NON_DATA,
9296 /*ata_flags*/ata_flags,
9297 /*tag_action*/MSG_SIMPLE_Q_TAG,
9304 /*timeout*/timeout ? timeout : 30 * 1000,
9307 if (retval == 0 && cmd == ATA_CHECK_POWER_MODE)
9308 retval = atapm_proc_resp(device, ccb);
9315 ataaxm(struct cam_device *device, int argc, char **argv,
9316 char *combinedopt, int retry_count, int timeout)
9324 ccb = cam_getccb(device);
9327 warnx("%s: error allocating ccb", __func__);
9331 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9341 if (strcmp(argv[1], "apm") == 0) {
9357 retval = ata_do_cmd(device,
9359 /*retries*/retry_count,
9360 /*flags*/CAM_DIR_NONE,
9361 /*protocol*/AP_PROTO_NON_DATA,
9363 /*tag_action*/MSG_SIMPLE_Q_TAG,
9364 /*command*/ATA_SETFEATURES,
9370 /*timeout*/timeout ? timeout : 30 * 1000,
9378 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9379 int show_sa_errors, int sa_set, int service_action,
9380 int timeout_desc, int task_attr, int retry_count, int timeout,
9381 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9383 union ccb *ccb = NULL;
9384 uint8_t *buf = NULL;
9385 uint32_t alloc_len = 0, num_opcodes;
9386 uint32_t valid_len = 0;
9387 uint32_t avail_len = 0;
9388 struct scsi_report_supported_opcodes_all *all_hdr;
9389 struct scsi_report_supported_opcodes_one *one;
9394 * Make it clear that we haven't yet allocated or filled anything.
9399 ccb = cam_getccb(device);
9401 warnx("couldn't allocate CCB");
9406 if (opcode_set != 0) {
9407 options |= RSO_OPTIONS_OC;
9409 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9412 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9413 sizeof(struct scsi_report_supported_opcodes_descr));
9416 if (timeout_desc != 0) {
9417 options |= RSO_RCTD;
9418 alloc_len += num_opcodes *
9419 sizeof(struct scsi_report_supported_opcodes_timeout);
9423 options |= RSO_OPTIONS_OC_SA;
9424 if (show_sa_errors != 0)
9425 options &= ~RSO_OPTIONS_OC;
9434 buf = malloc(alloc_len);
9436 warn("Unable to allocate %u bytes", alloc_len);
9440 bzero(buf, alloc_len);
9442 scsi_report_supported_opcodes(&ccb->csio,
9443 /*retries*/ retry_count,
9445 /*tag_action*/ task_attr,
9446 /*options*/ options,
9447 /*req_opcode*/ opcode,
9448 /*req_service_action*/ service_action,
9450 /*dxfer_len*/ alloc_len,
9451 /*sense_len*/ SSD_FULL_SIZE,
9452 /*timeout*/ timeout ? timeout : 10000);
9454 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9456 if (retry_count != 0)
9457 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9459 if (cam_send_ccb(device, ccb) < 0) {
9460 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9465 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9466 if (verbosemode != 0)
9467 cam_error_print(device, ccb, CAM_ESF_ALL,
9468 CAM_EPF_ALL, stderr);
9473 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9475 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9476 && (valid_len >= sizeof(*all_hdr))) {
9477 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9478 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9479 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9480 && (valid_len >= sizeof(*one))) {
9481 uint32_t cdb_length;
9483 one = (struct scsi_report_supported_opcodes_one *)buf;
9484 cdb_length = scsi_2btoul(one->cdb_length);
9485 avail_len = sizeof(*one) + cdb_length;
9486 if (one->support & RSO_ONE_CTDP) {
9487 struct scsi_report_supported_opcodes_timeout *td;
9489 td = (struct scsi_report_supported_opcodes_timeout *)
9491 if (valid_len >= (avail_len + sizeof(td->length))) {
9492 avail_len += scsi_2btoul(td->length) +
9495 avail_len += sizeof(*td);
9501 * avail_len could be zero if we didn't get enough data back from
9502 * thet target to determine
9504 if ((avail_len != 0)
9505 && (avail_len > valid_len)) {
9506 alloc_len = avail_len;
9510 *fill_len = valid_len;
9522 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9523 int req_sa, uint8_t *buf, uint32_t valid_len)
9525 struct scsi_report_supported_opcodes_one *one;
9526 struct scsi_report_supported_opcodes_timeout *td;
9527 uint32_t cdb_len = 0, td_len = 0;
9528 const char *op_desc = NULL;
9532 one = (struct scsi_report_supported_opcodes_one *)buf;
9535 * If we don't have the full single opcode descriptor, no point in
9538 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9540 warnx("Only %u bytes returned, not enough to verify support",
9546 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9548 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9551 printf(", SA 0x%x", req_sa);
9554 switch (one->support & RSO_ONE_SUP_MASK) {
9555 case RSO_ONE_SUP_UNAVAIL:
9556 printf("No command support information currently available\n");
9558 case RSO_ONE_SUP_NOT_SUP:
9559 printf("Command not supported\n");
9562 break; /*NOTREACHED*/
9563 case RSO_ONE_SUP_AVAIL:
9564 printf("Command is supported, complies with a SCSI standard\n");
9566 case RSO_ONE_SUP_VENDOR:
9567 printf("Command is supported, vendor-specific "
9568 "implementation\n");
9571 printf("Unknown command support flags 0x%#x\n",
9572 one->support & RSO_ONE_SUP_MASK);
9577 * If we don't have the CDB length, it isn't exactly an error, the
9578 * command probably isn't supported.
9580 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9584 cdb_len = scsi_2btoul(one->cdb_length);
9587 * If our valid data doesn't include the full reported length,
9588 * return. The caller should have detected this and adjusted his
9589 * allocation length to get all of the available data.
9591 if (valid_len < sizeof(*one) + cdb_len) {
9597 * If all we have is the opcode, there is no point in printing out
9605 printf("CDB usage bitmap:");
9606 for (i = 0; i < cdb_len; i++) {
9607 printf(" %02x", one->cdb_usage[i]);
9612 * If we don't have a timeout descriptor, we're done.
9614 if ((one->support & RSO_ONE_CTDP) == 0)
9618 * If we don't have enough valid length to include the timeout
9619 * descriptor length, we're done.
9621 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9624 td = (struct scsi_report_supported_opcodes_timeout *)
9625 &buf[sizeof(*one) + cdb_len];
9626 td_len = scsi_2btoul(td->length);
9627 td_len += sizeof(td->length);
9630 * If we don't have the full timeout descriptor, we're done.
9632 if (td_len < sizeof(*td))
9636 * If we don't have enough valid length to contain the full timeout
9637 * descriptor, we're done.
9639 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9642 printf("Timeout information:\n");
9643 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9644 printf("Nominal timeout: %u seconds\n",
9645 scsi_4btoul(td->nominal_time));
9646 printf("Recommended timeout: %u seconds\n",
9647 scsi_4btoul(td->recommended_time));
9654 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9657 struct scsi_report_supported_opcodes_all *hdr;
9658 struct scsi_report_supported_opcodes_descr *desc;
9659 uint32_t avail_len = 0, used_len = 0;
9663 if (valid_len < sizeof(*hdr)) {
9664 warnx("%s: not enough returned data (%u bytes) opcode list",
9665 __func__, valid_len);
9669 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9670 avail_len = scsi_4btoul(hdr->length);
9671 avail_len += sizeof(hdr->length);
9673 * Take the lesser of the amount of data the drive claims is
9674 * available, and the amount of data the HBA says was returned.
9676 avail_len = MIN(avail_len, valid_len);
9678 used_len = sizeof(hdr->length);
9680 printf("%-6s %4s %8s ",
9681 "Opcode", "SA", "CDB len" );
9684 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9685 printf(" Description\n");
9687 while ((avail_len - used_len) > sizeof(*desc)) {
9688 struct scsi_report_supported_opcodes_timeout *td;
9690 const char *op_desc = NULL;
9692 cur_ptr = &buf[used_len];
9693 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9695 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9696 if (op_desc == NULL)
9697 op_desc = "UNKNOWN";
9699 printf("0x%02x %#4x %8u ", desc->opcode,
9700 scsi_2btoul(desc->service_action),
9701 scsi_2btoul(desc->cdb_length));
9703 used_len += sizeof(*desc);
9705 if ((desc->flags & RSO_CTDP) == 0) {
9706 printf(" %s\n", op_desc);
9711 * If we don't have enough space to fit a timeout
9712 * descriptor, then we're done.
9714 if (avail_len - used_len < sizeof(*td)) {
9715 used_len = avail_len;
9716 printf(" %s\n", op_desc);
9719 cur_ptr = &buf[used_len];
9720 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9721 td_len = scsi_2btoul(td->length);
9722 td_len += sizeof(td->length);
9726 * If the given timeout descriptor length is less than what
9727 * we understand, skip it.
9729 if (td_len < sizeof(*td)) {
9730 printf(" %s\n", op_desc);
9734 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9735 scsi_4btoul(td->nominal_time),
9736 scsi_4btoul(td->recommended_time), op_desc);
9743 scsiopcodes(struct cam_device *device, int argc, char **argv,
9744 char *combinedopt, int task_attr, int retry_count, int timeout,
9748 uint32_t opcode = 0, service_action = 0;
9749 int td_set = 0, opcode_set = 0, sa_set = 0;
9750 int show_sa_errors = 1;
9751 uint32_t valid_len = 0;
9752 uint8_t *buf = NULL;
9756 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9762 opcode = strtoul(optarg, &endptr, 0);
9763 if (*endptr != '\0') {
9764 warnx("Invalid opcode \"%s\", must be a number",
9769 if (opcode > 0xff) {
9770 warnx("Invalid opcode 0x%#x, must be between"
9771 "0 and 0xff inclusive", opcode);
9778 service_action = strtoul(optarg, &endptr, 0);
9779 if (*endptr != '\0') {
9780 warnx("Invalid service action \"%s\", must "
9781 "be a number", optarg);
9785 if (service_action > 0xffff) {
9786 warnx("Invalid service action 0x%#x, must "
9787 "be between 0 and 0xffff inclusive",
9802 && (opcode_set == 0)) {
9803 warnx("You must specify an opcode with -o if a service "
9808 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9809 sa_set, service_action, td_set, task_attr,
9810 retry_count, timeout, verbosemode, &valid_len,
9815 if ((opcode_set != 0)
9817 retval = scsiprintoneopcode(device, opcode, sa_set,
9818 service_action, buf, valid_len);
9820 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9831 reprobe(struct cam_device *device)
9836 ccb = cam_getccb(device);
9839 warnx("%s: error allocating ccb", __func__);
9843 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9845 if (cam_send_ccb(device, ccb) < 0) {
9846 warn("error sending XPT_REPROBE_LUN CCB");
9851 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9852 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9864 usage(int printlong)
9867 fprintf(printlong ? stdout : stderr,
9868 "usage: camcontrol <command> [device id][generic args][command args]\n"
9869 " camcontrol devlist [-b] [-v]\n"
9870 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9871 " camcontrol tur [dev_id][generic args]\n"
9872 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9873 " camcontrol identify [dev_id][generic args] [-v]\n"
9874 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9875 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9877 " camcontrol start [dev_id][generic args]\n"
9878 " camcontrol stop [dev_id][generic args]\n"
9879 " camcontrol load [dev_id][generic args]\n"
9880 " camcontrol eject [dev_id][generic args]\n"
9881 " camcontrol reprobe [dev_id][generic args]\n"
9882 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9883 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9884 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9885 " [-q][-s][-S offset][-X]\n"
9886 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9887 " [-P pagectl][-e | -b][-d]\n"
9888 " camcontrol cmd [dev_id][generic args]\n"
9889 " <-a cmd [args] | -c cmd [args]>\n"
9890 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9891 " camcontrol smpcmd [dev_id][generic args]\n"
9892 " <-r len fmt [args]> <-R len fmt [args]>\n"
9893 " camcontrol smprg [dev_id][generic args][-l]\n"
9894 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9895 " [-o operation][-d name][-m rate][-M rate]\n"
9896 " [-T pp_timeout][-a enable|disable]\n"
9897 " [-A enable|disable][-s enable|disable]\n"
9898 " [-S enable|disable]\n"
9899 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9900 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9901 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9902 " <all|dev_id|bus[:target[:lun]]|off>\n"
9903 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9904 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9905 " [-D <enable|disable>][-M mode][-O offset]\n"
9906 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9907 " [-U][-W bus_width]\n"
9908 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9909 " camcontrol sanitize [dev_id][generic args]\n"
9910 " [-a overwrite|block|crypto|exitfailure]\n"
9911 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9913 " camcontrol idle [dev_id][generic args][-t time]\n"
9914 " camcontrol standby [dev_id][generic args][-t time]\n"
9915 " camcontrol sleep [dev_id][generic args]\n"
9916 " camcontrol powermode [dev_id][generic args]\n"
9917 " camcontrol apm [dev_id][generic args][-l level]\n"
9918 " camcontrol aam [dev_id][generic args][-l level]\n"
9919 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9921 " camcontrol security [dev_id][generic args]\n"
9922 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9923 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9924 " [-U <user|master>] [-y]\n"
9925 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9926 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9927 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9928 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9929 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9930 " [-s scope][-S][-T type][-U]\n"
9931 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9932 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9933 " [-p part][-s start][-T type][-V vol]\n"
9934 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9936 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9937 " [-o rep_opts] [-P print_opts]\n"
9938 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9939 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9940 " [-S power_src] [-T timer]\n"
9941 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9942 " <-s <-f format -T time | -U >>\n"
9943 " camcontrol devtype [dev_id]\n"
9944 " camcontrol depop [dev_id] [-d | -l | -r] [-e element] [-c capacity]\n"
9945 " camcontrol mmcsdcmd [dev_id] [[-c mmc_opcode] [-a mmc_arg]\n"
9946 " [-f mmc_flags] [-l data_len]\n"
9947 " [-W [-b data_byte]]] |\n"
9948 " [-F frequency] |\n"
9951 " [-S high|normal]\n"
9953 " camcontrol help\n");
9957 "Specify one of the following options:\n"
9958 "devlist list all CAM devices\n"
9959 "periphlist list all CAM peripheral drivers attached to a device\n"
9960 "tur send a test unit ready to the named device\n"
9961 "inquiry send a SCSI inquiry command to the named device\n"
9962 "identify send a ATA identify command to the named device\n"
9963 "reportluns send a SCSI report luns command to the device\n"
9964 "readcap send a SCSI read capacity command to the device\n"
9965 "start send a Start Unit command to the device\n"
9966 "stop send a Stop Unit command to the device\n"
9967 "load send a Start Unit command to the device with the load bit set\n"
9968 "eject send a Stop Unit command to the device with the eject bit set\n"
9969 "reprobe update capacity information of the given device\n"
9970 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9971 "reset reset all buses, the given bus, bus:target:lun or device\n"
9972 "defects read the defect list of the specified device\n"
9973 "modepage display or edit (-e) the given mode page\n"
9974 "cmd send the given SCSI command, may need -i or -o as well\n"
9975 "smpcmd send the given SMP command, requires -o and -i\n"
9976 "smprg send the SMP Report General command\n"
9977 "smppc send the SMP PHY Control command, requires -p\n"
9978 "smpphylist display phys attached to a SAS expander\n"
9979 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9980 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9981 "tags report or set the number of transaction slots for a device\n"
9982 "negotiate report or set device negotiation parameters\n"
9983 "format send the SCSI FORMAT UNIT command to the named device\n"
9984 "sanitize send the SCSI SANITIZE command to the named device\n"
9985 "idle send the ATA IDLE command to the named device\n"
9986 "standby send the ATA STANDBY command to the named device\n"
9987 "sleep send the ATA SLEEP command to the named device\n"
9988 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9989 "fwdownload program firmware of the named device with the given image\n"
9990 "security report or send ATA security commands to the named device\n"
9991 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9992 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9993 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9994 "zone manage Zoned Block (Shingled) devices\n"
9995 "epc send ATA Extended Power Conditions commands\n"
9996 "timestamp report or set the device's timestamp\n"
9997 "devtype report the type of device\n"
9998 "depop manage drive storage elements\n"
9999 "mmcsdcmd send the given MMC command, needs -c and -a as well\n"
10000 "help this message\n"
10001 "Device Identifiers:\n"
10002 "bus:target specify the bus and target, lun defaults to 0\n"
10003 "bus:target:lun specify the bus, target and lun\n"
10004 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
10005 "Generic arguments:\n"
10006 "-v be verbose, print out sense information\n"
10007 "-t timeout command timeout in seconds, overrides default timeout\n"
10008 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
10009 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
10010 "-E have the kernel attempt to perform SCSI error recovery\n"
10011 "-C count specify the SCSI command retry count (needs -E to work)\n"
10012 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
10013 "modepage arguments:\n"
10014 "-l list all available mode pages\n"
10015 "-m page specify the mode page to view or edit\n"
10016 "-e edit the specified mode page\n"
10017 "-b force view to binary mode\n"
10018 "-d disable block descriptors for mode sense\n"
10019 "-P pgctl page control field 0-3\n"
10020 "defects arguments:\n"
10021 "-f format specify defect list format (block, bfi or phys)\n"
10022 "-G get the grown defect list\n"
10023 "-P get the permanent defect list\n"
10024 "inquiry arguments:\n"
10025 "-D get the standard inquiry data\n"
10026 "-S get the serial number\n"
10027 "-R get the transfer rate, etc.\n"
10028 "reportluns arguments:\n"
10029 "-c only report a count of available LUNs\n"
10030 "-l only print out luns, and not a count\n"
10031 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10032 "readcap arguments\n"
10033 "-b only report the blocksize\n"
10034 "-h human readable device size, base 2\n"
10035 "-H human readable device size, base 10\n"
10036 "-N print the number of blocks instead of last block\n"
10037 "-q quiet, print numbers only\n"
10038 "-s only report the last block/device size\n"
10040 "-c cdb [args] specify the SCSI CDB\n"
10041 "-i len fmt specify input data and input data format\n"
10042 "-o len fmt [args] specify output data and output data fmt\n"
10043 "smpcmd arguments:\n"
10044 "-r len fmt [args] specify the SMP command to be sent\n"
10045 "-R len fmt [args] specify SMP response format\n"
10046 "smprg arguments:\n"
10047 "-l specify the long response format\n"
10048 "smppc arguments:\n"
10049 "-p phy specify the PHY to operate on\n"
10050 "-l specify the long request/response format\n"
10051 "-o operation specify the phy control operation\n"
10052 "-d name set the attached device name\n"
10053 "-m rate set the minimum physical link rate\n"
10054 "-M rate set the maximum physical link rate\n"
10055 "-T pp_timeout set the partial pathway timeout value\n"
10056 "-a enable|disable enable or disable SATA slumber\n"
10057 "-A enable|disable enable or disable SATA partial phy power\n"
10058 "-s enable|disable enable or disable SAS slumber\n"
10059 "-S enable|disable enable or disable SAS partial phy power\n"
10060 "smpphylist arguments:\n"
10061 "-l specify the long response format\n"
10062 "-q only print phys with attached devices\n"
10063 "smpmaninfo arguments:\n"
10064 "-l specify the long response format\n"
10065 "debug arguments:\n"
10066 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10067 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10068 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10069 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10070 "tags arguments:\n"
10071 "-N tags specify the number of tags to use for this device\n"
10072 "-q be quiet, don't report the number of tags\n"
10073 "-v report a number of tag-related parameters\n"
10074 "negotiate arguments:\n"
10075 "-a send a test unit ready after negotiation\n"
10076 "-c report/set current negotiation settings\n"
10077 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10078 "-M mode set ATA mode\n"
10079 "-O offset set command delay offset\n"
10080 "-q be quiet, don't report anything\n"
10081 "-R syncrate synchronization rate in MHz\n"
10082 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10083 "-U report/set user negotiation settings\n"
10084 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10085 "-v also print a Path Inquiry CCB for the controller\n"
10086 "format arguments:\n"
10087 "-q be quiet, don't print status messages\n"
10088 "-r run in report only mode\n"
10089 "-w don't send immediate format command\n"
10090 "-y don't ask any questions\n"
10091 "sanitize arguments:\n"
10092 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10093 "-c passes overwrite passes to perform (1 to 31)\n"
10094 "-I invert overwrite pattern after each pass\n"
10095 "-P pattern path to overwrite pattern file\n"
10096 "-q be quiet, don't print status messages\n"
10097 "-r run in report only mode\n"
10098 "-U run operation in unrestricted completion exit mode\n"
10099 "-w don't send immediate sanitize command\n"
10100 "-y don't ask any questions\n"
10101 "idle/standby arguments:\n"
10102 "-t <arg> number of seconds before respective state.\n"
10103 "fwdownload arguments:\n"
10104 "-f fw_image path to firmware image file\n"
10105 "-q don't print informational messages, only errors\n"
10106 "-s run in simulation mode\n"
10107 "-v print info for every firmware segment sent to device\n"
10108 "-y don't ask any questions\n"
10109 "security arguments:\n"
10110 "-d pwd disable security using the given password for the selected\n"
10112 "-e pwd erase the device using the given pwd for the selected user\n"
10113 "-f freeze the security configuration of the specified device\n"
10114 "-h pwd enhanced erase the device using the given pwd for the\n"
10116 "-k pwd unlock the device using the given pwd for the selected\n"
10118 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10119 "-q be quiet, do not print any status messages\n"
10120 "-s pwd password the device (enable security) using the given\n"
10121 " pwd for the selected user\n"
10122 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10123 "-U <user|master> specifies which user to set: user or master\n"
10124 "-y don't ask any questions\n"
10126 "-f freeze the HPA configuration of the device\n"
10127 "-l lock the HPA configuration of the device\n"
10128 "-P make the HPA max sectors persist\n"
10129 "-p pwd Set the HPA configuration password required for unlock\n"
10131 "-q be quiet, do not print any status messages\n"
10132 "-s sectors configures the maximum user accessible sectors of the\n"
10134 "-U pwd unlock the HPA configuration of the device\n"
10135 "-y don't ask any questions\n"
10137 "-f freeze the AMA configuration of the device\n"
10138 "-q be quiet, do not print any status messages\n"
10139 "-s sectors configures the maximum user accessible sectors of the\n"
10141 "persist arguments:\n"
10142 "-i action specify read_keys, read_reservation, report_cap, or\n"
10143 " read_full_status\n"
10144 "-o action specify register, register_ignore, reserve, release,\n"
10145 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10146 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10147 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10148 "-k key specify the Reservation Key\n"
10149 "-K sa_key specify the Service Action Reservation Key\n"
10150 "-p set the Activate Persist Through Power Loss bit\n"
10151 "-R rtp specify the Relative Target Port\n"
10152 "-s scope specify the scope: lun, extent, element or a number\n"
10153 "-S specify Transport ID for register, requires -I\n"
10154 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10155 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10156 "-U unregister the current initiator for register_move\n"
10157 "attrib arguments:\n"
10158 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10160 "-w attr specify an attribute to write, one -w argument per attr\n"
10161 "-a attr_num only display this attribute number\n"
10162 "-c get cached attributes\n"
10163 "-e elem_addr request attributes for the given element in a changer\n"
10164 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10165 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10166 " field_none, field_desc, field_num, field_size, field_rw\n"
10167 "-p partition request attributes for the given partition\n"
10168 "-s start_attr request attributes starting at the given number\n"
10169 "-T elem_type specify the element type (used with -e)\n"
10170 "-V logical_vol specify the logical volume ID\n"
10171 "opcodes arguments:\n"
10172 "-o opcode specify the individual opcode to list\n"
10173 "-s service_action specify the service action for the opcode\n"
10174 "-N do not return SCSI error for unsupported SA\n"
10175 "-T request nominal and recommended timeout values\n"
10176 "zone arguments:\n"
10177 "-c cmd required: rz, open, close, finish, or rwp\n"
10178 "-a apply the action to all zones\n"
10179 "-l LBA specify the zone starting LBA\n"
10180 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10181 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10182 "-P print_opt report zones printing: normal, summary, script\n"
10184 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10185 " source, status, list\n"
10186 "-d disable power mode (timer, state)\n"
10187 "-D delayed entry (goto)\n"
10188 "-e enable power mode (timer, state)\n"
10189 "-H hold power mode (goto)\n"
10190 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10192 "-P only display power mode (status)\n"
10193 "-r rst_src restore settings from: default, saved (restore)\n"
10194 "-s save mode (timer, state, restore)\n"
10195 "-S power_src set power source: battery, nonbattery (source)\n"
10196 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10197 "timestamp arguments:\n"
10198 "-r report the timestamp of the device\n"
10199 "-f format report the timestamp of the device with the given\n"
10200 " strftime(3) format string\n"
10201 "-m report the timestamp of the device as milliseconds since\n"
10202 " January 1st, 1970\n"
10203 "-U report the time with UTC instead of the local time zone\n"
10204 "-s set the timestamp of the device\n"
10205 "-f format the format of the time string passed into strptime(3)\n"
10206 "-T time the time value passed into strptime(3)\n"
10207 "-U set the timestamp of the device to UTC time\n"
10208 "depop arguments:\n"
10209 "-d remove an element from service\n"
10210 "-l list status of all elements of drive\n"
10211 "-r restore all elements to service\n"
10212 "-e elm element to remove\n"
10213 "-c capacity requested new capacity\n"
10214 "mmcsdcmd arguments:\n"
10215 "-c mmc_cmd MMC command to send to the card\n"
10216 "-a mmc_arg Argument for the MMC command\n"
10217 "-f mmc_flag Flags to set for the MMC command\n"
10218 "-l data_len Expect data_len bytes of data in reply and display them\n"
10219 "-W Fill the data buffer before invoking the MMC command\n"
10220 "-b data_byte One byte of data to fill the data buffer with\n"
10221 "-F frequency Operating frequency to set on the controller\n"
10222 "-4 Set bus width to 4 bit\n"
10223 "-1 Set bus width to 8 bit\n"
10224 "-S high | std Set high-speed or standard timing\n"
10225 "-I Display various card and host controller information\n"
10230 main(int argc, char **argv)
10233 char *device = NULL;
10235 struct cam_device *cam_dev = NULL;
10236 int timeout = 0, retry_count = 1;
10237 camcontrol_optret optreturn;
10239 const char *mainopt = "C:En:Q:t:u:v";
10240 const char *subopt = NULL;
10241 char combinedopt[256];
10242 int error = 0, optstart = 2;
10243 int task_attr = MSG_SIMPLE_Q_TAG;
10247 target_id_t target;
10250 cmdlist = CAM_CMD_NONE;
10251 arglist = CAM_ARG_NONE;
10259 * Get the base option.
10261 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10263 if (optreturn == CC_OR_AMBIGUOUS) {
10264 warnx("ambiguous option %s", argv[1]);
10267 } else if (optreturn == CC_OR_NOT_FOUND) {
10268 warnx("option %s not found", argv[1]);
10274 * Ahh, getopt(3) is a pain.
10276 * This is a gross hack. There really aren't many other good
10277 * options (excuse the pun) for parsing options in a situation like
10278 * this. getopt is kinda braindead, so you end up having to run
10279 * through the options twice, and give each invocation of getopt
10280 * the option string for the other invocation.
10282 * You would think that you could just have two groups of options.
10283 * The first group would get parsed by the first invocation of
10284 * getopt, and the second group would get parsed by the second
10285 * invocation of getopt. It doesn't quite work out that way. When
10286 * the first invocation of getopt finishes, it leaves optind pointing
10287 * to the argument _after_ the first argument in the second group.
10288 * So when the second invocation of getopt comes around, it doesn't
10289 * recognize the first argument it gets and then bails out.
10291 * A nice alternative would be to have a flag for getopt that says
10292 * "just keep parsing arguments even when you encounter an unknown
10293 * argument", but there isn't one. So there's no real clean way to
10294 * easily parse two sets of arguments without having one invocation
10295 * of getopt know about the other.
10297 * Without this hack, the first invocation of getopt would work as
10298 * long as the generic arguments are first, but the second invocation
10299 * (in the subfunction) would fail in one of two ways. In the case
10300 * where you don't set optreset, it would fail because optind may be
10301 * pointing to the argument after the one it should be pointing at.
10302 * In the case where you do set optreset, and reset optind, it would
10303 * fail because getopt would run into the first set of options, which
10304 * it doesn't understand.
10306 * All of this would "sort of" work if you could somehow figure out
10307 * whether optind had been incremented one option too far. The
10308 * mechanics of that, however, are more daunting than just giving
10309 * both invocations all of the expect options for either invocation.
10311 * Needless to say, I wouldn't mind if someone invented a better
10312 * (non-GPL!) command line parsing interface than getopt. I
10313 * wouldn't mind if someone added more knobs to getopt to make it
10314 * work better. Who knows, I may talk myself into doing it someday,
10315 * if the standards weenies let me. As it is, it just leads to
10316 * hackery like this and causes people to avoid it in some cases.
10318 * KDM, September 8th, 1998
10320 if (subopt != NULL)
10321 sprintf(combinedopt, "%s%s", mainopt, subopt);
10323 sprintf(combinedopt, "%s", mainopt);
10326 * For these options we do not parse optional device arguments and
10327 * we do not open a passthrough device.
10329 if ((cmdlist == CAM_CMD_RESCAN)
10330 || (cmdlist == CAM_CMD_RESET)
10331 || (cmdlist == CAM_CMD_DEVTREE)
10332 || (cmdlist == CAM_CMD_USAGE)
10333 || (cmdlist == CAM_CMD_DEBUG))
10337 && (argc > 2 && argv[2][0] != '-')) {
10341 if (isdigit(argv[2][0])) {
10342 /* device specified as bus:target[:lun] */
10343 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10345 errx(1, "numeric device specification must "
10346 "be either bus:target, or "
10348 /* default to 0 if lun was not specified */
10349 if ((arglist & CAM_ARG_LUN) == 0) {
10351 arglist |= CAM_ARG_LUN;
10355 if (cam_get_device(argv[2], name, sizeof name, &unit)
10357 errx(1, "%s", cam_errbuf);
10358 device = strdup(name);
10359 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10364 * Start getopt processing at argv[2/3], since we've already
10365 * accepted argv[1..2] as the command name, and as a possible
10371 * Now we run through the argument list looking for generic
10372 * options, and ignoring options that possibly belong to
10375 while ((c = getopt(argc, argv, combinedopt))!= -1){
10378 retry_count = strtol(optarg, NULL, 0);
10379 if (retry_count < 0)
10380 errx(1, "retry count %d is < 0",
10382 arglist |= CAM_ARG_RETRIES;
10385 arglist |= CAM_ARG_ERR_RECOVER;
10388 arglist |= CAM_ARG_DEVICE;
10390 while (isspace(*tstr) && (*tstr != '\0'))
10392 device = (char *)strdup(tstr);
10396 int table_entry = 0;
10399 while (isspace(*tstr) && (*tstr != '\0'))
10401 if (isdigit(*tstr)) {
10402 task_attr = strtol(tstr, &endptr, 0);
10403 if (*endptr != '\0') {
10404 errx(1, "Invalid queue option "
10409 scsi_nv_status status;
10411 table_size = sizeof(task_attrs) /
10412 sizeof(task_attrs[0]);
10413 status = scsi_get_nv(task_attrs,
10414 table_size, tstr, &table_entry,
10415 SCSI_NV_FLAG_IG_CASE);
10416 if (status == SCSI_NV_FOUND)
10417 task_attr = task_attrs[
10418 table_entry].value;
10420 errx(1, "%s option %s",
10421 (status == SCSI_NV_AMBIGUOUS)?
10422 "ambiguous" : "invalid",
10429 timeout = strtol(optarg, NULL, 0);
10431 errx(1, "invalid timeout %d", timeout);
10432 /* Convert the timeout from seconds to ms */
10434 arglist |= CAM_ARG_TIMEOUT;
10437 arglist |= CAM_ARG_UNIT;
10438 unit = strtol(optarg, NULL, 0);
10441 arglist |= CAM_ARG_VERBOSE;
10449 * For most commands we'll want to open the passthrough device
10450 * associated with the specified device. In the case of the rescan
10451 * commands, we don't use a passthrough device at all, just the
10452 * transport layer device.
10454 if (devopen == 1) {
10455 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10456 && (((arglist & CAM_ARG_DEVICE) == 0)
10457 || ((arglist & CAM_ARG_UNIT) == 0))) {
10458 errx(1, "subcommand \"%s\" requires a valid device "
10459 "identifier", argv[1]);
10462 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10463 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10464 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10466 errx(1,"%s", cam_errbuf);
10470 * Reset optind to 2, and reset getopt, so these routines can parse
10471 * the arguments again.
10477 case CAM_CMD_DEVLIST:
10478 error = getdevlist(cam_dev);
10481 error = atahpa(cam_dev, retry_count, timeout,
10482 argc, argv, combinedopt);
10485 error = ataama(cam_dev, retry_count, timeout,
10486 argc, argv, combinedopt);
10488 case CAM_CMD_DEVTREE:
10489 error = getdevtree(argc, argv, combinedopt);
10491 case CAM_CMD_DEVTYPE:
10492 error = getdevtype(cam_dev);
10495 error = testunitready(cam_dev, task_attr, retry_count,
10498 case CAM_CMD_INQUIRY:
10499 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10500 task_attr, retry_count, timeout);
10502 case CAM_CMD_IDENTIFY:
10503 error = identify(cam_dev, retry_count, timeout);
10505 case CAM_CMD_STARTSTOP:
10506 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10507 arglist & CAM_ARG_EJECT, task_attr,
10508 retry_count, timeout);
10510 case CAM_CMD_RESCAN:
10511 error = dorescan_or_reset(argc, argv, 1);
10513 case CAM_CMD_RESET:
10514 error = dorescan_or_reset(argc, argv, 0);
10516 case CAM_CMD_READ_DEFECTS:
10517 error = readdefects(cam_dev, argc, argv, combinedopt,
10518 task_attr, retry_count, timeout);
10520 case CAM_CMD_MODE_PAGE:
10521 modepage(cam_dev, argc, argv, combinedopt,
10522 task_attr, retry_count, timeout);
10524 case CAM_CMD_SCSI_CMD:
10525 error = scsicmd(cam_dev, argc, argv, combinedopt,
10526 task_attr, retry_count, timeout);
10528 case CAM_CMD_MMCSD_CMD:
10529 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10530 retry_count, timeout);
10532 case CAM_CMD_SMP_CMD:
10533 error = smpcmd(cam_dev, argc, argv, combinedopt,
10534 retry_count, timeout);
10536 case CAM_CMD_SMP_RG:
10537 error = smpreportgeneral(cam_dev, argc, argv,
10538 combinedopt, retry_count,
10541 case CAM_CMD_SMP_PC:
10542 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10543 retry_count, timeout);
10545 case CAM_CMD_SMP_PHYLIST:
10546 error = smpphylist(cam_dev, argc, argv, combinedopt,
10547 retry_count, timeout);
10549 case CAM_CMD_SMP_MANINFO:
10550 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10551 retry_count, timeout);
10553 case CAM_CMD_DEBUG:
10554 error = camdebug(argc, argv, combinedopt);
10557 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10560 error = ratecontrol(cam_dev, task_attr, retry_count,
10561 timeout, argc, argv, combinedopt);
10563 case CAM_CMD_FORMAT:
10564 error = scsiformat(cam_dev, argc, argv,
10565 combinedopt, task_attr, retry_count,
10568 case CAM_CMD_REPORTLUNS:
10569 error = scsireportluns(cam_dev, argc, argv,
10570 combinedopt, task_attr,
10571 retry_count, timeout);
10573 case CAM_CMD_READCAP:
10574 error = scsireadcapacity(cam_dev, argc, argv,
10575 combinedopt, task_attr,
10576 retry_count, timeout);
10579 case CAM_CMD_STANDBY:
10580 case CAM_CMD_SLEEP:
10581 case CAM_CMD_POWER_MODE:
10582 error = atapm(cam_dev, argc, argv,
10583 combinedopt, retry_count, timeout);
10587 error = ataaxm(cam_dev, argc, argv,
10588 combinedopt, retry_count, timeout);
10590 case CAM_CMD_SECURITY:
10591 error = atasecurity(cam_dev, retry_count, timeout,
10592 argc, argv, combinedopt);
10594 case CAM_CMD_DOWNLOAD_FW:
10595 error = fwdownload(cam_dev, argc, argv, combinedopt,
10596 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10599 case CAM_CMD_SANITIZE:
10600 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10601 retry_count, timeout);
10603 case CAM_CMD_PERSIST:
10604 error = scsipersist(cam_dev, argc, argv, combinedopt,
10605 task_attr, retry_count, timeout,
10606 arglist & CAM_ARG_VERBOSE,
10607 arglist & CAM_ARG_ERR_RECOVER);
10609 case CAM_CMD_ATTRIB:
10610 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10611 task_attr, retry_count, timeout,
10612 arglist & CAM_ARG_VERBOSE,
10613 arglist & CAM_ARG_ERR_RECOVER);
10615 case CAM_CMD_OPCODES:
10616 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10617 task_attr, retry_count, timeout,
10618 arglist & CAM_ARG_VERBOSE);
10620 case CAM_CMD_REPROBE:
10621 error = reprobe(cam_dev);
10624 error = zone(cam_dev, argc, argv, combinedopt,
10625 task_attr, retry_count, timeout,
10626 arglist & CAM_ARG_VERBOSE);
10629 error = epc(cam_dev, argc, argv, combinedopt,
10630 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10632 case CAM_CMD_TIMESTAMP:
10633 error = timestamp(cam_dev, argc, argv, combinedopt,
10634 task_attr, retry_count, timeout,
10635 arglist & CAM_ARG_VERBOSE);
10637 case CAM_CMD_DEPOP:
10638 error = depop(cam_dev, argc, argv, combinedopt,
10639 task_attr, retry_count, timeout,
10640 arglist & CAM_ARG_VERBOSE);
10642 case CAM_CMD_USAGE:
10651 if (cam_dev != NULL)
10652 cam_close_device(cam_dev);