2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
53 #include <cam/cam_debug.h>
54 #include <cam/cam_ccb.h>
55 #include <cam/scsi/scsi_all.h>
56 #include <cam/scsi/scsi_da.h>
57 #include <cam/scsi/scsi_pass.h>
58 #include <cam/scsi/scsi_message.h>
59 #include <cam/scsi/smp_all.h>
60 #include <cam/ata/ata_all.h>
61 #include <cam/mmc/mmc_all.h>
63 #include "camcontrol.h"
65 #include "nvmecontrol_ext.h"
118 CAM_ARG_NONE = 0x00000000,
119 CAM_ARG_VERBOSE = 0x00000001,
120 CAM_ARG_DEVICE = 0x00000002,
121 CAM_ARG_BUS = 0x00000004,
122 CAM_ARG_TARGET = 0x00000008,
123 CAM_ARG_LUN = 0x00000010,
124 CAM_ARG_EJECT = 0x00000020,
125 CAM_ARG_UNIT = 0x00000040,
126 CAM_ARG_FORMAT_BLOCK = 0x00000080,
127 CAM_ARG_FORMAT_BFI = 0x00000100,
128 CAM_ARG_FORMAT_PHYS = 0x00000200,
129 CAM_ARG_PLIST = 0x00000400,
130 CAM_ARG_GLIST = 0x00000800,
131 CAM_ARG_GET_SERIAL = 0x00001000,
132 CAM_ARG_GET_STDINQ = 0x00002000,
133 CAM_ARG_GET_XFERRATE = 0x00004000,
134 CAM_ARG_INQ_MASK = 0x00007000,
135 CAM_ARG_TIMEOUT = 0x00020000,
136 CAM_ARG_CMD_IN = 0x00040000,
137 CAM_ARG_CMD_OUT = 0x00080000,
138 CAM_ARG_ERR_RECOVER = 0x00200000,
139 CAM_ARG_RETRIES = 0x00400000,
140 CAM_ARG_START_UNIT = 0x00800000,
141 CAM_ARG_DEBUG_INFO = 0x01000000,
142 CAM_ARG_DEBUG_TRACE = 0x02000000,
143 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
144 CAM_ARG_DEBUG_CDB = 0x08000000,
145 CAM_ARG_DEBUG_XPT = 0x10000000,
146 CAM_ARG_DEBUG_PERIPH = 0x20000000,
147 CAM_ARG_DEBUG_PROBE = 0x40000000,
150 struct camcontrol_opts {
157 struct ata_set_max_pwd
160 u_int8_t password[32];
161 u_int16_t reserved2[239];
164 static struct scsi_nv task_attrs[] = {
165 { "simple", MSG_SIMPLE_Q_TAG },
166 { "head", MSG_HEAD_OF_Q_TAG },
167 { "ordered", MSG_ORDERED_Q_TAG },
168 { "iwr", MSG_IGN_WIDE_RESIDUE },
169 { "aca", MSG_ACA_TASK }
172 static const char scsicmd_opts[] = "a:c:dfi:o:r";
173 static const char readdefect_opts[] = "f:GPqsS:X";
174 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
175 static const char smprg_opts[] = "l";
176 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
177 static const char smpphylist_opts[] = "lq";
180 static struct camcontrol_opts option_table[] = {
181 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
182 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
183 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
184 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
185 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
186 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
187 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
188 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
189 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
190 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
191 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
192 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
193 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
194 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:F:f:Wb:l:41S:I"},
195 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
196 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
197 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
198 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
199 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
200 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
201 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
202 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
203 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
204 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
205 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
206 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
207 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
208 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
209 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm:DLP:"},
210 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
211 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
212 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
213 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
214 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
215 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
216 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
217 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
218 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
219 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
220 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
221 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
222 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
223 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
224 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
225 {"ama", CAM_CMD_AMA, CAM_ARG_NONE, "fqs:"},
226 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
227 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
228 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
229 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
230 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
231 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
232 {"depop", CAM_CMD_DEPOP, CAM_ARG_NONE, "ac:de:ls"},
233 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
234 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
235 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
240 struct device_match_result dev_match;
242 struct periph_match_result *periph_matches;
243 struct scsi_vpd_device_id *device_id;
245 STAILQ_ENTRY(cam_devitem) links;
249 STAILQ_HEAD(, cam_devitem) dev_queue;
253 static cam_argmask arglist;
255 static const char *devtype_names[] = {
265 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
266 uint32_t *cmdnum, cam_argmask *argnum,
267 const char **subopt);
268 static int getdevlist(struct cam_device *device);
269 static int getdevtree(int argc, char **argv, char *combinedopt);
270 static int getdevtype(struct cam_device *device);
271 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
272 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
273 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
274 static int print_dev_mmcsd(struct device_match_result *dev_result,
277 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
279 static int testunitready(struct cam_device *device, int task_attr,
280 int retry_count, int timeout, int quiet);
281 static int scsistart(struct cam_device *device, int startstop, int loadeject,
282 int task_attr, int retry_count, int timeout);
283 static int scsiinquiry(struct cam_device *device, int task_attr,
284 int retry_count, int timeout);
285 static int scsiserial(struct cam_device *device, int task_attr,
286 int retry_count, int timeout);
287 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
288 lun_id_t *lun, cam_argmask *arglst);
289 static int reprobe(struct cam_device *device);
290 static int dorescan_or_reset(int argc, char **argv, int rescan);
291 static int rescan_or_reset_bus(path_id_t bus, int rescan);
292 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
293 lun_id_t lun, int scan);
294 static int readdefects(struct cam_device *device, int argc, char **argv,
295 char *combinedopt, int task_attr, int retry_count,
297 static void modepage(struct cam_device *device, int argc, char **argv,
298 char *combinedopt, int task_attr, int retry_count,
300 static int scsicmd(struct cam_device *device, int argc, char **argv,
301 char *combinedopt, int task_attr, int retry_count,
303 static int smpcmd(struct cam_device *device, int argc, char **argv,
304 char *combinedopt, int retry_count, int timeout);
305 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
306 char *combinedopt, int retry_count, int timeout);
307 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
308 char *combinedopt, int retry_count, int timeout);
309 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
310 char *combinedopt, int retry_count, int timeout);
311 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
312 char *combinedopt, int retry_count, int timeout);
313 static int getdevid(struct cam_devitem *item);
314 static int buildbusdevlist(struct cam_devlist *devlist);
315 static void freebusdevlist(struct cam_devlist *devlist);
316 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
318 static int smpphylist(struct cam_device *device, int argc, char **argv,
319 char *combinedopt, int retry_count, int timeout);
320 static int tagcontrol(struct cam_device *device, int argc, char **argv,
322 static void cts_print(struct cam_device *device,
323 struct ccb_trans_settings *cts);
324 static void cpi_print(struct ccb_pathinq *cpi);
325 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
326 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
327 static int get_print_cts(struct cam_device *device, int user_settings,
328 int quiet, struct ccb_trans_settings *cts);
329 static int ratecontrol(struct cam_device *device, int task_attr,
330 int retry_count, int timeout, int argc, char **argv,
332 static int scsiformat(struct cam_device *device, int argc, char **argv,
333 char *combinedopt, int task_attr, int retry_count,
335 static int sanitize(struct cam_device *device, int argc, char **argv,
336 char *combinedopt, int task_attr, int retry_count,
338 static int scsireportluns(struct cam_device *device, int argc, char **argv,
339 char *combinedopt, int task_attr, int retry_count,
341 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
342 char *combinedopt, int task_attr, int retry_count,
344 static int atapm(struct cam_device *device, int argc, char **argv,
345 char *combinedopt, int retry_count, int timeout);
346 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
347 int argc, char **argv, char *combinedopt);
348 static int atahpa(struct cam_device *device, int retry_count, int timeout,
349 int argc, char **argv, char *combinedopt);
350 static int ataama(struct cam_device *device, int retry_count, int timeout,
351 int argc, char **argv, char *combinedopt);
352 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
353 int sa_set, int req_sa, uint8_t *buf,
355 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
357 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
358 char *combinedopt, int task_attr, int retry_count,
359 int timeout, int verbose);
362 #define min(a,b) (((a)<(b))?(a):(b))
365 #define max(a,b) (((a)>(b))?(a):(b))
369 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
370 cam_argmask *argnum, const char **subopt)
372 struct camcontrol_opts *opts;
375 for (opts = table; (opts != NULL) && (opts->optname != NULL);
377 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
378 *cmdnum = opts->cmdnum;
379 *argnum = opts->argnum;
380 *subopt = opts->subopt;
381 if (++num_matches > 1)
382 return (CC_OR_AMBIGUOUS);
387 return (CC_OR_FOUND);
389 return (CC_OR_NOT_FOUND);
393 getdevlist(struct cam_device *device)
399 ccb = cam_getccb(device);
401 ccb->ccb_h.func_code = XPT_GDEVLIST;
402 ccb->ccb_h.flags = CAM_DIR_NONE;
403 ccb->ccb_h.retry_count = 1;
405 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
406 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
407 if (cam_send_ccb(device, ccb) < 0) {
408 warn("error getting device list");
415 switch (ccb->cgdl.status) {
416 case CAM_GDEVLIST_MORE_DEVS:
417 strcpy(status, "MORE");
419 case CAM_GDEVLIST_LAST_DEVICE:
420 strcpy(status, "LAST");
422 case CAM_GDEVLIST_LIST_CHANGED:
423 strcpy(status, "CHANGED");
425 case CAM_GDEVLIST_ERROR:
426 strcpy(status, "ERROR");
431 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
432 ccb->cgdl.periph_name,
433 ccb->cgdl.unit_number,
434 ccb->cgdl.generation,
439 * If the list has changed, we need to start over from the
442 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
452 getdevtree(int argc, char **argv, char *combinedopt)
463 while ((c = getopt(argc, argv, combinedopt)) != -1) {
466 if ((arglist & CAM_ARG_VERBOSE) == 0)
474 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
475 warn("couldn't open %s", XPT_DEVICE);
479 bzero(&ccb, sizeof(union ccb));
481 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
482 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
483 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
485 ccb.ccb_h.func_code = XPT_DEV_MATCH;
486 bufsize = sizeof(struct dev_match_result) * 100;
487 ccb.cdm.match_buf_len = bufsize;
488 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
489 if (ccb.cdm.matches == NULL) {
490 warnx("can't malloc memory for matches");
494 ccb.cdm.num_matches = 0;
497 * We fetch all nodes, since we display most of them in the default
498 * case, and all in the verbose case.
500 ccb.cdm.num_patterns = 0;
501 ccb.cdm.pattern_buf_len = 0;
504 * We do the ioctl multiple times if necessary, in case there are
505 * more than 100 nodes in the EDT.
508 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
509 warn("error sending CAMIOCOMMAND ioctl");
514 if ((ccb.ccb_h.status != CAM_REQ_CMP)
515 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
516 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
517 warnx("got CAM error %#x, CDM error %d\n",
518 ccb.ccb_h.status, ccb.cdm.status);
523 for (i = 0; i < ccb.cdm.num_matches; i++) {
524 switch (ccb.cdm.matches[i].type) {
525 case DEV_MATCH_BUS: {
526 struct bus_match_result *bus_result;
529 * Only print the bus information if the
530 * user turns on the verbose flag.
532 if ((busonly == 0) &&
533 (arglist & CAM_ARG_VERBOSE) == 0)
537 &ccb.cdm.matches[i].result.bus_result;
540 fprintf(stdout, ")\n");
544 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
546 bus_result->dev_name,
547 bus_result->unit_number,
549 (busonly ? "" : ":"));
552 case DEV_MATCH_DEVICE: {
553 struct device_match_result *dev_result;
560 &ccb.cdm.matches[i].result.device_result;
562 if ((dev_result->flags
563 & DEV_RESULT_UNCONFIGURED)
564 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
570 if (dev_result->protocol == PROTO_SCSI) {
571 if (print_dev_scsi(dev_result,
576 } else if (dev_result->protocol == PROTO_ATA ||
577 dev_result->protocol == PROTO_SATAPM) {
578 if (print_dev_ata(dev_result,
583 } else if (dev_result->protocol == PROTO_MMCSD){
584 if (print_dev_mmcsd(dev_result,
589 } else if (dev_result->protocol == PROTO_SEMB) {
590 if (print_dev_semb(dev_result,
596 } else if (dev_result->protocol == PROTO_NVME) {
597 if (print_dev_nvme(dev_result,
604 sprintf(tmpstr, "<>");
607 fprintf(stdout, ")\n");
611 fprintf(stdout, "%-33s at scbus%d "
612 "target %d lun %jx (",
615 dev_result->target_id,
616 (uintmax_t)dev_result->target_lun);
622 case DEV_MATCH_PERIPH: {
623 struct periph_match_result *periph_result;
626 &ccb.cdm.matches[i].result.periph_result;
628 if (busonly || skip_device != 0)
632 fprintf(stdout, ",");
634 fprintf(stdout, "%s%d",
635 periph_result->periph_name,
636 periph_result->unit_number);
642 fprintf(stdout, "unknown match type\n");
647 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
648 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
651 fprintf(stdout, ")\n");
659 getdevtype(struct cam_device *cam_dev)
661 camcontrol_devtype dt;
665 * Get the device type and report it, request no I/O be done to do this.
667 error = get_device_type(cam_dev, -1, 0, 0, &dt);
668 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
669 fprintf(stdout, "illegal\n");
672 fprintf(stdout, "%s\n", devtype_names[dt]);
677 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
679 char vendor[16], product[48], revision[16];
681 cam_strvis(vendor, dev_result->inq_data.vendor,
682 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
683 cam_strvis(product, dev_result->inq_data.product,
684 sizeof(dev_result->inq_data.product), sizeof(product));
685 cam_strvis(revision, dev_result->inq_data.revision,
686 sizeof(dev_result->inq_data.revision), sizeof(revision));
687 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
693 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
695 char product[48], revision[16];
697 cam_strvis(product, dev_result->ident_data.model,
698 sizeof(dev_result->ident_data.model), sizeof(product));
699 cam_strvis(revision, dev_result->ident_data.revision,
700 sizeof(dev_result->ident_data.revision), sizeof(revision));
701 sprintf(tmpstr, "<%s %s>", product, revision);
707 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
709 struct sep_identify_data *sid;
710 char vendor[16], product[48], revision[16], fw[5];
712 sid = (struct sep_identify_data *)&dev_result->ident_data;
713 cam_strvis(vendor, sid->vendor_id,
714 sizeof(sid->vendor_id), sizeof(vendor));
715 cam_strvis(product, sid->product_id,
716 sizeof(sid->product_id), sizeof(product));
717 cam_strvis(revision, sid->product_rev,
718 sizeof(sid->product_rev), sizeof(revision));
719 cam_strvis(fw, sid->firmware_rev,
720 sizeof(sid->firmware_rev), sizeof(fw));
721 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
727 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
730 struct ccb_dev_advinfo *advi;
731 struct cam_device *dev;
732 struct mmc_params mmc_ident_data;
734 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
735 dev_result->target_lun, O_RDWR, NULL);
737 warnx("%s", cam_errbuf);
741 ccb = cam_getccb(dev);
743 warnx("couldn't allocate CCB");
744 cam_close_device(dev);
749 advi->ccb_h.flags = CAM_DIR_IN;
750 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
751 advi->flags = CDAI_FLAG_NONE;
752 advi->buftype = CDAI_TYPE_MMC_PARAMS;
753 advi->bufsiz = sizeof(struct mmc_params);
754 advi->buf = (uint8_t *)&mmc_ident_data;
756 if (cam_send_ccb(dev, ccb) < 0) {
757 warn("error sending XPT_DEV_ADVINFO CCB");
759 cam_close_device(dev);
763 if (strlen(mmc_ident_data.model) > 0) {
764 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
766 sprintf(tmpstr, "<%s card>",
767 mmc_ident_data.card_features &
768 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
772 cam_close_device(dev);
778 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
781 struct ccb_dev_advinfo *advi;
783 ccb = cam_getccb(dev);
785 warnx("couldn't allocate CCB");
786 cam_close_device(dev);
791 advi->ccb_h.flags = CAM_DIR_IN;
792 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
793 advi->flags = CDAI_FLAG_NONE;
794 advi->buftype = CDAI_TYPE_NVME_CNTRL;
795 advi->bufsiz = sizeof(struct nvme_controller_data);
796 advi->buf = (uint8_t *)cdata;
798 if (cam_send_ccb(dev, ccb) < 0) {
799 warn("error sending XPT_DEV_ADVINFO CCB");
801 cam_close_device(dev);
804 if (advi->ccb_h.status != CAM_REQ_CMP) {
805 warnx("got CAM error %#x", advi->ccb_h.status);
807 cam_close_device(dev);
815 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
817 struct cam_device *dev;
818 struct nvme_controller_data cdata;
819 char vendor[64], product[64];
821 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
822 dev_result->target_lun, O_RDWR, NULL);
824 warnx("%s", cam_errbuf);
828 if (nvme_get_cdata(dev, &cdata))
831 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
832 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
833 sprintf(tmpstr, "<%s %s>", vendor, product);
835 cam_close_device(dev);
841 testunitready(struct cam_device *device, int task_attr, int retry_count,
842 int timeout, int quiet)
847 ccb = cam_getccb(device);
849 scsi_test_unit_ready(&ccb->csio,
850 /* retries */ retry_count,
852 /* tag_action */ task_attr,
853 /* sense_len */ SSD_FULL_SIZE,
854 /* timeout */ timeout ? timeout : 5000);
856 /* Disable freezing the device queue */
857 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
859 if (arglist & CAM_ARG_ERR_RECOVER)
860 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
862 if (cam_send_ccb(device, ccb) < 0) {
864 warn("error sending TEST UNIT READY command");
869 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
871 fprintf(stdout, "Unit is ready\n");
874 fprintf(stdout, "Unit is not ready\n");
877 if (arglist & CAM_ARG_VERBOSE) {
878 cam_error_print(device, ccb, CAM_ESF_ALL,
879 CAM_EPF_ALL, stderr);
889 scsistart(struct cam_device *device, int startstop, int loadeject,
890 int task_attr, int retry_count, int timeout)
895 ccb = cam_getccb(device);
898 * If we're stopping, send an ordered tag so the drive in question
899 * will finish any previously queued writes before stopping. If
900 * the device isn't capable of tagged queueing, or if tagged
901 * queueing is turned off, the tag action is a no-op. We override
902 * the default simple tag, although this also has the effect of
903 * overriding the user's wishes if he wanted to specify a simple
907 && (task_attr == MSG_SIMPLE_Q_TAG))
908 task_attr = MSG_ORDERED_Q_TAG;
910 scsi_start_stop(&ccb->csio,
911 /* retries */ retry_count,
913 /* tag_action */ task_attr,
914 /* start/stop */ startstop,
915 /* load_eject */ loadeject,
917 /* sense_len */ SSD_FULL_SIZE,
918 /* timeout */ timeout ? timeout : 120000);
920 /* Disable freezing the device queue */
921 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
923 if (arglist & CAM_ARG_ERR_RECOVER)
924 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
926 if (cam_send_ccb(device, ccb) < 0) {
927 warn("error sending START STOP UNIT command");
932 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
934 fprintf(stdout, "Unit started successfully");
936 fprintf(stdout,", Media loaded\n");
938 fprintf(stdout,"\n");
940 fprintf(stdout, "Unit stopped successfully");
942 fprintf(stdout, ", Media ejected\n");
944 fprintf(stdout, "\n");
950 "Error received from start unit command\n");
953 "Error received from stop unit command\n");
955 if (arglist & CAM_ARG_VERBOSE) {
956 cam_error_print(device, ccb, CAM_ESF_ALL,
957 CAM_EPF_ALL, stderr);
967 scsidoinquiry(struct cam_device *device, int argc, char **argv,
968 char *combinedopt, int task_attr, int retry_count, int timeout)
973 while ((c = getopt(argc, argv, combinedopt)) != -1) {
976 arglist |= CAM_ARG_GET_STDINQ;
979 arglist |= CAM_ARG_GET_XFERRATE;
982 arglist |= CAM_ARG_GET_SERIAL;
990 * If the user didn't specify any inquiry options, he wants all of
993 if ((arglist & CAM_ARG_INQ_MASK) == 0)
994 arglist |= CAM_ARG_INQ_MASK;
996 if (arglist & CAM_ARG_GET_STDINQ)
997 error = scsiinquiry(device, task_attr, retry_count, timeout);
1002 if (arglist & CAM_ARG_GET_SERIAL)
1003 scsiserial(device, task_attr, retry_count, timeout);
1005 if (arglist & CAM_ARG_GET_XFERRATE)
1006 error = camxferrate(device);
1012 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1016 struct scsi_inquiry_data *inq_buf;
1019 ccb = cam_getccb(device);
1022 warnx("couldn't allocate CCB");
1026 inq_buf = (struct scsi_inquiry_data *)malloc(
1027 sizeof(struct scsi_inquiry_data));
1029 if (inq_buf == NULL) {
1031 warnx("can't malloc memory for inquiry\n");
1034 bzero(inq_buf, sizeof(*inq_buf));
1037 * Note that although the size of the inquiry buffer is the full
1038 * 256 bytes specified in the SCSI spec, we only tell the device
1039 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1040 * two reasons for this:
1042 * - The SCSI spec says that when a length field is only 1 byte,
1043 * a value of 0 will be interpreted as 256. Therefore
1044 * scsi_inquiry() will convert an inq_len (which is passed in as
1045 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1046 * to 0. Evidently, very few devices meet the spec in that
1047 * regard. Some devices, like many Seagate disks, take the 0 as
1048 * 0, and don't return any data. One Pioneer DVD-R drive
1049 * returns more data than the command asked for.
1051 * So, since there are numerous devices that just don't work
1052 * right with the full inquiry size, we don't send the full size.
1054 * - The second reason not to use the full inquiry data length is
1055 * that we don't need it here. The only reason we issue a
1056 * standard inquiry is to get the vendor name, device name,
1057 * and revision so scsi_print_inquiry() can print them.
1059 * If, at some point in the future, more inquiry data is needed for
1060 * some reason, this code should use a procedure similar to the
1061 * probe code. i.e., issue a short inquiry, and determine from
1062 * the additional length passed back from the device how much
1063 * inquiry data the device supports. Once the amount the device
1064 * supports is determined, issue an inquiry for that amount and no
1069 scsi_inquiry(&ccb->csio,
1070 /* retries */ retry_count,
1072 /* tag_action */ task_attr,
1073 /* inq_buf */ (u_int8_t *)inq_buf,
1074 /* inq_len */ SHORT_INQUIRY_LENGTH,
1077 /* sense_len */ SSD_FULL_SIZE,
1078 /* timeout */ timeout ? timeout : 5000);
1080 /* Disable freezing the device queue */
1081 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1083 if (arglist & CAM_ARG_ERR_RECOVER)
1084 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1086 if (cam_send_ccb(device, ccb) < 0) {
1087 warn("error sending INQUIRY command");
1092 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1095 if (arglist & CAM_ARG_VERBOSE) {
1096 cam_error_print(device, ccb, CAM_ESF_ALL,
1097 CAM_EPF_ALL, stderr);
1108 fprintf(stdout, "%s%d: ", device->device_name,
1109 device->dev_unit_num);
1110 scsi_print_inquiry(inq_buf);
1118 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1122 struct scsi_vpd_unit_serial_number *serial_buf;
1123 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1126 ccb = cam_getccb(device);
1129 warnx("couldn't allocate CCB");
1133 serial_buf = (struct scsi_vpd_unit_serial_number *)
1134 malloc(sizeof(*serial_buf));
1136 if (serial_buf == NULL) {
1138 warnx("can't malloc memory for serial number");
1142 scsi_inquiry(&ccb->csio,
1143 /*retries*/ retry_count,
1145 /* tag_action */ task_attr,
1146 /* inq_buf */ (u_int8_t *)serial_buf,
1147 /* inq_len */ sizeof(*serial_buf),
1149 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1150 /* sense_len */ SSD_FULL_SIZE,
1151 /* timeout */ timeout ? timeout : 5000);
1153 /* Disable freezing the device queue */
1154 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1156 if (arglist & CAM_ARG_ERR_RECOVER)
1157 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1159 if (cam_send_ccb(device, ccb) < 0) {
1160 warn("error sending INQUIRY command");
1166 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1169 if (arglist & CAM_ARG_VERBOSE) {
1170 cam_error_print(device, ccb, CAM_ESF_ALL,
1171 CAM_EPF_ALL, stderr);
1182 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1183 serial_num[serial_buf->length] = '\0';
1185 if ((arglist & CAM_ARG_GET_STDINQ)
1186 || (arglist & CAM_ARG_GET_XFERRATE))
1187 fprintf(stdout, "%s%d: Serial Number ",
1188 device->device_name, device->dev_unit_num);
1190 fprintf(stdout, "%.60s\n", serial_num);
1198 camxferrate(struct cam_device *device)
1200 struct ccb_pathinq cpi;
1202 u_int32_t speed = 0;
1207 if ((retval = get_cpi(device, &cpi)) != 0)
1210 ccb = cam_getccb(device);
1213 warnx("couldn't allocate CCB");
1217 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1218 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1220 if (((retval = cam_send_ccb(device, ccb)) < 0)
1221 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1222 const char error_string[] = "error getting transfer settings";
1227 warnx(error_string);
1229 if (arglist & CAM_ARG_VERBOSE)
1230 cam_error_print(device, ccb, CAM_ESF_ALL,
1231 CAM_EPF_ALL, stderr);
1235 goto xferrate_bailout;
1239 speed = cpi.base_transfer_speed;
1241 if (ccb->cts.transport == XPORT_SPI) {
1242 struct ccb_trans_settings_spi *spi =
1243 &ccb->cts.xport_specific.spi;
1245 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1246 freq = scsi_calc_syncsrate(spi->sync_period);
1249 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1250 speed *= (0x01 << spi->bus_width);
1252 } else if (ccb->cts.transport == XPORT_FC) {
1253 struct ccb_trans_settings_fc *fc =
1254 &ccb->cts.xport_specific.fc;
1256 if (fc->valid & CTS_FC_VALID_SPEED)
1257 speed = fc->bitrate;
1258 } else if (ccb->cts.transport == XPORT_SAS) {
1259 struct ccb_trans_settings_sas *sas =
1260 &ccb->cts.xport_specific.sas;
1262 if (sas->valid & CTS_SAS_VALID_SPEED)
1263 speed = sas->bitrate;
1264 } else if (ccb->cts.transport == XPORT_ATA) {
1265 struct ccb_trans_settings_pata *pata =
1266 &ccb->cts.xport_specific.ata;
1268 if (pata->valid & CTS_ATA_VALID_MODE)
1269 speed = ata_mode2speed(pata->mode);
1270 } else if (ccb->cts.transport == XPORT_SATA) {
1271 struct ccb_trans_settings_sata *sata =
1272 &ccb->cts.xport_specific.sata;
1274 if (sata->valid & CTS_SATA_VALID_REVISION)
1275 speed = ata_revision2speed(sata->revision);
1280 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1281 device->device_name, device->dev_unit_num,
1284 fprintf(stdout, "%s%d: %dKB/s transfers",
1285 device->device_name, device->dev_unit_num,
1289 if (ccb->cts.transport == XPORT_SPI) {
1290 struct ccb_trans_settings_spi *spi =
1291 &ccb->cts.xport_specific.spi;
1293 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1294 && (spi->sync_offset != 0))
1295 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1296 freq % 1000, spi->sync_offset);
1298 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1299 && (spi->bus_width > 0)) {
1300 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1301 && (spi->sync_offset != 0)) {
1302 fprintf(stdout, ", ");
1304 fprintf(stdout, " (");
1306 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1307 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1308 && (spi->sync_offset != 0)) {
1309 fprintf(stdout, ")");
1311 } else if (ccb->cts.transport == XPORT_ATA) {
1312 struct ccb_trans_settings_pata *pata =
1313 &ccb->cts.xport_specific.ata;
1316 if (pata->valid & CTS_ATA_VALID_MODE)
1317 printf("%s, ", ata_mode2string(pata->mode));
1318 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1319 printf("ATAPI %dbytes, ", pata->atapi);
1320 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1321 printf("PIO %dbytes", pata->bytecount);
1323 } else if (ccb->cts.transport == XPORT_SATA) {
1324 struct ccb_trans_settings_sata *sata =
1325 &ccb->cts.xport_specific.sata;
1328 if (sata->valid & CTS_SATA_VALID_REVISION)
1329 printf("SATA %d.x, ", sata->revision);
1332 if (sata->valid & CTS_SATA_VALID_MODE)
1333 printf("%s, ", ata_mode2string(sata->mode));
1334 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1335 printf("ATAPI %dbytes, ", sata->atapi);
1336 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1337 printf("PIO %dbytes", sata->bytecount);
1341 if (ccb->cts.protocol == PROTO_SCSI) {
1342 struct ccb_trans_settings_scsi *scsi =
1343 &ccb->cts.proto_specific.scsi;
1344 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1345 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1346 fprintf(stdout, ", Command Queueing Enabled");
1351 fprintf(stdout, "\n");
1361 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1363 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1364 ((u_int32_t)parm->lba_size_2 << 16);
1366 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1367 ((u_int64_t)parm->lba_size48_2 << 16) |
1368 ((u_int64_t)parm->lba_size48_3 << 32) |
1369 ((u_int64_t)parm->lba_size48_4 << 48);
1373 "Support Enabled Value\n");
1376 printf("Host Protected Area (HPA) ");
1377 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1378 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1379 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1382 printf("HPA - Security ");
1383 if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY)
1384 printf("yes %s\n", (parm->enabled.command2 &
1385 ATA_SUPPORT_MAXSECURITY) ? "yes" : "no ");
1394 ataama_print(struct ata_params *parm, u_int64_t nativesize, int header)
1396 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1397 ((u_int32_t)parm->lba_size_2 << 16);
1399 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1400 ((u_int64_t)parm->lba_size48_2 << 16) |
1401 ((u_int64_t)parm->lba_size48_3 << 32) |
1402 ((u_int64_t)parm->lba_size48_4 << 48);
1406 "Support Enabled Value\n");
1409 printf("Accessible Max Address Config ");
1410 if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) {
1411 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1412 printf("yes %s %ju/%ju\n",
1413 (nativesize > lba) ? "yes" : "no ", lba, nativesize);
1420 atasata(struct ata_params *parm)
1424 if (parm->satacapabilities != 0xffff &&
1425 parm->satacapabilities != 0x0000)
1432 atacapprint(struct ata_params *parm)
1435 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1436 ((u_int32_t)parm->lba_size_2 << 16);
1438 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1439 ((u_int64_t)parm->lba_size48_2 << 16) |
1440 ((u_int64_t)parm->lba_size48_3 << 32) |
1441 ((u_int64_t)parm->lba_size48_4 << 48);
1444 printf("protocol ");
1445 proto = (parm->config == ATA_PROTO_CFA) ? "CFA" :
1446 (parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
1447 if (ata_version(parm->version_major) == 0) {
1448 printf("%s", proto);
1449 } else if (ata_version(parm->version_major) <= 7) {
1450 printf("%s-%d", proto,
1451 ata_version(parm->version_major));
1452 } else if (ata_version(parm->version_major) == 8) {
1453 printf("%s8-ACS", proto);
1456 ata_version(parm->version_major) - 7, proto);
1458 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1459 if (parm->satacapabilities & ATA_SATA_GEN3)
1460 printf(" SATA 3.x\n");
1461 else if (parm->satacapabilities & ATA_SATA_GEN2)
1462 printf(" SATA 2.x\n");
1463 else if (parm->satacapabilities & ATA_SATA_GEN1)
1464 printf(" SATA 1.x\n");
1470 printf("device model %.40s\n", parm->model);
1471 printf("firmware revision %.8s\n", parm->revision);
1472 printf("serial number %.20s\n", parm->serial);
1473 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1474 printf("WWN %04x%04x%04x%04x\n",
1475 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1477 printf("additional product id %.8s\n", parm->product_id);
1478 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1479 printf("media serial number %.30s\n",
1480 parm->media_serial);
1483 printf("cylinders %d\n", parm->cylinders);
1484 printf("heads %d\n", parm->heads);
1485 printf("sectors/track %d\n", parm->sectors);
1486 printf("sector size logical %u, physical %lu, offset %lu\n",
1487 ata_logical_sector_size(parm),
1488 (unsigned long)ata_physical_sector_size(parm),
1489 (unsigned long)ata_logical_sector_offset(parm));
1491 if (parm->config == ATA_PROTO_CFA ||
1492 (parm->support.command2 & ATA_SUPPORT_CFA))
1493 printf("CFA supported\n");
1495 printf("LBA%ssupported ",
1496 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1498 printf("%d sectors\n", lbasize);
1502 printf("LBA48%ssupported ",
1503 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1505 printf("%ju sectors\n", (uintmax_t)lbasize48);
1509 printf("PIO supported PIO");
1510 switch (ata_max_pmode(parm)) {
1526 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1527 printf(" w/o IORDY");
1530 printf("DMA%ssupported ",
1531 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1532 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1533 if (parm->mwdmamodes & 0xff) {
1535 if (parm->mwdmamodes & 0x04)
1537 else if (parm->mwdmamodes & 0x02)
1539 else if (parm->mwdmamodes & 0x01)
1543 if ((parm->atavalid & ATA_FLAG_88) &&
1544 (parm->udmamodes & 0xff)) {
1546 if (parm->udmamodes & 0x40)
1548 else if (parm->udmamodes & 0x20)
1550 else if (parm->udmamodes & 0x10)
1552 else if (parm->udmamodes & 0x08)
1554 else if (parm->udmamodes & 0x04)
1556 else if (parm->udmamodes & 0x02)
1558 else if (parm->udmamodes & 0x01)
1565 if (parm->media_rotation_rate == 1) {
1566 printf("media RPM non-rotating\n");
1567 } else if (parm->media_rotation_rate >= 0x0401 &&
1568 parm->media_rotation_rate <= 0xFFFE) {
1569 printf("media RPM %d\n",
1570 parm->media_rotation_rate);
1573 printf("Zoned-Device Commands ");
1574 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1575 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1576 printf("device managed\n");
1578 case ATA_SUPPORT_ZONE_HOST_AWARE:
1579 printf("host aware\n");
1586 "Support Enabled Value Vendor\n");
1587 printf("read ahead %s %s\n",
1588 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1589 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1590 printf("write cache %s %s\n",
1591 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1592 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1593 printf("flush cache %s %s\n",
1594 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1595 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1596 printf("Native Command Queuing (NCQ) ");
1597 if (atasata(parm) && (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1598 printf("yes %d tags\n",
1599 ATA_QUEUE_LEN(parm->queue) + 1);
1600 printf("NCQ Priority Information %s\n",
1601 parm->satacapabilities & ATA_SUPPORT_NCQ_PRIO ?
1603 printf("NCQ Non-Data Command %s\n",
1604 parm->satacapabilities2 & ATA_SUPPORT_NCQ_NON_DATA ?
1606 printf("NCQ Streaming %s\n",
1607 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1609 printf("Receive & Send FPDMA Queued %s\n",
1610 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1612 printf("NCQ Autosense %s\n",
1613 parm->satasupport & ATA_SUPPORT_NCQ_AUTOSENSE ?
1618 printf("SMART %s %s\n",
1619 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1620 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1621 printf("security %s %s\n",
1622 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1623 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1624 printf("power management %s %s\n",
1625 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1626 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1627 printf("microcode download %s %s\n",
1628 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1629 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1630 printf("advanced power management %s %s",
1631 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1632 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1633 if (parm->support.command2 & ATA_SUPPORT_APM) {
1634 printf(" %d/0x%02X\n",
1635 parm->apm_value & 0xff, parm->apm_value & 0xff);
1638 printf("automatic acoustic management %s %s",
1639 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1640 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1641 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1642 printf(" %d/0x%02X %d/0x%02X\n",
1643 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1644 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1645 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1646 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1649 printf("media status notification %s %s\n",
1650 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1651 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1652 printf("power-up in Standby %s %s\n",
1653 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1654 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1655 printf("write-read-verify %s %s",
1656 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1657 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1658 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1659 printf(" %d/0x%x\n",
1660 parm->wrv_mode, parm->wrv_mode);
1663 printf("unload %s %s\n",
1664 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1665 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1666 printf("general purpose logging %s %s\n",
1667 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1668 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1669 printf("free-fall %s %s\n",
1670 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1671 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1672 printf("sense data reporting %s %s\n",
1673 parm->support2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no",
1674 parm->enabled2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no");
1675 printf("extended power conditions %s %s\n",
1676 parm->support2 & ATA_SUPPORT_EPC ? "yes" : "no",
1677 parm->enabled2 & ATA_SUPPORT_EPC ? "yes" : "no");
1678 printf("device statistics notification %s %s\n",
1679 parm->support2 & ATA_SUPPORT_DSN ? "yes" : "no",
1680 parm->enabled2 & ATA_SUPPORT_DSN ? "yes" : "no");
1681 printf("Data Set Management (DSM/TRIM) ");
1682 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1684 printf("DSM - max 512byte blocks ");
1685 if (parm->max_dsm_blocks == 0x00)
1686 printf("yes not specified\n");
1689 parm->max_dsm_blocks);
1691 printf("DSM - deterministic read ");
1692 if (parm->support3 & ATA_SUPPORT_DRAT) {
1693 if (parm->support3 & ATA_SUPPORT_RZAT)
1694 printf("yes zeroed\n");
1696 printf("yes any value\n");
1703 printf("Trusted Computing %s\n",
1704 ((parm->tcg & 0xc000) == 0x4000) && (parm->tcg & ATA_SUPPORT_TCG) ?
1706 printf("encrypts all user data %s\n",
1707 parm->support3 & ATA_ENCRYPTS_ALL_USER_DATA ? "yes" : "no");
1708 printf("Sanitize ");
1709 if (parm->multi & ATA_SUPPORT_SANITIZE) {
1710 printf("yes\t\t%s%s%s\n",
1711 parm->multi & ATA_SUPPORT_BLOCK_ERASE_EXT ? "block, " : "",
1712 parm->multi & ATA_SUPPORT_OVERWRITE_EXT ? "overwrite, " : "",
1713 parm->multi & ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT ? "crypto" : "");
1714 printf("Sanitize - commands allowed %s\n",
1715 parm->multi & ATA_SUPPORT_SANITIZE_ALLOWED ? "yes" : "no");
1716 printf("Sanitize - antifreeze lock %s\n",
1717 parm->multi & ATA_SUPPORT_ANTIFREEZE_LOCK_EXT ? "yes" : "no");
1724 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb)
1726 struct ata_pass_16 *ata_pass_16;
1727 struct ata_cmd ata_cmd;
1729 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1730 ata_cmd.command = ata_pass_16->command;
1731 ata_cmd.control = ata_pass_16->control;
1732 ata_cmd.features = ata_pass_16->features;
1734 if (arglist & CAM_ARG_VERBOSE) {
1735 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1736 ata_op_string(&ata_cmd),
1737 ccb->csio.ccb_h.timeout);
1740 /* Disable freezing the device queue */
1741 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1743 if (arglist & CAM_ARG_ERR_RECOVER)
1744 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1746 if (cam_send_ccb(device, ccb) < 0) {
1747 warn("error sending ATA %s via pass_16", ata_op_string(&ata_cmd));
1752 * Consider any non-CAM_REQ_CMP status as error and report it here,
1753 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible.
1755 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1756 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1757 warnx("ATA %s via pass_16 failed", ata_op_string(&ata_cmd));
1758 if (arglist & CAM_ARG_VERBOSE) {
1759 cam_error_print(device, ccb, CAM_ESF_ALL,
1760 CAM_EPF_ALL, stderr);
1770 ata_cam_send(struct cam_device *device, union ccb *ccb)
1772 if (arglist & CAM_ARG_VERBOSE) {
1773 warnx("sending ATA %s with timeout of %u msecs",
1774 ata_op_string(&(ccb->ataio.cmd)),
1775 ccb->ataio.ccb_h.timeout);
1778 /* Disable freezing the device queue */
1779 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1781 if (arglist & CAM_ARG_ERR_RECOVER)
1782 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1784 if (cam_send_ccb(device, ccb) < 0) {
1785 warn("error sending ATA %s", ata_op_string(&(ccb->ataio.cmd)));
1790 * Consider any non-CAM_REQ_CMP status as error and report it here,
1791 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible.
1793 if (!(ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT) &&
1794 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1795 warnx("ATA %s failed", ata_op_string(&(ccb->ataio.cmd)));
1796 if (arglist & CAM_ARG_VERBOSE) {
1797 cam_error_print(device, ccb, CAM_ESF_ALL,
1798 CAM_EPF_ALL, stderr);
1807 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1808 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1809 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1810 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1811 u_int16_t dxfer_len, int timeout)
1813 if (data_ptr != NULL) {
1814 if (flags & CAM_DIR_OUT)
1815 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1817 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1819 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1822 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1824 scsi_ata_pass_16(&ccb->csio,
1838 /*sense_len*/SSD_FULL_SIZE,
1841 return scsi_cam_pass_16_send(device, ccb);
1845 ata_try_pass_16(struct cam_device *device)
1847 struct ccb_pathinq cpi;
1849 if (get_cpi(device, &cpi) != 0) {
1850 warnx("couldn't get CPI");
1854 if (cpi.protocol == PROTO_SCSI) {
1855 /* possibly compatible with pass_16 */
1859 /* likely not compatible with pass_16 */
1864 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1865 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1866 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1867 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1868 u_int16_t dxfer_len, int timeout, int force48bit)
1872 retval = ata_try_pass_16(device);
1877 return (ata_do_pass_16(device, ccb, retries, flags, protocol,
1878 ata_flags, tag_action, command, features,
1879 lba, sector_count, data_ptr, dxfer_len,
1883 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1884 cam_fill_ataio(&ccb->ataio,
1893 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1894 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1896 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1898 if (ata_flags & AP_FLAG_CHK_COND)
1899 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1901 return ata_cam_send(device, ccb);
1905 dump_data(uint16_t *ptr, uint32_t len)
1909 for (i = 0; i < len / 2; i++) {
1911 printf(" %3d: ", i);
1912 printf("%04hx ", ptr[i]);
1921 atahpa_proc_resp(struct cam_device *device, union ccb *ccb, u_int64_t *hpasize)
1923 uint8_t error = 0, ata_device = 0, status = 0;
1928 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
1931 if (arglist & CAM_ARG_VERBOSE) {
1932 cam_error_print(device, ccb, CAM_ESF_ALL,
1933 CAM_EPF_ALL, stderr);
1935 warnx("Can't get ATA command status");
1939 if (status & ATA_STATUS_ERROR) {
1940 if (arglist & CAM_ARG_VERBOSE) {
1941 cam_error_print(device, ccb, CAM_ESF_ALL,
1942 CAM_EPF_ALL, stderr);
1945 if (error & ATA_ERROR_ID_NOT_FOUND) {
1946 warnx("Max address has already been set since "
1947 "last power-on or hardware reset");
1948 } else if (hpasize == NULL)
1949 warnx("Command failed with ATA error");
1954 if (hpasize != NULL) {
1955 if (retval == 2 || retval == 6)
1964 ata_read_native_max(struct cam_device *device, int retry_count,
1965 u_int32_t timeout, union ccb *ccb,
1966 struct ata_params *parm, u_int64_t *hpasize)
1972 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1973 protocol = AP_PROTO_NON_DATA;
1976 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1977 protocol |= AP_EXTEND;
1979 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1982 error = ata_do_cmd(device,
1985 /*flags*/CAM_DIR_NONE,
1986 /*protocol*/protocol,
1987 /*ata_flags*/AP_FLAG_CHK_COND,
1988 /*tag_action*/MSG_SIMPLE_Q_TAG,
1995 timeout ? timeout : 5000,
2001 return atahpa_proc_resp(device, ccb, hpasize);
2005 atahpa_set_max(struct cam_device *device, int retry_count,
2006 u_int32_t timeout, union ccb *ccb,
2007 int is48bit, u_int64_t maxsize, int persist)
2013 protocol = AP_PROTO_NON_DATA;
2016 cmd = ATA_SET_MAX_ADDRESS48;
2017 protocol |= AP_EXTEND;
2019 cmd = ATA_SET_MAX_ADDRESS;
2022 /* lba's are zero indexed so the max lba is requested max - 1 */
2026 error = ata_do_cmd(device,
2029 /*flags*/CAM_DIR_NONE,
2030 /*protocol*/protocol,
2031 /*ata_flags*/AP_FLAG_CHK_COND,
2032 /*tag_action*/MSG_SIMPLE_Q_TAG,
2034 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2036 /*sector_count*/persist,
2039 timeout ? timeout : 1000,
2045 return atahpa_proc_resp(device, ccb, NULL);
2049 atahpa_password(struct cam_device *device, int retry_count,
2050 u_int32_t timeout, union ccb *ccb,
2051 int is48bit, struct ata_set_max_pwd *pwd)
2056 protocol = AP_PROTO_PIO_OUT;
2057 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2059 return (ata_do_cmd(device,
2062 /*flags*/CAM_DIR_OUT,
2063 /*protocol*/protocol,
2064 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2065 AP_FLAG_TLEN_SECT_CNT,
2066 /*tag_action*/MSG_SIMPLE_Q_TAG,
2068 /*features*/ATA_HPA_FEAT_SET_PWD,
2070 /*sector_count*/sizeof(*pwd) / 512,
2071 /*data_ptr*/(u_int8_t*)pwd,
2072 /*dxfer_len*/sizeof(*pwd),
2073 timeout ? timeout : 1000,
2078 atahpa_lock(struct cam_device *device, int retry_count,
2079 u_int32_t timeout, union ccb *ccb, int is48bit)
2084 protocol = AP_PROTO_NON_DATA;
2085 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2087 return (ata_do_cmd(device,
2090 /*flags*/CAM_DIR_NONE,
2091 /*protocol*/protocol,
2093 /*tag_action*/MSG_SIMPLE_Q_TAG,
2095 /*features*/ATA_HPA_FEAT_LOCK,
2100 timeout ? timeout : 1000,
2105 atahpa_unlock(struct cam_device *device, int retry_count,
2106 u_int32_t timeout, union ccb *ccb,
2107 int is48bit, struct ata_set_max_pwd *pwd)
2112 protocol = AP_PROTO_PIO_OUT;
2113 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2115 return (ata_do_cmd(device,
2118 /*flags*/CAM_DIR_OUT,
2119 /*protocol*/protocol,
2120 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2121 AP_FLAG_TLEN_SECT_CNT,
2122 /*tag_action*/MSG_SIMPLE_Q_TAG,
2124 /*features*/ATA_HPA_FEAT_UNLOCK,
2126 /*sector_count*/sizeof(*pwd) / 512,
2127 /*data_ptr*/(u_int8_t*)pwd,
2128 /*dxfer_len*/sizeof(*pwd),
2129 timeout ? timeout : 1000,
2134 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2135 u_int32_t timeout, union ccb *ccb, int is48bit)
2140 protocol = AP_PROTO_NON_DATA;
2141 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2143 return (ata_do_cmd(device,
2146 /*flags*/CAM_DIR_NONE,
2147 /*protocol*/protocol,
2149 /*tag_action*/MSG_SIMPLE_Q_TAG,
2151 /*features*/ATA_HPA_FEAT_FREEZE,
2156 timeout ? timeout : 1000,
2161 ata_get_native_max(struct cam_device *device, int retry_count,
2162 u_int32_t timeout, union ccb *ccb,
2163 u_int64_t *nativesize)
2167 error = ata_do_cmd(device,
2170 /*flags*/CAM_DIR_NONE,
2171 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2172 /*ata_flags*/AP_FLAG_CHK_COND,
2173 /*tag_action*/MSG_SIMPLE_Q_TAG,
2174 /*command*/ATA_AMAX_ADDR,
2175 /*features*/ATA_AMAX_ADDR_GET,
2180 timeout ? timeout : 30 * 1000,
2186 return atahpa_proc_resp(device, ccb, nativesize);
2190 ataama_set(struct cam_device *device, int retry_count,
2191 u_int32_t timeout, union ccb *ccb, u_int64_t maxsize)
2195 /* lba's are zero indexed so the max lba is requested max - 1 */
2199 error = ata_do_cmd(device,
2202 /*flags*/CAM_DIR_NONE,
2203 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2204 /*ata_flags*/AP_FLAG_CHK_COND,
2205 /*tag_action*/MSG_SIMPLE_Q_TAG,
2206 /*command*/ATA_AMAX_ADDR,
2207 /*features*/ATA_AMAX_ADDR_SET,
2212 timeout ? timeout : 30 * 1000,
2218 return atahpa_proc_resp(device, ccb, NULL);
2222 ataama_freeze(struct cam_device *device, int retry_count,
2223 u_int32_t timeout, union ccb *ccb)
2226 return (ata_do_cmd(device,
2229 /*flags*/CAM_DIR_NONE,
2230 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2232 /*tag_action*/MSG_SIMPLE_Q_TAG,
2233 /*command*/ATA_AMAX_ADDR,
2234 /*features*/ATA_AMAX_ADDR_FREEZE,
2239 timeout ? timeout : 30 * 1000,
2244 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2245 union ccb *ccb, struct ata_params** ident_bufp)
2247 struct ata_params *ident_buf;
2248 struct ccb_pathinq cpi;
2249 struct ccb_getdev cgd;
2252 u_int8_t command, retry_command;
2254 if (get_cpi(device, &cpi) != 0) {
2255 warnx("couldn't get CPI");
2259 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2260 if (cpi.protocol == PROTO_ATA) {
2261 if (get_cgd(device, &cgd) != 0) {
2262 warnx("couldn't get CGD");
2266 command = (cgd.protocol == PROTO_ATA) ?
2267 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2270 /* We don't know which for sure so try both */
2271 command = ATA_ATA_IDENTIFY;
2272 retry_command = ATA_ATAPI_IDENTIFY;
2275 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2277 warnx("can't calloc memory for identify\n");
2282 error = ata_do_cmd(device,
2284 /*retries*/retry_count,
2285 /*flags*/CAM_DIR_IN,
2286 /*protocol*/AP_PROTO_PIO_IN,
2287 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2288 AP_FLAG_TLEN_SECT_CNT,
2289 /*tag_action*/MSG_SIMPLE_Q_TAG,
2293 /*sector_count*/sizeof(struct ata_params) / 512,
2294 /*data_ptr*/(u_int8_t *)ptr,
2295 /*dxfer_len*/sizeof(struct ata_params),
2296 /*timeout*/timeout ? timeout : 30 * 1000,
2300 if (retry_command != 0) {
2301 command = retry_command;
2309 ident_buf = (struct ata_params *)ptr;
2310 ata_param_fixup(ident_buf);
2313 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2318 /* check for invalid (all zero) response */
2320 warnx("Invalid identify response detected");
2325 *ident_bufp = ident_buf;
2332 ataidentify(struct cam_device *device, int retry_count, int timeout)
2335 struct ata_params *ident_buf;
2336 u_int64_t hpasize = 0, nativesize = 0;
2338 if ((ccb = cam_getccb(device)) == NULL) {
2339 warnx("couldn't allocate CCB");
2343 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2348 if (arglist & CAM_ARG_VERBOSE) {
2349 printf("%s%d: Raw identify data:\n",
2350 device->device_name, device->dev_unit_num);
2351 dump_data((uint16_t *)ident_buf, sizeof(struct ata_params));
2354 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2355 ata_read_native_max(device, retry_count, timeout, ccb,
2356 ident_buf, &hpasize);
2358 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2359 ata_get_native_max(device, retry_count, timeout, ccb,
2363 printf("%s%d: ", device->device_name, device->dev_unit_num);
2364 ata_print_ident(ident_buf);
2365 camxferrate(device);
2366 atacapprint(ident_buf);
2367 atahpa_print(ident_buf, hpasize, 0);
2368 ataama_print(ident_buf, nativesize, 0);
2378 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2380 struct nvme_controller_data cdata;
2382 if (nvme_get_cdata(device, &cdata))
2384 nvme_print_controller(&cdata);
2391 identify(struct cam_device *device, int retry_count, int timeout)
2394 struct ccb_pathinq cpi;
2396 if (get_cpi(device, &cpi) != 0) {
2397 warnx("couldn't get CPI");
2401 if (cpi.protocol == PROTO_NVME) {
2402 return (nvmeidentify(device, retry_count, timeout));
2405 return (ataidentify(device, retry_count, timeout));
2410 ATA_SECURITY_ACTION_PRINT,
2411 ATA_SECURITY_ACTION_FREEZE,
2412 ATA_SECURITY_ACTION_UNLOCK,
2413 ATA_SECURITY_ACTION_DISABLE,
2414 ATA_SECURITY_ACTION_ERASE,
2415 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2416 ATA_SECURITY_ACTION_SET_PASSWORD
2420 atasecurity_print_time(u_int16_t tw)
2424 printf("unspecified");
2426 printf("> 508 min");
2428 printf("%i min", 2 * tw);
2432 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2436 return 2 * 3600 * 1000; /* default: two hours */
2437 else if (timeout > 255)
2438 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2440 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2445 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2449 bzero(&cmd, sizeof(cmd));
2450 cmd.command = command;
2451 printf("Issuing %s", ata_op_string(&cmd));
2454 /* pwd->password may not be null terminated */
2455 char pass[sizeof(pwd->password)+1];
2457 strlcpy(pass, pwd->password, sizeof(pass));
2458 printf(" password='%s', user='%s'",
2460 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2463 if (command == ATA_SECURITY_SET_PASSWORD) {
2464 printf(", mode='%s'",
2465 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2466 "maximum" : "high");
2474 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2475 int retry_count, u_int32_t timeout, int quiet)
2479 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2481 return ata_do_cmd(device,
2484 /*flags*/CAM_DIR_NONE,
2485 /*protocol*/AP_PROTO_NON_DATA,
2487 /*tag_action*/MSG_SIMPLE_Q_TAG,
2488 /*command*/ATA_SECURITY_FREEZE_LOCK,
2499 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2500 int retry_count, u_int32_t timeout,
2501 struct ata_security_password *pwd, int quiet)
2505 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2507 return ata_do_cmd(device,
2510 /*flags*/CAM_DIR_OUT,
2511 /*protocol*/AP_PROTO_PIO_OUT,
2512 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2513 AP_FLAG_TLEN_SECT_CNT,
2514 /*tag_action*/MSG_SIMPLE_Q_TAG,
2515 /*command*/ATA_SECURITY_UNLOCK,
2518 /*sector_count*/sizeof(*pwd) / 512,
2519 /*data_ptr*/(u_int8_t *)pwd,
2520 /*dxfer_len*/sizeof(*pwd),
2526 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2527 int retry_count, u_int32_t timeout,
2528 struct ata_security_password *pwd, int quiet)
2532 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2533 return ata_do_cmd(device,
2536 /*flags*/CAM_DIR_OUT,
2537 /*protocol*/AP_PROTO_PIO_OUT,
2538 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2539 AP_FLAG_TLEN_SECT_CNT,
2540 /*tag_action*/MSG_SIMPLE_Q_TAG,
2541 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2544 /*sector_count*/sizeof(*pwd) / 512,
2545 /*data_ptr*/(u_int8_t *)pwd,
2546 /*dxfer_len*/sizeof(*pwd),
2553 atasecurity_erase_confirm(struct cam_device *device,
2554 struct ata_params* ident_buf)
2557 printf("\nYou are about to ERASE ALL DATA from the following"
2558 " device:\n%s%d,%s%d: ", device->device_name,
2559 device->dev_unit_num, device->given_dev_name,
2560 device->given_unit_number);
2561 ata_print_ident(ident_buf);
2565 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2567 if (fgets(str, sizeof(str), stdin) != NULL) {
2568 if (strncasecmp(str, "yes", 3) == 0) {
2570 } else if (strncasecmp(str, "no", 2) == 0) {
2573 printf("Please answer \"yes\" or "
2584 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2585 int retry_count, u_int32_t timeout,
2586 u_int32_t erase_timeout,
2587 struct ata_security_password *pwd, int quiet)
2592 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2594 error = ata_do_cmd(device,
2597 /*flags*/CAM_DIR_NONE,
2598 /*protocol*/AP_PROTO_NON_DATA,
2600 /*tag_action*/MSG_SIMPLE_Q_TAG,
2601 /*command*/ATA_SECURITY_ERASE_PREPARE,
2614 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2616 error = ata_do_cmd(device,
2619 /*flags*/CAM_DIR_OUT,
2620 /*protocol*/AP_PROTO_PIO_OUT,
2621 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2622 AP_FLAG_TLEN_SECT_CNT,
2623 /*tag_action*/MSG_SIMPLE_Q_TAG,
2624 /*command*/ATA_SECURITY_ERASE_UNIT,
2627 /*sector_count*/sizeof(*pwd) / 512,
2628 /*data_ptr*/(u_int8_t *)pwd,
2629 /*dxfer_len*/sizeof(*pwd),
2630 /*timeout*/erase_timeout,
2633 if (error == 0 && quiet == 0)
2634 printf("\nErase Complete\n");
2640 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2641 int retry_count, u_int32_t timeout,
2642 struct ata_security_password *pwd, int quiet)
2646 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2648 return ata_do_cmd(device,
2651 /*flags*/CAM_DIR_OUT,
2652 /*protocol*/AP_PROTO_PIO_OUT,
2653 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2654 AP_FLAG_TLEN_SECT_CNT,
2655 /*tag_action*/MSG_SIMPLE_Q_TAG,
2656 /*command*/ATA_SECURITY_SET_PASSWORD,
2659 /*sector_count*/sizeof(*pwd) / 512,
2660 /*data_ptr*/(u_int8_t *)pwd,
2661 /*dxfer_len*/sizeof(*pwd),
2667 atasecurity_print(struct ata_params *parm)
2670 printf("\nSecurity Option Value\n");
2671 if (arglist & CAM_ARG_VERBOSE) {
2672 printf("status %04x\n",
2673 parm->security_status);
2675 printf("supported %s\n",
2676 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2677 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2679 printf("enabled %s\n",
2680 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2681 printf("drive locked %s\n",
2682 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2683 printf("security config frozen %s\n",
2684 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2685 printf("count expired %s\n",
2686 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2687 printf("security level %s\n",
2688 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2689 printf("enhanced erase supported %s\n",
2690 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2691 printf("erase time ");
2692 atasecurity_print_time(parm->erase_time);
2694 printf("enhanced erase time ");
2695 atasecurity_print_time(parm->enhanced_erase_time);
2697 printf("master password rev %04x%s\n",
2698 parm->master_passwd_revision,
2699 parm->master_passwd_revision == 0x0000 ||
2700 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2704 * Validates and copies the password in optarg to the passed buffer.
2705 * If the password in optarg is the same length as the buffer then
2706 * the data will still be copied but no null termination will occur.
2709 ata_getpwd(u_int8_t *passwd, int max, char opt)
2713 len = strlen(optarg);
2715 warnx("-%c password is too long", opt);
2717 } else if (len == 0) {
2718 warnx("-%c password is missing", opt);
2720 } else if (optarg[0] == '-'){
2721 warnx("-%c password starts with '-' (generic arg?)", opt);
2723 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2724 warnx("-%c password conflicts with existing password from -%c",
2729 /* Callers pass in a buffer which does NOT need to be terminated */
2730 strncpy(passwd, optarg, max);
2737 ATA_HPA_ACTION_PRINT,
2738 ATA_HPA_ACTION_SET_MAX,
2739 ATA_HPA_ACTION_SET_PWD,
2740 ATA_HPA_ACTION_LOCK,
2741 ATA_HPA_ACTION_UNLOCK,
2742 ATA_HPA_ACTION_FREEZE_LOCK
2746 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2747 u_int64_t maxsize, int persist)
2749 printf("\nYou are about to configure HPA to limit the user accessible\n"
2750 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2751 persist ? "persistently" : "temporarily",
2752 device->device_name, device->dev_unit_num,
2753 device->given_dev_name, device->given_unit_number);
2754 ata_print_ident(ident_buf);
2758 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2760 if (NULL != fgets(str, sizeof(str), stdin)) {
2761 if (0 == strncasecmp(str, "yes", 3)) {
2763 } else if (0 == strncasecmp(str, "no", 2)) {
2766 printf("Please answer \"yes\" or "
2777 atahpa(struct cam_device *device, int retry_count, int timeout,
2778 int argc, char **argv, char *combinedopt)
2781 struct ata_params *ident_buf;
2782 struct ccb_getdev cgd;
2783 struct ata_set_max_pwd pwd;
2784 int error, confirm, quiet, c, action, actions, persist;
2785 int security, is48bit, pwdsize;
2786 u_int64_t hpasize, maxsize;
2795 memset(&pwd, 0, sizeof(pwd));
2797 /* default action is to print hpa information */
2798 action = ATA_HPA_ACTION_PRINT;
2799 pwdsize = sizeof(pwd.password);
2801 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2804 action = ATA_HPA_ACTION_SET_MAX;
2805 maxsize = strtoumax(optarg, NULL, 0);
2810 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2812 action = ATA_HPA_ACTION_SET_PWD;
2818 action = ATA_HPA_ACTION_LOCK;
2824 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2826 action = ATA_HPA_ACTION_UNLOCK;
2832 action = ATA_HPA_ACTION_FREEZE_LOCK;
2852 warnx("too many hpa actions specified");
2856 if (get_cgd(device, &cgd) != 0) {
2857 warnx("couldn't get CGD");
2861 ccb = cam_getccb(device);
2863 warnx("couldn't allocate CCB");
2867 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2874 printf("%s%d: ", device->device_name, device->dev_unit_num);
2875 ata_print_ident(ident_buf);
2876 camxferrate(device);
2879 if (action == ATA_HPA_ACTION_PRINT) {
2881 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2882 ata_read_native_max(device, retry_count, timeout, ccb,
2883 ident_buf, &hpasize);
2884 atahpa_print(ident_buf, hpasize, 1);
2891 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2892 warnx("HPA is not supported by this device");
2898 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
2899 warnx("HPA Security is not supported by this device");
2905 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2908 * The ATA spec requires:
2909 * 1. Read native max addr is called directly before set max addr
2910 * 2. Read native max addr is NOT called before any other set max call
2913 case ATA_HPA_ACTION_SET_MAX:
2915 atahpa_set_confirm(device, ident_buf, maxsize,
2922 error = ata_read_native_max(device, retry_count, timeout,
2923 ccb, ident_buf, &hpasize);
2925 error = atahpa_set_max(device, retry_count, timeout,
2926 ccb, is48bit, maxsize, persist);
2929 /* redo identify to get new values */
2930 error = ata_do_identify(device,
2931 retry_count, timeout, ccb,
2933 atahpa_print(ident_buf, hpasize, 1);
2935 /* Hint CAM to reprobe the device. */
2941 case ATA_HPA_ACTION_SET_PWD:
2942 error = atahpa_password(device, retry_count, timeout,
2943 ccb, is48bit, &pwd);
2944 if (error == 0 && quiet == 0)
2945 printf("HPA password has been set\n");
2948 case ATA_HPA_ACTION_LOCK:
2949 error = atahpa_lock(device, retry_count, timeout,
2951 if (error == 0 && quiet == 0)
2952 printf("HPA has been locked\n");
2955 case ATA_HPA_ACTION_UNLOCK:
2956 error = atahpa_unlock(device, retry_count, timeout,
2957 ccb, is48bit, &pwd);
2958 if (error == 0 && quiet == 0)
2959 printf("HPA has been unlocked\n");
2962 case ATA_HPA_ACTION_FREEZE_LOCK:
2963 error = atahpa_freeze_lock(device, retry_count, timeout,
2965 if (error == 0 && quiet == 0)
2966 printf("HPA has been frozen\n");
2970 errx(1, "Option currently not supported");
2980 ATA_AMA_ACTION_PRINT,
2981 ATA_AMA_ACTION_SET_MAX,
2982 ATA_AMA_ACTION_FREEZE_LOCK
2986 ataama(struct cam_device *device, int retry_count, int timeout,
2987 int argc, char **argv, char *combinedopt)
2990 struct ata_params *ident_buf;
2991 struct ccb_getdev cgd;
2992 int error, quiet, c, action, actions;
2993 u_int64_t nativesize, maxsize;
2999 /* default action is to print AMA information */
3000 action = ATA_AMA_ACTION_PRINT;
3002 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3005 action = ATA_AMA_ACTION_SET_MAX;
3006 maxsize = strtoumax(optarg, NULL, 0);
3011 action = ATA_AMA_ACTION_FREEZE_LOCK;
3022 warnx("too many AMA actions specified");
3026 if (get_cgd(device, &cgd) != 0) {
3027 warnx("couldn't get CGD");
3031 ccb = cam_getccb(device);
3033 warnx("couldn't allocate CCB");
3037 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3044 printf("%s%d: ", device->device_name, device->dev_unit_num);
3045 ata_print_ident(ident_buf);
3046 camxferrate(device);
3049 if (action == ATA_AMA_ACTION_PRINT) {
3051 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3052 ata_get_native_max(device, retry_count, timeout, ccb,
3054 ataama_print(ident_buf, nativesize, 1);
3061 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3062 warnx("Accessible Max Address is not supported by this device");
3069 case ATA_AMA_ACTION_SET_MAX:
3070 error = ata_get_native_max(device, retry_count, timeout, ccb,
3073 error = ataama_set(device, retry_count, timeout,
3077 /* redo identify to get new values */
3078 error = ata_do_identify(device,
3079 retry_count, timeout, ccb,
3081 ataama_print(ident_buf, nativesize, 1);
3083 /* Hint CAM to reprobe the device. */
3089 case ATA_AMA_ACTION_FREEZE_LOCK:
3090 error = ataama_freeze(device, retry_count, timeout,
3092 if (error == 0 && quiet == 0)
3093 printf("Accessible Max Address has been frozen\n");
3097 errx(1, "Option currently not supported");
3107 atasecurity(struct cam_device *device, int retry_count, int timeout,
3108 int argc, char **argv, char *combinedopt)
3111 struct ata_params *ident_buf;
3112 int error, confirm, quiet, c, action, actions, setpwd;
3113 int security_enabled, erase_timeout, pwdsize;
3114 struct ata_security_password pwd;
3122 memset(&pwd, 0, sizeof(pwd));
3124 /* default action is to print security information */
3125 action = ATA_SECURITY_ACTION_PRINT;
3127 /* user is master by default as its safer that way */
3128 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3129 pwdsize = sizeof(pwd.password);
3131 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3134 action = ATA_SECURITY_ACTION_FREEZE;
3139 if (strcasecmp(optarg, "user") == 0) {
3140 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3141 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3142 } else if (strcasecmp(optarg, "master") == 0) {
3143 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3144 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3146 warnx("-U argument '%s' is invalid (must be "
3147 "'user' or 'master')", optarg);
3153 if (strcasecmp(optarg, "high") == 0) {
3154 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3155 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3156 } else if (strcasecmp(optarg, "maximum") == 0) {
3157 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3158 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3160 warnx("-l argument '%s' is unknown (must be "
3161 "'high' or 'maximum')", optarg);
3167 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3169 action = ATA_SECURITY_ACTION_UNLOCK;
3174 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3176 action = ATA_SECURITY_ACTION_DISABLE;
3181 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3183 action = ATA_SECURITY_ACTION_ERASE;
3188 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3190 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3191 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3196 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3199 if (action == ATA_SECURITY_ACTION_PRINT)
3200 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3202 * Don't increment action as this can be combined
3203 * with other actions.
3216 erase_timeout = atoi(optarg) * 1000;
3222 warnx("too many security actions specified");
3226 if ((ccb = cam_getccb(device)) == NULL) {
3227 warnx("couldn't allocate CCB");
3231 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3238 printf("%s%d: ", device->device_name, device->dev_unit_num);
3239 ata_print_ident(ident_buf);
3240 camxferrate(device);
3243 if (action == ATA_SECURITY_ACTION_PRINT) {
3244 atasecurity_print(ident_buf);
3250 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3251 warnx("Security not supported");
3257 /* default timeout 15 seconds the same as linux hdparm */
3258 timeout = timeout ? timeout : 15 * 1000;
3260 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3262 /* first set the password if requested */
3264 /* confirm we can erase before setting the password if erasing */
3266 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3267 action == ATA_SECURITY_ACTION_ERASE) &&
3268 atasecurity_erase_confirm(device, ident_buf) == 0) {
3274 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3275 pwd.revision = ident_buf->master_passwd_revision;
3276 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3277 --pwd.revision == 0) {
3278 pwd.revision = 0xfffe;
3281 error = atasecurity_set_password(device, ccb, retry_count,
3282 timeout, &pwd, quiet);
3288 security_enabled = 1;
3292 case ATA_SECURITY_ACTION_FREEZE:
3293 error = atasecurity_freeze(device, ccb, retry_count,
3297 case ATA_SECURITY_ACTION_UNLOCK:
3298 if (security_enabled) {
3299 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3300 error = atasecurity_unlock(device, ccb,
3301 retry_count, timeout, &pwd, quiet);
3303 warnx("Can't unlock, drive is not locked");
3307 warnx("Can't unlock, security is disabled");
3312 case ATA_SECURITY_ACTION_DISABLE:
3313 if (security_enabled) {
3314 /* First unlock the drive if its locked */
3315 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3316 error = atasecurity_unlock(device, ccb,
3324 error = atasecurity_disable(device,
3332 warnx("Can't disable security (already disabled)");
3337 case ATA_SECURITY_ACTION_ERASE:
3338 if (security_enabled) {
3339 if (erase_timeout == 0) {
3340 erase_timeout = atasecurity_erase_timeout_msecs(
3341 ident_buf->erase_time);
3344 error = atasecurity_erase(device, ccb, retry_count,
3345 timeout, erase_timeout, &pwd, quiet);
3347 warnx("Can't secure erase (security is disabled)");
3352 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3353 if (security_enabled) {
3354 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3355 if (erase_timeout == 0) {
3357 atasecurity_erase_timeout_msecs(
3358 ident_buf->enhanced_erase_time);
3361 error = atasecurity_erase(device, ccb,
3362 retry_count, timeout,
3363 erase_timeout, &pwd,
3366 warnx("Enhanced erase is not supported");
3370 warnx("Can't secure erase (enhanced), "
3371 "(security is disabled)");
3384 * Convert periph name into a bus, target and lun.
3386 * Returns the number of parsed components, or 0.
3389 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3390 cam_argmask *arglst)
3395 bzero(&ccb, sizeof(ccb));
3396 ccb.ccb_h.func_code = XPT_GDEVLIST;
3397 if (cam_get_device(tstr, ccb.cgdl.periph_name,
3398 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3399 warnx("%s", cam_errbuf);
3404 * Attempt to get the passthrough device. This ioctl will
3405 * fail if the device name is null, if the device doesn't
3406 * exist, or if the passthrough driver isn't in the kernel.
3408 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3409 warn("Unable to open %s", XPT_DEVICE);
3412 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3413 warn("Unable to find bus:target:lun for device %s%d",
3414 ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3419 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3420 const struct cam_status_entry *entry;
3422 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3423 warnx("Unable to find bus:target_lun for device %s%d, "
3424 "CAM status: %s (%#x)",
3425 ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3426 entry ? entry->status_text : "Unknown",
3432 * The kernel fills in the bus/target/lun. We don't
3433 * need the passthrough device name and unit number since
3434 * we aren't going to open it.
3436 *bus = ccb.ccb_h.path_id;
3437 *target = ccb.ccb_h.target_id;
3438 *lun = ccb.ccb_h.target_lun;
3439 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3444 * Parse out a bus, or a bus, target and lun in the following
3450 * Returns the number of parsed components, or 0.
3453 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3454 cam_argmask *arglst)
3459 *bus = CAM_BUS_WILDCARD;
3460 *target = CAM_TARGET_WILDCARD;
3461 *lun = CAM_LUN_WILDCARD;
3463 while (isspace(*tstr) && (*tstr != '\0'))
3466 if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3467 arglist |= CAM_ARG_BUS;
3471 if (!isdigit(*tstr))
3472 return (parse_btl_name(tstr, bus, target, lun, arglst));
3474 tmpstr = strsep(&tstr, ":");
3475 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3476 *bus = strtol(tmpstr, &end, 0);
3479 *arglst |= CAM_ARG_BUS;
3481 tmpstr = strsep(&tstr, ":");
3482 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3483 *target = strtol(tmpstr, &end, 0);
3486 *arglst |= CAM_ARG_TARGET;
3488 tmpstr = strsep(&tstr, ":");
3489 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3490 *lun = strtoll(tmpstr, &end, 0);
3493 *arglst |= CAM_ARG_LUN;
3503 dorescan_or_reset(int argc, char **argv, int rescan)
3505 static const char must[] =
3506 "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3508 path_id_t bus = CAM_BUS_WILDCARD;
3509 target_id_t target = CAM_TARGET_WILDCARD;
3510 lun_id_t lun = CAM_LUN_WILDCARD;
3514 warnx(must, rescan? "rescan" : "reset");
3518 tstr = argv[optind];
3519 while (isspace(*tstr) && (*tstr != '\0'))
3521 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3522 arglist |= CAM_ARG_BUS;
3524 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3525 if (rv != 1 && rv != 3) {
3526 warnx(must, rescan ? "rescan" : "reset");
3531 if (arglist & CAM_ARG_LUN)
3532 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3534 error = rescan_or_reset_bus(bus, rescan);
3540 rescan_or_reset_bus(path_id_t bus, int rescan)
3542 union ccb *ccb = NULL, *matchccb = NULL;
3543 int fd = -1, retval;
3548 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3549 warnx("error opening transport layer device %s", XPT_DEVICE);
3550 warn("%s", XPT_DEVICE);
3554 ccb = malloc(sizeof(*ccb));
3556 warn("failed to allocate CCB");
3560 bzero(ccb, sizeof(*ccb));
3562 if (bus != CAM_BUS_WILDCARD) {
3563 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3564 ccb->ccb_h.path_id = bus;
3565 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3566 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3567 ccb->crcn.flags = CAM_FLAG_NONE;
3569 /* run this at a low priority */
3570 ccb->ccb_h.pinfo.priority = 5;
3572 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3573 warn("CAMIOCOMMAND ioctl failed");
3578 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3579 fprintf(stdout, "%s of bus %d was successful\n",
3580 rescan ? "Re-scan" : "Reset", bus);
3582 fprintf(stdout, "%s of bus %d returned error %#x\n",
3583 rescan ? "Re-scan" : "Reset", bus,
3584 ccb->ccb_h.status & CAM_STATUS_MASK);
3593 * The right way to handle this is to modify the xpt so that it can
3594 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3595 * that isn't implemented, so instead we enumerate the buses and
3596 * send the rescan or reset to those buses in the case where the
3597 * given bus is -1 (wildcard). We don't send a rescan or reset
3598 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3599 * no-op, sending a rescan to the xpt bus would result in a status of
3602 matchccb = malloc(sizeof(*matchccb));
3603 if (matchccb == NULL) {
3604 warn("failed to allocate CCB");
3608 bzero(matchccb, sizeof(*matchccb));
3609 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3610 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3611 bufsize = sizeof(struct dev_match_result) * 20;
3612 matchccb->cdm.match_buf_len = bufsize;
3613 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3614 if (matchccb->cdm.matches == NULL) {
3615 warnx("can't malloc memory for matches");
3619 matchccb->cdm.num_matches = 0;
3621 matchccb->cdm.num_patterns = 1;
3622 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3624 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3625 matchccb->cdm.pattern_buf_len);
3626 if (matchccb->cdm.patterns == NULL) {
3627 warnx("can't malloc memory for patterns");
3631 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3632 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3637 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3638 warn("CAMIOCOMMAND ioctl failed");
3643 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3644 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3645 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3646 warnx("got CAM error %#x, CDM error %d\n",
3647 matchccb->ccb_h.status, matchccb->cdm.status);
3652 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3653 struct bus_match_result *bus_result;
3655 /* This shouldn't happen. */
3656 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3659 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3662 * We don't want to rescan or reset the xpt bus.
3665 if (bus_result->path_id == CAM_XPT_PATH_ID)
3668 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3670 ccb->ccb_h.path_id = bus_result->path_id;
3671 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3672 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3673 ccb->crcn.flags = CAM_FLAG_NONE;
3675 /* run this at a low priority */
3676 ccb->ccb_h.pinfo.priority = 5;
3678 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3679 warn("CAMIOCOMMAND ioctl failed");
3684 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3685 fprintf(stdout, "%s of bus %d was successful\n",
3686 rescan? "Re-scan" : "Reset",
3687 bus_result->path_id);
3690 * Don't bail out just yet, maybe the other
3691 * rescan or reset commands will complete
3694 fprintf(stderr, "%s of bus %d returned error "
3695 "%#x\n", rescan? "Re-scan" : "Reset",
3696 bus_result->path_id,
3697 ccb->ccb_h.status & CAM_STATUS_MASK);
3701 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3702 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3709 if (matchccb != NULL) {
3710 free(matchccb->cdm.patterns);
3711 free(matchccb->cdm.matches);
3720 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3723 struct cam_device *device;
3728 if (bus == CAM_BUS_WILDCARD) {
3729 warnx("invalid bus number %d", bus);
3733 if (target == CAM_TARGET_WILDCARD) {
3734 warnx("invalid target number %d", target);
3738 if (lun == CAM_LUN_WILDCARD) {
3739 warnx("invalid lun number %jx", (uintmax_t)lun);
3745 bzero(&ccb, sizeof(union ccb));
3748 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3749 warnx("error opening transport layer device %s\n",
3751 warn("%s", XPT_DEVICE);
3755 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3756 if (device == NULL) {
3757 warnx("%s", cam_errbuf);
3762 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3763 ccb.ccb_h.path_id = bus;
3764 ccb.ccb_h.target_id = target;
3765 ccb.ccb_h.target_lun = lun;
3766 ccb.ccb_h.timeout = 5000;
3767 ccb.crcn.flags = CAM_FLAG_NONE;
3769 /* run this at a low priority */
3770 ccb.ccb_h.pinfo.priority = 5;
3773 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3774 warn("CAMIOCOMMAND ioctl failed");
3779 if (cam_send_ccb(device, &ccb) < 0) {
3780 warn("error sending XPT_RESET_DEV CCB");
3781 cam_close_device(device);
3789 cam_close_device(device);
3792 * An error code of CAM_BDR_SENT is normal for a BDR request.
3794 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3796 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3797 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3798 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3801 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3802 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3803 ccb.ccb_h.status & CAM_STATUS_MASK);
3809 static struct scsi_nv defect_list_type_map[] = {
3810 { "block", SRDD10_BLOCK_FORMAT },
3811 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3812 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3813 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3814 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3815 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3819 readdefects(struct cam_device *device, int argc, char **argv,
3820 char *combinedopt, int task_attr, int retry_count, int timeout)
3822 union ccb *ccb = NULL;
3823 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3824 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3825 size_t hdr_size = 0, entry_size = 0;
3828 u_int8_t *defect_list = NULL;
3829 u_int8_t list_format = 0;
3830 int list_type_set = 0;
3831 u_int32_t dlist_length = 0;
3832 u_int32_t returned_length = 0, valid_len = 0;
3833 u_int32_t num_returned = 0, num_valid = 0;
3834 u_int32_t max_possible_size = 0, hdr_max = 0;
3835 u_int32_t starting_offset = 0;
3836 u_int8_t returned_format, returned_type;
3838 int summary = 0, quiet = 0;
3840 int lists_specified = 0;
3841 int get_length = 1, first_pass = 1;
3844 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3848 scsi_nv_status status;
3851 status = scsi_get_nv(defect_list_type_map,
3852 sizeof(defect_list_type_map) /
3853 sizeof(defect_list_type_map[0]), optarg,
3854 &entry_num, SCSI_NV_FLAG_IG_CASE);
3856 if (status == SCSI_NV_FOUND) {
3857 list_format = defect_list_type_map[
3861 warnx("%s: %s %s option %s", __func__,
3862 (status == SCSI_NV_AMBIGUOUS) ?
3863 "ambiguous" : "invalid", "defect list type",
3866 goto defect_bailout;
3871 arglist |= CAM_ARG_GLIST;
3874 arglist |= CAM_ARG_PLIST;
3885 starting_offset = strtoul(optarg, &endptr, 0);
3886 if (*endptr != '\0') {
3888 warnx("invalid starting offset %s", optarg);
3889 goto defect_bailout;
3901 if (list_type_set == 0) {
3903 warnx("no defect list format specified");
3904 goto defect_bailout;
3907 if (arglist & CAM_ARG_PLIST) {
3908 list_format |= SRDD10_PLIST;
3912 if (arglist & CAM_ARG_GLIST) {
3913 list_format |= SRDD10_GLIST;
3918 * This implies a summary, and was the previous behavior.
3920 if (lists_specified == 0)
3923 ccb = cam_getccb(device);
3928 * We start off asking for just the header to determine how much
3929 * defect data is available. Some Hitachi drives return an error
3930 * if you ask for more data than the drive has. Once we know the
3931 * length, we retry the command with the returned length.
3933 if (use_12byte == 0)
3934 dlist_length = sizeof(*hdr10);
3936 dlist_length = sizeof(*hdr12);
3939 if (defect_list != NULL) {
3943 defect_list = malloc(dlist_length);
3944 if (defect_list == NULL) {
3945 warnx("can't malloc memory for defect list");
3947 goto defect_bailout;
3951 bzero(defect_list, dlist_length);
3954 * cam_getccb() zeros the CCB header only. So we need to zero the
3955 * payload portion of the ccb.
3957 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3959 scsi_read_defects(&ccb->csio,
3960 /*retries*/ retry_count,
3962 /*tag_action*/ task_attr,
3963 /*list_format*/ list_format,
3964 /*addr_desc_index*/ starting_offset,
3965 /*data_ptr*/ defect_list,
3966 /*dxfer_len*/ dlist_length,
3967 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3968 /*sense_len*/ SSD_FULL_SIZE,
3969 /*timeout*/ timeout ? timeout : 5000);
3971 /* Disable freezing the device queue */
3972 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3974 if (cam_send_ccb(device, ccb) < 0) {
3975 warn("error sending READ DEFECT DATA command");
3977 goto defect_bailout;
3980 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3982 if (use_12byte == 0) {
3983 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3984 hdr_size = sizeof(*hdr10);
3985 hdr_max = SRDDH10_MAX_LENGTH;
3987 if (valid_len >= hdr_size) {
3988 returned_length = scsi_2btoul(hdr10->length);
3989 returned_format = hdr10->format;
3991 returned_length = 0;
3992 returned_format = 0;
3995 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3996 hdr_size = sizeof(*hdr12);
3997 hdr_max = SRDDH12_MAX_LENGTH;
3999 if (valid_len >= hdr_size) {
4000 returned_length = scsi_4btoul(hdr12->length);
4001 returned_format = hdr12->format;
4003 returned_length = 0;
4004 returned_format = 0;
4008 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4009 switch (returned_type) {
4010 case SRDD10_BLOCK_FORMAT:
4011 entry_size = sizeof(struct scsi_defect_desc_block);
4013 case SRDD10_LONG_BLOCK_FORMAT:
4014 entry_size = sizeof(struct scsi_defect_desc_long_block);
4016 case SRDD10_EXT_PHYS_FORMAT:
4017 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4018 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4020 case SRDD10_EXT_BFI_FORMAT:
4021 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4022 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4025 warnx("Unknown defect format 0x%x\n", returned_type);
4027 goto defect_bailout;
4031 max_possible_size = (hdr_max / entry_size) * entry_size;
4032 num_returned = returned_length / entry_size;
4033 num_valid = min(returned_length, valid_len - hdr_size);
4034 num_valid /= entry_size;
4036 if (get_length != 0) {
4039 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4040 CAM_SCSI_STATUS_ERROR) {
4041 struct scsi_sense_data *sense;
4042 int error_code, sense_key, asc, ascq;
4044 sense = &ccb->csio.sense_data;
4045 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4046 ccb->csio.sense_resid, &error_code, &sense_key,
4047 &asc, &ascq, /*show_errors*/ 1);
4050 * If the drive is reporting that it just doesn't
4051 * support the defect list format, go ahead and use
4052 * the length it reported. Otherwise, the length
4053 * may not be valid, so use the maximum.
4055 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4056 && (asc == 0x1c) && (ascq == 0x00)
4057 && (returned_length > 0)) {
4058 if ((use_12byte == 0)
4059 && (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
4076 if (use_12byte == 0) {
4081 dlist_length = returned_length + hdr_size;
4082 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4083 && (asc == 0x24) && (ascq == 0x00)) {
4084 /* Invalid field in CDB */
4086 * SBC-3 says that if the drive has more
4087 * defects than can be reported with the
4088 * 10 byte command, it should return this
4089 * error and no data. Retry with the 12
4092 if (use_12byte == 0) {
4097 dlist_length = returned_length + hdr_size;
4100 * If we got a SCSI error and no valid length,
4101 * just use the 10 byte maximum. The 12
4102 * byte maximum is too large.
4104 if (returned_length == 0)
4105 dlist_length = SRDD10_MAX_LENGTH;
4107 if ((use_12byte == 0)
4108 && (returned_length >=
4109 max_possible_size)) {
4114 dlist_length = returned_length +
4118 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4121 warnx("Error reading defect header");
4122 if (arglist & CAM_ARG_VERBOSE)
4123 cam_error_print(device, ccb, CAM_ESF_ALL,
4124 CAM_EPF_ALL, stderr);
4125 goto defect_bailout;
4127 if ((use_12byte == 0)
4128 && (returned_length >= max_possible_size)) {
4133 dlist_length = returned_length + hdr_size;
4136 fprintf(stdout, "%u", num_returned);
4138 fprintf(stdout, " defect%s",
4139 (num_returned != 1) ? "s" : "");
4141 fprintf(stdout, "\n");
4143 goto defect_bailout;
4147 * We always limit the list length to the 10-byte maximum
4148 * length (0xffff). The reason is that some controllers
4149 * can't handle larger I/Os, and we can transfer the entire
4150 * 10 byte list in one shot. For drives that support the 12
4151 * byte read defects command, we'll step through the list
4152 * by specifying a starting offset. For drives that don't
4153 * support the 12 byte command's starting offset, we'll
4154 * just display the first 64K.
4156 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4162 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4163 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4164 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4165 struct scsi_sense_data *sense;
4166 int error_code, sense_key, asc, ascq;
4168 sense = &ccb->csio.sense_data;
4169 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4170 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4171 &ascq, /*show_errors*/ 1);
4174 * According to the SCSI spec, if the disk doesn't support
4175 * the requested format, it will generally return a sense
4176 * key of RECOVERED ERROR, and an additional sense code
4177 * of "DEFECT LIST NOT FOUND". HGST drives also return
4178 * Primary/Grown defect list not found errors. So just
4179 * check for an ASC of 0x1c.
4181 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4183 const char *format_str;
4185 format_str = scsi_nv_to_str(defect_list_type_map,
4186 sizeof(defect_list_type_map) /
4187 sizeof(defect_list_type_map[0]),
4188 list_format & SRDD10_DLIST_FORMAT_MASK);
4189 warnx("requested defect format %s not available",
4190 format_str ? format_str : "unknown");
4192 format_str = scsi_nv_to_str(defect_list_type_map,
4193 sizeof(defect_list_type_map) /
4194 sizeof(defect_list_type_map[0]), returned_type);
4195 if (format_str != NULL) {
4196 warnx("Device returned %s format",
4200 warnx("Device returned unknown defect"
4201 " data format %#x", returned_type);
4202 goto defect_bailout;
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;
4212 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4214 warnx("Error returned from read defect data command");
4215 if (arglist & CAM_ARG_VERBOSE)
4216 cam_error_print(device, ccb, CAM_ESF_ALL,
4217 CAM_EPF_ALL, stderr);
4218 goto defect_bailout;
4221 if (first_pass != 0) {
4222 fprintf(stderr, "Got %d defect", num_returned);
4224 if ((lists_specified == 0) || (num_returned == 0)) {
4225 fprintf(stderr, "s.\n");
4226 goto defect_bailout;
4227 } else if (num_returned == 1)
4228 fprintf(stderr, ":\n");
4230 fprintf(stderr, "s:\n");
4236 * XXX KDM I should probably clean up the printout format for the
4239 switch (returned_type) {
4240 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4241 case SRDD10_EXT_PHYS_FORMAT:
4243 struct scsi_defect_desc_phys_sector *dlist;
4245 dlist = (struct scsi_defect_desc_phys_sector *)
4246 (defect_list + hdr_size);
4248 for (i = 0; i < num_valid; i++) {
4251 sector = scsi_4btoul(dlist[i].sector);
4252 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4253 mads = (sector & SDD_EXT_PHYS_MADS) ?
4255 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4257 if (hex_format == 0)
4258 fprintf(stdout, "%d:%d:%d%s",
4259 scsi_3btoul(dlist[i].cylinder),
4261 scsi_4btoul(dlist[i].sector),
4262 mads ? " - " : "\n");
4264 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4265 scsi_3btoul(dlist[i].cylinder),
4267 scsi_4btoul(dlist[i].sector),
4268 mads ? " - " : "\n");
4271 if (num_valid < num_returned) {
4272 starting_offset += num_valid;
4277 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4278 case SRDD10_EXT_BFI_FORMAT:
4280 struct scsi_defect_desc_bytes_from_index *dlist;
4282 dlist = (struct scsi_defect_desc_bytes_from_index *)
4283 (defect_list + hdr_size);
4285 for (i = 0; i < num_valid; i++) {
4288 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4289 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4290 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4291 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4293 if (hex_format == 0)
4294 fprintf(stdout, "%d:%d:%d%s",
4295 scsi_3btoul(dlist[i].cylinder),
4297 scsi_4btoul(dlist[i].bytes_from_index),
4298 mads ? " - " : "\n");
4300 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4301 scsi_3btoul(dlist[i].cylinder),
4303 scsi_4btoul(dlist[i].bytes_from_index),
4304 mads ? " - " : "\n");
4308 if (num_valid < num_returned) {
4309 starting_offset += num_valid;
4314 case SRDDH10_BLOCK_FORMAT:
4316 struct scsi_defect_desc_block *dlist;
4318 dlist = (struct scsi_defect_desc_block *)
4319 (defect_list + hdr_size);
4321 for (i = 0; i < num_valid; i++) {
4322 if (hex_format == 0)
4323 fprintf(stdout, "%u\n",
4324 scsi_4btoul(dlist[i].address));
4326 fprintf(stdout, "0x%x\n",
4327 scsi_4btoul(dlist[i].address));
4330 if (num_valid < num_returned) {
4331 starting_offset += num_valid;
4337 case SRDD10_LONG_BLOCK_FORMAT:
4339 struct scsi_defect_desc_long_block *dlist;
4341 dlist = (struct scsi_defect_desc_long_block *)
4342 (defect_list + hdr_size);
4344 for (i = 0; i < num_valid; i++) {
4345 if (hex_format == 0)
4346 fprintf(stdout, "%ju\n",
4347 (uintmax_t)scsi_8btou64(
4350 fprintf(stdout, "0x%jx\n",
4351 (uintmax_t)scsi_8btou64(
4355 if (num_valid < num_returned) {
4356 starting_offset += num_valid;
4362 fprintf(stderr, "Unknown defect format 0x%x\n",
4369 if (defect_list != NULL)
4380 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4384 ccb = cam_getccb(device);
4391 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4392 int page, int subpage, int task_attr, int retry_count, int timeout,
4393 u_int8_t *data, int datalen)
4396 int error_code, sense_key, asc, ascq;
4398 ccb = cam_getccb(device);
4400 errx(1, "mode_sense: couldn't allocate CCB");
4404 * MODE SENSE(6) can't handle more then 255 bytes. If there are more,
4405 * device must return error, so we should not get trucated data.
4407 if (*cdb_len == 6 && datalen > 255)
4410 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4412 scsi_mode_sense_subpage(&ccb->csio,
4413 /* retries */ retry_count,
4415 /* tag_action */ task_attr,
4419 /* subpage */ subpage,
4420 /* param_buf */ data,
4421 /* param_len */ datalen,
4422 /* minimum_cmd_size */ *cdb_len,
4423 /* sense_len */ SSD_FULL_SIZE,
4424 /* timeout */ timeout ? timeout : 5000);
4425 if (llbaa && ccb->csio.cdb_len == 10) {
4426 struct scsi_mode_sense_10 *cdb =
4427 (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4428 cdb->byte2 |= SMS10_LLBAA;
4431 /* Record what CDB size the above function really set. */
4432 *cdb_len = ccb->csio.cdb_len;
4434 if (arglist & CAM_ARG_ERR_RECOVER)
4435 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4437 /* Disable freezing the device queue */
4438 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4440 if (cam_send_ccb(device, ccb) < 0)
4441 err(1, "error sending mode sense command");
4443 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4444 if (*cdb_len != 6 &&
4445 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4446 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4447 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4452 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4453 if (arglist & CAM_ARG_VERBOSE) {
4454 cam_error_print(device, ccb, CAM_ESF_ALL,
4455 CAM_EPF_ALL, stderr);
4458 cam_close_device(device);
4459 errx(1, "mode sense command returned error");
4466 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4467 int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4472 ccb = cam_getccb(device);
4475 errx(1, "mode_select: couldn't allocate CCB");
4477 scsi_mode_select_len(&ccb->csio,
4478 /* retries */ retry_count,
4480 /* tag_action */ task_attr,
4481 /* scsi_page_fmt */ 1,
4482 /* save_pages */ save_pages,
4483 /* param_buf */ data,
4484 /* param_len */ datalen,
4485 /* minimum_cmd_size */ cdb_len,
4486 /* sense_len */ SSD_FULL_SIZE,
4487 /* timeout */ timeout ? timeout : 5000);
4489 if (arglist & CAM_ARG_ERR_RECOVER)
4490 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4492 /* Disable freezing the device queue */
4493 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4495 if (((retval = cam_send_ccb(device, ccb)) < 0)
4496 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4497 if (arglist & CAM_ARG_VERBOSE) {
4498 cam_error_print(device, ccb, CAM_ESF_ALL,
4499 CAM_EPF_ALL, stderr);
4502 cam_close_device(device);
4505 err(1, "error sending mode select command");
4507 errx(1, "error sending mode select command");
4515 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4516 int task_attr, int retry_count, int timeout)
4519 int c, page = -1, subpage = 0, pc = 0, llbaa = 0;
4520 int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4522 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4540 str_subpage = optarg;
4541 strsep(&str_subpage, ",");
4542 page = strtol(optarg, NULL, 0);
4544 subpage = strtol(str_subpage, NULL, 0);
4545 if (page < 0 || page > 0x3f)
4546 errx(1, "invalid mode page %d", page);
4547 if (subpage < 0 || subpage > 0xff)
4548 errx(1, "invalid mode subpage %d", subpage);
4557 pc = strtol(optarg, NULL, 0);
4558 if ((pc < 0) || (pc > 3))
4559 errx(1, "invalid page control field %d", pc);
4566 if (desc && page == -1)
4567 page = SMS_ALL_PAGES_PAGE;
4569 if (page == -1 && list == 0)
4570 errx(1, "you must specify a mode page!");
4573 errx(1, "-d and -D are incompatible!");
4575 if (llbaa && cdb_len != 10)
4576 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4579 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4580 retry_count, timeout);
4582 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4583 edit, binary, task_attr, retry_count, timeout);
4588 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4589 int task_attr, int retry_count, int timeout)
4592 u_int32_t flags = CAM_DIR_NONE;
4593 u_int8_t *data_ptr = NULL;
4595 u_int8_t atacmd[12];
4596 struct get_hook hook;
4597 int c, data_bytes = 0, valid_bytes;
4603 char *datastr = NULL, *tstr, *resstr = NULL;
4605 int fd_data = 0, fd_res = 0;
4608 ccb = cam_getccb(device);
4611 warnx("scsicmd: error allocating ccb");
4615 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4619 while (isspace(*tstr) && (*tstr != '\0'))
4621 hook.argc = argc - optind;
4622 hook.argv = argv + optind;
4624 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4627 * Increment optind by the number of arguments the
4628 * encoding routine processed. After each call to
4629 * getopt(3), optind points to the argument that
4630 * getopt should process _next_. In this case,
4631 * that means it points to the first command string
4632 * argument, if there is one. Once we increment
4633 * this, it should point to either the next command
4634 * line argument, or it should be past the end of
4641 while (isspace(*tstr) && (*tstr != '\0'))
4643 hook.argc = argc - optind;
4644 hook.argv = argv + optind;
4646 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4649 * Increment optind by the number of arguments the
4650 * encoding routine processed. After each call to
4651 * getopt(3), optind points to the argument that
4652 * getopt should process _next_. In this case,
4653 * that means it points to the first command string
4654 * argument, if there is one. Once we increment
4655 * this, it should point to either the next command
4656 * line argument, or it should be past the end of
4668 if (arglist & CAM_ARG_CMD_OUT) {
4669 warnx("command must either be "
4670 "read or write, not both");
4672 goto scsicmd_bailout;
4674 arglist |= CAM_ARG_CMD_IN;
4676 data_bytes = strtol(optarg, NULL, 0);
4677 if (data_bytes <= 0) {
4678 warnx("invalid number of input bytes %d",
4681 goto scsicmd_bailout;
4683 hook.argc = argc - optind;
4684 hook.argv = argv + optind;
4687 datastr = cget(&hook, NULL);
4689 * If the user supplied "-" instead of a format, he
4690 * wants the data to be written to stdout.
4692 if ((datastr != NULL)
4693 && (datastr[0] == '-'))
4696 data_ptr = (u_int8_t *)malloc(data_bytes);
4697 if (data_ptr == NULL) {
4698 warnx("can't malloc memory for data_ptr");
4700 goto scsicmd_bailout;
4704 if (arglist & CAM_ARG_CMD_IN) {
4705 warnx("command must either be "
4706 "read or write, not both");
4708 goto scsicmd_bailout;
4710 arglist |= CAM_ARG_CMD_OUT;
4711 flags = CAM_DIR_OUT;
4712 data_bytes = strtol(optarg, NULL, 0);
4713 if (data_bytes <= 0) {
4714 warnx("invalid number of output bytes %d",
4717 goto scsicmd_bailout;
4719 hook.argc = argc - optind;
4720 hook.argv = argv + optind;
4722 datastr = cget(&hook, NULL);
4723 data_ptr = (u_int8_t *)malloc(data_bytes);
4724 if (data_ptr == NULL) {
4725 warnx("can't malloc memory for data_ptr");
4727 goto scsicmd_bailout;
4729 bzero(data_ptr, data_bytes);
4731 * If the user supplied "-" instead of a format, he
4732 * wants the data to be read from stdin.
4734 if ((datastr != NULL)
4735 && (datastr[0] == '-'))
4738 buff_encode_visit(data_ptr, data_bytes, datastr,
4744 hook.argc = argc - optind;
4745 hook.argv = argv + optind;
4747 resstr = cget(&hook, NULL);
4748 if ((resstr != NULL) && (resstr[0] == '-'))
4758 * If fd_data is set, and we're writing to the device, we need to
4759 * read the data the user wants written from stdin.
4761 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4763 int amt_to_read = data_bytes;
4764 u_int8_t *buf_ptr = data_ptr;
4766 for (amt_read = 0; amt_to_read > 0;
4767 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4768 if (amt_read == -1) {
4769 warn("error reading data from stdin");
4771 goto scsicmd_bailout;
4773 amt_to_read -= amt_read;
4774 buf_ptr += amt_read;
4778 if (arglist & CAM_ARG_ERR_RECOVER)
4779 flags |= CAM_PASS_ERR_RECOVER;
4781 /* Disable freezing the device queue */
4782 flags |= CAM_DEV_QFRZDIS;
4786 * This is taken from the SCSI-3 draft spec.
4787 * (T10/1157D revision 0.3)
4788 * The top 3 bits of an opcode are the group code.
4789 * The next 5 bits are the command code.
4790 * Group 0: six byte commands
4791 * Group 1: ten byte commands
4792 * Group 2: ten byte commands
4794 * Group 4: sixteen byte commands
4795 * Group 5: twelve byte commands
4796 * Group 6: vendor specific
4797 * Group 7: vendor specific
4799 switch((cdb[0] >> 5) & 0x7) {
4810 /* computed by buff_encode_visit */
4821 * We should probably use csio_build_visit or something like that
4822 * here, but it's easier to encode arguments as you go. The
4823 * alternative would be skipping the CDB argument and then encoding
4824 * it here, since we've got the data buffer argument by now.
4826 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4828 cam_fill_csio(&ccb->csio,
4829 /*retries*/ retry_count,
4832 /*tag_action*/ task_attr,
4833 /*data_ptr*/ data_ptr,
4834 /*dxfer_len*/ data_bytes,
4835 /*sense_len*/ SSD_FULL_SIZE,
4836 /*cdb_len*/ cdb_len,
4837 /*timeout*/ timeout ? timeout : 5000);
4840 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4842 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4844 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4846 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4848 cam_fill_ataio(&ccb->ataio,
4849 /*retries*/ retry_count,
4853 /*data_ptr*/ data_ptr,
4854 /*dxfer_len*/ data_bytes,
4855 /*timeout*/ timeout ? timeout : 5000);
4858 if (((retval = cam_send_ccb(device, ccb)) < 0)
4859 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4860 const char warnstr[] = "error sending command";
4867 if (arglist & CAM_ARG_VERBOSE) {
4868 cam_error_print(device, ccb, CAM_ESF_ALL,
4869 CAM_EPF_ALL, stderr);
4873 goto scsicmd_bailout;
4876 if (atacmd_len && need_res) {
4878 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4880 fprintf(stdout, "\n");
4883 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4884 ccb->ataio.res.status,
4885 ccb->ataio.res.error,
4886 ccb->ataio.res.lba_low,
4887 ccb->ataio.res.lba_mid,
4888 ccb->ataio.res.lba_high,
4889 ccb->ataio.res.device,
4890 ccb->ataio.res.lba_low_exp,
4891 ccb->ataio.res.lba_mid_exp,
4892 ccb->ataio.res.lba_high_exp,
4893 ccb->ataio.res.sector_count,
4894 ccb->ataio.res.sector_count_exp);
4900 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4902 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4903 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4904 && (arglist & CAM_ARG_CMD_IN)
4905 && (valid_bytes > 0)) {
4907 buff_decode_visit(data_ptr, valid_bytes, datastr,
4909 fprintf(stdout, "\n");
4911 ssize_t amt_written;
4912 int amt_to_write = valid_bytes;
4913 u_int8_t *buf_ptr = data_ptr;
4915 for (amt_written = 0; (amt_to_write > 0) &&
4916 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4917 amt_to_write -= amt_written;
4918 buf_ptr += amt_written;
4920 if (amt_written == -1) {
4921 warn("error writing data to stdout");
4923 goto scsicmd_bailout;
4924 } else if ((amt_written == 0)
4925 && (amt_to_write > 0)) {
4926 warnx("only wrote %u bytes out of %u",
4927 valid_bytes - amt_to_write, valid_bytes);
4934 if ((data_bytes > 0) && (data_ptr != NULL))
4943 camdebug(int argc, char **argv, char *combinedopt)
4946 path_id_t bus = CAM_BUS_WILDCARD;
4947 target_id_t target = CAM_TARGET_WILDCARD;
4948 lun_id_t lun = CAM_LUN_WILDCARD;
4953 bzero(&ccb, sizeof(union ccb));
4955 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4958 arglist |= CAM_ARG_DEBUG_INFO;
4959 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4962 arglist |= CAM_ARG_DEBUG_PERIPH;
4963 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4966 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4967 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4970 arglist |= CAM_ARG_DEBUG_TRACE;
4971 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4974 arglist |= CAM_ARG_DEBUG_XPT;
4975 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4978 arglist |= CAM_ARG_DEBUG_CDB;
4979 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4982 arglist |= CAM_ARG_DEBUG_PROBE;
4983 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4994 warnx("you must specify \"off\", \"all\" or a bus,");
4995 warnx("bus:target, bus:target:lun or periph");
5000 while (isspace(*tstr) && (*tstr != '\0'))
5003 if (strncmp(tstr, "off", 3) == 0) {
5004 ccb.cdbg.flags = CAM_DEBUG_NONE;
5005 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5006 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5007 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5009 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5011 warnx("you must specify \"all\", \"off\", or a bus,");
5012 warnx("bus:target, bus:target:lun or periph to debug");
5017 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5018 warnx("error opening transport layer device %s", XPT_DEVICE);
5019 warn("%s", XPT_DEVICE);
5023 ccb.ccb_h.func_code = XPT_DEBUG;
5024 ccb.ccb_h.path_id = bus;
5025 ccb.ccb_h.target_id = target;
5026 ccb.ccb_h.target_lun = lun;
5028 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5029 warn("CAMIOCOMMAND ioctl failed");
5032 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5033 CAM_FUNC_NOTAVAIL) {
5034 warnx("CAM debugging not available");
5035 warnx("you need to put options CAMDEBUG in"
5036 " your kernel config file!");
5038 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5040 warnx("XPT_DEBUG CCB failed with status %#x",
5044 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5046 "Debugging turned off\n");
5049 "Debugging enabled for "
5051 bus, target, (uintmax_t)lun);
5061 tagcontrol(struct cam_device *device, int argc, char **argv,
5071 ccb = cam_getccb(device);
5074 warnx("tagcontrol: error allocating ccb");
5078 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5081 numtags = strtol(optarg, NULL, 0);
5083 warnx("tag count %d is < 0", numtags);
5085 goto tagcontrol_bailout;
5096 cam_path_string(device, pathstr, sizeof(pathstr));
5099 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5100 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5101 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5102 ccb->crs.openings = numtags;
5105 if (cam_send_ccb(device, ccb) < 0) {
5106 warn("error sending XPT_REL_SIMQ CCB");
5108 goto tagcontrol_bailout;
5111 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5112 warnx("XPT_REL_SIMQ CCB failed");
5113 cam_error_print(device, ccb, CAM_ESF_ALL,
5114 CAM_EPF_ALL, stderr);
5116 goto tagcontrol_bailout;
5121 fprintf(stdout, "%stagged openings now %d\n",
5122 pathstr, ccb->crs.openings);
5125 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5127 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5129 if (cam_send_ccb(device, ccb) < 0) {
5130 warn("error sending XPT_GDEV_STATS CCB");
5132 goto tagcontrol_bailout;
5135 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5136 warnx("XPT_GDEV_STATS CCB failed");
5137 cam_error_print(device, ccb, CAM_ESF_ALL,
5138 CAM_EPF_ALL, stderr);
5140 goto tagcontrol_bailout;
5143 if (arglist & CAM_ARG_VERBOSE) {
5144 fprintf(stdout, "%s", pathstr);
5145 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5146 fprintf(stdout, "%s", pathstr);
5147 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5148 fprintf(stdout, "%s", pathstr);
5149 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5150 fprintf(stdout, "%s", pathstr);
5151 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5152 fprintf(stdout, "%s", pathstr);
5153 fprintf(stdout, "held %d\n", ccb->cgds.held);
5154 fprintf(stdout, "%s", pathstr);
5155 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5156 fprintf(stdout, "%s", pathstr);
5157 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5160 fprintf(stdout, "%s", pathstr);
5161 fprintf(stdout, "device openings: ");
5163 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5164 ccb->cgds.dev_active);
5174 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5178 cam_path_string(device, pathstr, sizeof(pathstr));
5180 if (cts->transport == XPORT_SPI) {
5181 struct ccb_trans_settings_spi *spi =
5182 &cts->xport_specific.spi;
5184 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5186 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5189 if (spi->sync_offset != 0) {
5192 freq = scsi_calc_syncsrate(spi->sync_period);
5193 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5194 pathstr, freq / 1000, freq % 1000);
5198 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5199 fprintf(stdout, "%soffset: %d\n", pathstr,
5203 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5204 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5205 (0x01 << spi->bus_width) * 8);
5208 if (spi->valid & CTS_SPI_VALID_DISC) {
5209 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5210 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5211 "enabled" : "disabled");
5214 if (cts->transport == XPORT_FC) {
5215 struct ccb_trans_settings_fc *fc =
5216 &cts->xport_specific.fc;
5218 if (fc->valid & CTS_FC_VALID_WWNN)
5219 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5220 (long long) fc->wwnn);
5221 if (fc->valid & CTS_FC_VALID_WWPN)
5222 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5223 (long long) fc->wwpn);
5224 if (fc->valid & CTS_FC_VALID_PORT)
5225 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5226 if (fc->valid & CTS_FC_VALID_SPEED)
5227 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5228 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5230 if (cts->transport == XPORT_SAS) {
5231 struct ccb_trans_settings_sas *sas =
5232 &cts->xport_specific.sas;
5234 if (sas->valid & CTS_SAS_VALID_SPEED)
5235 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5236 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5238 if (cts->transport == XPORT_ATA) {
5239 struct ccb_trans_settings_pata *pata =
5240 &cts->xport_specific.ata;
5242 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5243 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5244 ata_mode2string(pata->mode));
5246 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5247 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5250 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5251 fprintf(stdout, "%sPIO transaction length: %d\n",
5252 pathstr, pata->bytecount);
5255 if (cts->transport == XPORT_SATA) {
5256 struct ccb_trans_settings_sata *sata =
5257 &cts->xport_specific.sata;
5259 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5260 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5263 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5264 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5265 ata_mode2string(sata->mode));
5267 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5268 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5271 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5272 fprintf(stdout, "%sPIO transaction length: %d\n",
5273 pathstr, sata->bytecount);
5275 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5276 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5279 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5280 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5283 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5284 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5288 if (cts->protocol == PROTO_ATA) {
5289 struct ccb_trans_settings_ata *ata=
5290 &cts->proto_specific.ata;
5292 if (ata->valid & CTS_ATA_VALID_TQ) {
5293 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5294 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5295 "enabled" : "disabled");
5298 if (cts->protocol == PROTO_SCSI) {
5299 struct ccb_trans_settings_scsi *scsi=
5300 &cts->proto_specific.scsi;
5302 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5303 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5304 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5305 "enabled" : "disabled");
5309 if (cts->protocol == PROTO_NVME) {
5310 struct ccb_trans_settings_nvme *nvmex =
5311 &cts->xport_specific.nvme;
5313 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5314 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5315 NVME_MAJOR(nvmex->spec),
5316 NVME_MINOR(nvmex->spec));
5318 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5319 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5320 nvmex->lanes, nvmex->max_lanes);
5321 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5322 nvmex->speed, nvmex->max_speed);
5329 * Get a path inquiry CCB for the specified device.
5332 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5337 ccb = cam_getccb(device);
5339 warnx("get_cpi: couldn't allocate CCB");
5342 ccb->ccb_h.func_code = XPT_PATH_INQ;
5343 if (cam_send_ccb(device, ccb) < 0) {
5344 warn("get_cpi: error sending Path Inquiry CCB");
5346 goto get_cpi_bailout;
5348 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5349 if (arglist & CAM_ARG_VERBOSE)
5350 cam_error_print(device, ccb, CAM_ESF_ALL,
5351 CAM_EPF_ALL, stderr);
5353 goto get_cpi_bailout;
5355 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5363 * Get a get device CCB for the specified device.
5366 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5371 ccb = cam_getccb(device);
5373 warnx("get_cgd: couldn't allocate CCB");
5376 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5377 if (cam_send_ccb(device, ccb) < 0) {
5378 warn("get_cgd: error sending Get type information CCB");
5380 goto get_cgd_bailout;
5382 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5383 if (arglist & CAM_ARG_VERBOSE)
5384 cam_error_print(device, ccb, CAM_ESF_ALL,
5385 CAM_EPF_ALL, stderr);
5387 goto get_cgd_bailout;
5389 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5397 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5401 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5402 int timeout, int verbosemode)
5404 union ccb *ccb = NULL;
5405 struct scsi_vpd_supported_page_list sup_pages;
5409 ccb = cam_getccb(dev);
5411 warn("Unable to allocate CCB");
5416 bzero(&sup_pages, sizeof(sup_pages));
5418 scsi_inquiry(&ccb->csio,
5419 /*retries*/ retry_count,
5421 /* tag_action */ MSG_SIMPLE_Q_TAG,
5422 /* inq_buf */ (u_int8_t *)&sup_pages,
5423 /* inq_len */ sizeof(sup_pages),
5425 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5426 /* sense_len */ SSD_FULL_SIZE,
5427 /* timeout */ timeout ? timeout : 5000);
5429 /* Disable freezing the device queue */
5430 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5432 if (retry_count != 0)
5433 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5435 if (cam_send_ccb(dev, ccb) < 0) {
5442 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5443 if (verbosemode != 0)
5444 cam_error_print(dev, ccb, CAM_ESF_ALL,
5445 CAM_EPF_ALL, stderr);
5450 for (i = 0; i < sup_pages.length; i++) {
5451 if (sup_pages.list[i] == page_id) {
5464 * devtype is filled in with the type of device.
5465 * Returns 0 for success, non-zero for failure.
5468 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5469 int verbosemode, camcontrol_devtype *devtype)
5471 struct ccb_getdev cgd;
5474 retval = get_cgd(dev, &cgd);
5478 switch (cgd.protocol) {
5484 *devtype = CC_DT_ATA;
5486 break; /*NOTREACHED*/
5488 *devtype = CC_DT_NVME;
5490 break; /*NOTREACHED*/
5492 *devtype = CC_DT_MMCSD;
5494 break; /*NOTREACHED*/
5496 *devtype = CC_DT_UNKNOWN;
5498 break; /*NOTREACHED*/
5501 if (retry_count == -1) {
5503 * For a retry count of -1, used only the cached data to avoid
5504 * I/O to the drive. Sending the identify command to the drive
5505 * can cause issues for SATL attachaed drives since identify is
5506 * not an NCQ command. We check for the strings that windows
5507 * displays since those will not be NULs (they are supposed
5508 * to be space padded). We could check other bits, but anything
5509 * non-zero implies SATL.
5511 if (cgd.ident_data.serial[0] != 0 ||
5512 cgd.ident_data.revision[0] != 0 ||
5513 cgd.ident_data.model[0] != 0)
5514 *devtype = CC_DT_SATL;
5516 *devtype = CC_DT_SCSI;
5519 * Check for the ATA Information VPD page (0x89). If this is an
5520 * ATA device behind a SCSI to ATA translation layer (SATL),
5521 * this VPD page should be present.
5523 * If that VPD page isn't present, or we get an error back from
5524 * the INQUIRY command, we'll just treat it as a normal SCSI
5527 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5528 timeout, verbosemode);
5530 *devtype = CC_DT_SATL;
5532 *devtype = CC_DT_SCSI;
5541 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5542 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5543 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5544 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5545 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5546 int is48bit, camcontrol_devtype devtype)
5550 if (devtype == CC_DT_ATA) {
5551 cam_fill_ataio(&ccb->ataio,
5552 /*retries*/ retry_count,
5555 /*tag_action*/ tag_action,
5556 /*data_ptr*/ data_ptr,
5557 /*dxfer_len*/ dxfer_len,
5558 /*timeout*/ timeout);
5559 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5560 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5563 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5566 if (auxiliary != 0) {
5567 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5568 ccb->ataio.aux = auxiliary;
5571 if (ata_flags & AP_FLAG_CHK_COND)
5572 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5574 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5575 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5576 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5577 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5579 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5580 protocol |= AP_EXTEND;
5582 retval = scsi_ata_pass(&ccb->csio,
5583 /*retries*/ retry_count,
5586 /*tag_action*/ tag_action,
5587 /*protocol*/ protocol,
5588 /*ata_flags*/ ata_flags,
5589 /*features*/ features,
5590 /*sector_count*/ sector_count,
5592 /*command*/ command,
5595 /*auxiliary*/ auxiliary,
5597 /*data_ptr*/ data_ptr,
5598 /*dxfer_len*/ dxfer_len,
5599 /*cdb_storage*/ cdb_storage,
5600 /*cdb_storage_len*/ cdb_storage_len,
5601 /*minimum_cmd_size*/ 0,
5602 /*sense_len*/ sense_len,
5603 /*timeout*/ timeout);
5610 * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5611 * 4 -- count truncated, 6 -- lba and count truncated.
5614 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5615 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5619 switch (ccb->ccb_h.func_code) {
5622 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5626 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5627 * or 16 byte, and need to see what
5629 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5630 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5632 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5633 if ((opcode != ATA_PASS_12)
5634 && (opcode != ATA_PASS_16)) {
5635 warnx("%s: unsupported opcode %02x", __func__, opcode);
5639 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5641 /* Note: the _ccb() variant returns 0 for an error */
5645 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5646 switch (error_code) {
5647 case SSD_DESC_CURRENT_ERROR:
5648 case SSD_DESC_DEFERRED_ERROR: {
5649 struct scsi_sense_data_desc *sense;
5650 struct scsi_sense_ata_ret_desc *desc;
5653 sense = (struct scsi_sense_data_desc *)
5654 &ccb->csio.sense_data;
5656 desc_ptr = scsi_find_desc(sense, sense_len,
5658 if (desc_ptr == NULL) {
5659 cam_error_print(dev, ccb, CAM_ESF_ALL,
5660 CAM_EPF_ALL, stderr);
5663 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5665 *error = desc->error;
5666 *count = (desc->count_15_8 << 8) |
5668 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5669 ((uint64_t)desc->lba_39_32 << 32) |
5670 ((uint64_t)desc->lba_31_24 << 24) |
5671 (desc->lba_23_16 << 16) |
5672 (desc->lba_15_8 << 8) |
5674 *device = desc->device;
5675 *status = desc->status;
5678 * If the extend bit isn't set, the result is for a
5679 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5680 * command without the extend bit set. This means
5681 * that the device is supposed to return 28-bit
5682 * status. The count field is only 8 bits, and the
5683 * LBA field is only 8 bits.
5685 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5691 case SSD_CURRENT_ERROR:
5692 case SSD_DEFERRED_ERROR: {
5696 * In my understanding of SAT-5 specification, saying:
5697 * "without interpreting the contents of the STATUS",
5698 * this should not happen if CK_COND was set, but it
5699 * does at least for some devices, so try to revert.
5701 if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5702 (asc == 0) && (ascq == 0)) {
5703 *status = ATA_STATUS_ERROR;
5704 *error = ATA_ERROR_ABORT;
5711 if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5712 (asc != 0x00) || (ascq != 0x1d))
5716 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5717 SSD_DESC_INFO, &val, NULL);
5718 *error = (val >> 24) & 0xff;
5719 *status = (val >> 16) & 0xff;
5720 *device = (val >> 8) & 0xff;
5721 *count = val & 0xff;
5724 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5725 SSD_DESC_COMMAND, &val, NULL);
5726 *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5727 ((val & 0xff) << 16);
5729 /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5730 return ((val >> 28) & 0x06);
5739 struct ata_res *res;
5741 /* Only some statuses return ATA result register set. */
5742 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5743 cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5746 res = &ccb->ataio.res;
5747 *error = res->error;
5748 *status = res->status;
5749 *device = res->device;
5750 *count = res->sector_count;
5751 *lba = (res->lba_high << 16) |
5752 (res->lba_mid << 8) |
5754 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5755 *count |= (res->sector_count_exp << 8);
5756 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5757 ((uint64_t)res->lba_mid_exp << 32) |
5758 ((uint64_t)res->lba_high_exp << 40);
5760 *lba |= (res->device & 0xf) << 24;
5771 cpi_print(struct ccb_pathinq *cpi)
5773 char adapter_str[1024];
5776 snprintf(adapter_str, sizeof(adapter_str),
5777 "%s%d:", cpi->dev_name, cpi->unit_number);
5779 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5782 for (i = 1; i < UINT8_MAX; i = i << 1) {
5785 if ((i & cpi->hba_inquiry) == 0)
5788 fprintf(stdout, "%s supports ", adapter_str);
5792 str = "MDP message";
5795 str = "32 bit wide SCSI";
5798 str = "16 bit wide SCSI";
5801 str = "SDTR message";
5804 str = "linked CDBs";
5807 str = "tag queue messages";
5810 str = "soft reset alternative";
5813 str = "SATA Port Multiplier";
5816 str = "unknown PI bit set";
5819 fprintf(stdout, "%s\n", str);
5822 for (i = 1; i < UINT32_MAX; i = i << 1) {
5825 if ((i & cpi->hba_misc) == 0)
5828 fprintf(stdout, "%s ", adapter_str);
5832 str = "can understand ata_ext requests";
5835 str = "64bit extended LUNs supported";
5838 str = "bus scans from high ID to low ID";
5841 str = "removable devices not included in scan";
5843 case PIM_NOINITIATOR:
5844 str = "initiator role not supported";
5846 case PIM_NOBUSRESET:
5847 str = "user has disabled initial BUS RESET or"
5848 " controller is in target/mixed mode";
5851 str = "do not send 6-byte commands";
5854 str = "scan bus sequentially";
5857 str = "unmapped I/O supported";
5860 str = "does its own scanning";
5863 str = "unknown PIM bit set";
5866 fprintf(stdout, "%s\n", str);
5869 for (i = 1; i < UINT16_MAX; i = i << 1) {
5872 if ((i & cpi->target_sprt) == 0)
5875 fprintf(stdout, "%s supports ", adapter_str);
5878 str = "target mode processor mode";
5881 str = "target mode phase cog. mode";
5883 case PIT_DISCONNECT:
5884 str = "disconnects in target mode";
5887 str = "terminate I/O message in target mode";
5890 str = "group 6 commands in target mode";
5893 str = "group 7 commands in target mode";
5896 str = "unknown PIT bit set";
5900 fprintf(stdout, "%s\n", str);
5902 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5904 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5906 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5908 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5909 adapter_str, cpi->hpath_id);
5910 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5912 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5913 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5914 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5915 adapter_str, cpi->hba_vendor);
5916 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5917 adapter_str, cpi->hba_device);
5918 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5919 adapter_str, cpi->hba_subvendor);
5920 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5921 adapter_str, cpi->hba_subdevice);
5922 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5923 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5924 if (cpi->base_transfer_speed > 1000)
5925 fprintf(stdout, "%d.%03dMB/sec\n",
5926 cpi->base_transfer_speed / 1000,
5927 cpi->base_transfer_speed % 1000);
5929 fprintf(stdout, "%dKB/sec\n",
5930 (cpi->base_transfer_speed % 1000) * 1000);
5931 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5932 adapter_str, cpi->maxio);
5936 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5937 struct ccb_trans_settings *cts)
5943 ccb = cam_getccb(device);
5946 warnx("get_print_cts: error allocating ccb");
5950 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5952 if (user_settings == 0)
5953 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5955 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5957 if (cam_send_ccb(device, ccb) < 0) {
5958 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
5960 goto get_print_cts_bailout;
5963 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5964 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5965 if (arglist & CAM_ARG_VERBOSE)
5966 cam_error_print(device, ccb, CAM_ESF_ALL,
5967 CAM_EPF_ALL, stderr);
5969 goto get_print_cts_bailout;
5973 cts_print(device, &ccb->cts);
5976 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5978 get_print_cts_bailout:
5986 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5987 int timeout, int argc, char **argv, char *combinedopt)
5991 int user_settings = 0;
5993 int disc_enable = -1, tag_enable = -1;
5996 double syncrate = -1;
5999 int change_settings = 0, send_tur = 0;
6000 struct ccb_pathinq cpi;
6002 ccb = cam_getccb(device);
6004 warnx("ratecontrol: error allocating ccb");
6007 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6016 if (strncasecmp(optarg, "enable", 6) == 0)
6018 else if (strncasecmp(optarg, "disable", 7) == 0)
6021 warnx("-D argument \"%s\" is unknown", optarg);
6023 goto ratecontrol_bailout;
6025 change_settings = 1;
6028 mode = ata_string2mode(optarg);
6030 warnx("unknown mode '%s'", optarg);
6032 goto ratecontrol_bailout;
6034 change_settings = 1;
6037 offset = strtol(optarg, NULL, 0);
6039 warnx("offset value %d is < 0", offset);
6041 goto ratecontrol_bailout;
6043 change_settings = 1;
6049 syncrate = atof(optarg);
6051 warnx("sync rate %f is < 0", syncrate);
6053 goto ratecontrol_bailout;
6055 change_settings = 1;
6058 if (strncasecmp(optarg, "enable", 6) == 0)
6060 else if (strncasecmp(optarg, "disable", 7) == 0)
6063 warnx("-T argument \"%s\" is unknown", optarg);
6065 goto ratecontrol_bailout;
6067 change_settings = 1;
6073 bus_width = strtol(optarg, NULL, 0);
6074 if (bus_width < 0) {
6075 warnx("bus width %d is < 0", bus_width);
6077 goto ratecontrol_bailout;
6079 change_settings = 1;
6086 * Grab path inquiry information, so we can determine whether
6087 * or not the initiator is capable of the things that the user
6090 if ((retval = get_cpi(device, &cpi)) != 0)
6091 goto ratecontrol_bailout;
6093 fprintf(stdout, "%s parameters:\n",
6094 user_settings ? "User" : "Current");
6096 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6098 goto ratecontrol_bailout;
6100 if (arglist & CAM_ARG_VERBOSE)
6103 if (change_settings) {
6104 int didsettings = 0;
6105 struct ccb_trans_settings_spi *spi = NULL;
6106 struct ccb_trans_settings_pata *pata = NULL;
6107 struct ccb_trans_settings_sata *sata = NULL;
6108 struct ccb_trans_settings_ata *ata = NULL;
6109 struct ccb_trans_settings_scsi *scsi = NULL;
6111 if (ccb->cts.transport == XPORT_SPI)
6112 spi = &ccb->cts.xport_specific.spi;
6113 if (ccb->cts.transport == XPORT_ATA)
6114 pata = &ccb->cts.xport_specific.ata;
6115 if (ccb->cts.transport == XPORT_SATA)
6116 sata = &ccb->cts.xport_specific.sata;
6117 if (ccb->cts.protocol == PROTO_ATA)
6118 ata = &ccb->cts.proto_specific.ata;
6119 if (ccb->cts.protocol == PROTO_SCSI)
6120 scsi = &ccb->cts.proto_specific.scsi;
6121 ccb->cts.xport_specific.valid = 0;
6122 ccb->cts.proto_specific.valid = 0;
6123 if (spi && disc_enable != -1) {
6124 spi->valid |= CTS_SPI_VALID_DISC;
6125 if (disc_enable == 0)
6126 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6128 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6131 if (tag_enable != -1) {
6132 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6133 warnx("HBA does not support tagged queueing, "
6134 "so you cannot modify tag settings");
6136 goto ratecontrol_bailout;
6139 ata->valid |= CTS_SCSI_VALID_TQ;
6140 if (tag_enable == 0)
6141 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6143 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6146 scsi->valid |= CTS_SCSI_VALID_TQ;
6147 if (tag_enable == 0)
6148 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6150 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6154 if (spi && offset != -1) {
6155 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6156 warnx("HBA is not capable of changing offset");
6158 goto ratecontrol_bailout;
6160 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6161 spi->sync_offset = offset;
6164 if (spi && syncrate != -1) {
6165 int prelim_sync_period;
6167 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6168 warnx("HBA is not capable of changing "
6171 goto ratecontrol_bailout;
6173 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6175 * The sync rate the user gives us is in MHz.
6176 * We need to translate it into KHz for this
6181 * Next, we calculate a "preliminary" sync period
6182 * in tenths of a nanosecond.
6185 prelim_sync_period = 0;
6187 prelim_sync_period = 10000000 / syncrate;
6189 scsi_calc_syncparam(prelim_sync_period);
6192 if (sata && syncrate != -1) {
6193 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6194 warnx("HBA is not capable of changing "
6197 goto ratecontrol_bailout;
6199 if (!user_settings) {
6200 warnx("You can modify only user rate "
6201 "settings for SATA");
6203 goto ratecontrol_bailout;
6205 sata->revision = ata_speed2revision(syncrate * 100);
6206 if (sata->revision < 0) {
6207 warnx("Invalid rate %f", syncrate);
6209 goto ratecontrol_bailout;
6211 sata->valid |= CTS_SATA_VALID_REVISION;
6214 if ((pata || sata) && mode != -1) {
6215 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6216 warnx("HBA is not capable of changing "
6219 goto ratecontrol_bailout;
6221 if (!user_settings) {
6222 warnx("You can modify only user mode "
6223 "settings for ATA/SATA");
6225 goto ratecontrol_bailout;
6229 pata->valid |= CTS_ATA_VALID_MODE;
6232 sata->valid |= CTS_SATA_VALID_MODE;
6237 * The bus_width argument goes like this:
6241 * Therefore, if you shift the number of bits given on the
6242 * command line right by 4, you should get the correct
6245 if (spi && bus_width != -1) {
6247 * We might as well validate things here with a
6248 * decipherable error message, rather than what
6249 * will probably be an indecipherable error message
6250 * by the time it gets back to us.
6252 if ((bus_width == 16)
6253 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6254 warnx("HBA does not support 16 bit bus width");
6256 goto ratecontrol_bailout;
6257 } else if ((bus_width == 32)
6258 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6259 warnx("HBA does not support 32 bit bus width");
6261 goto ratecontrol_bailout;
6262 } else if ((bus_width != 8)
6263 && (bus_width != 16)
6264 && (bus_width != 32)) {
6265 warnx("Invalid bus width %d", bus_width);
6267 goto ratecontrol_bailout;
6269 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6270 spi->bus_width = bus_width >> 4;
6273 if (didsettings == 0) {
6274 goto ratecontrol_bailout;
6276 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6277 if (cam_send_ccb(device, ccb) < 0) {
6278 warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6280 goto ratecontrol_bailout;
6282 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6283 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6284 if (arglist & CAM_ARG_VERBOSE) {
6285 cam_error_print(device, ccb, CAM_ESF_ALL,
6286 CAM_EPF_ALL, stderr);
6289 goto ratecontrol_bailout;
6293 retval = testunitready(device, task_attr, retry_count, timeout,
6294 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6296 * If the TUR didn't succeed, just bail.
6300 fprintf(stderr, "Test Unit Ready failed\n");
6301 goto ratecontrol_bailout;
6304 if ((change_settings || send_tur) && !quiet &&
6305 (ccb->cts.transport == XPORT_ATA ||
6306 ccb->cts.transport == XPORT_SATA || send_tur)) {
6307 fprintf(stdout, "New parameters:\n");
6308 retval = get_print_cts(device, user_settings, 0, NULL);
6311 ratecontrol_bailout:
6317 scsiformat(struct cam_device *device, int argc, char **argv,
6318 char *combinedopt, int task_attr, int retry_count, int timeout)
6322 int ycount = 0, quiet = 0;
6323 int error = 0, retval = 0;
6324 int use_timeout = 10800 * 1000;
6326 struct format_defect_list_header fh;
6327 u_int8_t *data_ptr = NULL;
6328 u_int32_t dxfer_len = 0;
6330 int num_warnings = 0;
6333 ccb = cam_getccb(device);
6336 warnx("scsiformat: error allocating ccb");
6340 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6360 if (quiet == 0 && ycount == 0) {
6361 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6362 "following device:\n");
6364 error = scsidoinquiry(device, argc, argv, combinedopt,
6365 task_attr, retry_count, timeout);
6368 warnx("scsiformat: error sending inquiry");
6369 goto scsiformat_bailout;
6374 if (!get_confirmation()) {
6376 goto scsiformat_bailout;
6381 use_timeout = timeout;
6384 fprintf(stdout, "Current format timeout is %d seconds\n",
6385 use_timeout / 1000);
6389 * If the user hasn't disabled questions and didn't specify a
6390 * timeout on the command line, ask them if they want the current
6394 && (timeout == 0)) {
6396 int new_timeout = 0;
6398 fprintf(stdout, "Enter new timeout in seconds or press\n"
6399 "return to keep the current timeout [%d] ",
6400 use_timeout / 1000);
6402 if (fgets(str, sizeof(str), stdin) != NULL) {
6404 new_timeout = atoi(str);
6407 if (new_timeout != 0) {
6408 use_timeout = new_timeout * 1000;
6409 fprintf(stdout, "Using new timeout value %d\n",
6410 use_timeout / 1000);
6415 * Keep this outside the if block below to silence any unused
6416 * variable warnings.
6418 bzero(&fh, sizeof(fh));
6421 * If we're in immediate mode, we've got to include the format
6424 if (immediate != 0) {
6425 fh.byte2 = FU_DLH_IMMED;
6426 data_ptr = (u_int8_t *)&fh;
6427 dxfer_len = sizeof(fh);
6428 byte2 = FU_FMT_DATA;
6429 } else if (quiet == 0) {
6430 fprintf(stdout, "Formatting...");
6434 scsi_format_unit(&ccb->csio,
6435 /* retries */ retry_count,
6437 /* tag_action */ task_attr,
6440 /* data_ptr */ data_ptr,
6441 /* dxfer_len */ dxfer_len,
6442 /* sense_len */ SSD_FULL_SIZE,
6443 /* timeout */ use_timeout);
6445 /* Disable freezing the device queue */
6446 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6448 if (arglist & CAM_ARG_ERR_RECOVER)
6449 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6451 if (((retval = cam_send_ccb(device, ccb)) < 0)
6452 || ((immediate == 0)
6453 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6454 const char errstr[] = "error sending format command";
6461 if (arglist & CAM_ARG_VERBOSE) {
6462 cam_error_print(device, ccb, CAM_ESF_ALL,
6463 CAM_EPF_ALL, stderr);
6466 goto scsiformat_bailout;
6470 * If we ran in non-immediate mode, we already checked for errors
6471 * above and printed out any necessary information. If we're in
6472 * immediate mode, we need to loop through and get status
6473 * information periodically.
6475 if (immediate == 0) {
6477 fprintf(stdout, "Format Complete\n");
6479 goto scsiformat_bailout;
6486 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6489 * There's really no need to do error recovery or
6490 * retries here, since we're just going to sit in a
6491 * loop and wait for the device to finish formatting.
6493 scsi_test_unit_ready(&ccb->csio,
6496 /* tag_action */ task_attr,
6497 /* sense_len */ SSD_FULL_SIZE,
6498 /* timeout */ 5000);
6500 /* Disable freezing the device queue */
6501 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6503 retval = cam_send_ccb(device, ccb);
6506 * If we get an error from the ioctl, bail out. SCSI
6507 * errors are expected.
6510 warn("error sending TEST UNIT READY command");
6512 goto scsiformat_bailout;
6515 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6517 if ((status != CAM_REQ_CMP)
6518 && (status == CAM_SCSI_STATUS_ERROR)
6519 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6520 struct scsi_sense_data *sense;
6521 int error_code, sense_key, asc, ascq;
6523 sense = &ccb->csio.sense_data;
6524 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6525 ccb->csio.sense_resid, &error_code, &sense_key,
6526 &asc, &ascq, /*show_errors*/ 1);
6529 * According to the SCSI-2 and SCSI-3 specs, a
6530 * drive that is in the middle of a format should
6531 * return NOT READY with an ASC of "logical unit
6532 * not ready, format in progress". The sense key
6533 * specific bytes will then be a progress indicator.
6535 if ((sense_key == SSD_KEY_NOT_READY)
6536 && (asc == 0x04) && (ascq == 0x04)) {
6539 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6540 ccb->csio.sense_resid, sks) == 0)
6543 u_int64_t percentage;
6545 val = scsi_2btoul(&sks[1]);
6546 percentage = 10000ull * val;
6549 "\rFormatting: %ju.%02u %% "
6551 (uintmax_t)(percentage /
6553 (unsigned)((percentage /
6557 } else if ((quiet == 0)
6558 && (++num_warnings <= 1)) {
6559 warnx("Unexpected SCSI Sense Key "
6560 "Specific value returned "
6562 scsi_sense_print(device, &ccb->csio,
6564 warnx("Unable to print status "
6565 "information, but format will "
6567 warnx("will exit when format is "
6572 warnx("Unexpected SCSI error during format");
6573 cam_error_print(device, ccb, CAM_ESF_ALL,
6574 CAM_EPF_ALL, stderr);
6576 goto scsiformat_bailout;
6579 } else if (status != CAM_REQ_CMP) {
6580 warnx("Unexpected CAM status %#x", status);
6581 if (arglist & CAM_ARG_VERBOSE)
6582 cam_error_print(device, ccb, CAM_ESF_ALL,
6583 CAM_EPF_ALL, stderr);
6585 goto scsiformat_bailout;
6588 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6591 fprintf(stdout, "\nFormat Complete\n");
6601 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6602 camcontrol_devtype devtype)
6605 uint8_t error = 0, ata_device = 0, status = 0;
6611 retval = build_ata_cmd(ccb,
6613 /*flags*/ CAM_DIR_NONE,
6614 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6615 /*protocol*/ AP_PROTO_NON_DATA,
6616 /*ata_flags*/ AP_FLAG_CHK_COND,
6617 /*features*/ 0x00, /* SANITIZE STATUS EXT */
6620 /*command*/ ATA_SANITIZE,
6624 /*cdb_storage*/ NULL,
6625 /*cdb_storage_len*/ 0,
6626 /*sense_len*/ SSD_FULL_SIZE,
6629 /*devtype*/ devtype);
6631 warnx("%s: build_ata_cmd() failed, likely "
6632 "programmer error", __func__);
6636 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6637 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6638 retval = cam_send_ccb(device, ccb);
6640 warn("error sending SANITIZE STATUS EXT command");
6644 retval = get_ata_status(device, ccb, &error, &count, &lba,
6645 &ata_device, &status);
6647 warnx("Can't get SANITIZE STATUS EXT status, "
6648 "sanitize may still run.");
6651 if (status & ATA_STATUS_ERROR) {
6652 if (error & ATA_ERROR_ABORT) {
6653 switch (lba & 0xff) {
6655 warnx("Reason not reported or sanitize failed.");
6658 warnx("Sanitize command unsuccessful. ");
6661 warnx("Unsupported sanitize device command. ");
6664 warnx("Device is in sanitize frozen state. ");
6667 warnx("Sanitize antifreeze lock is enabled. ");
6671 warnx("SANITIZE STATUS EXT failed, "
6672 "sanitize may still run.");
6675 if (count & 0x4000) {
6680 "Sanitizing: %u.%02u%% (%d/%d)\r",
6681 (perc / (0x10000 * 100)),
6682 ((perc / 0x10000) % 100),
6694 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6696 int warnings = 0, retval;
6701 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6704 * There's really no need to do error recovery or
6705 * retries here, since we're just going to sit in a
6706 * loop and wait for the device to finish sanitizing.
6708 scsi_test_unit_ready(&ccb->csio,
6711 /* tag_action */ task_attr,
6712 /* sense_len */ SSD_FULL_SIZE,
6713 /* timeout */ 5000);
6715 /* Disable freezing the device queue */
6716 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6718 retval = cam_send_ccb(device, ccb);
6721 * If we get an error from the ioctl, bail out. SCSI
6722 * errors are expected.
6725 warn("error sending TEST UNIT READY command");
6729 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6730 if ((status == CAM_SCSI_STATUS_ERROR) &&
6731 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6732 struct scsi_sense_data *sense;
6733 int error_code, sense_key, asc, ascq;
6735 sense = &ccb->csio.sense_data;
6736 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6737 ccb->csio.sense_resid, &error_code, &sense_key,
6738 &asc, &ascq, /*show_errors*/ 1);
6741 * According to the SCSI-3 spec, a drive that is in the
6742 * middle of a sanitize should return NOT READY with an
6743 * ASC of "logical unit not ready, sanitize in
6744 * progress". The sense key specific bytes will then
6745 * be a progress indicator.
6747 if ((sense_key == SSD_KEY_NOT_READY)
6748 && (asc == 0x04) && (ascq == 0x1b)) {
6751 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6752 ccb->csio.sense_resid, sks) == 0)
6754 val = scsi_2btoul(&sks[1]);
6757 "Sanitizing: %u.%02u%% (%d/%d)\r",
6758 (perc / (0x10000 * 100)),
6759 ((perc / 0x10000) % 100),
6762 } else if ((quiet == 0) && (++warnings <= 1)) {
6763 warnx("Unexpected SCSI Sense Key "
6764 "Specific value returned "
6765 "during sanitize:");
6766 scsi_sense_print(device, &ccb->csio,
6768 warnx("Unable to print status "
6769 "information, but sanitze will "
6771 warnx("will exit when sanitize is "
6776 warnx("Unexpected SCSI error during sanitize");
6777 cam_error_print(device, ccb, CAM_ESF_ALL,
6778 CAM_EPF_ALL, stderr);
6782 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6783 warnx("Unexpected CAM status %#x", status);
6784 if (arglist & CAM_ARG_VERBOSE)
6785 cam_error_print(device, ccb, CAM_ESF_ALL,
6786 CAM_EPF_ALL, stderr);
6789 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6794 sanitize(struct cam_device *device, int argc, char **argv,
6795 char *combinedopt, int task_attr, int retry_count, int timeout)
6798 u_int8_t action = 0;
6800 int ycount = 0, quiet = 0;
6808 const char *pattern = NULL;
6809 u_int8_t *data_ptr = NULL;
6810 u_int32_t dxfer_len = 0;
6812 uint16_t feature, count;
6815 camcontrol_devtype dt;
6818 * Get the device type, request no I/O be done to do this.
6820 error = get_device_type(device, -1, 0, 0, &dt);
6821 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6822 warnx("sanitize: can't get device type");
6826 ccb = cam_getccb(device);
6829 warnx("sanitize: error allocating ccb");
6833 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6836 if (strcasecmp(optarg, "overwrite") == 0)
6837 action = SSZ_SERVICE_ACTION_OVERWRITE;
6838 else if (strcasecmp(optarg, "block") == 0)
6839 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6840 else if (strcasecmp(optarg, "crypto") == 0)
6841 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6842 else if (strcasecmp(optarg, "exitfailure") == 0)
6843 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6845 warnx("invalid service operation \"%s\"",
6848 goto sanitize_bailout;
6852 passes = strtol(optarg, NULL, 0);
6853 if (passes < 1 || passes > 31) {
6854 warnx("invalid passes value %d", passes);
6856 goto sanitize_bailout;
6875 /* ATA supports only immediate commands. */
6876 if (dt == CC_DT_SCSI)
6889 warnx("an action is required");
6891 goto sanitize_bailout;
6892 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6893 struct scsi_sanitize_parameter_list *pl;
6897 if (pattern == NULL) {
6898 warnx("overwrite action requires -P argument");
6900 goto sanitize_bailout;
6902 fd = open(pattern, O_RDONLY);
6904 warn("cannot open pattern file %s", pattern);
6906 goto sanitize_bailout;
6908 if (fstat(fd, &sb) < 0) {
6909 warn("cannot stat pattern file %s", pattern);
6911 goto sanitize_bailout;
6914 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6915 warnx("pattern file size exceeds maximum value %d",
6916 SSZPL_MAX_PATTERN_LENGTH);
6918 goto sanitize_bailout;
6920 dxfer_len = sizeof(*pl) + sz;
6921 data_ptr = calloc(1, dxfer_len);
6922 if (data_ptr == NULL) {
6923 warnx("cannot allocate parameter list buffer");
6925 goto sanitize_bailout;
6928 amt = read(fd, data_ptr + sizeof(*pl), sz);
6930 warn("cannot read pattern file");
6932 goto sanitize_bailout;
6933 } else if (amt != sz) {
6934 warnx("short pattern file read");
6936 goto sanitize_bailout;
6939 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6945 pl->byte1 |= SSZPL_INVERT;
6946 scsi_ulto2b(sz, pl->length);
6952 else if (invert != 0)
6954 else if (pattern != NULL)
6959 warnx("%s argument only valid with overwrite "
6962 goto sanitize_bailout;
6966 if (quiet == 0 && ycount == 0) {
6967 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6968 "following device:\n");
6970 if (dt == CC_DT_SCSI) {
6971 error = scsidoinquiry(device, argc, argv, combinedopt,
6972 task_attr, retry_count, timeout);
6973 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
6974 struct ata_params *ident_buf;
6975 error = ata_do_identify(device, retry_count, timeout,
6978 printf("%s%d: ", device->device_name,
6979 device->dev_unit_num);
6980 ata_print_ident(ident_buf);
6987 warnx("sanitize: error sending inquiry");
6988 goto sanitize_bailout;
6993 if (!get_confirmation()) {
6995 goto sanitize_bailout;
7000 use_timeout = timeout;
7002 use_timeout = (immediate ? 10 : 10800) * 1000;
7004 if (immediate == 0 && quiet == 0) {
7005 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7006 use_timeout / 1000);
7010 * If the user hasn't disabled questions and didn't specify a
7011 * timeout on the command line, ask them if they want the current
7014 if (immediate == 0 && ycount == 0 && timeout == 0) {
7016 int new_timeout = 0;
7018 fprintf(stdout, "Enter new timeout in seconds or press\n"
7019 "return to keep the current timeout [%d] ",
7020 use_timeout / 1000);
7022 if (fgets(str, sizeof(str), stdin) != NULL) {
7024 new_timeout = atoi(str);
7027 if (new_timeout != 0) {
7028 use_timeout = new_timeout * 1000;
7029 fprintf(stdout, "Using new timeout value %d\n",
7030 use_timeout / 1000);
7034 if (dt == CC_DT_SCSI) {
7037 byte2 |= SSZ_UNRESTRICTED_EXIT;
7040 scsi_sanitize(&ccb->csio,
7041 /* retries */ retry_count,
7043 /* tag_action */ task_attr,
7046 /* data_ptr */ data_ptr,
7047 /* dxfer_len */ dxfer_len,
7048 /* sense_len */ SSD_FULL_SIZE,
7049 /* timeout */ use_timeout);
7051 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7052 if (arglist & CAM_ARG_ERR_RECOVER)
7053 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7054 if (cam_send_ccb(device, ccb) < 0) {
7055 warn("error sending sanitize command");
7057 goto sanitize_bailout;
7059 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7060 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7061 feature = 0x14; /* OVERWRITE EXT */
7062 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7063 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7065 count |= 0x80; /* INVERT PATTERN */
7067 count |= 0x10; /* FAILURE MODE */
7068 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7069 feature = 0x12; /* BLOCK ERASE EXT */
7070 lba = 0x0000426B4572;
7073 count |= 0x10; /* FAILURE MODE */
7074 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7075 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7076 lba = 0x000043727970;
7079 count |= 0x10; /* FAILURE MODE */
7080 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7081 feature = 0x00; /* SANITIZE STATUS EXT */
7083 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7086 goto sanitize_bailout;
7089 error = ata_do_cmd(device,
7092 /*flags*/CAM_DIR_NONE,
7093 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7095 /*tag_action*/MSG_SIMPLE_Q_TAG,
7096 /*command*/ATA_SANITIZE,
7097 /*features*/feature,
7099 /*sector_count*/count,
7102 /*timeout*/ use_timeout,
7106 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7107 struct scsi_sense_data *sense;
7108 int error_code, sense_key, asc, ascq;
7110 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7111 CAM_SCSI_STATUS_ERROR) {
7112 sense = &ccb->csio.sense_data;
7113 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7114 ccb->csio.sense_resid, &error_code, &sense_key,
7115 &asc, &ascq, /*show_errors*/ 1);
7117 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7118 asc == 0x20 && ascq == 0x00)
7119 warnx("sanitize is not supported by "
7122 warnx("error sanitizing this device");
7124 warnx("error sanitizing this device");
7126 if (arglist & CAM_ARG_VERBOSE) {
7127 cam_error_print(device, ccb, CAM_ESF_ALL,
7128 CAM_EPF_ALL, stderr);
7131 goto sanitize_bailout;
7135 * If we ran in non-immediate mode, we already checked for errors
7136 * above and printed out any necessary information. If we're in
7137 * immediate mode, we need to loop through and get status
7138 * information periodically.
7140 if (immediate == 0) {
7142 fprintf(stdout, "Sanitize Complete\n");
7144 goto sanitize_bailout;
7148 if (dt == CC_DT_SCSI) {
7149 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7150 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7151 error = sanitize_wait_ata(device, ccb, quiet, dt);
7154 if (error == 0 && quiet == 0)
7155 fprintf(stdout, "Sanitize Complete \n");
7160 if (data_ptr != NULL)
7168 scsireportluns(struct cam_device *device, int argc, char **argv,
7169 char *combinedopt, int task_attr, int retry_count, int timeout)
7172 int c, countonly, lunsonly;
7173 struct scsi_report_luns_data *lundata;
7175 uint8_t report_type;
7176 uint32_t list_len, i, j;
7181 report_type = RPL_REPORT_DEFAULT;
7182 ccb = cam_getccb(device);
7185 warnx("%s: error allocating ccb", __func__);
7192 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7201 if (strcasecmp(optarg, "default") == 0)
7202 report_type = RPL_REPORT_DEFAULT;
7203 else if (strcasecmp(optarg, "wellknown") == 0)
7204 report_type = RPL_REPORT_WELLKNOWN;
7205 else if (strcasecmp(optarg, "all") == 0)
7206 report_type = RPL_REPORT_ALL;
7208 warnx("%s: invalid report type \"%s\"",
7219 if ((countonly != 0)
7220 && (lunsonly != 0)) {
7221 warnx("%s: you can only specify one of -c or -l", __func__);
7226 * According to SPC-4, the allocation length must be at least 16
7227 * bytes -- enough for the header and one LUN.
7229 alloc_len = sizeof(*lundata) + 8;
7233 lundata = malloc(alloc_len);
7235 if (lundata == NULL) {
7236 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7241 scsi_report_luns(&ccb->csio,
7242 /*retries*/ retry_count,
7244 /*tag_action*/ task_attr,
7245 /*select_report*/ report_type,
7246 /*rpl_buf*/ lundata,
7247 /*alloc_len*/ alloc_len,
7248 /*sense_len*/ SSD_FULL_SIZE,
7249 /*timeout*/ timeout ? timeout : 5000);
7251 /* Disable freezing the device queue */
7252 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7254 if (arglist & CAM_ARG_ERR_RECOVER)
7255 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7257 if (cam_send_ccb(device, ccb) < 0) {
7258 warn("error sending REPORT LUNS command");
7263 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7264 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7270 list_len = scsi_4btoul(lundata->length);
7273 * If we need to list the LUNs, and our allocation
7274 * length was too short, reallocate and retry.
7276 if ((countonly == 0)
7277 && (list_len > (alloc_len - sizeof(*lundata)))) {
7278 alloc_len = list_len + sizeof(*lundata);
7284 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7285 ((list_len / 8) > 1) ? "s" : "");
7290 for (i = 0; i < (list_len / 8); i++) {
7294 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7296 fprintf(stdout, ",");
7297 switch (lundata->luns[i].lundata[j] &
7298 RPL_LUNDATA_ATYP_MASK) {
7299 case RPL_LUNDATA_ATYP_PERIPH:
7300 if ((lundata->luns[i].lundata[j] &
7301 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7302 fprintf(stdout, "%d:",
7303 lundata->luns[i].lundata[j] &
7304 RPL_LUNDATA_PERIPH_BUS_MASK);
7306 && ((lundata->luns[i].lundata[j+2] &
7307 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7310 fprintf(stdout, "%d",
7311 lundata->luns[i].lundata[j+1]);
7313 case RPL_LUNDATA_ATYP_FLAT: {
7315 tmplun[0] = lundata->luns[i].lundata[j] &
7316 RPL_LUNDATA_FLAT_LUN_MASK;
7317 tmplun[1] = lundata->luns[i].lundata[j+1];
7319 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7323 case RPL_LUNDATA_ATYP_LUN:
7324 fprintf(stdout, "%d:%d:%d",
7325 (lundata->luns[i].lundata[j+1] &
7326 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7327 lundata->luns[i].lundata[j] &
7328 RPL_LUNDATA_LUN_TARG_MASK,
7329 lundata->luns[i].lundata[j+1] &
7330 RPL_LUNDATA_LUN_LUN_MASK);
7332 case RPL_LUNDATA_ATYP_EXTLUN: {
7333 int field_len_code, eam_code;
7335 eam_code = lundata->luns[i].lundata[j] &
7336 RPL_LUNDATA_EXT_EAM_MASK;
7337 field_len_code = (lundata->luns[i].lundata[j] &
7338 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7340 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7341 && (field_len_code == 0x00)) {
7342 fprintf(stdout, "%d",
7343 lundata->luns[i].lundata[j+1]);
7344 } else if ((eam_code ==
7345 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7346 && (field_len_code == 0x03)) {
7350 * This format takes up all 8 bytes.
7351 * If we aren't starting at offset 0,
7355 fprintf(stdout, "Invalid "
7358 "specified format", j);
7362 bzero(tmp_lun, sizeof(tmp_lun));
7363 bcopy(&lundata->luns[i].lundata[j+1],
7364 &tmp_lun[1], sizeof(tmp_lun) - 1);
7365 fprintf(stdout, "%#jx",
7366 (intmax_t)scsi_8btou64(tmp_lun));
7369 fprintf(stderr, "Unknown Extended LUN"
7370 "Address method %#x, length "
7371 "code %#x", eam_code,
7378 fprintf(stderr, "Unknown LUN address method "
7379 "%#x\n", lundata->luns[i].lundata[0] &
7380 RPL_LUNDATA_ATYP_MASK);
7384 * For the flat addressing method, there are no
7385 * other levels after it.
7390 fprintf(stdout, "\n");
7403 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7404 char *combinedopt, int task_attr, int retry_count, int timeout)
7407 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7408 struct scsi_read_capacity_data rcap;
7409 struct scsi_read_capacity_data_long rcaplong;
7424 ccb = cam_getccb(device);
7427 warnx("%s: error allocating ccb", __func__);
7431 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7461 if ((blocksizeonly != 0)
7462 && (numblocks != 0)) {
7463 warnx("%s: you can only specify one of -b or -N", __func__);
7468 if ((blocksizeonly != 0)
7469 && (sizeonly != 0)) {
7470 warnx("%s: you can only specify one of -b or -s", __func__);
7477 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7483 && (blocksizeonly != 0)) {
7484 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7492 scsi_read_capacity(&ccb->csio,
7493 /*retries*/ retry_count,
7495 /*tag_action*/ task_attr,
7498 /*timeout*/ timeout ? timeout : 5000);
7500 /* Disable freezing the device queue */
7501 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7503 if (arglist & CAM_ARG_ERR_RECOVER)
7504 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7506 if (cam_send_ccb(device, ccb) < 0) {
7507 warn("error sending READ CAPACITY command");
7512 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7513 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7518 maxsector = scsi_4btoul(rcap.addr);
7519 block_len = scsi_4btoul(rcap.length);
7522 * A last block of 2^32-1 means that the true capacity is over 2TB,
7523 * and we need to issue the long READ CAPACITY to get the real
7524 * capacity. Otherwise, we're all set.
7526 if (maxsector != 0xffffffff)
7530 scsi_read_capacity_16(&ccb->csio,
7531 /*retries*/ retry_count,
7533 /*tag_action*/ task_attr,
7537 /*rcap_buf*/ (uint8_t *)&rcaplong,
7538 /*rcap_buf_len*/ sizeof(rcaplong),
7539 /*sense_len*/ SSD_FULL_SIZE,
7540 /*timeout*/ timeout ? timeout : 5000);
7542 /* Disable freezing the device queue */
7543 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7545 if (arglist & CAM_ARG_ERR_RECOVER)
7546 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7548 if (cam_send_ccb(device, ccb) < 0) {
7549 warn("error sending READ CAPACITY (16) command");
7554 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7555 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7560 maxsector = scsi_8btou64(rcaplong.addr);
7561 block_len = scsi_4btoul(rcaplong.length);
7564 if (blocksizeonly == 0) {
7566 * Humanize implies !quiet, and also implies numblocks.
7568 if (humanize != 0) {
7573 tmpbytes = (maxsector + 1) * block_len;
7574 ret = humanize_number(tmpstr, sizeof(tmpstr),
7575 tmpbytes, "", HN_AUTOSCALE,
7578 HN_DIVISOR_1000 : 0));
7580 warnx("%s: humanize_number failed!", __func__);
7584 fprintf(stdout, "Device Size: %s%s", tmpstr,
7585 (sizeonly == 0) ? ", " : "\n");
7586 } else if (numblocks != 0) {
7587 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7588 "Blocks: " : "", (uintmax_t)maxsector + 1,
7589 (sizeonly == 0) ? ", " : "\n");
7591 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7592 "Last Block: " : "", (uintmax_t)maxsector,
7593 (sizeonly == 0) ? ", " : "\n");
7597 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7598 "Block Length: " : "", block_len, (quiet == 0) ?
7607 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7608 int retry_count, int timeout)
7612 uint8_t *smp_request = NULL, *smp_response = NULL;
7613 int request_size = 0, response_size = 0;
7614 int fd_request = 0, fd_response = 0;
7615 char *datastr = NULL;
7616 struct get_hook hook;
7621 * Note that at the moment we don't support sending SMP CCBs to
7622 * devices that aren't probed by CAM.
7624 ccb = cam_getccb(device);
7626 warnx("%s: error allocating CCB", __func__);
7630 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7633 arglist |= CAM_ARG_CMD_IN;
7634 response_size = strtol(optarg, NULL, 0);
7635 if (response_size <= 0) {
7636 warnx("invalid number of response bytes %d",
7639 goto smpcmd_bailout;
7641 hook.argc = argc - optind;
7642 hook.argv = argv + optind;
7645 datastr = cget(&hook, NULL);
7647 * If the user supplied "-" instead of a format, he
7648 * wants the data to be written to stdout.
7650 if ((datastr != NULL)
7651 && (datastr[0] == '-'))
7654 smp_response = (u_int8_t *)malloc(response_size);
7655 if (smp_response == NULL) {
7656 warn("can't malloc memory for SMP response");
7658 goto smpcmd_bailout;
7662 arglist |= CAM_ARG_CMD_OUT;
7663 request_size = strtol(optarg, NULL, 0);
7664 if (request_size <= 0) {
7665 warnx("invalid number of request bytes %d",
7668 goto smpcmd_bailout;
7670 hook.argc = argc - optind;
7671 hook.argv = argv + optind;
7673 datastr = cget(&hook, NULL);
7674 smp_request = (u_int8_t *)malloc(request_size);
7675 if (smp_request == NULL) {
7676 warn("can't malloc memory for SMP request");
7678 goto smpcmd_bailout;
7680 bzero(smp_request, request_size);
7682 * If the user supplied "-" instead of a format, he
7683 * wants the data to be read from stdin.
7685 if ((datastr != NULL)
7686 && (datastr[0] == '-'))
7689 buff_encode_visit(smp_request, request_size,
7700 * If fd_data is set, and we're writing to the device, we need to
7701 * read the data the user wants written from stdin.
7703 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7705 int amt_to_read = request_size;
7706 u_int8_t *buf_ptr = smp_request;
7708 for (amt_read = 0; amt_to_read > 0;
7709 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7710 if (amt_read == -1) {
7711 warn("error reading data from stdin");
7713 goto smpcmd_bailout;
7715 amt_to_read -= amt_read;
7716 buf_ptr += amt_read;
7720 if (((arglist & CAM_ARG_CMD_IN) == 0)
7721 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7722 warnx("%s: need both the request (-r) and response (-R) "
7723 "arguments", __func__);
7725 goto smpcmd_bailout;
7728 flags |= CAM_DEV_QFRZDIS;
7730 cam_fill_smpio(&ccb->smpio,
7731 /*retries*/ retry_count,
7734 /*smp_request*/ smp_request,
7735 /*smp_request_len*/ request_size,
7736 /*smp_response*/ smp_response,
7737 /*smp_response_len*/ response_size,
7738 /*timeout*/ timeout ? timeout : 5000);
7740 ccb->smpio.flags = SMP_FLAG_NONE;
7742 if (((retval = cam_send_ccb(device, ccb)) < 0)
7743 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7744 const char warnstr[] = "error sending command";
7751 if (arglist & CAM_ARG_VERBOSE) {
7752 cam_error_print(device, ccb, CAM_ESF_ALL,
7753 CAM_EPF_ALL, stderr);
7757 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7758 && (response_size > 0)) {
7759 if (fd_response == 0) {
7760 buff_decode_visit(smp_response, response_size,
7761 datastr, arg_put, NULL);
7762 fprintf(stdout, "\n");
7764 ssize_t amt_written;
7765 int amt_to_write = response_size;
7766 u_int8_t *buf_ptr = smp_response;
7768 for (amt_written = 0; (amt_to_write > 0) &&
7769 (amt_written = write(STDOUT_FILENO, buf_ptr,
7770 amt_to_write)) > 0;){
7771 amt_to_write -= amt_written;
7772 buf_ptr += amt_written;
7774 if (amt_written == -1) {
7775 warn("error writing data to stdout");
7777 goto smpcmd_bailout;
7778 } else if ((amt_written == 0)
7779 && (amt_to_write > 0)) {
7780 warnx("only wrote %u bytes out of %u",
7781 response_size - amt_to_write,
7790 if (smp_request != NULL)
7793 if (smp_response != NULL)
7800 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7801 int retry_count, int timeout)
7805 int32_t mmc_opcode = 0, mmc_arg = 0;
7806 int32_t mmc_flags = -1;
7809 int is_bw_4 = 0, is_bw_1 = 0;
7810 int is_frequency = 0;
7811 int is_highspeed = 0, is_stdspeed = 0;
7812 int is_info_request = 0;
7814 uint8_t mmc_data_byte = 0;
7815 uint32_t mmc_frequency = 0;
7817 /* For IO_RW_EXTENDED command */
7818 uint8_t *mmc_data = NULL;
7819 struct mmc_data mmc_d;
7820 int mmc_data_len = 0;
7823 * Note that at the moment we don't support sending SMP CCBs to
7824 * devices that aren't probed by CAM.
7826 ccb = cam_getccb(device);
7828 warnx("%s: error allocating CCB", __func__);
7832 bzero(&(&ccb->ccb_h)[1],
7833 sizeof(union ccb) - sizeof(struct ccb_hdr));
7835 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7844 if (!strcmp(optarg, "high"))
7850 is_info_request = 1;
7854 mmc_frequency = strtol(optarg, NULL, 0);
7857 mmc_opcode = strtol(optarg, NULL, 0);
7858 if (mmc_opcode < 0) {
7859 warnx("invalid MMC opcode %d",
7862 goto mmccmd_bailout;
7866 mmc_arg = strtol(optarg, NULL, 0);
7868 warnx("invalid MMC arg %d",
7871 goto mmccmd_bailout;
7875 mmc_flags = strtol(optarg, NULL, 0);
7876 if (mmc_flags < 0) {
7877 warnx("invalid MMC flags %d",
7880 goto mmccmd_bailout;
7884 mmc_data_len = strtol(optarg, NULL, 0);
7885 if (mmc_data_len <= 0) {
7886 warnx("invalid MMC data len %d",
7889 goto mmccmd_bailout;
7896 mmc_data_byte = strtol(optarg, NULL, 0);
7902 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7904 /* If flags are left default, supply the right flags */
7906 switch (mmc_opcode) {
7907 case MMC_GO_IDLE_STATE:
7908 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7910 case IO_SEND_OP_COND:
7911 mmc_flags = MMC_RSP_R4;
7913 case SD_SEND_RELATIVE_ADDR:
7914 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7916 case MMC_SELECT_CARD:
7917 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7918 mmc_arg = mmc_arg << 16;
7920 case SD_IO_RW_DIRECT:
7921 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7922 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7924 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7926 case SD_IO_RW_EXTENDED:
7927 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7928 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7929 int len_arg = mmc_data_len;
7930 if (mmc_data_len == 512)
7934 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7936 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7939 mmc_flags = MMC_RSP_R1;
7943 // Switch bus width instead of sending IO command
7944 if (is_bw_4 || is_bw_1) {
7945 struct ccb_trans_settings_mmc *cts;
7946 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7947 ccb->ccb_h.flags = 0;
7948 cts = &ccb->cts.proto_specific.mmc;
7949 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7950 cts->ios_valid = MMC_BW;
7951 if (((retval = cam_send_ccb(device, ccb)) < 0)
7952 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7953 warn("Error sending command");
7955 printf("Parameters set OK\n");
7962 struct ccb_trans_settings_mmc *cts;
7963 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7964 ccb->ccb_h.flags = 0;
7965 cts = &ccb->cts.proto_specific.mmc;
7966 cts->ios.clock = mmc_frequency;
7967 cts->ios_valid = MMC_CLK;
7968 if (((retval = cam_send_ccb(device, ccb)) < 0)
7969 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7970 warn("Error sending command");
7972 printf("Parameters set OK\n");
7978 // Switch bus speed instead of sending IO command
7979 if (is_stdspeed || is_highspeed) {
7980 struct ccb_trans_settings_mmc *cts;
7981 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7982 ccb->ccb_h.flags = 0;
7983 cts = &ccb->cts.proto_specific.mmc;
7984 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7985 cts->ios_valid = MMC_BT;
7986 if (((retval = cam_send_ccb(device, ccb)) < 0)
7987 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7988 warn("Error sending command");
7990 printf("Speed set OK (HS: %d)\n", is_highspeed);
7996 // Get information about controller and its settings
7997 if (is_info_request) {
7998 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7999 ccb->ccb_h.flags = 0;
8000 struct ccb_trans_settings_mmc *cts;
8001 cts = &ccb->cts.proto_specific.mmc;
8002 if (((retval = cam_send_ccb(device, ccb)) < 0)
8003 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8004 warn("Error sending command");
8007 printf("Host controller information\n");
8008 printf("Host OCR: 0x%x\n", cts->host_ocr);
8009 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8010 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8011 printf("Supported bus width:\n");
8012 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8014 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8017 printf("Supported operating modes:\n");
8018 if (cts->host_caps & MMC_CAP_HSPEED)
8019 printf(" Can do High Speed transfers\n");
8020 if (cts->host_caps & MMC_CAP_UHS_SDR12)
8021 printf(" Can do UHS SDR12\n");
8022 if (cts->host_caps & MMC_CAP_UHS_SDR25)
8023 printf(" Can do UHS SDR25\n");
8024 if (cts->host_caps & MMC_CAP_UHS_SDR50)
8025 printf(" Can do UHS SDR50\n");
8026 if (cts->host_caps & MMC_CAP_UHS_SDR104)
8027 printf(" Can do UHS SDR104\n");
8028 if (cts->host_caps & MMC_CAP_UHS_DDR50)
8029 printf(" Can do UHS DDR50\n");
8030 if (cts->host_caps & MMC_CAP_MMC_DDR52_120)
8031 printf(" Can do eMMC DDR52 at 1.2V\n");
8032 if (cts->host_caps & MMC_CAP_MMC_DDR52_180)
8033 printf(" Can do eMMC DDR52 at 1.8V\n");
8034 if (cts->host_caps & MMC_CAP_MMC_HS200_120)
8035 printf(" Can do eMMC HS200 at 1.2V\n");
8036 if (cts->host_caps & MMC_CAP_MMC_HS200_180)
8037 printf(" Can do eMMC HS200 at 1.8V\n");
8038 if (cts->host_caps & MMC_CAP_MMC_HS400_120)
8039 printf(" Can do eMMC HS400 at 1.2V\n");
8040 if (cts->host_caps & MMC_CAP_MMC_HS400_180)
8041 printf(" Can do eMMC HS400 at 1.8V\n");
8043 printf("Supported VCCQ voltages:\n");
8044 if (cts->host_caps & MMC_CAP_SIGNALING_120)
8046 if (cts->host_caps & MMC_CAP_SIGNALING_180)
8048 if (cts->host_caps & MMC_CAP_SIGNALING_330)
8051 printf("Current settings:\n");
8052 printf(" Bus width: ");
8053 switch (cts->ios.bus_width) {
8064 printf(" Freq: %d.%03d MHz%s\n",
8065 cts->ios.clock / 1000000,
8066 (cts->ios.clock / 1000) % 1000,
8067 cts->ios.timing == bus_timing_hs ? " (high-speed timing)" : "");
8070 switch (cts->ios.vccq) {
8084 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8086 if (mmc_data_len > 0) {
8087 flags |= CAM_DIR_IN;
8088 mmc_data = malloc(mmc_data_len);
8089 memset(mmc_data, 0, mmc_data_len);
8090 memset(&mmc_d, 0, sizeof(mmc_d));
8091 mmc_d.len = mmc_data_len;
8092 mmc_d.data = mmc_data;
8093 mmc_d.flags = MMC_DATA_READ;
8094 } else flags |= CAM_DIR_NONE;
8096 cam_fill_mmcio(&ccb->mmcio,
8097 /*retries*/ retry_count,
8100 /*mmc_opcode*/ mmc_opcode,
8101 /*mmc_arg*/ mmc_arg,
8102 /*mmc_flags*/ mmc_flags,
8103 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8104 /*timeout*/ timeout ? timeout : 5000);
8106 if (((retval = cam_send_ccb(device, ccb)) < 0)
8107 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8108 const char warnstr[] = "error sending command";
8115 if (arglist & CAM_ARG_VERBOSE) {
8116 cam_error_print(device, ccb, CAM_ESF_ALL,
8117 CAM_EPF_ALL, stderr);
8121 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8122 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8123 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8124 ccb->mmcio.cmd.resp[1],
8125 ccb->mmcio.cmd.resp[2],
8126 ccb->mmcio.cmd.resp[3]);
8128 switch (mmc_opcode) {
8129 case SD_IO_RW_DIRECT:
8130 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8131 SD_R5_DATA(ccb->mmcio.cmd.resp),
8132 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8134 case SD_IO_RW_EXTENDED:
8135 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8136 hexdump(mmc_data, mmc_data_len, NULL, 0);
8138 case SD_SEND_RELATIVE_ADDR:
8139 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8142 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8149 if (mmc_data_len > 0 && mmc_data != NULL)
8156 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8157 char *combinedopt, int retry_count, int timeout)
8160 struct smp_report_general_request *request = NULL;
8161 struct smp_report_general_response *response = NULL;
8162 struct sbuf *sb = NULL;
8164 int c, long_response = 0;
8168 * Note that at the moment we don't support sending SMP CCBs to
8169 * devices that aren't probed by CAM.
8171 ccb = cam_getccb(device);
8173 warnx("%s: error allocating CCB", __func__);
8177 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8186 request = malloc(sizeof(*request));
8187 if (request == NULL) {
8188 warn("%s: unable to allocate %zd bytes", __func__,
8194 response = malloc(sizeof(*response));
8195 if (response == NULL) {
8196 warn("%s: unable to allocate %zd bytes", __func__,
8203 smp_report_general(&ccb->smpio,
8207 /*request_len*/ sizeof(*request),
8208 (uint8_t *)response,
8209 /*response_len*/ sizeof(*response),
8210 /*long_response*/ long_response,
8213 if (((retval = cam_send_ccb(device, ccb)) < 0)
8214 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8215 const char warnstr[] = "error sending command";
8222 if (arglist & CAM_ARG_VERBOSE) {
8223 cam_error_print(device, ccb, CAM_ESF_ALL,
8224 CAM_EPF_ALL, stderr);
8231 * If the device supports the long response bit, try again and see
8232 * if we can get all of the data.
8234 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8235 && (long_response == 0)) {
8236 ccb->ccb_h.status = CAM_REQ_INPROG;
8237 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8243 * XXX KDM detect and decode SMP errors here.
8245 sb = sbuf_new_auto();
8247 warnx("%s: error allocating sbuf", __func__);
8251 smp_report_general_sbuf(response, sizeof(*response), sb);
8253 if (sbuf_finish(sb) != 0) {
8254 warnx("%s: sbuf_finish", __func__);
8258 printf("%s", sbuf_data(sb));
8264 if (request != NULL)
8267 if (response != NULL)
8276 static struct camcontrol_opts phy_ops[] = {
8277 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8278 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8279 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8280 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8281 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8282 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8283 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8284 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8285 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8290 smpphycontrol(struct cam_device *device, int argc, char **argv,
8291 char *combinedopt, int retry_count, int timeout)
8294 struct smp_phy_control_request *request = NULL;
8295 struct smp_phy_control_response *response = NULL;
8296 int long_response = 0;
8299 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8301 uint64_t attached_dev_name = 0;
8302 int dev_name_set = 0;
8303 uint32_t min_plr = 0, max_plr = 0;
8304 uint32_t pp_timeout_val = 0;
8305 int slumber_partial = 0;
8306 int set_pp_timeout_val = 0;
8310 * Note that at the moment we don't support sending SMP CCBs to
8311 * devices that aren't probed by CAM.
8313 ccb = cam_getccb(device);
8315 warnx("%s: error allocating CCB", __func__);
8319 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8327 if (strcasecmp(optarg, "enable") == 0)
8329 else if (strcasecmp(optarg, "disable") == 0)
8332 warnx("%s: Invalid argument %s", __func__,
8339 slumber_partial |= enable <<
8340 SMP_PC_SAS_SLUMBER_SHIFT;
8343 slumber_partial |= enable <<
8344 SMP_PC_SAS_PARTIAL_SHIFT;
8347 slumber_partial |= enable <<
8348 SMP_PC_SATA_SLUMBER_SHIFT;
8351 slumber_partial |= enable <<
8352 SMP_PC_SATA_PARTIAL_SHIFT;
8355 warnx("%s: programmer error", __func__);
8358 break; /*NOTREACHED*/
8363 attached_dev_name = (uintmax_t)strtoumax(optarg,
8372 * We don't do extensive checking here, so this
8373 * will continue to work when new speeds come out.
8375 min_plr = strtoul(optarg, NULL, 0);
8377 || (min_plr > 0xf)) {
8378 warnx("%s: invalid link rate %x",
8386 * We don't do extensive checking here, so this
8387 * will continue to work when new speeds come out.
8389 max_plr = strtoul(optarg, NULL, 0);
8391 || (max_plr > 0xf)) {
8392 warnx("%s: invalid link rate %x",
8399 camcontrol_optret optreturn;
8400 cam_argmask argnums;
8403 if (phy_op_set != 0) {
8404 warnx("%s: only one phy operation argument "
8405 "(-o) allowed", __func__);
8413 * Allow the user to specify the phy operation
8414 * numerically, as well as with a name. This will
8415 * future-proof it a bit, so options that are added
8416 * in future specs can be used.
8418 if (isdigit(optarg[0])) {
8419 phy_operation = strtoul(optarg, NULL, 0);
8420 if ((phy_operation == 0)
8421 || (phy_operation > 0xff)) {
8422 warnx("%s: invalid phy operation %#x",
8423 __func__, phy_operation);
8429 optreturn = getoption(phy_ops, optarg, &phy_operation,
8432 if (optreturn == CC_OR_AMBIGUOUS) {
8433 warnx("%s: ambiguous option %s", __func__,
8438 } else if (optreturn == CC_OR_NOT_FOUND) {
8439 warnx("%s: option %s not found", __func__,
8451 pp_timeout_val = strtoul(optarg, NULL, 0);
8452 if (pp_timeout_val > 15) {
8453 warnx("%s: invalid partial pathway timeout "
8454 "value %u, need a value less than 16",
8455 __func__, pp_timeout_val);
8459 set_pp_timeout_val = 1;
8467 warnx("%s: a PHY (-p phy) argument is required",__func__);
8472 if (((dev_name_set != 0)
8473 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8474 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8475 && (dev_name_set == 0))) {
8476 warnx("%s: -d name and -o setdevname arguments both "
8477 "required to set device name", __func__);
8482 request = malloc(sizeof(*request));
8483 if (request == NULL) {
8484 warn("%s: unable to allocate %zd bytes", __func__,
8490 response = malloc(sizeof(*response));
8491 if (response == NULL) {
8492 warn("%s: unable to allocate %zd bytes", __func__,
8498 smp_phy_control(&ccb->smpio,
8503 (uint8_t *)response,
8506 /*expected_exp_change_count*/ 0,
8509 (set_pp_timeout_val != 0) ? 1 : 0,
8517 if (((retval = cam_send_ccb(device, ccb)) < 0)
8518 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8519 const char warnstr[] = "error sending command";
8526 if (arglist & CAM_ARG_VERBOSE) {
8528 * Use CAM_EPF_NORMAL so we only get one line of
8529 * SMP command decoding.
8531 cam_error_print(device, ccb, CAM_ESF_ALL,
8532 CAM_EPF_NORMAL, stderr);
8538 /* XXX KDM print out something here for success? */
8543 if (request != NULL)
8546 if (response != NULL)
8553 smpmaninfo(struct cam_device *device, int argc, char **argv,
8554 char *combinedopt, int retry_count, int timeout)
8557 struct smp_report_manuf_info_request request;
8558 struct smp_report_manuf_info_response response;
8559 struct sbuf *sb = NULL;
8560 int long_response = 0;
8565 * Note that at the moment we don't support sending SMP CCBs to
8566 * devices that aren't probed by CAM.
8568 ccb = cam_getccb(device);
8570 warnx("%s: error allocating CCB", __func__);
8574 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8583 bzero(&request, sizeof(request));
8584 bzero(&response, sizeof(response));
8586 smp_report_manuf_info(&ccb->smpio,
8591 (uint8_t *)&response,
8596 if (((retval = cam_send_ccb(device, ccb)) < 0)
8597 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8598 const char warnstr[] = "error sending command";
8605 if (arglist & CAM_ARG_VERBOSE) {
8606 cam_error_print(device, ccb, CAM_ESF_ALL,
8607 CAM_EPF_ALL, stderr);
8613 sb = sbuf_new_auto();
8615 warnx("%s: error allocating sbuf", __func__);
8619 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8621 if (sbuf_finish(sb) != 0) {
8622 warnx("%s: sbuf_finish", __func__);
8626 printf("%s", sbuf_data(sb));
8640 getdevid(struct cam_devitem *item)
8643 union ccb *ccb = NULL;
8645 struct cam_device *dev;
8647 dev = cam_open_btl(item->dev_match.path_id,
8648 item->dev_match.target_id,
8649 item->dev_match.target_lun, O_RDWR, NULL);
8652 warnx("%s", cam_errbuf);
8657 item->device_id_len = 0;
8659 ccb = cam_getccb(dev);
8661 warnx("%s: error allocating CCB", __func__);
8667 * On the first try, we just probe for the size of the data, and
8668 * then allocate that much memory and try again.
8671 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8672 ccb->ccb_h.flags = CAM_DIR_IN;
8673 ccb->cdai.flags = CDAI_FLAG_NONE;
8674 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8675 ccb->cdai.bufsiz = item->device_id_len;
8676 if (item->device_id_len != 0)
8677 ccb->cdai.buf = (uint8_t *)item->device_id;
8679 if (cam_send_ccb(dev, ccb) < 0) {
8680 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8685 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8686 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8691 if (item->device_id_len == 0) {
8693 * This is our first time through. Allocate the buffer,
8694 * and then go back to get the data.
8696 if (ccb->cdai.provsiz == 0) {
8697 warnx("%s: invalid .provsiz field returned with "
8698 "XPT_GDEV_ADVINFO CCB", __func__);
8702 item->device_id_len = ccb->cdai.provsiz;
8703 item->device_id = malloc(item->device_id_len);
8704 if (item->device_id == NULL) {
8705 warn("%s: unable to allocate %d bytes", __func__,
8706 item->device_id_len);
8710 ccb->ccb_h.status = CAM_REQ_INPROG;
8716 cam_close_device(dev);
8725 * XXX KDM merge this code with getdevtree()?
8728 buildbusdevlist(struct cam_devlist *devlist)
8731 int bufsize, fd = -1;
8732 struct dev_match_pattern *patterns;
8733 struct cam_devitem *item = NULL;
8734 int skip_device = 0;
8737 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8738 warn("couldn't open %s", XPT_DEVICE);
8742 bzero(&ccb, sizeof(union ccb));
8744 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8745 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8746 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8748 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8749 bufsize = sizeof(struct dev_match_result) * 100;
8750 ccb.cdm.match_buf_len = bufsize;
8751 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8752 if (ccb.cdm.matches == NULL) {
8753 warnx("can't malloc memory for matches");
8757 ccb.cdm.num_matches = 0;
8758 ccb.cdm.num_patterns = 2;
8759 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8760 ccb.cdm.num_patterns;
8762 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8763 if (patterns == NULL) {
8764 warnx("can't malloc memory for patterns");
8769 ccb.cdm.patterns = patterns;
8770 bzero(patterns, ccb.cdm.pattern_buf_len);
8772 patterns[0].type = DEV_MATCH_DEVICE;
8773 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8774 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8775 patterns[1].type = DEV_MATCH_PERIPH;
8776 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8777 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8780 * We do the ioctl multiple times if necessary, in case there are
8781 * more than 100 nodes in the EDT.
8786 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8787 warn("error sending CAMIOCOMMAND ioctl");
8792 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8793 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8794 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8795 warnx("got CAM error %#x, CDM error %d\n",
8796 ccb.ccb_h.status, ccb.cdm.status);
8801 for (i = 0; i < ccb.cdm.num_matches; i++) {
8802 switch (ccb.cdm.matches[i].type) {
8803 case DEV_MATCH_DEVICE: {
8804 struct device_match_result *dev_result;
8807 &ccb.cdm.matches[i].result.device_result;
8809 if (dev_result->flags &
8810 DEV_RESULT_UNCONFIGURED) {
8816 item = malloc(sizeof(*item));
8818 warn("%s: unable to allocate %zd bytes",
8819 __func__, sizeof(*item));
8823 bzero(item, sizeof(*item));
8824 bcopy(dev_result, &item->dev_match,
8825 sizeof(*dev_result));
8826 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8829 if (getdevid(item) != 0) {
8835 case DEV_MATCH_PERIPH: {
8836 struct periph_match_result *periph_result;
8839 &ccb.cdm.matches[i].result.periph_result;
8841 if (skip_device != 0)
8843 item->num_periphs++;
8844 item->periph_matches = realloc(
8845 item->periph_matches,
8847 sizeof(struct periph_match_result));
8848 if (item->periph_matches == NULL) {
8849 warn("%s: error allocating periph "
8854 bcopy(periph_result, &item->periph_matches[
8855 item->num_periphs - 1],
8856 sizeof(*periph_result));
8860 fprintf(stderr, "%s: unexpected match "
8861 "type %d\n", __func__,
8862 ccb.cdm.matches[i].type);
8865 break; /*NOTREACHED*/
8868 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8869 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8877 free(ccb.cdm.matches);
8880 freebusdevlist(devlist);
8886 freebusdevlist(struct cam_devlist *devlist)
8888 struct cam_devitem *item, *item2;
8890 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8891 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8893 free(item->device_id);
8894 free(item->periph_matches);
8899 static struct cam_devitem *
8900 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8902 struct cam_devitem *item;
8904 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8905 struct scsi_vpd_id_descriptor *idd;
8908 * XXX KDM look for LUN IDs as well?
8910 idd = scsi_get_devid(item->device_id,
8911 item->device_id_len,
8912 scsi_devid_is_sas_target);
8916 if (scsi_8btou64(idd->identifier) == sasaddr)
8924 smpphylist(struct cam_device *device, int argc, char **argv,
8925 char *combinedopt, int retry_count, int timeout)
8927 struct smp_report_general_request *rgrequest = NULL;
8928 struct smp_report_general_response *rgresponse = NULL;
8929 struct smp_discover_request *disrequest = NULL;
8930 struct smp_discover_response *disresponse = NULL;
8931 struct cam_devlist devlist;
8933 int long_response = 0;
8940 * Note that at the moment we don't support sending SMP CCBs to
8941 * devices that aren't probed by CAM.
8943 ccb = cam_getccb(device);
8945 warnx("%s: error allocating CCB", __func__);
8949 STAILQ_INIT(&devlist.dev_queue);
8951 rgrequest = malloc(sizeof(*rgrequest));
8952 if (rgrequest == NULL) {
8953 warn("%s: unable to allocate %zd bytes", __func__,
8954 sizeof(*rgrequest));
8959 rgresponse = malloc(sizeof(*rgresponse));
8960 if (rgresponse == NULL) {
8961 warn("%s: unable to allocate %zd bytes", __func__,
8962 sizeof(*rgresponse));
8967 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8980 smp_report_general(&ccb->smpio,
8984 /*request_len*/ sizeof(*rgrequest),
8985 (uint8_t *)rgresponse,
8986 /*response_len*/ sizeof(*rgresponse),
8987 /*long_response*/ long_response,
8990 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8992 if (((retval = cam_send_ccb(device, ccb)) < 0)
8993 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8994 const char warnstr[] = "error sending command";
9001 if (arglist & CAM_ARG_VERBOSE) {
9002 cam_error_print(device, ccb, CAM_ESF_ALL,
9003 CAM_EPF_ALL, stderr);
9009 num_phys = rgresponse->num_phys;
9011 if (num_phys == 0) {
9013 fprintf(stdout, "%s: No Phys reported\n", __func__);
9018 devlist.path_id = device->path_id;
9020 retval = buildbusdevlist(&devlist);
9025 fprintf(stdout, "%d PHYs:\n", num_phys);
9026 fprintf(stdout, "PHY Attached SAS Address\n");
9029 disrequest = malloc(sizeof(*disrequest));
9030 if (disrequest == NULL) {
9031 warn("%s: unable to allocate %zd bytes", __func__,
9032 sizeof(*disrequest));
9037 disresponse = malloc(sizeof(*disresponse));
9038 if (disresponse == NULL) {
9039 warn("%s: unable to allocate %zd bytes", __func__,
9040 sizeof(*disresponse));
9045 for (i = 0; i < num_phys; i++) {
9046 struct cam_devitem *item;
9047 struct device_match_result *dev_match;
9048 char vendor[16], product[48], revision[16];
9052 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9054 ccb->ccb_h.status = CAM_REQ_INPROG;
9055 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9057 smp_discover(&ccb->smpio,
9061 sizeof(*disrequest),
9062 (uint8_t *)disresponse,
9063 sizeof(*disresponse),
9065 /*ignore_zone_group*/ 0,
9069 if (((retval = cam_send_ccb(device, ccb)) < 0)
9070 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9071 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9072 const char warnstr[] = "error sending command";
9079 if (arglist & CAM_ARG_VERBOSE) {
9080 cam_error_print(device, ccb, CAM_ESF_ALL,
9081 CAM_EPF_ALL, stderr);
9087 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9089 fprintf(stdout, "%3d <vacant>\n", i);
9093 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9096 item = findsasdevice(&devlist,
9097 scsi_8btou64(disresponse->attached_sas_address));
9101 || (item != NULL)) {
9102 fprintf(stdout, "%3d 0x%016jx", i,
9103 (uintmax_t)scsi_8btou64(
9104 disresponse->attached_sas_address));
9106 fprintf(stdout, "\n");
9109 } else if (quiet != 0)
9112 dev_match = &item->dev_match;
9114 if (dev_match->protocol == PROTO_SCSI) {
9115 cam_strvis(vendor, dev_match->inq_data.vendor,
9116 sizeof(dev_match->inq_data.vendor),
9118 cam_strvis(product, dev_match->inq_data.product,
9119 sizeof(dev_match->inq_data.product),
9121 cam_strvis(revision, dev_match->inq_data.revision,
9122 sizeof(dev_match->inq_data.revision),
9124 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9126 } else if ((dev_match->protocol == PROTO_ATA)
9127 || (dev_match->protocol == PROTO_SATAPM)) {
9128 cam_strvis(product, dev_match->ident_data.model,
9129 sizeof(dev_match->ident_data.model),
9131 cam_strvis(revision, dev_match->ident_data.revision,
9132 sizeof(dev_match->ident_data.revision),
9134 sprintf(tmpstr, "<%s %s>", product, revision);
9136 sprintf(tmpstr, "<>");
9138 fprintf(stdout, " %-33s ", tmpstr);
9141 * If we have 0 periphs, that's a bug...
9143 if (item->num_periphs == 0) {
9144 fprintf(stdout, "\n");
9148 fprintf(stdout, "(");
9149 for (j = 0; j < item->num_periphs; j++) {
9151 fprintf(stdout, ",");
9153 fprintf(stdout, "%s%d",
9154 item->periph_matches[j].periph_name,
9155 item->periph_matches[j].unit_number);
9158 fprintf(stdout, ")\n");
9172 freebusdevlist(&devlist);
9178 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9180 uint8_t error = 0, ata_device = 0, status = 0;
9185 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9188 if (arglist & CAM_ARG_VERBOSE) {
9189 cam_error_print(device, ccb, CAM_ESF_ALL,
9190 CAM_EPF_ALL, stderr);
9192 warnx("Can't get ATA command status");
9196 if (status & ATA_STATUS_ERROR) {
9197 cam_error_print(device, ccb, CAM_ESF_ALL,
9198 CAM_EPF_ALL, stderr);
9202 printf("%s%d: ", device->device_name, device->dev_unit_num);
9205 printf("Standby mode\n");
9208 printf("Standby_y mode\n");
9211 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9214 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9217 printf("Idle mode\n");
9220 printf("Idle_a mode\n");
9223 printf("Idle_b mode\n");
9226 printf("Idle_c mode\n");
9229 printf("Active or Idle mode\n");
9232 printf("Unknown mode 0x%02x\n", count);
9240 atapm(struct cam_device *device, int argc, char **argv,
9241 char *combinedopt, int retry_count, int timeout)
9247 u_int8_t ata_flags = 0;
9250 ccb = cam_getccb(device);
9253 warnx("%s: error allocating ccb", __func__);
9257 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9266 if (strcmp(argv[1], "idle") == 0) {
9268 cmd = ATA_IDLE_IMMEDIATE;
9271 } else if (strcmp(argv[1], "standby") == 0) {
9273 cmd = ATA_STANDBY_IMMEDIATE;
9275 cmd = ATA_STANDBY_CMD;
9276 } else if (strcmp(argv[1], "powermode") == 0) {
9277 cmd = ATA_CHECK_POWER_MODE;
9278 ata_flags = AP_FLAG_CHK_COND;
9287 else if (t <= (240 * 5))
9289 else if (t <= (252 * 5))
9290 /* special encoding for 21 minutes */
9292 else if (t <= (11 * 30 * 60))
9293 sc = (t - 1) / (30 * 60) + 241;
9297 retval = ata_do_cmd(device,
9299 /*retries*/retry_count,
9300 /*flags*/CAM_DIR_NONE,
9301 /*protocol*/AP_PROTO_NON_DATA,
9302 /*ata_flags*/ata_flags,
9303 /*tag_action*/MSG_SIMPLE_Q_TAG,
9310 /*timeout*/timeout ? timeout : 30 * 1000,
9315 if (retval || cmd != ATA_CHECK_POWER_MODE)
9318 return (atapm_proc_resp(device, ccb));
9322 ataaxm(struct cam_device *device, int argc, char **argv,
9323 char *combinedopt, int retry_count, int timeout)
9331 ccb = cam_getccb(device);
9334 warnx("%s: error allocating ccb", __func__);
9338 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9348 if (strcmp(argv[1], "apm") == 0) {
9364 retval = ata_do_cmd(device,
9366 /*retries*/retry_count,
9367 /*flags*/CAM_DIR_NONE,
9368 /*protocol*/AP_PROTO_NON_DATA,
9370 /*tag_action*/MSG_SIMPLE_Q_TAG,
9371 /*command*/ATA_SETFEATURES,
9377 /*timeout*/timeout ? timeout : 30 * 1000,
9385 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9386 int show_sa_errors, int sa_set, int service_action,
9387 int timeout_desc, int task_attr, int retry_count, int timeout,
9388 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9390 union ccb *ccb = NULL;
9391 uint8_t *buf = NULL;
9392 uint32_t alloc_len = 0, num_opcodes;
9393 uint32_t valid_len = 0;
9394 uint32_t avail_len = 0;
9395 struct scsi_report_supported_opcodes_all *all_hdr;
9396 struct scsi_report_supported_opcodes_one *one;
9401 * Make it clear that we haven't yet allocated or filled anything.
9406 ccb = cam_getccb(device);
9408 warnx("couldn't allocate CCB");
9413 if (opcode_set != 0) {
9414 options |= RSO_OPTIONS_OC;
9416 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9419 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9420 sizeof(struct scsi_report_supported_opcodes_descr));
9423 if (timeout_desc != 0) {
9424 options |= RSO_RCTD;
9425 alloc_len += num_opcodes *
9426 sizeof(struct scsi_report_supported_opcodes_timeout);
9430 options |= RSO_OPTIONS_OC_SA;
9431 if (show_sa_errors != 0)
9432 options &= ~RSO_OPTIONS_OC;
9441 buf = malloc(alloc_len);
9443 warn("Unable to allocate %u bytes", alloc_len);
9447 bzero(buf, alloc_len);
9449 scsi_report_supported_opcodes(&ccb->csio,
9450 /*retries*/ retry_count,
9452 /*tag_action*/ task_attr,
9453 /*options*/ options,
9454 /*req_opcode*/ opcode,
9455 /*req_service_action*/ service_action,
9457 /*dxfer_len*/ alloc_len,
9458 /*sense_len*/ SSD_FULL_SIZE,
9459 /*timeout*/ timeout ? timeout : 10000);
9461 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9463 if (retry_count != 0)
9464 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9466 if (cam_send_ccb(device, ccb) < 0) {
9467 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9472 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9473 if (verbosemode != 0)
9474 cam_error_print(device, ccb, CAM_ESF_ALL,
9475 CAM_EPF_ALL, stderr);
9480 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9482 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9483 && (valid_len >= sizeof(*all_hdr))) {
9484 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9485 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9486 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9487 && (valid_len >= sizeof(*one))) {
9488 uint32_t cdb_length;
9490 one = (struct scsi_report_supported_opcodes_one *)buf;
9491 cdb_length = scsi_2btoul(one->cdb_length);
9492 avail_len = sizeof(*one) + cdb_length;
9493 if (one->support & RSO_ONE_CTDP) {
9494 struct scsi_report_supported_opcodes_timeout *td;
9496 td = (struct scsi_report_supported_opcodes_timeout *)
9498 if (valid_len >= (avail_len + sizeof(td->length))) {
9499 avail_len += scsi_2btoul(td->length) +
9502 avail_len += sizeof(*td);
9508 * avail_len could be zero if we didn't get enough data back from
9509 * thet target to determine
9511 if ((avail_len != 0)
9512 && (avail_len > valid_len)) {
9513 alloc_len = avail_len;
9517 *fill_len = valid_len;
9529 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9530 int req_sa, uint8_t *buf, uint32_t valid_len)
9532 struct scsi_report_supported_opcodes_one *one;
9533 struct scsi_report_supported_opcodes_timeout *td;
9534 uint32_t cdb_len = 0, td_len = 0;
9535 const char *op_desc = NULL;
9539 one = (struct scsi_report_supported_opcodes_one *)buf;
9542 * If we don't have the full single opcode descriptor, no point in
9545 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9547 warnx("Only %u bytes returned, not enough to verify support",
9553 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9555 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9558 printf(", SA 0x%x", req_sa);
9561 switch (one->support & RSO_ONE_SUP_MASK) {
9562 case RSO_ONE_SUP_UNAVAIL:
9563 printf("No command support information currently available\n");
9565 case RSO_ONE_SUP_NOT_SUP:
9566 printf("Command not supported\n");
9569 break; /*NOTREACHED*/
9570 case RSO_ONE_SUP_AVAIL:
9571 printf("Command is supported, complies with a SCSI standard\n");
9573 case RSO_ONE_SUP_VENDOR:
9574 printf("Command is supported, vendor-specific "
9575 "implementation\n");
9578 printf("Unknown command support flags 0x%#x\n",
9579 one->support & RSO_ONE_SUP_MASK);
9584 * If we don't have the CDB length, it isn't exactly an error, the
9585 * command probably isn't supported.
9587 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9591 cdb_len = scsi_2btoul(one->cdb_length);
9594 * If our valid data doesn't include the full reported length,
9595 * return. The caller should have detected this and adjusted his
9596 * allocation length to get all of the available data.
9598 if (valid_len < sizeof(*one) + cdb_len) {
9604 * If all we have is the opcode, there is no point in printing out
9612 printf("CDB usage bitmap:");
9613 for (i = 0; i < cdb_len; i++) {
9614 printf(" %02x", one->cdb_usage[i]);
9619 * If we don't have a timeout descriptor, we're done.
9621 if ((one->support & RSO_ONE_CTDP) == 0)
9625 * If we don't have enough valid length to include the timeout
9626 * descriptor length, we're done.
9628 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9631 td = (struct scsi_report_supported_opcodes_timeout *)
9632 &buf[sizeof(*one) + cdb_len];
9633 td_len = scsi_2btoul(td->length);
9634 td_len += sizeof(td->length);
9637 * If we don't have the full timeout descriptor, we're done.
9639 if (td_len < sizeof(*td))
9643 * If we don't have enough valid length to contain the full timeout
9644 * descriptor, we're done.
9646 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9649 printf("Timeout information:\n");
9650 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9651 printf("Nominal timeout: %u seconds\n",
9652 scsi_4btoul(td->nominal_time));
9653 printf("Recommended timeout: %u seconds\n",
9654 scsi_4btoul(td->recommended_time));
9661 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9664 struct scsi_report_supported_opcodes_all *hdr;
9665 struct scsi_report_supported_opcodes_descr *desc;
9666 uint32_t avail_len = 0, used_len = 0;
9670 if (valid_len < sizeof(*hdr)) {
9671 warnx("%s: not enough returned data (%u bytes) opcode list",
9672 __func__, valid_len);
9676 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9677 avail_len = scsi_4btoul(hdr->length);
9678 avail_len += sizeof(hdr->length);
9680 * Take the lesser of the amount of data the drive claims is
9681 * available, and the amount of data the HBA says was returned.
9683 avail_len = MIN(avail_len, valid_len);
9685 used_len = sizeof(hdr->length);
9687 printf("%-6s %4s %8s ",
9688 "Opcode", "SA", "CDB len" );
9691 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9692 printf(" Description\n");
9694 while ((avail_len - used_len) > sizeof(*desc)) {
9695 struct scsi_report_supported_opcodes_timeout *td;
9697 const char *op_desc = NULL;
9699 cur_ptr = &buf[used_len];
9700 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9702 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9703 if (op_desc == NULL)
9704 op_desc = "UNKNOWN";
9706 printf("0x%02x %#4x %8u ", desc->opcode,
9707 scsi_2btoul(desc->service_action),
9708 scsi_2btoul(desc->cdb_length));
9710 used_len += sizeof(*desc);
9712 if ((desc->flags & RSO_CTDP) == 0) {
9713 printf(" %s\n", op_desc);
9718 * If we don't have enough space to fit a timeout
9719 * descriptor, then we're done.
9721 if (avail_len - used_len < sizeof(*td)) {
9722 used_len = avail_len;
9723 printf(" %s\n", op_desc);
9726 cur_ptr = &buf[used_len];
9727 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9728 td_len = scsi_2btoul(td->length);
9729 td_len += sizeof(td->length);
9733 * If the given timeout descriptor length is less than what
9734 * we understand, skip it.
9736 if (td_len < sizeof(*td)) {
9737 printf(" %s\n", op_desc);
9741 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9742 scsi_4btoul(td->nominal_time),
9743 scsi_4btoul(td->recommended_time), op_desc);
9750 scsiopcodes(struct cam_device *device, int argc, char **argv,
9751 char *combinedopt, int task_attr, int retry_count, int timeout,
9755 uint32_t opcode = 0, service_action = 0;
9756 int td_set = 0, opcode_set = 0, sa_set = 0;
9757 int show_sa_errors = 1;
9758 uint32_t valid_len = 0;
9759 uint8_t *buf = NULL;
9763 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9769 opcode = strtoul(optarg, &endptr, 0);
9770 if (*endptr != '\0') {
9771 warnx("Invalid opcode \"%s\", must be a number",
9776 if (opcode > 0xff) {
9777 warnx("Invalid opcode 0x%#x, must be between"
9778 "0 and 0xff inclusive", opcode);
9785 service_action = strtoul(optarg, &endptr, 0);
9786 if (*endptr != '\0') {
9787 warnx("Invalid service action \"%s\", must "
9788 "be a number", optarg);
9792 if (service_action > 0xffff) {
9793 warnx("Invalid service action 0x%#x, must "
9794 "be between 0 and 0xffff inclusive",
9809 && (opcode_set == 0)) {
9810 warnx("You must specify an opcode with -o if a service "
9815 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9816 sa_set, service_action, td_set, task_attr,
9817 retry_count, timeout, verbosemode, &valid_len,
9822 if ((opcode_set != 0)
9824 retval = scsiprintoneopcode(device, opcode, sa_set,
9825 service_action, buf, valid_len);
9827 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9838 reprobe(struct cam_device *device)
9843 ccb = cam_getccb(device);
9846 warnx("%s: error allocating ccb", __func__);
9850 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9852 if (cam_send_ccb(device, ccb) < 0) {
9853 warn("error sending XPT_REPROBE_LUN CCB");
9858 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9859 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9871 usage(int printlong)
9874 fprintf(printlong ? stdout : stderr,
9875 "usage: camcontrol <command> [device id][generic args][command args]\n"
9876 " camcontrol devlist [-b] [-v]\n"
9877 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9878 " camcontrol tur [dev_id][generic args]\n"
9879 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9880 " camcontrol identify [dev_id][generic args] [-v]\n"
9881 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9882 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9884 " camcontrol start [dev_id][generic args]\n"
9885 " camcontrol stop [dev_id][generic args]\n"
9886 " camcontrol load [dev_id][generic args]\n"
9887 " camcontrol eject [dev_id][generic args]\n"
9888 " camcontrol reprobe [dev_id][generic args]\n"
9889 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9890 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9891 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9892 " [-q][-s][-S offset][-X]\n"
9893 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9894 " [-P pagectl][-e | -b][-d]\n"
9895 " camcontrol cmd [dev_id][generic args]\n"
9896 " <-a cmd [args] | -c cmd [args]>\n"
9897 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9898 " camcontrol smpcmd [dev_id][generic args]\n"
9899 " <-r len fmt [args]> <-R len fmt [args]>\n"
9900 " camcontrol smprg [dev_id][generic args][-l]\n"
9901 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9902 " [-o operation][-d name][-m rate][-M rate]\n"
9903 " [-T pp_timeout][-a enable|disable]\n"
9904 " [-A enable|disable][-s enable|disable]\n"
9905 " [-S enable|disable]\n"
9906 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9907 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9908 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9909 " <all|dev_id|bus[:target[:lun]]|off>\n"
9910 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9911 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9912 " [-D <enable|disable>][-M mode][-O offset]\n"
9913 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9914 " [-U][-W bus_width]\n"
9915 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9916 " camcontrol sanitize [dev_id][generic args]\n"
9917 " [-a overwrite|block|crypto|exitfailure]\n"
9918 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9920 " camcontrol idle [dev_id][generic args][-t time]\n"
9921 " camcontrol standby [dev_id][generic args][-t time]\n"
9922 " camcontrol sleep [dev_id][generic args]\n"
9923 " camcontrol powermode [dev_id][generic args]\n"
9924 " camcontrol apm [dev_id][generic args][-l level]\n"
9925 " camcontrol aam [dev_id][generic args][-l level]\n"
9926 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9928 " camcontrol security [dev_id][generic args]\n"
9929 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9930 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9931 " [-U <user|master>] [-y]\n"
9932 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9933 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9934 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9935 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9936 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9937 " [-s scope][-S][-T type][-U]\n"
9938 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9939 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9940 " [-p part][-s start][-T type][-V vol]\n"
9941 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9943 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9944 " [-o rep_opts] [-P print_opts]\n"
9945 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9946 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9947 " [-S power_src] [-T timer]\n"
9948 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9949 " <-s <-f format -T time | -U >>\n"
9950 " camcontrol devtype [dev_id]\n"
9951 " camcontrol depop [dev_id] [-d | -l | -r] [-e element] [-c capacity]\n"
9952 " camcontrol mmcsdcmd [dev_id] [[-c mmc_opcode] [-a mmc_arg]\n"
9953 " [-f mmc_flags] [-l data_len]\n"
9954 " [-W [-b data_byte]]] |\n"
9955 " [-F frequency] |\n"
9958 " [-S high|normal]\n"
9960 " camcontrol help\n");
9964 "Specify one of the following options:\n"
9965 "devlist list all CAM devices\n"
9966 "periphlist list all CAM peripheral drivers attached to a device\n"
9967 "tur send a test unit ready to the named device\n"
9968 "inquiry send a SCSI inquiry command to the named device\n"
9969 "identify send a ATA identify command to the named device\n"
9970 "reportluns send a SCSI report luns command to the device\n"
9971 "readcap send a SCSI read capacity command to the device\n"
9972 "start send a Start Unit command to the device\n"
9973 "stop send a Stop Unit command to the device\n"
9974 "load send a Start Unit command to the device with the load bit set\n"
9975 "eject send a Stop Unit command to the device with the eject bit set\n"
9976 "reprobe update capacity information of the given device\n"
9977 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9978 "reset reset all buses, the given bus, bus:target:lun or device\n"
9979 "defects read the defect list of the specified device\n"
9980 "modepage display or edit (-e) the given mode page\n"
9981 "cmd send the given SCSI command, may need -i or -o as well\n"
9982 "smpcmd send the given SMP command, requires -o and -i\n"
9983 "smprg send the SMP Report General command\n"
9984 "smppc send the SMP PHY Control command, requires -p\n"
9985 "smpphylist display phys attached to a SAS expander\n"
9986 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9987 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9988 "tags report or set the number of transaction slots for a device\n"
9989 "negotiate report or set device negotiation parameters\n"
9990 "format send the SCSI FORMAT UNIT command to the named device\n"
9991 "sanitize send the SCSI SANITIZE command to the named device\n"
9992 "idle send the ATA IDLE command to the named device\n"
9993 "standby send the ATA STANDBY command to the named device\n"
9994 "sleep send the ATA SLEEP command to the named device\n"
9995 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9996 "fwdownload program firmware of the named device with the given image\n"
9997 "security report or send ATA security commands to the named device\n"
9998 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9999 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
10000 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
10001 "zone manage Zoned Block (Shingled) devices\n"
10002 "epc send ATA Extended Power Conditions commands\n"
10003 "timestamp report or set the device's timestamp\n"
10004 "devtype report the type of device\n"
10005 "depop manage drive storage elements\n"
10006 "mmcsdcmd send the given MMC command, needs -c and -a as well\n"
10007 "help this message\n"
10008 "Device Identifiers:\n"
10009 "bus:target specify the bus and target, lun defaults to 0\n"
10010 "bus:target:lun specify the bus, target and lun\n"
10011 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
10012 "Generic arguments:\n"
10013 "-v be verbose, print out sense information\n"
10014 "-t timeout command timeout in seconds, overrides default timeout\n"
10015 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
10016 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
10017 "-E have the kernel attempt to perform SCSI error recovery\n"
10018 "-C count specify the SCSI command retry count (needs -E to work)\n"
10019 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
10020 "modepage arguments:\n"
10021 "-l list all available mode pages\n"
10022 "-m page specify the mode page to view or edit\n"
10023 "-e edit the specified mode page\n"
10024 "-b force view to binary mode\n"
10025 "-d disable block descriptors for mode sense\n"
10026 "-P pgctl page control field 0-3\n"
10027 "defects arguments:\n"
10028 "-f format specify defect list format (block, bfi or phys)\n"
10029 "-G get the grown defect list\n"
10030 "-P get the permanent defect list\n"
10031 "inquiry arguments:\n"
10032 "-D get the standard inquiry data\n"
10033 "-S get the serial number\n"
10034 "-R get the transfer rate, etc.\n"
10035 "reportluns arguments:\n"
10036 "-c only report a count of available LUNs\n"
10037 "-l only print out luns, and not a count\n"
10038 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10039 "readcap arguments\n"
10040 "-b only report the blocksize\n"
10041 "-h human readable device size, base 2\n"
10042 "-H human readable device size, base 10\n"
10043 "-N print the number of blocks instead of last block\n"
10044 "-q quiet, print numbers only\n"
10045 "-s only report the last block/device size\n"
10047 "-c cdb [args] specify the SCSI CDB\n"
10048 "-i len fmt specify input data and input data format\n"
10049 "-o len fmt [args] specify output data and output data fmt\n"
10050 "smpcmd arguments:\n"
10051 "-r len fmt [args] specify the SMP command to be sent\n"
10052 "-R len fmt [args] specify SMP response format\n"
10053 "smprg arguments:\n"
10054 "-l specify the long response format\n"
10055 "smppc arguments:\n"
10056 "-p phy specify the PHY to operate on\n"
10057 "-l specify the long request/response format\n"
10058 "-o operation specify the phy control operation\n"
10059 "-d name set the attached device name\n"
10060 "-m rate set the minimum physical link rate\n"
10061 "-M rate set the maximum physical link rate\n"
10062 "-T pp_timeout set the partial pathway timeout value\n"
10063 "-a enable|disable enable or disable SATA slumber\n"
10064 "-A enable|disable enable or disable SATA partial phy power\n"
10065 "-s enable|disable enable or disable SAS slumber\n"
10066 "-S enable|disable enable or disable SAS partial phy power\n"
10067 "smpphylist arguments:\n"
10068 "-l specify the long response format\n"
10069 "-q only print phys with attached devices\n"
10070 "smpmaninfo arguments:\n"
10071 "-l specify the long response format\n"
10072 "debug arguments:\n"
10073 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10074 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10075 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10076 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10077 "tags arguments:\n"
10078 "-N tags specify the number of tags to use for this device\n"
10079 "-q be quiet, don't report the number of tags\n"
10080 "-v report a number of tag-related parameters\n"
10081 "negotiate arguments:\n"
10082 "-a send a test unit ready after negotiation\n"
10083 "-c report/set current negotiation settings\n"
10084 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10085 "-M mode set ATA mode\n"
10086 "-O offset set command delay offset\n"
10087 "-q be quiet, don't report anything\n"
10088 "-R syncrate synchronization rate in MHz\n"
10089 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10090 "-U report/set user negotiation settings\n"
10091 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10092 "-v also print a Path Inquiry CCB for the controller\n"
10093 "format arguments:\n"
10094 "-q be quiet, don't print status messages\n"
10095 "-r run in report only mode\n"
10096 "-w don't send immediate format command\n"
10097 "-y don't ask any questions\n"
10098 "sanitize arguments:\n"
10099 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10100 "-c passes overwrite passes to perform (1 to 31)\n"
10101 "-I invert overwrite pattern after each pass\n"
10102 "-P pattern path to overwrite pattern file\n"
10103 "-q be quiet, don't print status messages\n"
10104 "-r run in report only mode\n"
10105 "-U run operation in unrestricted completion exit mode\n"
10106 "-w don't send immediate sanitize command\n"
10107 "-y don't ask any questions\n"
10108 "idle/standby arguments:\n"
10109 "-t <arg> number of seconds before respective state.\n"
10110 "fwdownload arguments:\n"
10111 "-f fw_image path to firmware image file\n"
10112 "-q don't print informational messages, only errors\n"
10113 "-s run in simulation mode\n"
10114 "-v print info for every firmware segment sent to device\n"
10115 "-y don't ask any questions\n"
10116 "security arguments:\n"
10117 "-d pwd disable security using the given password for the selected\n"
10119 "-e pwd erase the device using the given pwd for the selected user\n"
10120 "-f freeze the security configuration of the specified device\n"
10121 "-h pwd enhanced erase the device using the given pwd for the\n"
10123 "-k pwd unlock the device using the given pwd for the selected\n"
10125 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10126 "-q be quiet, do not print any status messages\n"
10127 "-s pwd password the device (enable security) using the given\n"
10128 " pwd for the selected user\n"
10129 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10130 "-U <user|master> specifies which user to set: user or master\n"
10131 "-y don't ask any questions\n"
10133 "-f freeze the HPA configuration of the device\n"
10134 "-l lock the HPA configuration of the device\n"
10135 "-P make the HPA max sectors persist\n"
10136 "-p pwd Set the HPA configuration password required for unlock\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 "-U pwd unlock the HPA configuration of the device\n"
10142 "-y don't ask any questions\n"
10144 "-f freeze the AMA configuration of the device\n"
10145 "-q be quiet, do not print any status messages\n"
10146 "-s sectors configures the maximum user accessible sectors of the\n"
10148 "persist arguments:\n"
10149 "-i action specify read_keys, read_reservation, report_cap, or\n"
10150 " read_full_status\n"
10151 "-o action specify register, register_ignore, reserve, release,\n"
10152 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10153 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10154 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10155 "-k key specify the Reservation Key\n"
10156 "-K sa_key specify the Service Action Reservation Key\n"
10157 "-p set the Activate Persist Through Power Loss bit\n"
10158 "-R rtp specify the Relative Target Port\n"
10159 "-s scope specify the scope: lun, extent, element or a number\n"
10160 "-S specify Transport ID for register, requires -I\n"
10161 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10162 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10163 "-U unregister the current initiator for register_move\n"
10164 "attrib arguments:\n"
10165 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10167 "-w attr specify an attribute to write, one -w argument per attr\n"
10168 "-a attr_num only display this attribute number\n"
10169 "-c get cached attributes\n"
10170 "-e elem_addr request attributes for the given element in a changer\n"
10171 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10172 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10173 " field_none, field_desc, field_num, field_size, field_rw\n"
10174 "-p partition request attributes for the given partition\n"
10175 "-s start_attr request attributes starting at the given number\n"
10176 "-T elem_type specify the element type (used with -e)\n"
10177 "-V logical_vol specify the logical volume ID\n"
10178 "opcodes arguments:\n"
10179 "-o opcode specify the individual opcode to list\n"
10180 "-s service_action specify the service action for the opcode\n"
10181 "-N do not return SCSI error for unsupported SA\n"
10182 "-T request nominal and recommended timeout values\n"
10183 "zone arguments:\n"
10184 "-c cmd required: rz, open, close, finish, or rwp\n"
10185 "-a apply the action to all zones\n"
10186 "-l LBA specify the zone starting LBA\n"
10187 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10188 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10189 "-P print_opt report zones printing: normal, summary, script\n"
10191 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10192 " source, status, list\n"
10193 "-d disable power mode (timer, state)\n"
10194 "-D delayed entry (goto)\n"
10195 "-e enable power mode (timer, state)\n"
10196 "-H hold power mode (goto)\n"
10197 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10199 "-P only display power mode (status)\n"
10200 "-r rst_src restore settings from: default, saved (restore)\n"
10201 "-s save mode (timer, state, restore)\n"
10202 "-S power_src set power source: battery, nonbattery (source)\n"
10203 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10204 "timestamp arguments:\n"
10205 "-r report the timestamp of the device\n"
10206 "-f format report the timestamp of the device with the given\n"
10207 " strftime(3) format string\n"
10208 "-m report the timestamp of the device as milliseconds since\n"
10209 " January 1st, 1970\n"
10210 "-U report the time with UTC instead of the local time zone\n"
10211 "-s set the timestamp of the device\n"
10212 "-f format the format of the time string passed into strptime(3)\n"
10213 "-T time the time value passed into strptime(3)\n"
10214 "-U set the timestamp of the device to UTC time\n"
10215 "depop arguments:\n"
10216 "-d remove an element from service\n"
10217 "-l list status of all elements of drive\n"
10218 "-r restore all elements to service\n"
10219 "-e elm element to remove\n"
10220 "-c capacity requested new capacity\n"
10221 "mmcsdcmd arguments:\n"
10222 "-c mmc_cmd MMC command to send to the card\n"
10223 "-a mmc_arg Argument for the MMC command\n"
10224 "-f mmc_flag Flags to set for the MMC command\n"
10225 "-l data_len Expect data_len bytes of data in reply and display them\n"
10226 "-W Fill the data buffer before invoking the MMC command\n"
10227 "-b data_byte One byte of data to fill the data buffer with\n"
10228 "-F frequency Operating frequency to set on the controller\n"
10229 "-4 Set bus width to 4 bit\n"
10230 "-1 Set bus width to 8 bit\n"
10231 "-S high | std Set high-speed or standard timing\n"
10232 "-I Display various card and host controller information\n"
10237 main(int argc, char **argv)
10240 char *device = NULL;
10242 struct cam_device *cam_dev = NULL;
10243 int timeout = 0, retry_count = 1;
10244 camcontrol_optret optreturn;
10246 const char *mainopt = "C:En:Q:t:u:v";
10247 const char *subopt = NULL;
10248 char combinedopt[256];
10249 int error = 0, optstart = 2;
10250 int task_attr = MSG_SIMPLE_Q_TAG;
10254 target_id_t target;
10257 cmdlist = CAM_CMD_NONE;
10258 arglist = CAM_ARG_NONE;
10266 * Get the base option.
10268 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10270 if (optreturn == CC_OR_AMBIGUOUS) {
10271 warnx("ambiguous option %s", argv[1]);
10274 } else if (optreturn == CC_OR_NOT_FOUND) {
10275 warnx("option %s not found", argv[1]);
10281 * Ahh, getopt(3) is a pain.
10283 * This is a gross hack. There really aren't many other good
10284 * options (excuse the pun) for parsing options in a situation like
10285 * this. getopt is kinda braindead, so you end up having to run
10286 * through the options twice, and give each invocation of getopt
10287 * the option string for the other invocation.
10289 * You would think that you could just have two groups of options.
10290 * The first group would get parsed by the first invocation of
10291 * getopt, and the second group would get parsed by the second
10292 * invocation of getopt. It doesn't quite work out that way. When
10293 * the first invocation of getopt finishes, it leaves optind pointing
10294 * to the argument _after_ the first argument in the second group.
10295 * So when the second invocation of getopt comes around, it doesn't
10296 * recognize the first argument it gets and then bails out.
10298 * A nice alternative would be to have a flag for getopt that says
10299 * "just keep parsing arguments even when you encounter an unknown
10300 * argument", but there isn't one. So there's no real clean way to
10301 * easily parse two sets of arguments without having one invocation
10302 * of getopt know about the other.
10304 * Without this hack, the first invocation of getopt would work as
10305 * long as the generic arguments are first, but the second invocation
10306 * (in the subfunction) would fail in one of two ways. In the case
10307 * where you don't set optreset, it would fail because optind may be
10308 * pointing to the argument after the one it should be pointing at.
10309 * In the case where you do set optreset, and reset optind, it would
10310 * fail because getopt would run into the first set of options, which
10311 * it doesn't understand.
10313 * All of this would "sort of" work if you could somehow figure out
10314 * whether optind had been incremented one option too far. The
10315 * mechanics of that, however, are more daunting than just giving
10316 * both invocations all of the expect options for either invocation.
10318 * Needless to say, I wouldn't mind if someone invented a better
10319 * (non-GPL!) command line parsing interface than getopt. I
10320 * wouldn't mind if someone added more knobs to getopt to make it
10321 * work better. Who knows, I may talk myself into doing it someday,
10322 * if the standards weenies let me. As it is, it just leads to
10323 * hackery like this and causes people to avoid it in some cases.
10325 * KDM, September 8th, 1998
10327 if (subopt != NULL)
10328 sprintf(combinedopt, "%s%s", mainopt, subopt);
10330 sprintf(combinedopt, "%s", mainopt);
10333 * For these options we do not parse optional device arguments and
10334 * we do not open a passthrough device.
10336 if ((cmdlist == CAM_CMD_RESCAN)
10337 || (cmdlist == CAM_CMD_RESET)
10338 || (cmdlist == CAM_CMD_DEVTREE)
10339 || (cmdlist == CAM_CMD_USAGE)
10340 || (cmdlist == CAM_CMD_DEBUG))
10344 && (argc > 2 && argv[2][0] != '-')) {
10348 if (isdigit(argv[2][0])) {
10349 /* device specified as bus:target[:lun] */
10350 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10352 errx(1, "numeric device specification must "
10353 "be either bus:target, or "
10355 /* default to 0 if lun was not specified */
10356 if ((arglist & CAM_ARG_LUN) == 0) {
10358 arglist |= CAM_ARG_LUN;
10362 if (cam_get_device(argv[2], name, sizeof name, &unit)
10364 errx(1, "%s", cam_errbuf);
10365 device = strdup(name);
10366 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10371 * Start getopt processing at argv[2/3], since we've already
10372 * accepted argv[1..2] as the command name, and as a possible
10378 * Now we run through the argument list looking for generic
10379 * options, and ignoring options that possibly belong to
10382 while ((c = getopt(argc, argv, combinedopt))!= -1){
10385 retry_count = strtol(optarg, NULL, 0);
10386 if (retry_count < 0)
10387 errx(1, "retry count %d is < 0",
10389 arglist |= CAM_ARG_RETRIES;
10392 arglist |= CAM_ARG_ERR_RECOVER;
10395 arglist |= CAM_ARG_DEVICE;
10397 while (isspace(*tstr) && (*tstr != '\0'))
10399 device = (char *)strdup(tstr);
10403 int table_entry = 0;
10406 while (isspace(*tstr) && (*tstr != '\0'))
10408 if (isdigit(*tstr)) {
10409 task_attr = strtol(tstr, &endptr, 0);
10410 if (*endptr != '\0') {
10411 errx(1, "Invalid queue option "
10416 scsi_nv_status status;
10418 table_size = sizeof(task_attrs) /
10419 sizeof(task_attrs[0]);
10420 status = scsi_get_nv(task_attrs,
10421 table_size, tstr, &table_entry,
10422 SCSI_NV_FLAG_IG_CASE);
10423 if (status == SCSI_NV_FOUND)
10424 task_attr = task_attrs[
10425 table_entry].value;
10427 errx(1, "%s option %s",
10428 (status == SCSI_NV_AMBIGUOUS)?
10429 "ambiguous" : "invalid",
10436 timeout = strtol(optarg, NULL, 0);
10438 errx(1, "invalid timeout %d", timeout);
10439 /* Convert the timeout from seconds to ms */
10441 arglist |= CAM_ARG_TIMEOUT;
10444 arglist |= CAM_ARG_UNIT;
10445 unit = strtol(optarg, NULL, 0);
10448 arglist |= CAM_ARG_VERBOSE;
10456 * For most commands we'll want to open the passthrough device
10457 * associated with the specified device. In the case of the rescan
10458 * commands, we don't use a passthrough device at all, just the
10459 * transport layer device.
10461 if (devopen == 1) {
10462 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10463 && (((arglist & CAM_ARG_DEVICE) == 0)
10464 || ((arglist & CAM_ARG_UNIT) == 0))) {
10465 errx(1, "subcommand \"%s\" requires a valid device "
10466 "identifier", argv[1]);
10469 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10470 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10471 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10473 errx(1,"%s", cam_errbuf);
10477 * Reset optind to 2, and reset getopt, so these routines can parse
10478 * the arguments again.
10484 case CAM_CMD_DEVLIST:
10485 error = getdevlist(cam_dev);
10488 error = atahpa(cam_dev, retry_count, timeout,
10489 argc, argv, combinedopt);
10492 error = ataama(cam_dev, retry_count, timeout,
10493 argc, argv, combinedopt);
10495 case CAM_CMD_DEVTREE:
10496 error = getdevtree(argc, argv, combinedopt);
10498 case CAM_CMD_DEVTYPE:
10499 error = getdevtype(cam_dev);
10502 error = testunitready(cam_dev, task_attr, retry_count,
10505 case CAM_CMD_INQUIRY:
10506 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10507 task_attr, retry_count, timeout);
10509 case CAM_CMD_IDENTIFY:
10510 error = identify(cam_dev, retry_count, timeout);
10512 case CAM_CMD_STARTSTOP:
10513 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10514 arglist & CAM_ARG_EJECT, task_attr,
10515 retry_count, timeout);
10517 case CAM_CMD_RESCAN:
10518 error = dorescan_or_reset(argc, argv, 1);
10520 case CAM_CMD_RESET:
10521 error = dorescan_or_reset(argc, argv, 0);
10523 case CAM_CMD_READ_DEFECTS:
10524 error = readdefects(cam_dev, argc, argv, combinedopt,
10525 task_attr, retry_count, timeout);
10527 case CAM_CMD_MODE_PAGE:
10528 modepage(cam_dev, argc, argv, combinedopt,
10529 task_attr, retry_count, timeout);
10531 case CAM_CMD_SCSI_CMD:
10532 error = scsicmd(cam_dev, argc, argv, combinedopt,
10533 task_attr, retry_count, timeout);
10535 case CAM_CMD_MMCSD_CMD:
10536 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10537 retry_count, timeout);
10539 case CAM_CMD_SMP_CMD:
10540 error = smpcmd(cam_dev, argc, argv, combinedopt,
10541 retry_count, timeout);
10543 case CAM_CMD_SMP_RG:
10544 error = smpreportgeneral(cam_dev, argc, argv,
10545 combinedopt, retry_count,
10548 case CAM_CMD_SMP_PC:
10549 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10550 retry_count, timeout);
10552 case CAM_CMD_SMP_PHYLIST:
10553 error = smpphylist(cam_dev, argc, argv, combinedopt,
10554 retry_count, timeout);
10556 case CAM_CMD_SMP_MANINFO:
10557 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10558 retry_count, timeout);
10560 case CAM_CMD_DEBUG:
10561 error = camdebug(argc, argv, combinedopt);
10564 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10567 error = ratecontrol(cam_dev, task_attr, retry_count,
10568 timeout, argc, argv, combinedopt);
10570 case CAM_CMD_FORMAT:
10571 error = scsiformat(cam_dev, argc, argv,
10572 combinedopt, task_attr, retry_count,
10575 case CAM_CMD_REPORTLUNS:
10576 error = scsireportluns(cam_dev, argc, argv,
10577 combinedopt, task_attr,
10578 retry_count, timeout);
10580 case CAM_CMD_READCAP:
10581 error = scsireadcapacity(cam_dev, argc, argv,
10582 combinedopt, task_attr,
10583 retry_count, timeout);
10586 case CAM_CMD_STANDBY:
10587 case CAM_CMD_SLEEP:
10588 case CAM_CMD_POWER_MODE:
10589 error = atapm(cam_dev, argc, argv,
10590 combinedopt, retry_count, timeout);
10594 error = ataaxm(cam_dev, argc, argv,
10595 combinedopt, retry_count, timeout);
10597 case CAM_CMD_SECURITY:
10598 error = atasecurity(cam_dev, retry_count, timeout,
10599 argc, argv, combinedopt);
10601 case CAM_CMD_DOWNLOAD_FW:
10602 error = fwdownload(cam_dev, argc, argv, combinedopt,
10603 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10606 case CAM_CMD_SANITIZE:
10607 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10608 retry_count, timeout);
10610 case CAM_CMD_PERSIST:
10611 error = scsipersist(cam_dev, argc, argv, combinedopt,
10612 task_attr, retry_count, timeout,
10613 arglist & CAM_ARG_VERBOSE,
10614 arglist & CAM_ARG_ERR_RECOVER);
10616 case CAM_CMD_ATTRIB:
10617 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10618 task_attr, retry_count, timeout,
10619 arglist & CAM_ARG_VERBOSE,
10620 arglist & CAM_ARG_ERR_RECOVER);
10622 case CAM_CMD_OPCODES:
10623 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10624 task_attr, retry_count, timeout,
10625 arglist & CAM_ARG_VERBOSE);
10627 case CAM_CMD_REPROBE:
10628 error = reprobe(cam_dev);
10631 error = zone(cam_dev, argc, argv, combinedopt,
10632 task_attr, retry_count, timeout,
10633 arglist & CAM_ARG_VERBOSE);
10636 error = epc(cam_dev, argc, argv, combinedopt,
10637 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10639 case CAM_CMD_TIMESTAMP:
10640 error = timestamp(cam_dev, argc, argv, combinedopt,
10641 task_attr, retry_count, timeout,
10642 arglist & CAM_ARG_VERBOSE);
10644 case CAM_CMD_DEPOP:
10645 error = depop(cam_dev, argc, argv, combinedopt,
10646 task_attr, retry_count, timeout,
10647 arglist & CAM_ARG_VERBOSE);
10649 case CAM_CMD_USAGE:
10658 if (cam_dev != NULL)
10659 cam_close_device(cam_dev);