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>
54 #include <cam/cam_debug.h>
55 #include <cam/cam_ccb.h>
56 #include <cam/scsi/scsi_all.h>
57 #include <cam/scsi/scsi_da.h>
58 #include <cam/scsi/scsi_pass.h>
59 #include <cam/scsi/scsi_message.h>
60 #include <cam/scsi/smp_all.h>
61 #include <cam/ata/ata_all.h>
62 #include <cam/mmc/mmc_all.h>
64 #include "camcontrol.h"
66 #include "nvmecontrol_ext.h"
119 CAM_ARG_NONE = 0x00000000,
120 CAM_ARG_VERBOSE = 0x00000001,
121 CAM_ARG_DEVICE = 0x00000002,
122 CAM_ARG_BUS = 0x00000004,
123 CAM_ARG_TARGET = 0x00000008,
124 CAM_ARG_LUN = 0x00000010,
125 CAM_ARG_EJECT = 0x00000020,
126 CAM_ARG_UNIT = 0x00000040,
127 /* unused 0x00000080 */
128 /* unused 0x00000100 */
129 /* unused 0x00000200 */
130 /* unused 0x00000400 */
131 /* unused 0x00000800 */
132 CAM_ARG_GET_SERIAL = 0x00001000,
133 CAM_ARG_GET_STDINQ = 0x00002000,
134 CAM_ARG_GET_XFERRATE = 0x00004000,
135 CAM_ARG_INQ_MASK = 0x00007000,
136 /* unused 0x00008000 */
137 /* unused 0x00010000 */
138 CAM_ARG_TIMEOUT = 0x00020000,
139 CAM_ARG_CMD_IN = 0x00040000,
140 CAM_ARG_CMD_OUT = 0x00080000,
141 /* unused 0x00100000 */
142 CAM_ARG_ERR_RECOVER = 0x00200000,
143 CAM_ARG_RETRIES = 0x00400000,
144 CAM_ARG_START_UNIT = 0x00800000,
145 CAM_ARG_DEBUG_INFO = 0x01000000,
146 CAM_ARG_DEBUG_TRACE = 0x02000000,
147 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
148 CAM_ARG_DEBUG_CDB = 0x08000000,
149 CAM_ARG_DEBUG_XPT = 0x10000000,
150 CAM_ARG_DEBUG_PERIPH = 0x20000000,
151 CAM_ARG_DEBUG_PROBE = 0x40000000,
152 /* unused 0x80000000 */
155 struct camcontrol_opts {
162 struct ata_set_max_pwd
165 u_int8_t password[32];
166 u_int16_t reserved2[239];
169 static struct scsi_nv task_attrs[] = {
170 { "simple", MSG_SIMPLE_Q_TAG },
171 { "head", MSG_HEAD_OF_Q_TAG },
172 { "ordered", MSG_ORDERED_Q_TAG },
173 { "iwr", MSG_IGN_WIDE_RESIDUE },
174 { "aca", MSG_ACA_TASK }
177 static const char scsicmd_opts[] = "a:c:dfi:o:r";
178 static const char readdefect_opts[] = "f:GPqsS:X";
179 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
180 static const char smprg_opts[] = "l";
181 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
182 static const char smpphylist_opts[] = "lq";
185 static struct camcontrol_opts option_table[] = {
186 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
187 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
188 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
189 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
190 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
191 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
192 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
193 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
194 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
195 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
196 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
197 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
198 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
199 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:F:f:Wb:l:41S:I"},
200 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
201 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
202 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
203 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
204 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
205 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
206 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
207 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
208 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
209 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
210 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
211 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
212 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
213 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
214 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm:DLP:"},
215 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
216 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
217 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
218 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
219 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
220 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
221 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
222 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
223 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
224 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
225 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
226 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
227 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
228 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
229 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
230 {"ama", CAM_CMD_AMA, CAM_ARG_NONE, "fqs:"},
231 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
232 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
233 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
234 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
235 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
236 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
237 {"depop", CAM_CMD_DEPOP, CAM_ARG_NONE, "ac:de:ls"},
238 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
239 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
240 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
245 struct device_match_result dev_match;
247 struct periph_match_result *periph_matches;
248 struct scsi_vpd_device_id *device_id;
250 STAILQ_ENTRY(cam_devitem) links;
254 STAILQ_HEAD(, cam_devitem) dev_queue;
258 static cam_argmask arglist;
260 static const char *devtype_names[] = {
270 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
271 uint32_t *cmdnum, cam_argmask *argnum,
272 const char **subopt);
273 static int getdevlist(struct cam_device *device);
274 static int getdevtree(int argc, char **argv, char *combinedopt);
275 static int getdevtype(struct cam_device *device);
276 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
277 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
278 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
279 static int print_dev_mmcsd(struct device_match_result *dev_result,
282 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
284 static int testunitready(struct cam_device *device, int task_attr,
285 int retry_count, int timeout, int quiet);
286 static int scsistart(struct cam_device *device, int startstop, int loadeject,
287 int task_attr, int retry_count, int timeout);
288 static int scsiinquiry(struct cam_device *device, int task_attr,
289 int retry_count, int timeout);
290 static int scsiserial(struct cam_device *device, int task_attr,
291 int retry_count, int timeout);
292 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
293 lun_id_t *lun, cam_argmask *arglst);
294 static int reprobe(struct cam_device *device);
295 static int dorescan_or_reset(int argc, char **argv, int rescan);
296 static int rescan_or_reset_bus(path_id_t bus, int rescan);
297 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
298 lun_id_t lun, int scan);
299 static int readdefects(struct cam_device *device, int argc, char **argv,
300 char *combinedopt, int task_attr, int retry_count,
302 static void modepage(struct cam_device *device, int argc, char **argv,
303 char *combinedopt, int task_attr, int retry_count,
305 static int scsicmd(struct cam_device *device, int argc, char **argv,
306 char *combinedopt, int task_attr, int retry_count,
308 static int smpcmd(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int retry_count, int timeout);
310 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
311 char *combinedopt, int retry_count, int timeout);
312 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
313 char *combinedopt, int retry_count, int timeout);
314 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int retry_count, int timeout);
316 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
317 char *combinedopt, int retry_count, int timeout);
318 static int getdevid(struct cam_devitem *item);
319 static int buildbusdevlist(struct cam_devlist *devlist);
320 static void freebusdevlist(struct cam_devlist *devlist);
321 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
323 static int smpphylist(struct cam_device *device, int argc, char **argv,
324 char *combinedopt, int retry_count, int timeout);
325 static int tagcontrol(struct cam_device *device, int argc, char **argv,
327 static void cts_print(struct cam_device *device,
328 struct ccb_trans_settings *cts);
329 static void cpi_print(struct ccb_pathinq *cpi);
330 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
331 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
332 static int get_print_cts(struct cam_device *device, int user_settings,
333 int quiet, struct ccb_trans_settings *cts);
334 static int ratecontrol(struct cam_device *device, int task_attr,
335 int retry_count, int timeout, int argc, char **argv,
337 static int scsiformat(struct cam_device *device, int argc, char **argv,
338 char *combinedopt, int task_attr, int retry_count,
340 static int sanitize(struct cam_device *device, int argc, char **argv,
341 char *combinedopt, int task_attr, int retry_count,
343 static int scsireportluns(struct cam_device *device, int argc, char **argv,
344 char *combinedopt, int task_attr, int retry_count,
346 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
347 char *combinedopt, int task_attr, int retry_count,
349 static int atapm(struct cam_device *device, int argc, char **argv,
350 char *combinedopt, int retry_count, int timeout);
351 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
352 int argc, char **argv, char *combinedopt);
353 static int atahpa(struct cam_device *device, int retry_count, int timeout,
354 int argc, char **argv, char *combinedopt);
355 static int ataama(struct cam_device *device, int retry_count, int timeout,
356 int argc, char **argv, char *combinedopt);
357 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
358 int sa_set, int req_sa, uint8_t *buf,
360 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
362 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
363 char *combinedopt, int task_attr, int retry_count,
364 int timeout, int verbose);
367 #define min(a,b) (((a)<(b))?(a):(b))
370 #define max(a,b) (((a)>(b))?(a):(b))
374 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
375 cam_argmask *argnum, const char **subopt)
377 struct camcontrol_opts *opts;
380 for (opts = table; (opts != NULL) && (opts->optname != NULL);
382 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
383 *cmdnum = opts->cmdnum;
384 *argnum = opts->argnum;
385 *subopt = opts->subopt;
386 if (++num_matches > 1)
387 return (CC_OR_AMBIGUOUS);
392 return (CC_OR_FOUND);
394 return (CC_OR_NOT_FOUND);
398 getdevlist(struct cam_device *device)
404 ccb = cam_getccb(device);
406 ccb->ccb_h.func_code = XPT_GDEVLIST;
407 ccb->ccb_h.flags = CAM_DIR_NONE;
408 ccb->ccb_h.retry_count = 1;
410 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
411 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
412 if (cam_send_ccb(device, ccb) < 0) {
413 warn("error getting device list");
420 switch (ccb->cgdl.status) {
421 case CAM_GDEVLIST_MORE_DEVS:
422 strcpy(status, "MORE");
424 case CAM_GDEVLIST_LAST_DEVICE:
425 strcpy(status, "LAST");
427 case CAM_GDEVLIST_LIST_CHANGED:
428 strcpy(status, "CHANGED");
430 case CAM_GDEVLIST_ERROR:
431 strcpy(status, "ERROR");
436 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
437 ccb->cgdl.periph_name,
438 ccb->cgdl.unit_number,
439 ccb->cgdl.generation,
444 * If the list has changed, we need to start over from the
447 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
457 getdevtree(int argc, char **argv, char *combinedopt)
468 while ((c = getopt(argc, argv, combinedopt)) != -1) {
471 if ((arglist & CAM_ARG_VERBOSE) == 0)
479 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
480 warn("couldn't open %s", XPT_DEVICE);
484 bzero(&ccb, sizeof(union ccb));
486 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
487 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
488 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
490 ccb.ccb_h.func_code = XPT_DEV_MATCH;
491 bufsize = sizeof(struct dev_match_result) * 100;
492 ccb.cdm.match_buf_len = bufsize;
493 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
494 if (ccb.cdm.matches == NULL) {
495 warnx("can't malloc memory for matches");
499 ccb.cdm.num_matches = 0;
502 * We fetch all nodes, since we display most of them in the default
503 * case, and all in the verbose case.
505 ccb.cdm.num_patterns = 0;
506 ccb.cdm.pattern_buf_len = 0;
509 * We do the ioctl multiple times if necessary, in case there are
510 * more than 100 nodes in the EDT.
513 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
514 warn("error sending CAMIOCOMMAND ioctl");
519 if ((ccb.ccb_h.status != CAM_REQ_CMP)
520 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
521 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
522 warnx("got CAM error %#x, CDM error %d\n",
523 ccb.ccb_h.status, ccb.cdm.status);
528 for (i = 0; i < ccb.cdm.num_matches; i++) {
529 switch (ccb.cdm.matches[i].type) {
530 case DEV_MATCH_BUS: {
531 struct bus_match_result *bus_result;
534 * Only print the bus information if the
535 * user turns on the verbose flag.
537 if ((busonly == 0) &&
538 (arglist & CAM_ARG_VERBOSE) == 0)
542 &ccb.cdm.matches[i].result.bus_result;
545 fprintf(stdout, ")\n");
549 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
551 bus_result->dev_name,
552 bus_result->unit_number,
554 (busonly ? "" : ":"));
557 case DEV_MATCH_DEVICE: {
558 struct device_match_result *dev_result;
565 &ccb.cdm.matches[i].result.device_result;
567 if ((dev_result->flags
568 & DEV_RESULT_UNCONFIGURED)
569 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
575 if (dev_result->protocol == PROTO_SCSI) {
576 if (print_dev_scsi(dev_result,
581 } else if (dev_result->protocol == PROTO_ATA ||
582 dev_result->protocol == PROTO_SATAPM) {
583 if (print_dev_ata(dev_result,
588 } else if (dev_result->protocol == PROTO_MMCSD){
589 if (print_dev_mmcsd(dev_result,
594 } else if (dev_result->protocol == PROTO_SEMB) {
595 if (print_dev_semb(dev_result,
601 } else if (dev_result->protocol == PROTO_NVME) {
602 if (print_dev_nvme(dev_result,
609 sprintf(tmpstr, "<>");
612 fprintf(stdout, ")\n");
616 fprintf(stdout, "%-33s at scbus%d "
617 "target %d lun %jx (",
620 dev_result->target_id,
621 (uintmax_t)dev_result->target_lun);
627 case DEV_MATCH_PERIPH: {
628 struct periph_match_result *periph_result;
631 &ccb.cdm.matches[i].result.periph_result;
633 if (busonly || skip_device != 0)
637 fprintf(stdout, ",");
639 fprintf(stdout, "%s%d",
640 periph_result->periph_name,
641 periph_result->unit_number);
647 fprintf(stdout, "unknown match type\n");
652 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
653 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
656 fprintf(stdout, ")\n");
664 getdevtype(struct cam_device *cam_dev)
666 camcontrol_devtype dt;
670 * Get the device type and report it, request no I/O be done to do this.
672 error = get_device_type(cam_dev, -1, 0, 0, &dt);
673 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
674 fprintf(stdout, "illegal\n");
677 fprintf(stdout, "%s\n", devtype_names[dt]);
682 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
684 char vendor[16], product[48], revision[16];
686 cam_strvis(vendor, dev_result->inq_data.vendor,
687 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
688 cam_strvis(product, dev_result->inq_data.product,
689 sizeof(dev_result->inq_data.product), sizeof(product));
690 cam_strvis(revision, dev_result->inq_data.revision,
691 sizeof(dev_result->inq_data.revision), sizeof(revision));
692 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
698 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
700 char product[48], revision[16];
702 cam_strvis(product, dev_result->ident_data.model,
703 sizeof(dev_result->ident_data.model), sizeof(product));
704 cam_strvis(revision, dev_result->ident_data.revision,
705 sizeof(dev_result->ident_data.revision), sizeof(revision));
706 sprintf(tmpstr, "<%s %s>", product, revision);
712 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
714 struct sep_identify_data *sid;
715 char vendor[16], product[48], revision[16], fw[5];
717 sid = (struct sep_identify_data *)&dev_result->ident_data;
718 cam_strvis(vendor, sid->vendor_id,
719 sizeof(sid->vendor_id), sizeof(vendor));
720 cam_strvis(product, sid->product_id,
721 sizeof(sid->product_id), sizeof(product));
722 cam_strvis(revision, sid->product_rev,
723 sizeof(sid->product_rev), sizeof(revision));
724 cam_strvis(fw, sid->firmware_rev,
725 sizeof(sid->firmware_rev), sizeof(fw));
726 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
732 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
735 struct ccb_dev_advinfo *advi;
736 struct cam_device *dev;
737 struct mmc_params mmc_ident_data;
739 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
740 dev_result->target_lun, O_RDWR, NULL);
742 warnx("%s", cam_errbuf);
746 ccb = cam_getccb(dev);
748 warnx("couldn't allocate CCB");
749 cam_close_device(dev);
754 advi->ccb_h.flags = CAM_DIR_IN;
755 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
756 advi->flags = CDAI_FLAG_NONE;
757 advi->buftype = CDAI_TYPE_MMC_PARAMS;
758 advi->bufsiz = sizeof(struct mmc_params);
759 advi->buf = (uint8_t *)&mmc_ident_data;
761 if (cam_send_ccb(dev, ccb) < 0) {
762 warn("error sending XPT_DEV_ADVINFO CCB");
764 cam_close_device(dev);
768 if (strlen(mmc_ident_data.model) > 0) {
769 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
771 sprintf(tmpstr, "<%s card>",
772 mmc_ident_data.card_features &
773 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
777 cam_close_device(dev);
783 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
786 struct ccb_dev_advinfo *advi;
788 ccb = cam_getccb(dev);
790 warnx("couldn't allocate CCB");
791 cam_close_device(dev);
796 advi->ccb_h.flags = CAM_DIR_IN;
797 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
798 advi->flags = CDAI_FLAG_NONE;
799 advi->buftype = CDAI_TYPE_NVME_CNTRL;
800 advi->bufsiz = sizeof(struct nvme_controller_data);
801 advi->buf = (uint8_t *)cdata;
803 if (cam_send_ccb(dev, ccb) < 0) {
804 warn("error sending XPT_DEV_ADVINFO CCB");
806 cam_close_device(dev);
809 if (advi->ccb_h.status != CAM_REQ_CMP) {
810 warnx("got CAM error %#x", advi->ccb_h.status);
812 cam_close_device(dev);
820 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
822 struct cam_device *dev;
823 struct nvme_controller_data cdata;
824 char vendor[64], product[64];
826 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
827 dev_result->target_lun, O_RDWR, NULL);
829 warnx("%s", cam_errbuf);
833 if (nvme_get_cdata(dev, &cdata))
836 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
837 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
838 sprintf(tmpstr, "<%s %s>", vendor, product);
840 cam_close_device(dev);
846 testunitready(struct cam_device *device, int task_attr, int retry_count,
847 int timeout, int quiet)
852 ccb = cam_getccb(device);
854 scsi_test_unit_ready(&ccb->csio,
855 /* retries */ retry_count,
857 /* tag_action */ task_attr,
858 /* sense_len */ SSD_FULL_SIZE,
859 /* timeout */ timeout ? timeout : 5000);
861 /* Disable freezing the device queue */
862 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
864 if (arglist & CAM_ARG_ERR_RECOVER)
865 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
867 if (cam_send_ccb(device, ccb) < 0) {
869 warn("error sending TEST UNIT READY command");
874 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
876 fprintf(stdout, "Unit is ready\n");
879 fprintf(stdout, "Unit is not ready\n");
882 if (arglist & CAM_ARG_VERBOSE) {
883 cam_error_print(device, ccb, CAM_ESF_ALL,
884 CAM_EPF_ALL, stderr);
894 scsistart(struct cam_device *device, int startstop, int loadeject,
895 int task_attr, int retry_count, int timeout)
900 ccb = cam_getccb(device);
903 * If we're stopping, send an ordered tag so the drive in question
904 * will finish any previously queued writes before stopping. If
905 * the device isn't capable of tagged queueing, or if tagged
906 * queueing is turned off, the tag action is a no-op. We override
907 * the default simple tag, although this also has the effect of
908 * overriding the user's wishes if he wanted to specify a simple
912 && (task_attr == MSG_SIMPLE_Q_TAG))
913 task_attr = MSG_ORDERED_Q_TAG;
915 scsi_start_stop(&ccb->csio,
916 /* retries */ retry_count,
918 /* tag_action */ task_attr,
919 /* start/stop */ startstop,
920 /* load_eject */ loadeject,
922 /* sense_len */ SSD_FULL_SIZE,
923 /* timeout */ timeout ? timeout : 120000);
925 /* Disable freezing the device queue */
926 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
928 if (arglist & CAM_ARG_ERR_RECOVER)
929 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
931 if (cam_send_ccb(device, ccb) < 0) {
932 warn("error sending START STOP UNIT command");
937 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
939 fprintf(stdout, "Unit started successfully");
941 fprintf(stdout,", Media loaded\n");
943 fprintf(stdout,"\n");
945 fprintf(stdout, "Unit stopped successfully");
947 fprintf(stdout, ", Media ejected\n");
949 fprintf(stdout, "\n");
955 "Error received from start unit command\n");
958 "Error received from stop unit command\n");
960 if (arglist & CAM_ARG_VERBOSE) {
961 cam_error_print(device, ccb, CAM_ESF_ALL,
962 CAM_EPF_ALL, stderr);
972 scsidoinquiry(struct cam_device *device, int argc, char **argv,
973 char *combinedopt, int task_attr, int retry_count, int timeout)
978 while ((c = getopt(argc, argv, combinedopt)) != -1) {
981 arglist |= CAM_ARG_GET_STDINQ;
984 arglist |= CAM_ARG_GET_XFERRATE;
987 arglist |= CAM_ARG_GET_SERIAL;
995 * If the user didn't specify any inquiry options, he wants all of
998 if ((arglist & CAM_ARG_INQ_MASK) == 0)
999 arglist |= CAM_ARG_INQ_MASK;
1001 if (arglist & CAM_ARG_GET_STDINQ)
1002 error = scsiinquiry(device, task_attr, retry_count, timeout);
1007 if (arglist & CAM_ARG_GET_SERIAL)
1008 scsiserial(device, task_attr, retry_count, timeout);
1010 if (arglist & CAM_ARG_GET_XFERRATE)
1011 error = camxferrate(device);
1017 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1021 struct scsi_inquiry_data *inq_buf;
1024 ccb = cam_getccb(device);
1027 warnx("couldn't allocate CCB");
1031 inq_buf = (struct scsi_inquiry_data *)malloc(
1032 sizeof(struct scsi_inquiry_data));
1034 if (inq_buf == NULL) {
1036 warnx("can't malloc memory for inquiry\n");
1039 bzero(inq_buf, sizeof(*inq_buf));
1042 * Note that although the size of the inquiry buffer is the full
1043 * 256 bytes specified in the SCSI spec, we only tell the device
1044 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1045 * two reasons for this:
1047 * - The SCSI spec says that when a length field is only 1 byte,
1048 * a value of 0 will be interpreted as 256. Therefore
1049 * scsi_inquiry() will convert an inq_len (which is passed in as
1050 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1051 * to 0. Evidently, very few devices meet the spec in that
1052 * regard. Some devices, like many Seagate disks, take the 0 as
1053 * 0, and don't return any data. One Pioneer DVD-R drive
1054 * returns more data than the command asked for.
1056 * So, since there are numerous devices that just don't work
1057 * right with the full inquiry size, we don't send the full size.
1059 * - The second reason not to use the full inquiry data length is
1060 * that we don't need it here. The only reason we issue a
1061 * standard inquiry is to get the vendor name, device name,
1062 * and revision so scsi_print_inquiry() can print them.
1064 * If, at some point in the future, more inquiry data is needed for
1065 * some reason, this code should use a procedure similar to the
1066 * probe code. i.e., issue a short inquiry, and determine from
1067 * the additional length passed back from the device how much
1068 * inquiry data the device supports. Once the amount the device
1069 * supports is determined, issue an inquiry for that amount and no
1074 scsi_inquiry(&ccb->csio,
1075 /* retries */ retry_count,
1077 /* tag_action */ task_attr,
1078 /* inq_buf */ (u_int8_t *)inq_buf,
1079 /* inq_len */ SHORT_INQUIRY_LENGTH,
1082 /* sense_len */ SSD_FULL_SIZE,
1083 /* timeout */ timeout ? timeout : 5000);
1085 /* Disable freezing the device queue */
1086 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1088 if (arglist & CAM_ARG_ERR_RECOVER)
1089 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1091 if (cam_send_ccb(device, ccb) < 0) {
1092 warn("error sending INQUIRY command");
1097 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1100 if (arglist & CAM_ARG_VERBOSE) {
1101 cam_error_print(device, ccb, CAM_ESF_ALL,
1102 CAM_EPF_ALL, stderr);
1113 fprintf(stdout, "%s%d: ", device->device_name,
1114 device->dev_unit_num);
1115 scsi_print_inquiry(inq_buf);
1123 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1127 struct scsi_vpd_unit_serial_number *serial_buf;
1128 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1131 ccb = cam_getccb(device);
1134 warnx("couldn't allocate CCB");
1138 serial_buf = (struct scsi_vpd_unit_serial_number *)
1139 malloc(sizeof(*serial_buf));
1141 if (serial_buf == NULL) {
1143 warnx("can't malloc memory for serial number");
1147 scsi_inquiry(&ccb->csio,
1148 /*retries*/ retry_count,
1150 /* tag_action */ task_attr,
1151 /* inq_buf */ (u_int8_t *)serial_buf,
1152 /* inq_len */ sizeof(*serial_buf),
1154 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1155 /* sense_len */ SSD_FULL_SIZE,
1156 /* timeout */ timeout ? timeout : 5000);
1158 /* Disable freezing the device queue */
1159 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1161 if (arglist & CAM_ARG_ERR_RECOVER)
1162 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1164 if (cam_send_ccb(device, ccb) < 0) {
1165 warn("error sending INQUIRY command");
1171 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1174 if (arglist & CAM_ARG_VERBOSE) {
1175 cam_error_print(device, ccb, CAM_ESF_ALL,
1176 CAM_EPF_ALL, stderr);
1187 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1188 serial_num[serial_buf->length] = '\0';
1190 if ((arglist & CAM_ARG_GET_STDINQ)
1191 || (arglist & CAM_ARG_GET_XFERRATE))
1192 fprintf(stdout, "%s%d: Serial Number ",
1193 device->device_name, device->dev_unit_num);
1195 fprintf(stdout, "%.60s\n", serial_num);
1203 camxferrate(struct cam_device *device)
1205 struct ccb_pathinq cpi;
1207 u_int32_t speed = 0;
1212 if ((retval = get_cpi(device, &cpi)) != 0)
1215 ccb = cam_getccb(device);
1218 warnx("couldn't allocate CCB");
1222 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1223 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1225 if (((retval = cam_send_ccb(device, ccb)) < 0)
1226 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1227 const char error_string[] = "error getting transfer settings";
1232 warnx(error_string);
1234 if (arglist & CAM_ARG_VERBOSE)
1235 cam_error_print(device, ccb, CAM_ESF_ALL,
1236 CAM_EPF_ALL, stderr);
1240 goto xferrate_bailout;
1244 speed = cpi.base_transfer_speed;
1246 if (ccb->cts.transport == XPORT_SPI) {
1247 struct ccb_trans_settings_spi *spi =
1248 &ccb->cts.xport_specific.spi;
1250 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1251 freq = scsi_calc_syncsrate(spi->sync_period);
1254 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1255 speed *= (0x01 << spi->bus_width);
1257 } else if (ccb->cts.transport == XPORT_FC) {
1258 struct ccb_trans_settings_fc *fc =
1259 &ccb->cts.xport_specific.fc;
1261 if (fc->valid & CTS_FC_VALID_SPEED)
1262 speed = fc->bitrate;
1263 } else if (ccb->cts.transport == XPORT_SAS) {
1264 struct ccb_trans_settings_sas *sas =
1265 &ccb->cts.xport_specific.sas;
1267 if (sas->valid & CTS_SAS_VALID_SPEED)
1268 speed = sas->bitrate;
1269 } else if (ccb->cts.transport == XPORT_ATA) {
1270 struct ccb_trans_settings_pata *pata =
1271 &ccb->cts.xport_specific.ata;
1273 if (pata->valid & CTS_ATA_VALID_MODE)
1274 speed = ata_mode2speed(pata->mode);
1275 } else if (ccb->cts.transport == XPORT_SATA) {
1276 struct ccb_trans_settings_sata *sata =
1277 &ccb->cts.xport_specific.sata;
1279 if (sata->valid & CTS_SATA_VALID_REVISION)
1280 speed = ata_revision2speed(sata->revision);
1285 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1286 device->device_name, device->dev_unit_num,
1289 fprintf(stdout, "%s%d: %dKB/s transfers",
1290 device->device_name, device->dev_unit_num,
1294 if (ccb->cts.transport == XPORT_SPI) {
1295 struct ccb_trans_settings_spi *spi =
1296 &ccb->cts.xport_specific.spi;
1298 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1299 && (spi->sync_offset != 0))
1300 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1301 freq % 1000, spi->sync_offset);
1303 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1304 && (spi->bus_width > 0)) {
1305 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1306 && (spi->sync_offset != 0)) {
1307 fprintf(stdout, ", ");
1309 fprintf(stdout, " (");
1311 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1312 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1313 && (spi->sync_offset != 0)) {
1314 fprintf(stdout, ")");
1316 } else if (ccb->cts.transport == XPORT_ATA) {
1317 struct ccb_trans_settings_pata *pata =
1318 &ccb->cts.xport_specific.ata;
1321 if (pata->valid & CTS_ATA_VALID_MODE)
1322 printf("%s, ", ata_mode2string(pata->mode));
1323 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1324 printf("ATAPI %dbytes, ", pata->atapi);
1325 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1326 printf("PIO %dbytes", pata->bytecount);
1328 } else if (ccb->cts.transport == XPORT_SATA) {
1329 struct ccb_trans_settings_sata *sata =
1330 &ccb->cts.xport_specific.sata;
1333 if (sata->valid & CTS_SATA_VALID_REVISION)
1334 printf("SATA %d.x, ", sata->revision);
1337 if (sata->valid & CTS_SATA_VALID_MODE)
1338 printf("%s, ", ata_mode2string(sata->mode));
1339 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1340 printf("ATAPI %dbytes, ", sata->atapi);
1341 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1342 printf("PIO %dbytes", sata->bytecount);
1346 if (ccb->cts.protocol == PROTO_SCSI) {
1347 struct ccb_trans_settings_scsi *scsi =
1348 &ccb->cts.proto_specific.scsi;
1349 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1350 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1351 fprintf(stdout, ", Command Queueing Enabled");
1356 fprintf(stdout, "\n");
1366 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1368 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1369 ((u_int32_t)parm->lba_size_2 << 16);
1371 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1372 ((u_int64_t)parm->lba_size48_2 << 16) |
1373 ((u_int64_t)parm->lba_size48_3 << 32) |
1374 ((u_int64_t)parm->lba_size48_4 << 48);
1378 "Support Enabled Value\n");
1381 printf("Host Protected Area (HPA) ");
1382 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1383 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1384 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1387 printf("HPA - Security ");
1388 if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY)
1389 printf("yes %s\n", (parm->enabled.command2 &
1390 ATA_SUPPORT_MAXSECURITY) ? "yes" : "no ");
1399 ataama_print(struct ata_params *parm, u_int64_t nativesize, int header)
1401 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1402 ((u_int32_t)parm->lba_size_2 << 16);
1404 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1405 ((u_int64_t)parm->lba_size48_2 << 16) |
1406 ((u_int64_t)parm->lba_size48_3 << 32) |
1407 ((u_int64_t)parm->lba_size48_4 << 48);
1411 "Support Enabled Value\n");
1414 printf("Accessible Max Address Config ");
1415 if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) {
1416 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1417 printf("yes %s %ju/%ju\n",
1418 (nativesize > lba) ? "yes" : "no ", lba, nativesize);
1425 atasata(struct ata_params *parm)
1429 if (parm->satacapabilities != 0xffff &&
1430 parm->satacapabilities != 0x0000)
1437 atacapprint(struct ata_params *parm)
1440 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1441 ((u_int32_t)parm->lba_size_2 << 16);
1443 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1444 ((u_int64_t)parm->lba_size48_2 << 16) |
1445 ((u_int64_t)parm->lba_size48_3 << 32) |
1446 ((u_int64_t)parm->lba_size48_4 << 48);
1449 printf("protocol ");
1450 proto = (parm->config == ATA_PROTO_CFA) ? "CFA" :
1451 (parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
1452 if (ata_version(parm->version_major) == 0) {
1453 printf("%s", proto);
1454 } else if (ata_version(parm->version_major) <= 7) {
1455 printf("%s-%d", proto,
1456 ata_version(parm->version_major));
1457 } else if (ata_version(parm->version_major) == 8) {
1458 printf("%s8-ACS", proto);
1461 ata_version(parm->version_major) - 7, proto);
1463 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1464 if (parm->satacapabilities & ATA_SATA_GEN3)
1465 printf(" SATA 3.x\n");
1466 else if (parm->satacapabilities & ATA_SATA_GEN2)
1467 printf(" SATA 2.x\n");
1468 else if (parm->satacapabilities & ATA_SATA_GEN1)
1469 printf(" SATA 1.x\n");
1475 printf("device model %.40s\n", parm->model);
1476 printf("firmware revision %.8s\n", parm->revision);
1477 printf("serial number %.20s\n", parm->serial);
1478 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1479 printf("WWN %04x%04x%04x%04x\n",
1480 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1482 printf("additional product id %.8s\n", parm->product_id);
1483 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1484 printf("media serial number %.30s\n",
1485 parm->media_serial);
1488 printf("cylinders %d\n", parm->cylinders);
1489 printf("heads %d\n", parm->heads);
1490 printf("sectors/track %d\n", parm->sectors);
1491 printf("sector size logical %u, physical %lu, offset %lu\n",
1492 ata_logical_sector_size(parm),
1493 (unsigned long)ata_physical_sector_size(parm),
1494 (unsigned long)ata_logical_sector_offset(parm));
1496 if (parm->config == ATA_PROTO_CFA ||
1497 (parm->support.command2 & ATA_SUPPORT_CFA))
1498 printf("CFA supported\n");
1500 printf("LBA%ssupported ",
1501 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1503 printf("%d sectors\n", lbasize);
1507 printf("LBA48%ssupported ",
1508 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1510 printf("%ju sectors\n", (uintmax_t)lbasize48);
1514 printf("PIO supported PIO");
1515 switch (ata_max_pmode(parm)) {
1531 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1532 printf(" w/o IORDY");
1535 printf("DMA%ssupported ",
1536 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1537 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1538 if (parm->mwdmamodes & 0xff) {
1540 if (parm->mwdmamodes & 0x04)
1542 else if (parm->mwdmamodes & 0x02)
1544 else if (parm->mwdmamodes & 0x01)
1548 if ((parm->atavalid & ATA_FLAG_88) &&
1549 (parm->udmamodes & 0xff)) {
1551 if (parm->udmamodes & 0x40)
1553 else if (parm->udmamodes & 0x20)
1555 else if (parm->udmamodes & 0x10)
1557 else if (parm->udmamodes & 0x08)
1559 else if (parm->udmamodes & 0x04)
1561 else if (parm->udmamodes & 0x02)
1563 else if (parm->udmamodes & 0x01)
1570 if (parm->media_rotation_rate == 1) {
1571 printf("media RPM non-rotating\n");
1572 } else if (parm->media_rotation_rate >= 0x0401 &&
1573 parm->media_rotation_rate <= 0xFFFE) {
1574 printf("media RPM %d\n",
1575 parm->media_rotation_rate);
1578 printf("Zoned-Device Commands ");
1579 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1580 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1581 printf("device managed\n");
1583 case ATA_SUPPORT_ZONE_HOST_AWARE:
1584 printf("host aware\n");
1591 "Support Enabled Value Vendor\n");
1592 printf("read ahead %s %s\n",
1593 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1594 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1595 printf("write cache %s %s\n",
1596 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1597 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1598 printf("flush cache %s %s\n",
1599 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1600 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1601 printf("Native Command Queuing (NCQ) ");
1602 if (atasata(parm) && (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1603 printf("yes %d tags\n",
1604 ATA_QUEUE_LEN(parm->queue) + 1);
1605 printf("NCQ Priority Information %s\n",
1606 parm->satacapabilities & ATA_SUPPORT_NCQ_PRIO ?
1608 printf("NCQ Non-Data Command %s\n",
1609 parm->satacapabilities2 & ATA_SUPPORT_NCQ_NON_DATA ?
1611 printf("NCQ Streaming %s\n",
1612 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1614 printf("Receive & Send FPDMA Queued %s\n",
1615 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1617 printf("NCQ Autosense %s\n",
1618 parm->satasupport & ATA_SUPPORT_NCQ_AUTOSENSE ?
1623 printf("SMART %s %s\n",
1624 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1625 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1626 printf("security %s %s\n",
1627 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1628 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1629 printf("power management %s %s\n",
1630 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1631 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1632 printf("microcode download %s %s\n",
1633 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1634 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1635 printf("advanced power management %s %s",
1636 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1637 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1638 if (parm->support.command2 & ATA_SUPPORT_APM) {
1639 printf(" %d/0x%02X\n",
1640 parm->apm_value & 0xff, parm->apm_value & 0xff);
1643 printf("automatic acoustic management %s %s",
1644 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1645 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1646 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1647 printf(" %d/0x%02X %d/0x%02X\n",
1648 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1649 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1650 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1651 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1654 printf("media status notification %s %s\n",
1655 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1656 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1657 printf("power-up in Standby %s %s\n",
1658 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1659 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1660 printf("write-read-verify %s %s",
1661 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1662 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1663 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1664 printf(" %d/0x%x\n",
1665 parm->wrv_mode, parm->wrv_mode);
1668 printf("unload %s %s\n",
1669 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1670 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1671 printf("general purpose logging %s %s\n",
1672 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1673 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1674 printf("free-fall %s %s\n",
1675 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1676 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1677 printf("sense data reporting %s %s\n",
1678 parm->support2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no",
1679 parm->enabled2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no");
1680 printf("extended power conditions %s %s\n",
1681 parm->support2 & ATA_SUPPORT_EPC ? "yes" : "no",
1682 parm->enabled2 & ATA_SUPPORT_EPC ? "yes" : "no");
1683 printf("device statistics notification %s %s\n",
1684 parm->support2 & ATA_SUPPORT_DSN ? "yes" : "no",
1685 parm->enabled2 & ATA_SUPPORT_DSN ? "yes" : "no");
1686 printf("Data Set Management (DSM/TRIM) ");
1687 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1689 printf("DSM - max 512byte blocks ");
1690 if (parm->max_dsm_blocks == 0x00)
1691 printf("yes not specified\n");
1694 parm->max_dsm_blocks);
1696 printf("DSM - deterministic read ");
1697 if (parm->support3 & ATA_SUPPORT_DRAT) {
1698 if (parm->support3 & ATA_SUPPORT_RZAT)
1699 printf("yes zeroed\n");
1701 printf("yes any value\n");
1708 printf("Trusted Computing %s\n",
1709 ((parm->tcg & 0xc000) == 0x4000) && (parm->tcg & ATA_SUPPORT_TCG) ?
1711 printf("encrypts all user data %s\n",
1712 parm->support3 & ATA_ENCRYPTS_ALL_USER_DATA ? "yes" : "no");
1713 printf("Sanitize ");
1714 if (parm->multi & ATA_SUPPORT_SANITIZE) {
1715 printf("yes\t\t%s%s%s\n",
1716 parm->multi & ATA_SUPPORT_BLOCK_ERASE_EXT ? "block, " : "",
1717 parm->multi & ATA_SUPPORT_OVERWRITE_EXT ? "overwrite, " : "",
1718 parm->multi & ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT ? "crypto" : "");
1719 printf("Sanitize - commands allowed %s\n",
1720 parm->multi & ATA_SUPPORT_SANITIZE_ALLOWED ? "yes" : "no");
1721 printf("Sanitize - antifreeze lock %s\n",
1722 parm->multi & ATA_SUPPORT_ANTIFREEZE_LOCK_EXT ? "yes" : "no");
1729 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb)
1731 struct ata_pass_16 *ata_pass_16;
1732 struct ata_cmd ata_cmd;
1734 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1735 ata_cmd.command = ata_pass_16->command;
1736 ata_cmd.control = ata_pass_16->control;
1737 ata_cmd.features = ata_pass_16->features;
1739 if (arglist & CAM_ARG_VERBOSE) {
1740 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1741 ata_op_string(&ata_cmd),
1742 ccb->csio.ccb_h.timeout);
1745 /* Disable freezing the device queue */
1746 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1748 if (arglist & CAM_ARG_ERR_RECOVER)
1749 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1751 if (cam_send_ccb(device, ccb) < 0) {
1752 warn("error sending ATA %s via pass_16", ata_op_string(&ata_cmd));
1757 * Consider any non-CAM_REQ_CMP status as error and report it here,
1758 * unless caller set AP_FLAG_CHK_COND, in which case it is responsible.
1760 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1761 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1762 warnx("ATA %s via pass_16 failed", ata_op_string(&ata_cmd));
1763 if (arglist & CAM_ARG_VERBOSE) {
1764 cam_error_print(device, ccb, CAM_ESF_ALL,
1765 CAM_EPF_ALL, stderr);
1775 ata_cam_send(struct cam_device *device, union ccb *ccb)
1777 if (arglist & CAM_ARG_VERBOSE) {
1778 warnx("sending ATA %s with timeout of %u msecs",
1779 ata_op_string(&(ccb->ataio.cmd)),
1780 ccb->ataio.ccb_h.timeout);
1783 /* Disable freezing the device queue */
1784 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1786 if (arglist & CAM_ARG_ERR_RECOVER)
1787 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1789 if (cam_send_ccb(device, ccb) < 0) {
1790 warn("error sending ATA %s", ata_op_string(&(ccb->ataio.cmd)));
1795 * Consider any non-CAM_REQ_CMP status as error and report it here,
1796 * unless caller set AP_FLAG_CHK_COND, in which case it is responsible.
1798 if (!(ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT) &&
1799 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1800 warnx("ATA %s failed", ata_op_string(&(ccb->ataio.cmd)));
1801 if (arglist & CAM_ARG_VERBOSE) {
1802 cam_error_print(device, ccb, CAM_ESF_ALL,
1803 CAM_EPF_ALL, stderr);
1812 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1813 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1814 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1815 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1816 u_int16_t dxfer_len, int timeout)
1818 if (data_ptr != NULL) {
1819 if (flags & CAM_DIR_OUT)
1820 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1822 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1824 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1827 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1829 scsi_ata_pass_16(&ccb->csio,
1843 /*sense_len*/SSD_FULL_SIZE,
1846 return scsi_cam_pass_16_send(device, ccb);
1850 ata_try_pass_16(struct cam_device *device)
1852 struct ccb_pathinq cpi;
1854 if (get_cpi(device, &cpi) != 0) {
1855 warnx("couldn't get CPI");
1859 if (cpi.protocol == PROTO_SCSI) {
1860 /* possibly compatible with pass_16 */
1864 /* likely not compatible with pass_16 */
1869 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1870 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1871 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1872 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1873 u_int16_t dxfer_len, int timeout, int force48bit)
1877 retval = ata_try_pass_16(device);
1882 return (ata_do_pass_16(device, ccb, retries, flags, protocol,
1883 ata_flags, tag_action, command, features,
1884 lba, sector_count, data_ptr, dxfer_len,
1888 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1889 cam_fill_ataio(&ccb->ataio,
1898 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1899 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1901 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1903 if (ata_flags & AP_FLAG_CHK_COND)
1904 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1906 return ata_cam_send(device, ccb);
1910 dump_data(uint16_t *ptr, uint32_t len)
1914 for (i = 0; i < len / 2; i++) {
1916 printf(" %3d: ", i);
1917 printf("%04hx ", ptr[i]);
1926 atahpa_proc_resp(struct cam_device *device, union ccb *ccb, u_int64_t *hpasize)
1928 uint8_t error = 0, ata_device = 0, status = 0;
1933 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
1936 if (arglist & CAM_ARG_VERBOSE) {
1937 cam_error_print(device, ccb, CAM_ESF_ALL,
1938 CAM_EPF_ALL, stderr);
1940 warnx("Can't get ATA command status");
1944 if (status & ATA_STATUS_ERROR) {
1945 if (arglist & CAM_ARG_VERBOSE) {
1946 cam_error_print(device, ccb, CAM_ESF_ALL,
1947 CAM_EPF_ALL, stderr);
1950 if (error & ATA_ERROR_ID_NOT_FOUND) {
1951 warnx("Max address has already been set since "
1952 "last power-on or hardware reset");
1953 } else if (hpasize == NULL)
1954 warnx("Command failed with ATA error");
1959 if (hpasize != NULL) {
1960 if (retval == 2 || retval == 6)
1969 ata_read_native_max(struct cam_device *device, int retry_count,
1970 u_int32_t timeout, union ccb *ccb,
1971 struct ata_params *parm, u_int64_t *hpasize)
1977 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1978 protocol = AP_PROTO_NON_DATA;
1981 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1982 protocol |= AP_EXTEND;
1984 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1987 error = ata_do_cmd(device,
1990 /*flags*/CAM_DIR_NONE,
1991 /*protocol*/protocol,
1992 /*ata_flags*/AP_FLAG_CHK_COND,
1993 /*tag_action*/MSG_SIMPLE_Q_TAG,
2000 timeout ? timeout : 5000,
2006 return atahpa_proc_resp(device, ccb, hpasize);
2010 atahpa_set_max(struct cam_device *device, int retry_count,
2011 u_int32_t timeout, union ccb *ccb,
2012 int is48bit, u_int64_t maxsize, int persist)
2018 protocol = AP_PROTO_NON_DATA;
2021 cmd = ATA_SET_MAX_ADDRESS48;
2022 protocol |= AP_EXTEND;
2024 cmd = ATA_SET_MAX_ADDRESS;
2027 /* lba's are zero indexed so the max lba is requested max - 1 */
2031 error = ata_do_cmd(device,
2034 /*flags*/CAM_DIR_NONE,
2035 /*protocol*/protocol,
2036 /*ata_flags*/AP_FLAG_CHK_COND,
2037 /*tag_action*/MSG_SIMPLE_Q_TAG,
2039 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2041 /*sector_count*/persist,
2044 timeout ? timeout : 1000,
2050 return atahpa_proc_resp(device, ccb, NULL);
2054 atahpa_password(struct cam_device *device, int retry_count,
2055 u_int32_t timeout, union ccb *ccb,
2056 int is48bit, struct ata_set_max_pwd *pwd)
2061 protocol = AP_PROTO_PIO_OUT;
2062 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2064 return (ata_do_cmd(device,
2067 /*flags*/CAM_DIR_OUT,
2068 /*protocol*/protocol,
2069 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2070 AP_FLAG_TLEN_SECT_CNT,
2071 /*tag_action*/MSG_SIMPLE_Q_TAG,
2073 /*features*/ATA_HPA_FEAT_SET_PWD,
2075 /*sector_count*/sizeof(*pwd) / 512,
2076 /*data_ptr*/(u_int8_t*)pwd,
2077 /*dxfer_len*/sizeof(*pwd),
2078 timeout ? timeout : 1000,
2083 atahpa_lock(struct cam_device *device, int retry_count,
2084 u_int32_t timeout, union ccb *ccb, int is48bit)
2089 protocol = AP_PROTO_NON_DATA;
2090 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2092 return (ata_do_cmd(device,
2095 /*flags*/CAM_DIR_NONE,
2096 /*protocol*/protocol,
2098 /*tag_action*/MSG_SIMPLE_Q_TAG,
2100 /*features*/ATA_HPA_FEAT_LOCK,
2105 timeout ? timeout : 1000,
2110 atahpa_unlock(struct cam_device *device, int retry_count,
2111 u_int32_t timeout, union ccb *ccb,
2112 int is48bit, struct ata_set_max_pwd *pwd)
2117 protocol = AP_PROTO_PIO_OUT;
2118 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2120 return (ata_do_cmd(device,
2123 /*flags*/CAM_DIR_OUT,
2124 /*protocol*/protocol,
2125 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2126 AP_FLAG_TLEN_SECT_CNT,
2127 /*tag_action*/MSG_SIMPLE_Q_TAG,
2129 /*features*/ATA_HPA_FEAT_UNLOCK,
2131 /*sector_count*/sizeof(*pwd) / 512,
2132 /*data_ptr*/(u_int8_t*)pwd,
2133 /*dxfer_len*/sizeof(*pwd),
2134 timeout ? timeout : 1000,
2139 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2140 u_int32_t timeout, union ccb *ccb, int is48bit)
2145 protocol = AP_PROTO_NON_DATA;
2146 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2148 return (ata_do_cmd(device,
2151 /*flags*/CAM_DIR_NONE,
2152 /*protocol*/protocol,
2154 /*tag_action*/MSG_SIMPLE_Q_TAG,
2156 /*features*/ATA_HPA_FEAT_FREEZE,
2161 timeout ? timeout : 1000,
2166 ata_get_native_max(struct cam_device *device, int retry_count,
2167 u_int32_t timeout, union ccb *ccb,
2168 u_int64_t *nativesize)
2172 error = ata_do_cmd(device,
2175 /*flags*/CAM_DIR_NONE,
2176 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2177 /*ata_flags*/AP_FLAG_CHK_COND,
2178 /*tag_action*/MSG_SIMPLE_Q_TAG,
2179 /*command*/ATA_AMAX_ADDR,
2180 /*features*/ATA_AMAX_ADDR_GET,
2185 timeout ? timeout : 30 * 1000,
2191 return atahpa_proc_resp(device, ccb, nativesize);
2195 ataama_set(struct cam_device *device, int retry_count,
2196 u_int32_t timeout, union ccb *ccb, u_int64_t maxsize)
2200 /* lba's are zero indexed so the max lba is requested max - 1 */
2204 error = ata_do_cmd(device,
2207 /*flags*/CAM_DIR_NONE,
2208 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2209 /*ata_flags*/AP_FLAG_CHK_COND,
2210 /*tag_action*/MSG_SIMPLE_Q_TAG,
2211 /*command*/ATA_AMAX_ADDR,
2212 /*features*/ATA_AMAX_ADDR_SET,
2217 timeout ? timeout : 30 * 1000,
2223 return atahpa_proc_resp(device, ccb, NULL);
2227 ataama_freeze(struct cam_device *device, int retry_count,
2228 u_int32_t timeout, union ccb *ccb)
2231 return (ata_do_cmd(device,
2234 /*flags*/CAM_DIR_NONE,
2235 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2237 /*tag_action*/MSG_SIMPLE_Q_TAG,
2238 /*command*/ATA_AMAX_ADDR,
2239 /*features*/ATA_AMAX_ADDR_FREEZE,
2244 timeout ? timeout : 30 * 1000,
2249 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2250 union ccb *ccb, struct ata_params** ident_bufp)
2252 struct ata_params *ident_buf;
2253 struct ccb_pathinq cpi;
2254 struct ccb_getdev cgd;
2257 u_int8_t command, retry_command;
2259 if (get_cpi(device, &cpi) != 0) {
2260 warnx("couldn't get CPI");
2264 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2265 if (cpi.protocol == PROTO_ATA) {
2266 if (get_cgd(device, &cgd) != 0) {
2267 warnx("couldn't get CGD");
2271 command = (cgd.protocol == PROTO_ATA) ?
2272 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2275 /* We don't know which for sure so try both */
2276 command = ATA_ATA_IDENTIFY;
2277 retry_command = ATA_ATAPI_IDENTIFY;
2280 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2282 warnx("can't calloc memory for identify\n");
2287 error = ata_do_cmd(device,
2289 /*retries*/retry_count,
2290 /*flags*/CAM_DIR_IN,
2291 /*protocol*/AP_PROTO_PIO_IN,
2292 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2293 AP_FLAG_TLEN_SECT_CNT,
2294 /*tag_action*/MSG_SIMPLE_Q_TAG,
2298 /*sector_count*/sizeof(struct ata_params) / 512,
2299 /*data_ptr*/(u_int8_t *)ptr,
2300 /*dxfer_len*/sizeof(struct ata_params),
2301 /*timeout*/timeout ? timeout : 30 * 1000,
2305 if (retry_command != 0) {
2306 command = retry_command;
2314 ident_buf = (struct ata_params *)ptr;
2315 ata_param_fixup(ident_buf);
2318 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2323 /* check for invalid (all zero) response */
2325 warnx("Invalid identify response detected");
2330 *ident_bufp = ident_buf;
2337 ataidentify(struct cam_device *device, int retry_count, int timeout)
2340 struct ata_params *ident_buf;
2341 u_int64_t hpasize = 0, nativesize = 0;
2343 if ((ccb = cam_getccb(device)) == NULL) {
2344 warnx("couldn't allocate CCB");
2348 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2353 if (arglist & CAM_ARG_VERBOSE) {
2354 printf("%s%d: Raw identify data:\n",
2355 device->device_name, device->dev_unit_num);
2356 dump_data((uint16_t *)ident_buf, sizeof(struct ata_params));
2359 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2360 ata_read_native_max(device, retry_count, timeout, ccb,
2361 ident_buf, &hpasize);
2363 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2364 ata_get_native_max(device, retry_count, timeout, ccb,
2368 printf("%s%d: ", device->device_name, device->dev_unit_num);
2369 ata_print_ident(ident_buf);
2370 camxferrate(device);
2371 atacapprint(ident_buf);
2372 atahpa_print(ident_buf, hpasize, 0);
2373 ataama_print(ident_buf, nativesize, 0);
2383 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2385 struct nvme_controller_data cdata;
2387 if (nvme_get_cdata(device, &cdata))
2389 nvme_print_controller(&cdata);
2396 identify(struct cam_device *device, int retry_count, int timeout)
2399 struct ccb_pathinq cpi;
2401 if (get_cpi(device, &cpi) != 0) {
2402 warnx("couldn't get CPI");
2406 if (cpi.protocol == PROTO_NVME) {
2407 return (nvmeidentify(device, retry_count, timeout));
2410 return (ataidentify(device, retry_count, timeout));
2415 ATA_SECURITY_ACTION_PRINT,
2416 ATA_SECURITY_ACTION_FREEZE,
2417 ATA_SECURITY_ACTION_UNLOCK,
2418 ATA_SECURITY_ACTION_DISABLE,
2419 ATA_SECURITY_ACTION_ERASE,
2420 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2421 ATA_SECURITY_ACTION_SET_PASSWORD
2425 atasecurity_print_time(u_int16_t tw)
2429 printf("unspecified");
2431 printf("> 508 min");
2433 printf("%i min", 2 * tw);
2437 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2441 return 2 * 3600 * 1000; /* default: two hours */
2442 else if (timeout > 255)
2443 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2445 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2450 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2454 bzero(&cmd, sizeof(cmd));
2455 cmd.command = command;
2456 printf("Issuing %s", ata_op_string(&cmd));
2459 /* pwd->password may not be null terminated */
2460 char pass[sizeof(pwd->password)+1];
2462 strlcpy(pass, pwd->password, sizeof(pass));
2463 printf(" password='%s', user='%s'",
2465 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2468 if (command == ATA_SECURITY_SET_PASSWORD) {
2469 printf(", mode='%s'",
2470 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2471 "maximum" : "high");
2479 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2480 int retry_count, u_int32_t timeout, int quiet)
2484 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2486 return ata_do_cmd(device,
2489 /*flags*/CAM_DIR_NONE,
2490 /*protocol*/AP_PROTO_NON_DATA,
2492 /*tag_action*/MSG_SIMPLE_Q_TAG,
2493 /*command*/ATA_SECURITY_FREEZE_LOCK,
2504 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2505 int retry_count, u_int32_t timeout,
2506 struct ata_security_password *pwd, int quiet)
2510 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2512 return ata_do_cmd(device,
2515 /*flags*/CAM_DIR_OUT,
2516 /*protocol*/AP_PROTO_PIO_OUT,
2517 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2518 AP_FLAG_TLEN_SECT_CNT,
2519 /*tag_action*/MSG_SIMPLE_Q_TAG,
2520 /*command*/ATA_SECURITY_UNLOCK,
2523 /*sector_count*/sizeof(*pwd) / 512,
2524 /*data_ptr*/(u_int8_t *)pwd,
2525 /*dxfer_len*/sizeof(*pwd),
2531 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2532 int retry_count, u_int32_t timeout,
2533 struct ata_security_password *pwd, int quiet)
2537 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2538 return ata_do_cmd(device,
2541 /*flags*/CAM_DIR_OUT,
2542 /*protocol*/AP_PROTO_PIO_OUT,
2543 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2544 AP_FLAG_TLEN_SECT_CNT,
2545 /*tag_action*/MSG_SIMPLE_Q_TAG,
2546 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2549 /*sector_count*/sizeof(*pwd) / 512,
2550 /*data_ptr*/(u_int8_t *)pwd,
2551 /*dxfer_len*/sizeof(*pwd),
2558 atasecurity_erase_confirm(struct cam_device *device,
2559 struct ata_params* ident_buf)
2562 printf("\nYou are about to ERASE ALL DATA from the following"
2563 " device:\n%s%d,%s%d: ", device->device_name,
2564 device->dev_unit_num, device->given_dev_name,
2565 device->given_unit_number);
2566 ata_print_ident(ident_buf);
2570 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2572 if (fgets(str, sizeof(str), stdin) != NULL) {
2573 if (strncasecmp(str, "yes", 3) == 0) {
2575 } else if (strncasecmp(str, "no", 2) == 0) {
2578 printf("Please answer \"yes\" or "
2589 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2590 int retry_count, u_int32_t timeout,
2591 u_int32_t erase_timeout,
2592 struct ata_security_password *pwd, int quiet)
2597 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2599 error = ata_do_cmd(device,
2602 /*flags*/CAM_DIR_NONE,
2603 /*protocol*/AP_PROTO_NON_DATA,
2605 /*tag_action*/MSG_SIMPLE_Q_TAG,
2606 /*command*/ATA_SECURITY_ERASE_PREPARE,
2619 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2621 error = ata_do_cmd(device,
2624 /*flags*/CAM_DIR_OUT,
2625 /*protocol*/AP_PROTO_PIO_OUT,
2626 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2627 AP_FLAG_TLEN_SECT_CNT,
2628 /*tag_action*/MSG_SIMPLE_Q_TAG,
2629 /*command*/ATA_SECURITY_ERASE_UNIT,
2632 /*sector_count*/sizeof(*pwd) / 512,
2633 /*data_ptr*/(u_int8_t *)pwd,
2634 /*dxfer_len*/sizeof(*pwd),
2635 /*timeout*/erase_timeout,
2638 if (error == 0 && quiet == 0)
2639 printf("\nErase Complete\n");
2645 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2646 int retry_count, u_int32_t timeout,
2647 struct ata_security_password *pwd, int quiet)
2651 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2653 return ata_do_cmd(device,
2656 /*flags*/CAM_DIR_OUT,
2657 /*protocol*/AP_PROTO_PIO_OUT,
2658 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2659 AP_FLAG_TLEN_SECT_CNT,
2660 /*tag_action*/MSG_SIMPLE_Q_TAG,
2661 /*command*/ATA_SECURITY_SET_PASSWORD,
2664 /*sector_count*/sizeof(*pwd) / 512,
2665 /*data_ptr*/(u_int8_t *)pwd,
2666 /*dxfer_len*/sizeof(*pwd),
2672 atasecurity_print(struct ata_params *parm)
2675 printf("\nSecurity Option Value\n");
2676 if (arglist & CAM_ARG_VERBOSE) {
2677 printf("status %04x\n",
2678 parm->security_status);
2680 printf("supported %s\n",
2681 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2682 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2684 printf("enabled %s\n",
2685 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2686 printf("drive locked %s\n",
2687 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2688 printf("security config frozen %s\n",
2689 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2690 printf("count expired %s\n",
2691 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2692 printf("security level %s\n",
2693 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2694 printf("enhanced erase supported %s\n",
2695 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2696 printf("erase time ");
2697 atasecurity_print_time(parm->erase_time);
2699 printf("enhanced erase time ");
2700 atasecurity_print_time(parm->enhanced_erase_time);
2702 printf("master password rev %04x%s\n",
2703 parm->master_passwd_revision,
2704 parm->master_passwd_revision == 0x0000 ||
2705 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2709 * Validates and copies the password in optarg to the passed buffer.
2710 * If the password in optarg is the same length as the buffer then
2711 * the data will still be copied but no null termination will occur.
2714 ata_getpwd(u_int8_t *passwd, int max, char opt)
2718 len = strlen(optarg);
2720 warnx("-%c password is too long", opt);
2722 } else if (len == 0) {
2723 warnx("-%c password is missing", opt);
2725 } else if (optarg[0] == '-'){
2726 warnx("-%c password starts with '-' (generic arg?)", opt);
2728 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2729 warnx("-%c password conflicts with existing password from -%c",
2734 /* Callers pass in a buffer which does NOT need to be terminated */
2735 strncpy(passwd, optarg, max);
2742 ATA_HPA_ACTION_PRINT,
2743 ATA_HPA_ACTION_SET_MAX,
2744 ATA_HPA_ACTION_SET_PWD,
2745 ATA_HPA_ACTION_LOCK,
2746 ATA_HPA_ACTION_UNLOCK,
2747 ATA_HPA_ACTION_FREEZE_LOCK
2751 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2752 u_int64_t maxsize, int persist)
2754 printf("\nYou are about to configure HPA to limit the user accessible\n"
2755 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2756 persist ? "persistently" : "temporarily",
2757 device->device_name, device->dev_unit_num,
2758 device->given_dev_name, device->given_unit_number);
2759 ata_print_ident(ident_buf);
2763 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2765 if (NULL != fgets(str, sizeof(str), stdin)) {
2766 if (0 == strncasecmp(str, "yes", 3)) {
2768 } else if (0 == strncasecmp(str, "no", 2)) {
2771 printf("Please answer \"yes\" or "
2782 atahpa(struct cam_device *device, int retry_count, int timeout,
2783 int argc, char **argv, char *combinedopt)
2786 struct ata_params *ident_buf;
2787 struct ccb_getdev cgd;
2788 struct ata_set_max_pwd pwd;
2789 int error, confirm, quiet, c, action, actions, persist;
2790 int security, is48bit, pwdsize;
2791 u_int64_t hpasize, maxsize;
2800 memset(&pwd, 0, sizeof(pwd));
2802 /* default action is to print hpa information */
2803 action = ATA_HPA_ACTION_PRINT;
2804 pwdsize = sizeof(pwd.password);
2806 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2809 action = ATA_HPA_ACTION_SET_MAX;
2810 maxsize = strtoumax(optarg, NULL, 0);
2815 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2817 action = ATA_HPA_ACTION_SET_PWD;
2823 action = ATA_HPA_ACTION_LOCK;
2829 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2831 action = ATA_HPA_ACTION_UNLOCK;
2837 action = ATA_HPA_ACTION_FREEZE_LOCK;
2857 warnx("too many hpa actions specified");
2861 if (get_cgd(device, &cgd) != 0) {
2862 warnx("couldn't get CGD");
2866 ccb = cam_getccb(device);
2868 warnx("couldn't allocate CCB");
2872 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2879 printf("%s%d: ", device->device_name, device->dev_unit_num);
2880 ata_print_ident(ident_buf);
2881 camxferrate(device);
2884 if (action == ATA_HPA_ACTION_PRINT) {
2886 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2887 ata_read_native_max(device, retry_count, timeout, ccb,
2888 ident_buf, &hpasize);
2889 atahpa_print(ident_buf, hpasize, 1);
2896 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2897 warnx("HPA is not supported by this device");
2903 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
2904 warnx("HPA Security is not supported by this device");
2910 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2913 * The ATA spec requires:
2914 * 1. Read native max addr is called directly before set max addr
2915 * 2. Read native max addr is NOT called before any other set max call
2918 case ATA_HPA_ACTION_SET_MAX:
2920 atahpa_set_confirm(device, ident_buf, maxsize,
2927 error = ata_read_native_max(device, retry_count, timeout,
2928 ccb, ident_buf, &hpasize);
2930 error = atahpa_set_max(device, retry_count, timeout,
2931 ccb, is48bit, maxsize, persist);
2934 /* redo identify to get new values */
2935 error = ata_do_identify(device,
2936 retry_count, timeout, ccb,
2938 atahpa_print(ident_buf, hpasize, 1);
2940 /* Hint CAM to reprobe the device. */
2946 case ATA_HPA_ACTION_SET_PWD:
2947 error = atahpa_password(device, retry_count, timeout,
2948 ccb, is48bit, &pwd);
2949 if (error == 0 && quiet == 0)
2950 printf("HPA password has been set\n");
2953 case ATA_HPA_ACTION_LOCK:
2954 error = atahpa_lock(device, retry_count, timeout,
2956 if (error == 0 && quiet == 0)
2957 printf("HPA has been locked\n");
2960 case ATA_HPA_ACTION_UNLOCK:
2961 error = atahpa_unlock(device, retry_count, timeout,
2962 ccb, is48bit, &pwd);
2963 if (error == 0 && quiet == 0)
2964 printf("HPA has been unlocked\n");
2967 case ATA_HPA_ACTION_FREEZE_LOCK:
2968 error = atahpa_freeze_lock(device, retry_count, timeout,
2970 if (error == 0 && quiet == 0)
2971 printf("HPA has been frozen\n");
2975 errx(1, "Option currently not supported");
2985 ATA_AMA_ACTION_PRINT,
2986 ATA_AMA_ACTION_SET_MAX,
2987 ATA_AMA_ACTION_FREEZE_LOCK
2991 ataama(struct cam_device *device, int retry_count, int timeout,
2992 int argc, char **argv, char *combinedopt)
2995 struct ata_params *ident_buf;
2996 struct ccb_getdev cgd;
2997 int error, quiet, c, action, actions;
2998 u_int64_t nativesize, maxsize;
3004 /* default action is to print AMA information */
3005 action = ATA_AMA_ACTION_PRINT;
3007 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3010 action = ATA_AMA_ACTION_SET_MAX;
3011 maxsize = strtoumax(optarg, NULL, 0);
3016 action = ATA_AMA_ACTION_FREEZE_LOCK;
3027 warnx("too many AMA actions specified");
3031 if (get_cgd(device, &cgd) != 0) {
3032 warnx("couldn't get CGD");
3036 ccb = cam_getccb(device);
3038 warnx("couldn't allocate CCB");
3042 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3049 printf("%s%d: ", device->device_name, device->dev_unit_num);
3050 ata_print_ident(ident_buf);
3051 camxferrate(device);
3054 if (action == ATA_AMA_ACTION_PRINT) {
3056 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3057 ata_get_native_max(device, retry_count, timeout, ccb,
3059 ataama_print(ident_buf, nativesize, 1);
3066 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3067 warnx("Accessible Max Address is not supported by this device");
3074 case ATA_AMA_ACTION_SET_MAX:
3075 error = ata_get_native_max(device, retry_count, timeout, ccb,
3078 error = ataama_set(device, retry_count, timeout,
3082 /* redo identify to get new values */
3083 error = ata_do_identify(device,
3084 retry_count, timeout, ccb,
3086 ataama_print(ident_buf, nativesize, 1);
3088 /* Hint CAM to reprobe the device. */
3094 case ATA_AMA_ACTION_FREEZE_LOCK:
3095 error = ataama_freeze(device, retry_count, timeout,
3097 if (error == 0 && quiet == 0)
3098 printf("Accessible Max Address has been frozen\n");
3102 errx(1, "Option currently not supported");
3112 atasecurity(struct cam_device *device, int retry_count, int timeout,
3113 int argc, char **argv, char *combinedopt)
3116 struct ata_params *ident_buf;
3117 int error, confirm, quiet, c, action, actions, setpwd;
3118 int security_enabled, erase_timeout, pwdsize;
3119 struct ata_security_password pwd;
3127 memset(&pwd, 0, sizeof(pwd));
3129 /* default action is to print security information */
3130 action = ATA_SECURITY_ACTION_PRINT;
3132 /* user is master by default as its safer that way */
3133 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3134 pwdsize = sizeof(pwd.password);
3136 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3139 action = ATA_SECURITY_ACTION_FREEZE;
3144 if (strcasecmp(optarg, "user") == 0) {
3145 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3146 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3147 } else if (strcasecmp(optarg, "master") == 0) {
3148 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3149 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3151 warnx("-U argument '%s' is invalid (must be "
3152 "'user' or 'master')", optarg);
3158 if (strcasecmp(optarg, "high") == 0) {
3159 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3160 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3161 } else if (strcasecmp(optarg, "maximum") == 0) {
3162 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3163 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3165 warnx("-l argument '%s' is unknown (must be "
3166 "'high' or 'maximum')", optarg);
3172 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3174 action = ATA_SECURITY_ACTION_UNLOCK;
3179 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3181 action = ATA_SECURITY_ACTION_DISABLE;
3186 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3188 action = ATA_SECURITY_ACTION_ERASE;
3193 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3195 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3196 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3201 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3204 if (action == ATA_SECURITY_ACTION_PRINT)
3205 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3207 * Don't increment action as this can be combined
3208 * with other actions.
3221 erase_timeout = atoi(optarg) * 1000;
3227 warnx("too many security actions specified");
3231 if ((ccb = cam_getccb(device)) == NULL) {
3232 warnx("couldn't allocate CCB");
3236 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3243 printf("%s%d: ", device->device_name, device->dev_unit_num);
3244 ata_print_ident(ident_buf);
3245 camxferrate(device);
3248 if (action == ATA_SECURITY_ACTION_PRINT) {
3249 atasecurity_print(ident_buf);
3255 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3256 warnx("Security not supported");
3262 /* default timeout 15 seconds the same as linux hdparm */
3263 timeout = timeout ? timeout : 15 * 1000;
3265 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3267 /* first set the password if requested */
3269 /* confirm we can erase before setting the password if erasing */
3271 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3272 action == ATA_SECURITY_ACTION_ERASE) &&
3273 atasecurity_erase_confirm(device, ident_buf) == 0) {
3279 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3280 pwd.revision = ident_buf->master_passwd_revision;
3281 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3282 --pwd.revision == 0) {
3283 pwd.revision = 0xfffe;
3286 error = atasecurity_set_password(device, ccb, retry_count,
3287 timeout, &pwd, quiet);
3293 security_enabled = 1;
3297 case ATA_SECURITY_ACTION_FREEZE:
3298 error = atasecurity_freeze(device, ccb, retry_count,
3302 case ATA_SECURITY_ACTION_UNLOCK:
3303 if (security_enabled) {
3304 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3305 error = atasecurity_unlock(device, ccb,
3306 retry_count, timeout, &pwd, quiet);
3308 warnx("Can't unlock, drive is not locked");
3312 warnx("Can't unlock, security is disabled");
3317 case ATA_SECURITY_ACTION_DISABLE:
3318 if (security_enabled) {
3319 /* First unlock the drive if its locked */
3320 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3321 error = atasecurity_unlock(device, ccb,
3329 error = atasecurity_disable(device,
3337 warnx("Can't disable security (already disabled)");
3342 case ATA_SECURITY_ACTION_ERASE:
3343 if (security_enabled) {
3344 if (erase_timeout == 0) {
3345 erase_timeout = atasecurity_erase_timeout_msecs(
3346 ident_buf->erase_time);
3349 error = atasecurity_erase(device, ccb, retry_count,
3350 timeout, erase_timeout, &pwd, quiet);
3352 warnx("Can't secure erase (security is disabled)");
3357 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3358 if (security_enabled) {
3359 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3360 if (erase_timeout == 0) {
3362 atasecurity_erase_timeout_msecs(
3363 ident_buf->enhanced_erase_time);
3366 error = atasecurity_erase(device, ccb,
3367 retry_count, timeout,
3368 erase_timeout, &pwd,
3371 warnx("Enhanced erase is not supported");
3375 warnx("Can't secure erase (enhanced), "
3376 "(security is disabled)");
3389 * Convert periph name into a bus, target and lun.
3391 * Returns the number of parsed components, or 0.
3394 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3395 cam_argmask *arglst)
3400 bzero(&ccb, sizeof(ccb));
3401 ccb.ccb_h.func_code = XPT_GDEVLIST;
3402 if (cam_get_device(tstr, ccb.cgdl.periph_name,
3403 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3404 warnx("%s", cam_errbuf);
3409 * Attempt to get the passthrough device. This ioctl will
3410 * fail if the device name is null, if the device doesn't
3411 * exist, or if the passthrough driver isn't in the kernel.
3413 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3414 warn("Unable to open %s", XPT_DEVICE);
3417 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3418 warn("Unable to find bus:target:lun for device %s%d",
3419 ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3424 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3425 const struct cam_status_entry *entry;
3427 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3428 warnx("Unable to find bus:target_lun for device %s%d, "
3429 "CAM status: %s (%#x)",
3430 ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3431 entry ? entry->status_text : "Unknown",
3437 * The kernel fills in the bus/target/lun. We don't
3438 * need the passthrough device name and unit number since
3439 * we aren't going to open it.
3441 *bus = ccb.ccb_h.path_id;
3442 *target = ccb.ccb_h.target_id;
3443 *lun = ccb.ccb_h.target_lun;
3444 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3449 * Parse out a bus, or a bus, target and lun in the following
3455 * Returns the number of parsed components, or 0.
3458 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3459 cam_argmask *arglst)
3464 *bus = CAM_BUS_WILDCARD;
3465 *target = CAM_TARGET_WILDCARD;
3466 *lun = CAM_LUN_WILDCARD;
3468 while (isspace(*tstr) && (*tstr != '\0'))
3471 if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3472 arglist |= CAM_ARG_BUS;
3476 if (!isdigit(*tstr))
3477 return (parse_btl_name(tstr, bus, target, lun, arglst));
3479 tmpstr = strsep(&tstr, ":");
3480 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3481 *bus = strtol(tmpstr, &end, 0);
3484 *arglst |= CAM_ARG_BUS;
3486 tmpstr = strsep(&tstr, ":");
3487 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3488 *target = strtol(tmpstr, &end, 0);
3491 *arglst |= CAM_ARG_TARGET;
3493 tmpstr = strsep(&tstr, ":");
3494 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3495 *lun = strtoll(tmpstr, &end, 0);
3498 *arglst |= CAM_ARG_LUN;
3508 dorescan_or_reset(int argc, char **argv, int rescan)
3510 static const char must[] =
3511 "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3513 path_id_t bus = CAM_BUS_WILDCARD;
3514 target_id_t target = CAM_TARGET_WILDCARD;
3515 lun_id_t lun = CAM_LUN_WILDCARD;
3519 warnx(must, rescan? "rescan" : "reset");
3523 tstr = argv[optind];
3524 while (isspace(*tstr) && (*tstr != '\0'))
3526 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3527 arglist |= CAM_ARG_BUS;
3529 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3530 if (rv != 1 && rv != 3) {
3531 warnx(must, rescan ? "rescan" : "reset");
3536 if (arglist & CAM_ARG_LUN)
3537 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3539 error = rescan_or_reset_bus(bus, rescan);
3545 rescan_or_reset_bus(path_id_t bus, int rescan)
3547 union ccb *ccb = NULL, *matchccb = NULL;
3548 int fd = -1, retval;
3553 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3554 warnx("error opening transport layer device %s", XPT_DEVICE);
3555 warn("%s", XPT_DEVICE);
3559 ccb = malloc(sizeof(*ccb));
3561 warn("failed to allocate CCB");
3565 bzero(ccb, sizeof(*ccb));
3567 if (bus != CAM_BUS_WILDCARD) {
3568 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3569 ccb->ccb_h.path_id = bus;
3570 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3571 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3572 ccb->crcn.flags = CAM_FLAG_NONE;
3574 /* run this at a low priority */
3575 ccb->ccb_h.pinfo.priority = 5;
3577 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3578 warn("CAMIOCOMMAND ioctl failed");
3583 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3584 fprintf(stdout, "%s of bus %d was successful\n",
3585 rescan ? "Re-scan" : "Reset", bus);
3587 fprintf(stdout, "%s of bus %d returned error %#x\n",
3588 rescan ? "Re-scan" : "Reset", bus,
3589 ccb->ccb_h.status & CAM_STATUS_MASK);
3598 * The right way to handle this is to modify the xpt so that it can
3599 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3600 * that isn't implemented, so instead we enumerate the buses and
3601 * send the rescan or reset to those buses in the case where the
3602 * given bus is -1 (wildcard). We don't send a rescan or reset
3603 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3604 * no-op, sending a rescan to the xpt bus would result in a status of
3607 matchccb = malloc(sizeof(*matchccb));
3608 if (matchccb == NULL) {
3609 warn("failed to allocate CCB");
3613 bzero(matchccb, sizeof(*matchccb));
3614 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3615 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3616 bufsize = sizeof(struct dev_match_result) * 20;
3617 matchccb->cdm.match_buf_len = bufsize;
3618 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3619 if (matchccb->cdm.matches == NULL) {
3620 warnx("can't malloc memory for matches");
3624 matchccb->cdm.num_matches = 0;
3626 matchccb->cdm.num_patterns = 1;
3627 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3629 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3630 matchccb->cdm.pattern_buf_len);
3631 if (matchccb->cdm.patterns == NULL) {
3632 warnx("can't malloc memory for patterns");
3636 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3637 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3642 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3643 warn("CAMIOCOMMAND ioctl failed");
3648 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3649 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3650 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3651 warnx("got CAM error %#x, CDM error %d\n",
3652 matchccb->ccb_h.status, matchccb->cdm.status);
3657 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3658 struct bus_match_result *bus_result;
3660 /* This shouldn't happen. */
3661 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3664 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3667 * We don't want to rescan or reset the xpt bus.
3670 if (bus_result->path_id == CAM_XPT_PATH_ID)
3673 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3675 ccb->ccb_h.path_id = bus_result->path_id;
3676 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3677 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3678 ccb->crcn.flags = CAM_FLAG_NONE;
3680 /* run this at a low priority */
3681 ccb->ccb_h.pinfo.priority = 5;
3683 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3684 warn("CAMIOCOMMAND ioctl failed");
3689 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3690 fprintf(stdout, "%s of bus %d was successful\n",
3691 rescan? "Re-scan" : "Reset",
3692 bus_result->path_id);
3695 * Don't bail out just yet, maybe the other
3696 * rescan or reset commands will complete
3699 fprintf(stderr, "%s of bus %d returned error "
3700 "%#x\n", rescan? "Re-scan" : "Reset",
3701 bus_result->path_id,
3702 ccb->ccb_h.status & CAM_STATUS_MASK);
3706 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3707 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3714 if (matchccb != NULL) {
3715 free(matchccb->cdm.patterns);
3716 free(matchccb->cdm.matches);
3725 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3728 struct cam_device *device;
3733 if (bus == CAM_BUS_WILDCARD) {
3734 warnx("invalid bus number %d", bus);
3738 if (target == CAM_TARGET_WILDCARD) {
3739 warnx("invalid target number %d", target);
3743 if (lun == CAM_LUN_WILDCARD) {
3744 warnx("invalid lun number %jx", (uintmax_t)lun);
3750 bzero(&ccb, sizeof(union ccb));
3753 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3754 warnx("error opening transport layer device %s\n",
3756 warn("%s", XPT_DEVICE);
3760 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3761 if (device == NULL) {
3762 warnx("%s", cam_errbuf);
3767 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3768 ccb.ccb_h.path_id = bus;
3769 ccb.ccb_h.target_id = target;
3770 ccb.ccb_h.target_lun = lun;
3771 ccb.ccb_h.timeout = 5000;
3772 ccb.crcn.flags = CAM_FLAG_NONE;
3774 /* run this at a low priority */
3775 ccb.ccb_h.pinfo.priority = 5;
3778 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3779 warn("CAMIOCOMMAND ioctl failed");
3784 if (cam_send_ccb(device, &ccb) < 0) {
3785 warn("error sending XPT_RESET_DEV CCB");
3786 cam_close_device(device);
3794 cam_close_device(device);
3797 * An error code of CAM_BDR_SENT is normal for a BDR request.
3799 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3801 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3802 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3803 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3806 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3807 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3808 ccb.ccb_h.status & CAM_STATUS_MASK);
3814 static struct scsi_nv defect_list_type_map[] = {
3815 { "block", SRDD10_BLOCK_FORMAT },
3816 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3817 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3818 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3819 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3820 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3824 readdefects(struct cam_device *device, int argc, char **argv,
3825 char *combinedopt, int task_attr, int retry_count, int timeout)
3827 union ccb *ccb = NULL;
3828 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3829 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3830 size_t hdr_size = 0, entry_size = 0;
3831 u_int8_t *defect_list = NULL;
3832 u_int8_t list_format = 0;
3833 u_int32_t dlist_length = 0;
3834 u_int32_t returned_length = 0, valid_len = 0;
3835 u_int32_t num_returned = 0, num_valid = 0;
3836 u_int32_t max_possible_size = 0, hdr_max = 0;
3837 u_int32_t starting_offset = 0;
3838 u_int8_t returned_format, returned_type;
3842 bool summary = false, quiet = false, list_type_set = false;
3843 bool get_length = true, use_12byte = false, first_pass = true;
3844 bool hex_format = false;
3846 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3850 scsi_nv_status status;
3853 if (list_type_set) {
3854 warnx("%s: -f specified twice", __func__);
3856 goto defect_bailout;
3859 status = scsi_get_nv(defect_list_type_map,
3860 sizeof(defect_list_type_map) /
3861 sizeof(defect_list_type_map[0]), optarg,
3862 &entry_num, SCSI_NV_FLAG_IG_CASE);
3864 if (status == SCSI_NV_FOUND) {
3865 list_format |= defect_list_type_map[
3867 list_type_set = true;
3869 warnx("%s: %s %s option %s", __func__,
3870 (status == SCSI_NV_AMBIGUOUS) ?
3871 "ambiguous" : "invalid", "defect list type",
3874 goto defect_bailout;
3879 list_format |= SRDD10_GLIST;
3882 list_format |= SRDD10_PLIST;
3893 starting_offset = strtoul(optarg, &endptr, 0);
3894 if (*endptr != '\0') {
3896 warnx("invalid starting offset %s", optarg);
3897 goto defect_bailout;
3910 if (!list_type_set) {
3912 warnx("no defect list format specified");
3913 goto defect_bailout;
3917 * This implies a summary, and was the previous behavior.
3919 if ((list_format & ~SRDD10_DLIST_FORMAT_MASK) == 0)
3922 ccb = cam_getccb(device);
3925 * We start off asking for just the header to determine how much defect
3926 * data is available. Some Hitachi drives return an error if you ask
3927 * for more data than the drive has. Once we know the length, we retry
3928 * the command with the returned length. When we're retrying the with
3929 * 12-byte command, we're always changing to the 12-byte command and
3930 * need to get the length. Simplify the logic below by always setting
3931 * use_12byte in this case with this slightly more complex logic here.
3934 dlist_length = sizeof(*hdr10);
3939 dlist_length = sizeof(*hdr12);
3943 if (defect_list != NULL) {
3947 defect_list = malloc(dlist_length);
3948 if (defect_list == NULL) {
3949 warnx("can't malloc memory for defect list");
3951 goto defect_bailout;
3955 bzero(defect_list, dlist_length);
3958 * cam_getccb() zeros the CCB header only. So we need to zero the
3959 * payload portion of the ccb.
3961 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3963 scsi_read_defects(&ccb->csio,
3964 /*retries*/ retry_count,
3966 /*tag_action*/ task_attr,
3967 /*list_format*/ list_format,
3968 /*addr_desc_index*/ starting_offset,
3969 /*data_ptr*/ defect_list,
3970 /*dxfer_len*/ dlist_length,
3971 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3972 /*sense_len*/ SSD_FULL_SIZE,
3973 /*timeout*/ timeout ? timeout : 5000);
3975 /* Disable freezing the device queue */
3976 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3978 if (cam_send_ccb(device, ccb) < 0) {
3979 warn("error sending READ DEFECT DATA command");
3981 goto defect_bailout;
3984 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3987 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3988 hdr_size = sizeof(*hdr10);
3989 hdr_max = SRDDH10_MAX_LENGTH;
3991 if (valid_len >= hdr_size) {
3992 returned_length = scsi_2btoul(hdr10->length);
3993 returned_format = hdr10->format;
3995 returned_length = 0;
3996 returned_format = 0;
3999 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4000 hdr_size = sizeof(*hdr12);
4001 hdr_max = SRDDH12_MAX_LENGTH;
4003 if (valid_len >= hdr_size) {
4004 returned_length = scsi_4btoul(hdr12->length);
4005 returned_format = hdr12->format;
4007 returned_length = 0;
4008 returned_format = 0;
4012 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4013 switch (returned_type) {
4014 case SRDD10_BLOCK_FORMAT:
4015 entry_size = sizeof(struct scsi_defect_desc_block);
4017 case SRDD10_LONG_BLOCK_FORMAT:
4018 entry_size = sizeof(struct scsi_defect_desc_long_block);
4020 case SRDD10_EXT_PHYS_FORMAT:
4021 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4022 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4024 case SRDD10_EXT_BFI_FORMAT:
4025 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4026 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4029 warnx("Unknown defect format 0x%x\n", returned_type);
4031 goto defect_bailout;
4035 max_possible_size = (hdr_max / entry_size) * entry_size;
4036 num_returned = returned_length / entry_size;
4037 num_valid = min(returned_length, valid_len - hdr_size);
4038 num_valid /= entry_size;
4043 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4044 CAM_SCSI_STATUS_ERROR) {
4045 struct scsi_sense_data *sense;
4046 int error_code, sense_key, asc, ascq;
4048 sense = &ccb->csio.sense_data;
4049 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4050 ccb->csio.sense_resid, &error_code, &sense_key,
4051 &asc, &ascq, /*show_errors*/ 1);
4054 * If the drive is reporting that it just doesn't
4055 * support the defect list format, go ahead and use
4056 * the length it reported. Otherwise, the length
4057 * may not be valid, so use the maximum.
4059 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4060 && (asc == 0x1c) && (ascq == 0x00)
4061 && (returned_length > 0)) {
4063 && (returned_length >= max_possible_size)) {
4066 dlist_length = returned_length + hdr_size;
4067 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4068 && (asc == 0x1f) && (ascq == 0x00)
4069 && (returned_length > 0)) {
4070 /* Partial defect list transfer */
4072 * Hitachi drives return this error
4073 * along with a partial defect list if they
4074 * have more defects than the 10 byte
4075 * command can support. Retry with the 12
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
4095 dlist_length = returned_length + hdr_size;
4098 * If we got a SCSI error and no valid length,
4099 * just use the 10 byte maximum. The 12
4100 * byte maximum is too large.
4102 if (returned_length == 0)
4103 dlist_length = SRDD10_MAX_LENGTH;
4106 && (returned_length >=
4107 max_possible_size)) {
4110 dlist_length = returned_length +
4114 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4117 warnx("Error reading defect header");
4118 if (arglist & CAM_ARG_VERBOSE)
4119 cam_error_print(device, ccb, CAM_ESF_ALL,
4120 CAM_EPF_ALL, stderr);
4121 goto defect_bailout;
4124 && (returned_length >= max_possible_size)) {
4127 dlist_length = returned_length + hdr_size;
4130 fprintf(stdout, "%u", num_returned);
4132 fprintf(stdout, " defect%s",
4133 (num_returned != 1) ? "s" : "");
4135 fprintf(stdout, "\n");
4137 goto defect_bailout;
4141 * We always limit the list length to the 10-byte maximum
4142 * length (0xffff). The reason is that some controllers
4143 * can't handle larger I/Os, and we can transfer the entire
4144 * 10 byte list in one shot. For drives that support the 12
4145 * byte read defects command, we'll step through the list
4146 * by specifying a starting offset. For drives that don't
4147 * support the 12 byte command's starting offset, we'll
4148 * just display the first 64K.
4150 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4156 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4157 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4158 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4159 struct scsi_sense_data *sense;
4160 int error_code, sense_key, asc, ascq;
4162 sense = &ccb->csio.sense_data;
4163 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4164 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4165 &ascq, /*show_errors*/ 1);
4168 * According to the SCSI spec, if the disk doesn't support
4169 * the requested format, it will generally return a sense
4170 * key of RECOVERED ERROR, and an additional sense code
4171 * of "DEFECT LIST NOT FOUND". HGST drives also return
4172 * Primary/Grown defect list not found errors. So just
4173 * check for an ASC of 0x1c.
4175 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4177 const char *format_str;
4179 format_str = scsi_nv_to_str(defect_list_type_map,
4180 sizeof(defect_list_type_map) /
4181 sizeof(defect_list_type_map[0]),
4182 list_format & SRDD10_DLIST_FORMAT_MASK);
4183 warnx("requested defect format %s not available",
4184 format_str ? format_str : "unknown");
4186 format_str = scsi_nv_to_str(defect_list_type_map,
4187 sizeof(defect_list_type_map) /
4188 sizeof(defect_list_type_map[0]), returned_type);
4189 if (format_str != NULL) {
4190 warnx("Device returned %s format",
4194 warnx("Device returned unknown defect"
4195 " data format %#x", returned_type);
4196 goto defect_bailout;
4200 warnx("Error returned from read defect data command");
4201 if (arglist & CAM_ARG_VERBOSE)
4202 cam_error_print(device, ccb, CAM_ESF_ALL,
4203 CAM_EPF_ALL, stderr);
4204 goto defect_bailout;
4206 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4208 warnx("Error returned from read defect data command");
4209 if (arglist & CAM_ARG_VERBOSE)
4210 cam_error_print(device, ccb, CAM_ESF_ALL,
4211 CAM_EPF_ALL, stderr);
4212 goto defect_bailout;
4216 fprintf(stderr, "Got %d defect", num_returned);
4218 if (!summary || (num_returned == 0)) {
4219 fprintf(stderr, "s.\n");
4220 goto defect_bailout;
4221 } else if (num_returned == 1)
4222 fprintf(stderr, ":\n");
4224 fprintf(stderr, "s:\n");
4230 * XXX KDM I should probably clean up the printout format for the
4233 switch (returned_type) {
4234 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4235 case SRDD10_EXT_PHYS_FORMAT:
4237 struct scsi_defect_desc_phys_sector *dlist;
4239 dlist = (struct scsi_defect_desc_phys_sector *)
4240 (defect_list + hdr_size);
4242 for (i = 0; i < num_valid; i++) {
4245 sector = scsi_4btoul(dlist[i].sector);
4246 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4247 mads = (sector & SDD_EXT_PHYS_MADS) ?
4249 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4252 fprintf(stdout, "%d:%d:%d%s",
4253 scsi_3btoul(dlist[i].cylinder),
4255 scsi_4btoul(dlist[i].sector),
4256 mads ? " - " : "\n");
4258 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4259 scsi_3btoul(dlist[i].cylinder),
4261 scsi_4btoul(dlist[i].sector),
4262 mads ? " - " : "\n");
4265 if (num_valid < num_returned) {
4266 starting_offset += num_valid;
4271 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4272 case SRDD10_EXT_BFI_FORMAT:
4274 struct scsi_defect_desc_bytes_from_index *dlist;
4276 dlist = (struct scsi_defect_desc_bytes_from_index *)
4277 (defect_list + hdr_size);
4279 for (i = 0; i < num_valid; i++) {
4282 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4283 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4284 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4285 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4288 fprintf(stdout, "%d:%d:%d%s",
4289 scsi_3btoul(dlist[i].cylinder),
4291 scsi_4btoul(dlist[i].bytes_from_index),
4292 mads ? " - " : "\n");
4294 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4295 scsi_3btoul(dlist[i].cylinder),
4297 scsi_4btoul(dlist[i].bytes_from_index),
4298 mads ? " - " : "\n");
4302 if (num_valid < num_returned) {
4303 starting_offset += num_valid;
4308 case SRDDH10_BLOCK_FORMAT:
4310 struct scsi_defect_desc_block *dlist;
4312 dlist = (struct scsi_defect_desc_block *)
4313 (defect_list + hdr_size);
4315 for (i = 0; i < num_valid; i++) {
4317 fprintf(stdout, "%u\n",
4318 scsi_4btoul(dlist[i].address));
4320 fprintf(stdout, "0x%x\n",
4321 scsi_4btoul(dlist[i].address));
4324 if (num_valid < num_returned) {
4325 starting_offset += num_valid;
4331 case SRDD10_LONG_BLOCK_FORMAT:
4333 struct scsi_defect_desc_long_block *dlist;
4335 dlist = (struct scsi_defect_desc_long_block *)
4336 (defect_list + hdr_size);
4338 for (i = 0; i < num_valid; i++) {
4340 fprintf(stdout, "%ju\n",
4341 (uintmax_t)scsi_8btou64(
4344 fprintf(stdout, "0x%jx\n",
4345 (uintmax_t)scsi_8btou64(
4349 if (num_valid < num_returned) {
4350 starting_offset += num_valid;
4356 fprintf(stderr, "Unknown defect format 0x%x\n",
4363 if (defect_list != NULL)
4374 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4378 ccb = cam_getccb(device);
4385 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4386 int page, int subpage, int task_attr, int retry_count, int timeout,
4387 u_int8_t *data, int datalen)
4390 int error_code, sense_key, asc, ascq;
4392 ccb = cam_getccb(device);
4394 errx(1, "mode_sense: couldn't allocate CCB");
4398 * MODE SENSE(6) can't handle more then 255 bytes. If there are more,
4399 * device must return error, so we should not get truncated data.
4401 if (*cdb_len == 6 && datalen > 255)
4404 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4406 scsi_mode_sense_subpage(&ccb->csio,
4407 /* retries */ retry_count,
4409 /* tag_action */ task_attr,
4413 /* subpage */ subpage,
4414 /* param_buf */ data,
4415 /* param_len */ datalen,
4416 /* minimum_cmd_size */ *cdb_len,
4417 /* sense_len */ SSD_FULL_SIZE,
4418 /* timeout */ timeout ? timeout : 5000);
4419 if (llbaa && ccb->csio.cdb_len == 10) {
4420 struct scsi_mode_sense_10 *cdb =
4421 (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4422 cdb->byte2 |= SMS10_LLBAA;
4425 /* Record what CDB size the above function really set. */
4426 *cdb_len = ccb->csio.cdb_len;
4428 if (arglist & CAM_ARG_ERR_RECOVER)
4429 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4431 /* Disable freezing the device queue */
4432 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4434 if (cam_send_ccb(device, ccb) < 0)
4435 err(1, "error sending mode sense command");
4437 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4438 if (*cdb_len != 6 &&
4439 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4440 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4441 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4446 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4447 if (arglist & CAM_ARG_VERBOSE) {
4448 cam_error_print(device, ccb, CAM_ESF_ALL,
4449 CAM_EPF_ALL, stderr);
4452 cam_close_device(device);
4453 errx(1, "mode sense command returned error");
4460 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4461 int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4466 ccb = cam_getccb(device);
4469 errx(1, "mode_select: couldn't allocate CCB");
4471 scsi_mode_select_len(&ccb->csio,
4472 /* retries */ retry_count,
4474 /* tag_action */ task_attr,
4475 /* scsi_page_fmt */ 1,
4476 /* save_pages */ save_pages,
4477 /* param_buf */ data,
4478 /* param_len */ datalen,
4479 /* minimum_cmd_size */ cdb_len,
4480 /* sense_len */ SSD_FULL_SIZE,
4481 /* timeout */ timeout ? timeout : 5000);
4483 if (arglist & CAM_ARG_ERR_RECOVER)
4484 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4486 /* Disable freezing the device queue */
4487 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4489 if (((retval = cam_send_ccb(device, ccb)) < 0)
4490 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4491 if (arglist & CAM_ARG_VERBOSE) {
4492 cam_error_print(device, ccb, CAM_ESF_ALL,
4493 CAM_EPF_ALL, stderr);
4496 cam_close_device(device);
4499 err(1, "error sending mode select command");
4501 errx(1, "error sending mode select command");
4509 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4510 int task_attr, int retry_count, int timeout)
4513 int c, page = -1, subpage = 0, pc = 0, llbaa = 0;
4514 int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4516 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4534 str_subpage = optarg;
4535 strsep(&str_subpage, ",");
4536 page = strtol(optarg, NULL, 0);
4538 subpage = strtol(str_subpage, NULL, 0);
4539 if (page < 0 || page > 0x3f)
4540 errx(1, "invalid mode page %d", page);
4541 if (subpage < 0 || subpage > 0xff)
4542 errx(1, "invalid mode subpage %d", subpage);
4551 pc = strtol(optarg, NULL, 0);
4552 if ((pc < 0) || (pc > 3))
4553 errx(1, "invalid page control field %d", pc);
4560 if (desc && page == -1)
4561 page = SMS_ALL_PAGES_PAGE;
4563 if (page == -1 && list == 0)
4564 errx(1, "you must specify a mode page!");
4567 errx(1, "-d and -D are incompatible!");
4569 if (llbaa && cdb_len != 10)
4570 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4573 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4574 retry_count, timeout);
4576 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4577 edit, binary, task_attr, retry_count, timeout);
4582 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4583 int task_attr, int retry_count, int timeout)
4586 u_int32_t flags = CAM_DIR_NONE;
4587 u_int8_t *data_ptr = NULL;
4589 u_int8_t atacmd[12];
4590 struct get_hook hook;
4591 int c, data_bytes = 0, valid_bytes;
4597 char *datastr = NULL, *tstr, *resstr = NULL;
4599 int fd_data = 0, fd_res = 0;
4602 ccb = cam_getccb(device);
4605 warnx("scsicmd: error allocating ccb");
4609 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4613 while (isspace(*tstr) && (*tstr != '\0'))
4615 hook.argc = argc - optind;
4616 hook.argv = argv + optind;
4618 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4621 * Increment optind by the number of arguments the
4622 * encoding routine processed. After each call to
4623 * getopt(3), optind points to the argument that
4624 * getopt should process _next_. In this case,
4625 * that means it points to the first command string
4626 * argument, if there is one. Once we increment
4627 * this, it should point to either the next command
4628 * line argument, or it should be past the end of
4635 while (isspace(*tstr) && (*tstr != '\0'))
4637 hook.argc = argc - optind;
4638 hook.argv = argv + optind;
4640 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4643 * Increment optind by the number of arguments the
4644 * encoding routine processed. After each call to
4645 * getopt(3), optind points to the argument that
4646 * getopt should process _next_. In this case,
4647 * that means it points to the first command string
4648 * argument, if there is one. Once we increment
4649 * this, it should point to either the next command
4650 * line argument, or it should be past the end of
4662 if (arglist & CAM_ARG_CMD_OUT) {
4663 warnx("command must either be "
4664 "read or write, not both");
4666 goto scsicmd_bailout;
4668 arglist |= CAM_ARG_CMD_IN;
4670 data_bytes = strtol(optarg, NULL, 0);
4671 if (data_bytes <= 0) {
4672 warnx("invalid number of input bytes %d",
4675 goto scsicmd_bailout;
4677 hook.argc = argc - optind;
4678 hook.argv = argv + optind;
4681 datastr = cget(&hook, NULL);
4683 * If the user supplied "-" instead of a format, he
4684 * wants the data to be written to stdout.
4686 if ((datastr != NULL)
4687 && (datastr[0] == '-'))
4690 data_ptr = (u_int8_t *)malloc(data_bytes);
4691 if (data_ptr == NULL) {
4692 warnx("can't malloc memory for data_ptr");
4694 goto scsicmd_bailout;
4698 if (arglist & CAM_ARG_CMD_IN) {
4699 warnx("command must either be "
4700 "read or write, not both");
4702 goto scsicmd_bailout;
4704 arglist |= CAM_ARG_CMD_OUT;
4705 flags = CAM_DIR_OUT;
4706 data_bytes = strtol(optarg, NULL, 0);
4707 if (data_bytes <= 0) {
4708 warnx("invalid number of output bytes %d",
4711 goto scsicmd_bailout;
4713 hook.argc = argc - optind;
4714 hook.argv = argv + optind;
4716 datastr = cget(&hook, NULL);
4717 data_ptr = (u_int8_t *)malloc(data_bytes);
4718 if (data_ptr == NULL) {
4719 warnx("can't malloc memory for data_ptr");
4721 goto scsicmd_bailout;
4723 bzero(data_ptr, data_bytes);
4725 * If the user supplied "-" instead of a format, he
4726 * wants the data to be read from stdin.
4728 if ((datastr != NULL)
4729 && (datastr[0] == '-'))
4732 buff_encode_visit(data_ptr, data_bytes, datastr,
4738 hook.argc = argc - optind;
4739 hook.argv = argv + optind;
4741 resstr = cget(&hook, NULL);
4742 if ((resstr != NULL) && (resstr[0] == '-'))
4752 * If fd_data is set, and we're writing to the device, we need to
4753 * read the data the user wants written from stdin.
4755 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4757 int amt_to_read = data_bytes;
4758 u_int8_t *buf_ptr = data_ptr;
4760 for (amt_read = 0; amt_to_read > 0;
4761 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4762 if (amt_read == -1) {
4763 warn("error reading data from stdin");
4765 goto scsicmd_bailout;
4767 amt_to_read -= amt_read;
4768 buf_ptr += amt_read;
4772 if (arglist & CAM_ARG_ERR_RECOVER)
4773 flags |= CAM_PASS_ERR_RECOVER;
4775 /* Disable freezing the device queue */
4776 flags |= CAM_DEV_QFRZDIS;
4780 * This is taken from the SCSI-3 draft spec.
4781 * (T10/1157D revision 0.3)
4782 * The top 3 bits of an opcode are the group code.
4783 * The next 5 bits are the command code.
4784 * Group 0: six byte commands
4785 * Group 1: ten byte commands
4786 * Group 2: ten byte commands
4788 * Group 4: sixteen byte commands
4789 * Group 5: twelve byte commands
4790 * Group 6: vendor specific
4791 * Group 7: vendor specific
4793 switch((cdb[0] >> 5) & 0x7) {
4804 /* computed by buff_encode_visit */
4815 * We should probably use csio_build_visit or something like that
4816 * here, but it's easier to encode arguments as you go. The
4817 * alternative would be skipping the CDB argument and then encoding
4818 * it here, since we've got the data buffer argument by now.
4820 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4822 cam_fill_csio(&ccb->csio,
4823 /*retries*/ retry_count,
4826 /*tag_action*/ task_attr,
4827 /*data_ptr*/ data_ptr,
4828 /*dxfer_len*/ data_bytes,
4829 /*sense_len*/ SSD_FULL_SIZE,
4830 /*cdb_len*/ cdb_len,
4831 /*timeout*/ timeout ? timeout : 5000);
4834 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4836 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4838 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4840 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4842 cam_fill_ataio(&ccb->ataio,
4843 /*retries*/ retry_count,
4847 /*data_ptr*/ data_ptr,
4848 /*dxfer_len*/ data_bytes,
4849 /*timeout*/ timeout ? timeout : 5000);
4852 if (((retval = cam_send_ccb(device, ccb)) < 0)
4853 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4854 const char warnstr[] = "error sending command";
4861 if (arglist & CAM_ARG_VERBOSE) {
4862 cam_error_print(device, ccb, CAM_ESF_ALL,
4863 CAM_EPF_ALL, stderr);
4867 goto scsicmd_bailout;
4870 if (atacmd_len && need_res) {
4872 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4874 fprintf(stdout, "\n");
4877 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4878 ccb->ataio.res.status,
4879 ccb->ataio.res.error,
4880 ccb->ataio.res.lba_low,
4881 ccb->ataio.res.lba_mid,
4882 ccb->ataio.res.lba_high,
4883 ccb->ataio.res.device,
4884 ccb->ataio.res.lba_low_exp,
4885 ccb->ataio.res.lba_mid_exp,
4886 ccb->ataio.res.lba_high_exp,
4887 ccb->ataio.res.sector_count,
4888 ccb->ataio.res.sector_count_exp);
4894 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4896 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4897 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4898 && (arglist & CAM_ARG_CMD_IN)
4899 && (valid_bytes > 0)) {
4901 buff_decode_visit(data_ptr, valid_bytes, datastr,
4903 fprintf(stdout, "\n");
4905 ssize_t amt_written;
4906 int amt_to_write = valid_bytes;
4907 u_int8_t *buf_ptr = data_ptr;
4909 for (amt_written = 0; (amt_to_write > 0) &&
4910 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4911 amt_to_write -= amt_written;
4912 buf_ptr += amt_written;
4914 if (amt_written == -1) {
4915 warn("error writing data to stdout");
4917 goto scsicmd_bailout;
4918 } else if ((amt_written == 0)
4919 && (amt_to_write > 0)) {
4920 warnx("only wrote %u bytes out of %u",
4921 valid_bytes - amt_to_write, valid_bytes);
4928 if ((data_bytes > 0) && (data_ptr != NULL))
4937 camdebug(int argc, char **argv, char *combinedopt)
4940 path_id_t bus = CAM_BUS_WILDCARD;
4941 target_id_t target = CAM_TARGET_WILDCARD;
4942 lun_id_t lun = CAM_LUN_WILDCARD;
4947 bzero(&ccb, sizeof(union ccb));
4949 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4952 arglist |= CAM_ARG_DEBUG_INFO;
4953 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4956 arglist |= CAM_ARG_DEBUG_PERIPH;
4957 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4960 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4961 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4964 arglist |= CAM_ARG_DEBUG_TRACE;
4965 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4968 arglist |= CAM_ARG_DEBUG_XPT;
4969 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4972 arglist |= CAM_ARG_DEBUG_CDB;
4973 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4976 arglist |= CAM_ARG_DEBUG_PROBE;
4977 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4988 warnx("you must specify \"off\", \"all\" or a bus,");
4989 warnx("bus:target, bus:target:lun or periph");
4994 while (isspace(*tstr) && (*tstr != '\0'))
4997 if (strncmp(tstr, "off", 3) == 0) {
4998 ccb.cdbg.flags = CAM_DEBUG_NONE;
4999 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5000 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5001 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5003 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5005 warnx("you must specify \"all\", \"off\", or a bus,");
5006 warnx("bus:target, bus:target:lun or periph to debug");
5011 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5012 warnx("error opening transport layer device %s", XPT_DEVICE);
5013 warn("%s", XPT_DEVICE);
5017 ccb.ccb_h.func_code = XPT_DEBUG;
5018 ccb.ccb_h.path_id = bus;
5019 ccb.ccb_h.target_id = target;
5020 ccb.ccb_h.target_lun = lun;
5022 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5023 warn("CAMIOCOMMAND ioctl failed");
5026 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5027 CAM_FUNC_NOTAVAIL) {
5028 warnx("CAM debugging not available");
5029 warnx("you need to put options CAMDEBUG in"
5030 " your kernel config file!");
5032 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5034 warnx("XPT_DEBUG CCB failed with status %#x",
5038 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5040 "Debugging turned off\n");
5043 "Debugging enabled for "
5045 bus, target, (uintmax_t)lun);
5055 tagcontrol(struct cam_device *device, int argc, char **argv,
5065 ccb = cam_getccb(device);
5068 warnx("tagcontrol: error allocating ccb");
5072 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5075 numtags = strtol(optarg, NULL, 0);
5077 warnx("tag count %d is < 0", numtags);
5079 goto tagcontrol_bailout;
5090 cam_path_string(device, pathstr, sizeof(pathstr));
5093 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5094 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5095 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5096 ccb->crs.openings = numtags;
5099 if (cam_send_ccb(device, ccb) < 0) {
5100 warn("error sending XPT_REL_SIMQ CCB");
5102 goto tagcontrol_bailout;
5105 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5106 warnx("XPT_REL_SIMQ CCB failed");
5107 cam_error_print(device, ccb, CAM_ESF_ALL,
5108 CAM_EPF_ALL, stderr);
5110 goto tagcontrol_bailout;
5115 fprintf(stdout, "%stagged openings now %d\n",
5116 pathstr, ccb->crs.openings);
5119 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5121 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5123 if (cam_send_ccb(device, ccb) < 0) {
5124 warn("error sending XPT_GDEV_STATS CCB");
5126 goto tagcontrol_bailout;
5129 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5130 warnx("XPT_GDEV_STATS CCB failed");
5131 cam_error_print(device, ccb, CAM_ESF_ALL,
5132 CAM_EPF_ALL, stderr);
5134 goto tagcontrol_bailout;
5137 if (arglist & CAM_ARG_VERBOSE) {
5138 fprintf(stdout, "%s", pathstr);
5139 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5140 fprintf(stdout, "%s", pathstr);
5141 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5142 fprintf(stdout, "%s", pathstr);
5143 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5144 fprintf(stdout, "%s", pathstr);
5145 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5146 fprintf(stdout, "%s", pathstr);
5147 fprintf(stdout, "held %d\n", ccb->cgds.held);
5148 fprintf(stdout, "%s", pathstr);
5149 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5150 fprintf(stdout, "%s", pathstr);
5151 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5154 fprintf(stdout, "%s", pathstr);
5155 fprintf(stdout, "device openings: ");
5157 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5158 ccb->cgds.dev_active);
5168 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5172 cam_path_string(device, pathstr, sizeof(pathstr));
5174 if (cts->transport == XPORT_SPI) {
5175 struct ccb_trans_settings_spi *spi =
5176 &cts->xport_specific.spi;
5178 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5180 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5183 if (spi->sync_offset != 0) {
5186 freq = scsi_calc_syncsrate(spi->sync_period);
5187 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5188 pathstr, freq / 1000, freq % 1000);
5192 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5193 fprintf(stdout, "%soffset: %d\n", pathstr,
5197 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5198 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5199 (0x01 << spi->bus_width) * 8);
5202 if (spi->valid & CTS_SPI_VALID_DISC) {
5203 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5204 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5205 "enabled" : "disabled");
5208 if (cts->transport == XPORT_FC) {
5209 struct ccb_trans_settings_fc *fc =
5210 &cts->xport_specific.fc;
5212 if (fc->valid & CTS_FC_VALID_WWNN)
5213 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5214 (long long) fc->wwnn);
5215 if (fc->valid & CTS_FC_VALID_WWPN)
5216 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5217 (long long) fc->wwpn);
5218 if (fc->valid & CTS_FC_VALID_PORT)
5219 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5220 if (fc->valid & CTS_FC_VALID_SPEED)
5221 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5222 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5224 if (cts->transport == XPORT_SAS) {
5225 struct ccb_trans_settings_sas *sas =
5226 &cts->xport_specific.sas;
5228 if (sas->valid & CTS_SAS_VALID_SPEED)
5229 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5230 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5232 if (cts->transport == XPORT_ATA) {
5233 struct ccb_trans_settings_pata *pata =
5234 &cts->xport_specific.ata;
5236 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5237 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5238 ata_mode2string(pata->mode));
5240 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5241 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5244 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5245 fprintf(stdout, "%sPIO transaction length: %d\n",
5246 pathstr, pata->bytecount);
5249 if (cts->transport == XPORT_SATA) {
5250 struct ccb_trans_settings_sata *sata =
5251 &cts->xport_specific.sata;
5253 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5254 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5257 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5258 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5259 ata_mode2string(sata->mode));
5261 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5262 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5265 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5266 fprintf(stdout, "%sPIO transaction length: %d\n",
5267 pathstr, sata->bytecount);
5269 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5270 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5273 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5274 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5277 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5278 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5282 if (cts->protocol == PROTO_ATA) {
5283 struct ccb_trans_settings_ata *ata=
5284 &cts->proto_specific.ata;
5286 if (ata->valid & CTS_ATA_VALID_TQ) {
5287 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5288 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5289 "enabled" : "disabled");
5292 if (cts->protocol == PROTO_SCSI) {
5293 struct ccb_trans_settings_scsi *scsi=
5294 &cts->proto_specific.scsi;
5296 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5297 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5298 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5299 "enabled" : "disabled");
5303 if (cts->protocol == PROTO_NVME) {
5304 struct ccb_trans_settings_nvme *nvmex =
5305 &cts->xport_specific.nvme;
5307 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5308 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5309 NVME_MAJOR(nvmex->spec),
5310 NVME_MINOR(nvmex->spec));
5312 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5313 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5314 nvmex->lanes, nvmex->max_lanes);
5315 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5316 nvmex->speed, nvmex->max_speed);
5323 * Get a path inquiry CCB for the specified device.
5326 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5331 ccb = cam_getccb(device);
5333 warnx("get_cpi: couldn't allocate CCB");
5336 ccb->ccb_h.func_code = XPT_PATH_INQ;
5337 if (cam_send_ccb(device, ccb) < 0) {
5338 warn("get_cpi: error sending Path Inquiry CCB");
5340 goto get_cpi_bailout;
5342 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5343 if (arglist & CAM_ARG_VERBOSE)
5344 cam_error_print(device, ccb, CAM_ESF_ALL,
5345 CAM_EPF_ALL, stderr);
5347 goto get_cpi_bailout;
5349 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5357 * Get a get device CCB for the specified device.
5360 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5365 ccb = cam_getccb(device);
5367 warnx("get_cgd: couldn't allocate CCB");
5370 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5371 if (cam_send_ccb(device, ccb) < 0) {
5372 warn("get_cgd: error sending Get type information CCB");
5374 goto get_cgd_bailout;
5376 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5377 if (arglist & CAM_ARG_VERBOSE)
5378 cam_error_print(device, ccb, CAM_ESF_ALL,
5379 CAM_EPF_ALL, stderr);
5381 goto get_cgd_bailout;
5383 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5391 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5395 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5396 int timeout, int verbosemode)
5398 union ccb *ccb = NULL;
5399 struct scsi_vpd_supported_page_list sup_pages;
5403 ccb = cam_getccb(dev);
5405 warn("Unable to allocate CCB");
5410 bzero(&sup_pages, sizeof(sup_pages));
5412 scsi_inquiry(&ccb->csio,
5413 /*retries*/ retry_count,
5415 /* tag_action */ MSG_SIMPLE_Q_TAG,
5416 /* inq_buf */ (u_int8_t *)&sup_pages,
5417 /* inq_len */ sizeof(sup_pages),
5419 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5420 /* sense_len */ SSD_FULL_SIZE,
5421 /* timeout */ timeout ? timeout : 5000);
5423 /* Disable freezing the device queue */
5424 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5426 if (retry_count != 0)
5427 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5429 if (cam_send_ccb(dev, ccb) < 0) {
5436 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5437 if (verbosemode != 0)
5438 cam_error_print(dev, ccb, CAM_ESF_ALL,
5439 CAM_EPF_ALL, stderr);
5444 for (i = 0; i < sup_pages.length; i++) {
5445 if (sup_pages.list[i] == page_id) {
5458 * devtype is filled in with the type of device.
5459 * Returns 0 for success, non-zero for failure.
5462 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5463 int verbosemode, camcontrol_devtype *devtype)
5465 struct ccb_getdev cgd;
5468 retval = get_cgd(dev, &cgd);
5472 switch (cgd.protocol) {
5478 *devtype = CC_DT_ATA;
5480 break; /*NOTREACHED*/
5482 *devtype = CC_DT_NVME;
5484 break; /*NOTREACHED*/
5486 *devtype = CC_DT_MMCSD;
5488 break; /*NOTREACHED*/
5490 *devtype = CC_DT_UNKNOWN;
5492 break; /*NOTREACHED*/
5495 if (retry_count == -1) {
5497 * For a retry count of -1, used only the cached data to avoid
5498 * I/O to the drive. Sending the identify command to the drive
5499 * can cause issues for SATL attachaed drives since identify is
5500 * not an NCQ command. We check for the strings that windows
5501 * displays since those will not be NULs (they are supposed
5502 * to be space padded). We could check other bits, but anything
5503 * non-zero implies SATL.
5505 if (cgd.ident_data.serial[0] != 0 ||
5506 cgd.ident_data.revision[0] != 0 ||
5507 cgd.ident_data.model[0] != 0)
5508 *devtype = CC_DT_SATL;
5510 *devtype = CC_DT_SCSI;
5513 * Check for the ATA Information VPD page (0x89). If this is an
5514 * ATA device behind a SCSI to ATA translation layer (SATL),
5515 * this VPD page should be present.
5517 * If that VPD page isn't present, or we get an error back from
5518 * the INQUIRY command, we'll just treat it as a normal SCSI
5521 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5522 timeout, verbosemode);
5524 *devtype = CC_DT_SATL;
5526 *devtype = CC_DT_SCSI;
5535 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5536 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5537 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5538 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5539 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5540 int is48bit, camcontrol_devtype devtype)
5544 if (devtype == CC_DT_ATA) {
5545 cam_fill_ataio(&ccb->ataio,
5546 /*retries*/ retry_count,
5549 /*tag_action*/ tag_action,
5550 /*data_ptr*/ data_ptr,
5551 /*dxfer_len*/ dxfer_len,
5552 /*timeout*/ timeout);
5553 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5554 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5557 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5560 if (auxiliary != 0) {
5561 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5562 ccb->ataio.aux = auxiliary;
5565 if (ata_flags & AP_FLAG_CHK_COND)
5566 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5568 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5569 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5570 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5571 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5573 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5574 protocol |= AP_EXTEND;
5576 retval = scsi_ata_pass(&ccb->csio,
5577 /*retries*/ retry_count,
5580 /*tag_action*/ tag_action,
5581 /*protocol*/ protocol,
5582 /*ata_flags*/ ata_flags,
5583 /*features*/ features,
5584 /*sector_count*/ sector_count,
5586 /*command*/ command,
5589 /*auxiliary*/ auxiliary,
5591 /*data_ptr*/ data_ptr,
5592 /*dxfer_len*/ dxfer_len,
5593 /*cdb_storage*/ cdb_storage,
5594 /*cdb_storage_len*/ cdb_storage_len,
5595 /*minimum_cmd_size*/ 0,
5596 /*sense_len*/ sense_len,
5597 /*timeout*/ timeout);
5604 * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5605 * 4 -- count truncated, 6 -- lba and count truncated.
5608 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5609 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5613 switch (ccb->ccb_h.func_code) {
5616 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5620 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5621 * or 16 byte, and need to see what
5623 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5624 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5626 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5627 if ((opcode != ATA_PASS_12)
5628 && (opcode != ATA_PASS_16)) {
5629 warnx("%s: unsupported opcode %02x", __func__, opcode);
5633 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5635 /* Note: the _ccb() variant returns 0 for an error */
5639 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5640 switch (error_code) {
5641 case SSD_DESC_CURRENT_ERROR:
5642 case SSD_DESC_DEFERRED_ERROR: {
5643 struct scsi_sense_data_desc *sense;
5644 struct scsi_sense_ata_ret_desc *desc;
5647 sense = (struct scsi_sense_data_desc *)
5648 &ccb->csio.sense_data;
5650 desc_ptr = scsi_find_desc(sense, sense_len,
5652 if (desc_ptr == NULL) {
5653 cam_error_print(dev, ccb, CAM_ESF_ALL,
5654 CAM_EPF_ALL, stderr);
5657 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5659 *error = desc->error;
5660 *count = (desc->count_15_8 << 8) |
5662 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5663 ((uint64_t)desc->lba_39_32 << 32) |
5664 ((uint64_t)desc->lba_31_24 << 24) |
5665 (desc->lba_23_16 << 16) |
5666 (desc->lba_15_8 << 8) |
5668 *device = desc->device;
5669 *status = desc->status;
5672 * If the extend bit isn't set, the result is for a
5673 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5674 * command without the extend bit set. This means
5675 * that the device is supposed to return 28-bit
5676 * status. The count field is only 8 bits, and the
5677 * LBA field is only 8 bits.
5679 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5685 case SSD_CURRENT_ERROR:
5686 case SSD_DEFERRED_ERROR: {
5690 * In my understanding of SAT-5 specification, saying:
5691 * "without interpreting the contents of the STATUS",
5692 * this should not happen if CK_COND was set, but it
5693 * does at least for some devices, so try to revert.
5695 if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5696 (asc == 0) && (ascq == 0)) {
5697 *status = ATA_STATUS_ERROR;
5698 *error = ATA_ERROR_ABORT;
5705 if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5706 (asc != 0x00) || (ascq != 0x1d))
5710 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5711 SSD_DESC_INFO, &val, NULL);
5712 *error = (val >> 24) & 0xff;
5713 *status = (val >> 16) & 0xff;
5714 *device = (val >> 8) & 0xff;
5715 *count = val & 0xff;
5718 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5719 SSD_DESC_COMMAND, &val, NULL);
5720 *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5721 ((val & 0xff) << 16);
5723 /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5724 return ((val >> 28) & 0x06);
5733 struct ata_res *res;
5735 /* Only some statuses return ATA result register set. */
5736 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5737 cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5740 res = &ccb->ataio.res;
5741 *error = res->error;
5742 *status = res->status;
5743 *device = res->device;
5744 *count = res->sector_count;
5745 *lba = (res->lba_high << 16) |
5746 (res->lba_mid << 8) |
5748 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5749 *count |= (res->sector_count_exp << 8);
5750 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5751 ((uint64_t)res->lba_mid_exp << 32) |
5752 ((uint64_t)res->lba_high_exp << 40);
5754 *lba |= (res->device & 0xf) << 24;
5765 cpi_print(struct ccb_pathinq *cpi)
5767 char adapter_str[1024];
5770 snprintf(adapter_str, sizeof(adapter_str),
5771 "%s%d:", cpi->dev_name, cpi->unit_number);
5773 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5776 for (i = 1; i < UINT8_MAX; i = i << 1) {
5779 if ((i & cpi->hba_inquiry) == 0)
5782 fprintf(stdout, "%s supports ", adapter_str);
5786 str = "MDP message";
5789 str = "32 bit wide SCSI";
5792 str = "16 bit wide SCSI";
5795 str = "SDTR message";
5798 str = "linked CDBs";
5801 str = "tag queue messages";
5804 str = "soft reset alternative";
5807 str = "SATA Port Multiplier";
5810 str = "unknown PI bit set";
5813 fprintf(stdout, "%s\n", str);
5816 for (i = 1; i < UINT32_MAX; i = i << 1) {
5819 if ((i & cpi->hba_misc) == 0)
5822 fprintf(stdout, "%s ", adapter_str);
5826 str = "can understand ata_ext requests";
5829 str = "64bit extended LUNs supported";
5832 str = "bus scans from high ID to low ID";
5835 str = "removable devices not included in scan";
5837 case PIM_NOINITIATOR:
5838 str = "initiator role not supported";
5840 case PIM_NOBUSRESET:
5841 str = "user has disabled initial BUS RESET or"
5842 " controller is in target/mixed mode";
5845 str = "do not send 6-byte commands";
5848 str = "scan bus sequentially";
5851 str = "unmapped I/O supported";
5854 str = "does its own scanning";
5857 str = "unknown PIM bit set";
5860 fprintf(stdout, "%s\n", str);
5863 for (i = 1; i < UINT16_MAX; i = i << 1) {
5866 if ((i & cpi->target_sprt) == 0)
5869 fprintf(stdout, "%s supports ", adapter_str);
5872 str = "target mode processor mode";
5875 str = "target mode phase cog. mode";
5877 case PIT_DISCONNECT:
5878 str = "disconnects in target mode";
5881 str = "terminate I/O message in target mode";
5884 str = "group 6 commands in target mode";
5887 str = "group 7 commands in target mode";
5890 str = "unknown PIT bit set";
5894 fprintf(stdout, "%s\n", str);
5896 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5898 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5900 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5902 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5903 adapter_str, cpi->hpath_id);
5904 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5906 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5907 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5908 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5909 adapter_str, cpi->hba_vendor);
5910 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5911 adapter_str, cpi->hba_device);
5912 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5913 adapter_str, cpi->hba_subvendor);
5914 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5915 adapter_str, cpi->hba_subdevice);
5916 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5917 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5918 if (cpi->base_transfer_speed > 1000)
5919 fprintf(stdout, "%d.%03dMB/sec\n",
5920 cpi->base_transfer_speed / 1000,
5921 cpi->base_transfer_speed % 1000);
5923 fprintf(stdout, "%dKB/sec\n",
5924 (cpi->base_transfer_speed % 1000) * 1000);
5925 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5926 adapter_str, cpi->maxio);
5930 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5931 struct ccb_trans_settings *cts)
5937 ccb = cam_getccb(device);
5940 warnx("get_print_cts: error allocating ccb");
5944 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5946 if (user_settings == 0)
5947 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5949 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5951 if (cam_send_ccb(device, ccb) < 0) {
5952 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
5954 goto get_print_cts_bailout;
5957 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5958 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5959 if (arglist & CAM_ARG_VERBOSE)
5960 cam_error_print(device, ccb, CAM_ESF_ALL,
5961 CAM_EPF_ALL, stderr);
5963 goto get_print_cts_bailout;
5967 cts_print(device, &ccb->cts);
5970 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5972 get_print_cts_bailout:
5980 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5981 int timeout, int argc, char **argv, char *combinedopt)
5985 int user_settings = 0;
5987 int disc_enable = -1, tag_enable = -1;
5990 double syncrate = -1;
5993 int change_settings = 0, send_tur = 0;
5994 struct ccb_pathinq cpi;
5996 ccb = cam_getccb(device);
5998 warnx("ratecontrol: error allocating ccb");
6001 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6010 if (strncasecmp(optarg, "enable", 6) == 0)
6012 else if (strncasecmp(optarg, "disable", 7) == 0)
6015 warnx("-D argument \"%s\" is unknown", optarg);
6017 goto ratecontrol_bailout;
6019 change_settings = 1;
6022 mode = ata_string2mode(optarg);
6024 warnx("unknown mode '%s'", optarg);
6026 goto ratecontrol_bailout;
6028 change_settings = 1;
6031 offset = strtol(optarg, NULL, 0);
6033 warnx("offset value %d is < 0", offset);
6035 goto ratecontrol_bailout;
6037 change_settings = 1;
6043 syncrate = atof(optarg);
6045 warnx("sync rate %f is < 0", syncrate);
6047 goto ratecontrol_bailout;
6049 change_settings = 1;
6052 if (strncasecmp(optarg, "enable", 6) == 0)
6054 else if (strncasecmp(optarg, "disable", 7) == 0)
6057 warnx("-T argument \"%s\" is unknown", optarg);
6059 goto ratecontrol_bailout;
6061 change_settings = 1;
6067 bus_width = strtol(optarg, NULL, 0);
6068 if (bus_width < 0) {
6069 warnx("bus width %d is < 0", bus_width);
6071 goto ratecontrol_bailout;
6073 change_settings = 1;
6080 * Grab path inquiry information, so we can determine whether
6081 * or not the initiator is capable of the things that the user
6084 if ((retval = get_cpi(device, &cpi)) != 0)
6085 goto ratecontrol_bailout;
6087 fprintf(stdout, "%s parameters:\n",
6088 user_settings ? "User" : "Current");
6090 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6092 goto ratecontrol_bailout;
6094 if (arglist & CAM_ARG_VERBOSE)
6097 if (change_settings) {
6098 int didsettings = 0;
6099 struct ccb_trans_settings_spi *spi = NULL;
6100 struct ccb_trans_settings_pata *pata = NULL;
6101 struct ccb_trans_settings_sata *sata = NULL;
6102 struct ccb_trans_settings_ata *ata = NULL;
6103 struct ccb_trans_settings_scsi *scsi = NULL;
6105 if (ccb->cts.transport == XPORT_SPI)
6106 spi = &ccb->cts.xport_specific.spi;
6107 if (ccb->cts.transport == XPORT_ATA)
6108 pata = &ccb->cts.xport_specific.ata;
6109 if (ccb->cts.transport == XPORT_SATA)
6110 sata = &ccb->cts.xport_specific.sata;
6111 if (ccb->cts.protocol == PROTO_ATA)
6112 ata = &ccb->cts.proto_specific.ata;
6113 if (ccb->cts.protocol == PROTO_SCSI)
6114 scsi = &ccb->cts.proto_specific.scsi;
6115 ccb->cts.xport_specific.valid = 0;
6116 ccb->cts.proto_specific.valid = 0;
6117 if (spi && disc_enable != -1) {
6118 spi->valid |= CTS_SPI_VALID_DISC;
6119 if (disc_enable == 0)
6120 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6122 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6125 if (tag_enable != -1) {
6126 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6127 warnx("HBA does not support tagged queueing, "
6128 "so you cannot modify tag settings");
6130 goto ratecontrol_bailout;
6133 ata->valid |= CTS_SCSI_VALID_TQ;
6134 if (tag_enable == 0)
6135 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6137 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6140 scsi->valid |= CTS_SCSI_VALID_TQ;
6141 if (tag_enable == 0)
6142 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6144 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6148 if (spi && offset != -1) {
6149 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6150 warnx("HBA is not capable of changing offset");
6152 goto ratecontrol_bailout;
6154 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6155 spi->sync_offset = offset;
6158 if (spi && syncrate != -1) {
6159 int prelim_sync_period;
6161 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6162 warnx("HBA is not capable of changing "
6165 goto ratecontrol_bailout;
6167 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6169 * The sync rate the user gives us is in MHz.
6170 * We need to translate it into KHz for this
6175 * Next, we calculate a "preliminary" sync period
6176 * in tenths of a nanosecond.
6179 prelim_sync_period = 0;
6181 prelim_sync_period = 10000000 / syncrate;
6183 scsi_calc_syncparam(prelim_sync_period);
6186 if (sata && syncrate != -1) {
6187 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6188 warnx("HBA is not capable of changing "
6191 goto ratecontrol_bailout;
6193 if (!user_settings) {
6194 warnx("You can modify only user rate "
6195 "settings for SATA");
6197 goto ratecontrol_bailout;
6199 sata->revision = ata_speed2revision(syncrate * 100);
6200 if (sata->revision < 0) {
6201 warnx("Invalid rate %f", syncrate);
6203 goto ratecontrol_bailout;
6205 sata->valid |= CTS_SATA_VALID_REVISION;
6208 if ((pata || sata) && mode != -1) {
6209 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6210 warnx("HBA is not capable of changing "
6213 goto ratecontrol_bailout;
6215 if (!user_settings) {
6216 warnx("You can modify only user mode "
6217 "settings for ATA/SATA");
6219 goto ratecontrol_bailout;
6223 pata->valid |= CTS_ATA_VALID_MODE;
6226 sata->valid |= CTS_SATA_VALID_MODE;
6231 * The bus_width argument goes like this:
6235 * Therefore, if you shift the number of bits given on the
6236 * command line right by 4, you should get the correct
6239 if (spi && bus_width != -1) {
6241 * We might as well validate things here with a
6242 * decipherable error message, rather than what
6243 * will probably be an indecipherable error message
6244 * by the time it gets back to us.
6246 if ((bus_width == 16)
6247 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6248 warnx("HBA does not support 16 bit bus width");
6250 goto ratecontrol_bailout;
6251 } else if ((bus_width == 32)
6252 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6253 warnx("HBA does not support 32 bit bus width");
6255 goto ratecontrol_bailout;
6256 } else if ((bus_width != 8)
6257 && (bus_width != 16)
6258 && (bus_width != 32)) {
6259 warnx("Invalid bus width %d", bus_width);
6261 goto ratecontrol_bailout;
6263 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6264 spi->bus_width = bus_width >> 4;
6267 if (didsettings == 0) {
6268 goto ratecontrol_bailout;
6270 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6271 if (cam_send_ccb(device, ccb) < 0) {
6272 warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6274 goto ratecontrol_bailout;
6276 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6277 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6278 if (arglist & CAM_ARG_VERBOSE) {
6279 cam_error_print(device, ccb, CAM_ESF_ALL,
6280 CAM_EPF_ALL, stderr);
6283 goto ratecontrol_bailout;
6287 retval = testunitready(device, task_attr, retry_count, timeout,
6288 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6290 * If the TUR didn't succeed, just bail.
6294 fprintf(stderr, "Test Unit Ready failed\n");
6295 goto ratecontrol_bailout;
6298 if ((change_settings || send_tur) && !quiet &&
6299 (ccb->cts.transport == XPORT_ATA ||
6300 ccb->cts.transport == XPORT_SATA || send_tur)) {
6301 fprintf(stdout, "New parameters:\n");
6302 retval = get_print_cts(device, user_settings, 0, NULL);
6305 ratecontrol_bailout:
6311 scsiformat(struct cam_device *device, int argc, char **argv,
6312 char *combinedopt, int task_attr, int retry_count, int timeout)
6316 int ycount = 0, quiet = 0;
6317 int error = 0, retval = 0;
6318 int use_timeout = 10800 * 1000;
6320 struct format_defect_list_header fh;
6321 u_int8_t *data_ptr = NULL;
6322 u_int32_t dxfer_len = 0;
6324 int num_warnings = 0;
6327 ccb = cam_getccb(device);
6330 warnx("scsiformat: error allocating ccb");
6334 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6354 if (quiet == 0 && ycount == 0) {
6355 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6356 "following device:\n");
6358 error = scsidoinquiry(device, argc, argv, combinedopt,
6359 task_attr, retry_count, timeout);
6362 warnx("scsiformat: error sending inquiry");
6363 goto scsiformat_bailout;
6368 if (!get_confirmation()) {
6370 goto scsiformat_bailout;
6375 use_timeout = timeout;
6378 fprintf(stdout, "Current format timeout is %d seconds\n",
6379 use_timeout / 1000);
6383 * If the user hasn't disabled questions and didn't specify a
6384 * timeout on the command line, ask them if they want the current
6388 && (timeout == 0)) {
6390 int new_timeout = 0;
6392 fprintf(stdout, "Enter new timeout in seconds or press\n"
6393 "return to keep the current timeout [%d] ",
6394 use_timeout / 1000);
6396 if (fgets(str, sizeof(str), stdin) != NULL) {
6398 new_timeout = atoi(str);
6401 if (new_timeout != 0) {
6402 use_timeout = new_timeout * 1000;
6403 fprintf(stdout, "Using new timeout value %d\n",
6404 use_timeout / 1000);
6409 * Keep this outside the if block below to silence any unused
6410 * variable warnings.
6412 bzero(&fh, sizeof(fh));
6415 * If we're in immediate mode, we've got to include the format
6418 if (immediate != 0) {
6419 fh.byte2 = FU_DLH_IMMED;
6420 data_ptr = (u_int8_t *)&fh;
6421 dxfer_len = sizeof(fh);
6422 byte2 = FU_FMT_DATA;
6423 } else if (quiet == 0) {
6424 fprintf(stdout, "Formatting...");
6428 scsi_format_unit(&ccb->csio,
6429 /* retries */ retry_count,
6431 /* tag_action */ task_attr,
6434 /* data_ptr */ data_ptr,
6435 /* dxfer_len */ dxfer_len,
6436 /* sense_len */ SSD_FULL_SIZE,
6437 /* timeout */ use_timeout);
6439 /* Disable freezing the device queue */
6440 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6442 if (arglist & CAM_ARG_ERR_RECOVER)
6443 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6445 if (((retval = cam_send_ccb(device, ccb)) < 0)
6446 || ((immediate == 0)
6447 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6448 const char errstr[] = "error sending format command";
6455 if (arglist & CAM_ARG_VERBOSE) {
6456 cam_error_print(device, ccb, CAM_ESF_ALL,
6457 CAM_EPF_ALL, stderr);
6460 goto scsiformat_bailout;
6464 * If we ran in non-immediate mode, we already checked for errors
6465 * above and printed out any necessary information. If we're in
6466 * immediate mode, we need to loop through and get status
6467 * information periodically.
6469 if (immediate == 0) {
6471 fprintf(stdout, "Format Complete\n");
6473 goto scsiformat_bailout;
6480 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6483 * There's really no need to do error recovery or
6484 * retries here, since we're just going to sit in a
6485 * loop and wait for the device to finish formatting.
6487 scsi_test_unit_ready(&ccb->csio,
6490 /* tag_action */ task_attr,
6491 /* sense_len */ SSD_FULL_SIZE,
6492 /* timeout */ 5000);
6494 /* Disable freezing the device queue */
6495 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6497 retval = cam_send_ccb(device, ccb);
6500 * If we get an error from the ioctl, bail out. SCSI
6501 * errors are expected.
6504 warn("error sending TEST UNIT READY command");
6506 goto scsiformat_bailout;
6509 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6511 if ((status != CAM_REQ_CMP)
6512 && (status == CAM_SCSI_STATUS_ERROR)
6513 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6514 struct scsi_sense_data *sense;
6515 int error_code, sense_key, asc, ascq;
6517 sense = &ccb->csio.sense_data;
6518 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6519 ccb->csio.sense_resid, &error_code, &sense_key,
6520 &asc, &ascq, /*show_errors*/ 1);
6523 * According to the SCSI-2 and SCSI-3 specs, a
6524 * drive that is in the middle of a format should
6525 * return NOT READY with an ASC of "logical unit
6526 * not ready, format in progress". The sense key
6527 * specific bytes will then be a progress indicator.
6529 if ((sense_key == SSD_KEY_NOT_READY)
6530 && (asc == 0x04) && (ascq == 0x04)) {
6533 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6534 ccb->csio.sense_resid, sks) == 0)
6537 u_int64_t percentage;
6539 val = scsi_2btoul(&sks[1]);
6540 percentage = 10000ull * val;
6543 "\rFormatting: %ju.%02u %% "
6545 (uintmax_t)(percentage /
6547 (unsigned)((percentage /
6551 } else if ((quiet == 0)
6552 && (++num_warnings <= 1)) {
6553 warnx("Unexpected SCSI Sense Key "
6554 "Specific value returned "
6556 scsi_sense_print(device, &ccb->csio,
6558 warnx("Unable to print status "
6559 "information, but format will "
6561 warnx("will exit when format is "
6566 warnx("Unexpected SCSI error during format");
6567 cam_error_print(device, ccb, CAM_ESF_ALL,
6568 CAM_EPF_ALL, stderr);
6570 goto scsiformat_bailout;
6573 } else if (status != CAM_REQ_CMP) {
6574 warnx("Unexpected CAM status %#x", status);
6575 if (arglist & CAM_ARG_VERBOSE)
6576 cam_error_print(device, ccb, CAM_ESF_ALL,
6577 CAM_EPF_ALL, stderr);
6579 goto scsiformat_bailout;
6582 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6585 fprintf(stdout, "\nFormat Complete\n");
6595 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6596 camcontrol_devtype devtype)
6599 uint8_t error = 0, ata_device = 0, status = 0;
6605 retval = build_ata_cmd(ccb,
6607 /*flags*/ CAM_DIR_NONE,
6608 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6609 /*protocol*/ AP_PROTO_NON_DATA,
6610 /*ata_flags*/ AP_FLAG_CHK_COND,
6611 /*features*/ 0x00, /* SANITIZE STATUS EXT */
6614 /*command*/ ATA_SANITIZE,
6618 /*cdb_storage*/ NULL,
6619 /*cdb_storage_len*/ 0,
6620 /*sense_len*/ SSD_FULL_SIZE,
6623 /*devtype*/ devtype);
6625 warnx("%s: build_ata_cmd() failed, likely "
6626 "programmer error", __func__);
6630 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6631 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6632 retval = cam_send_ccb(device, ccb);
6634 warn("error sending SANITIZE STATUS EXT command");
6638 retval = get_ata_status(device, ccb, &error, &count, &lba,
6639 &ata_device, &status);
6641 warnx("Can't get SANITIZE STATUS EXT status, "
6642 "sanitize may still run.");
6645 if (status & ATA_STATUS_ERROR) {
6646 if (error & ATA_ERROR_ABORT) {
6647 switch (lba & 0xff) {
6649 warnx("Reason not reported or sanitize failed.");
6652 warnx("Sanitize command unsuccessful. ");
6655 warnx("Unsupported sanitize device command. ");
6658 warnx("Device is in sanitize frozen state. ");
6661 warnx("Sanitize antifreeze lock is enabled. ");
6665 warnx("SANITIZE STATUS EXT failed, "
6666 "sanitize may still run.");
6669 if (count & 0x4000) {
6674 "Sanitizing: %u.%02u%% (%d/%d)\r",
6675 (perc / (0x10000 * 100)),
6676 ((perc / 0x10000) % 100),
6688 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6690 int warnings = 0, retval;
6695 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6698 * There's really no need to do error recovery or
6699 * retries here, since we're just going to sit in a
6700 * loop and wait for the device to finish sanitizing.
6702 scsi_test_unit_ready(&ccb->csio,
6705 /* tag_action */ task_attr,
6706 /* sense_len */ SSD_FULL_SIZE,
6707 /* timeout */ 5000);
6709 /* Disable freezing the device queue */
6710 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6712 retval = cam_send_ccb(device, ccb);
6715 * If we get an error from the ioctl, bail out. SCSI
6716 * errors are expected.
6719 warn("error sending TEST UNIT READY command");
6723 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6724 if ((status == CAM_SCSI_STATUS_ERROR) &&
6725 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6726 struct scsi_sense_data *sense;
6727 int error_code, sense_key, asc, ascq;
6729 sense = &ccb->csio.sense_data;
6730 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6731 ccb->csio.sense_resid, &error_code, &sense_key,
6732 &asc, &ascq, /*show_errors*/ 1);
6735 * According to the SCSI-3 spec, a drive that is in the
6736 * middle of a sanitize should return NOT READY with an
6737 * ASC of "logical unit not ready, sanitize in
6738 * progress". The sense key specific bytes will then
6739 * be a progress indicator.
6741 if ((sense_key == SSD_KEY_NOT_READY)
6742 && (asc == 0x04) && (ascq == 0x1b)) {
6745 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6746 ccb->csio.sense_resid, sks) == 0)
6748 val = scsi_2btoul(&sks[1]);
6751 "Sanitizing: %u.%02u%% (%d/%d)\r",
6752 (perc / (0x10000 * 100)),
6753 ((perc / 0x10000) % 100),
6756 } else if ((quiet == 0) && (++warnings <= 1)) {
6757 warnx("Unexpected SCSI Sense Key "
6758 "Specific value returned "
6759 "during sanitize:");
6760 scsi_sense_print(device, &ccb->csio,
6762 warnx("Unable to print status "
6763 "information, but sanitze will "
6765 warnx("will exit when sanitize is "
6770 warnx("Unexpected SCSI error during sanitize");
6771 cam_error_print(device, ccb, CAM_ESF_ALL,
6772 CAM_EPF_ALL, stderr);
6776 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6777 warnx("Unexpected CAM status %#x", status);
6778 if (arglist & CAM_ARG_VERBOSE)
6779 cam_error_print(device, ccb, CAM_ESF_ALL,
6780 CAM_EPF_ALL, stderr);
6783 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6788 sanitize(struct cam_device *device, int argc, char **argv,
6789 char *combinedopt, int task_attr, int retry_count, int timeout)
6792 u_int8_t action = 0;
6794 int ycount = 0, quiet = 0;
6802 const char *pattern = NULL;
6803 u_int8_t *data_ptr = NULL;
6804 u_int32_t dxfer_len = 0;
6806 uint16_t feature, count;
6809 camcontrol_devtype dt;
6812 * Get the device type, request no I/O be done to do this.
6814 error = get_device_type(device, -1, 0, 0, &dt);
6815 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6816 warnx("sanitize: can't get device type");
6820 ccb = cam_getccb(device);
6823 warnx("sanitize: error allocating ccb");
6827 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6830 if (strcasecmp(optarg, "overwrite") == 0)
6831 action = SSZ_SERVICE_ACTION_OVERWRITE;
6832 else if (strcasecmp(optarg, "block") == 0)
6833 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6834 else if (strcasecmp(optarg, "crypto") == 0)
6835 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6836 else if (strcasecmp(optarg, "exitfailure") == 0)
6837 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6839 warnx("invalid service operation \"%s\"",
6842 goto sanitize_bailout;
6846 passes = strtol(optarg, NULL, 0);
6847 if (passes < 1 || passes > 31) {
6848 warnx("invalid passes value %d", passes);
6850 goto sanitize_bailout;
6869 /* ATA supports only immediate commands. */
6870 if (dt == CC_DT_SCSI)
6883 warnx("an action is required");
6885 goto sanitize_bailout;
6886 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6887 struct scsi_sanitize_parameter_list *pl;
6891 if (pattern == NULL) {
6892 warnx("overwrite action requires -P argument");
6894 goto sanitize_bailout;
6896 fd = open(pattern, O_RDONLY);
6898 warn("cannot open pattern file %s", pattern);
6900 goto sanitize_bailout;
6902 if (fstat(fd, &sb) < 0) {
6903 warn("cannot stat pattern file %s", pattern);
6905 goto sanitize_bailout;
6908 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6909 warnx("pattern file size exceeds maximum value %d",
6910 SSZPL_MAX_PATTERN_LENGTH);
6912 goto sanitize_bailout;
6914 dxfer_len = sizeof(*pl) + sz;
6915 data_ptr = calloc(1, dxfer_len);
6916 if (data_ptr == NULL) {
6917 warnx("cannot allocate parameter list buffer");
6919 goto sanitize_bailout;
6922 amt = read(fd, data_ptr + sizeof(*pl), sz);
6924 warn("cannot read pattern file");
6926 goto sanitize_bailout;
6927 } else if (amt != sz) {
6928 warnx("short pattern file read");
6930 goto sanitize_bailout;
6933 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6939 pl->byte1 |= SSZPL_INVERT;
6940 scsi_ulto2b(sz, pl->length);
6946 else if (invert != 0)
6948 else if (pattern != NULL)
6953 warnx("%s argument only valid with overwrite "
6956 goto sanitize_bailout;
6960 if (quiet == 0 && ycount == 0) {
6961 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6962 "following device:\n");
6964 if (dt == CC_DT_SCSI) {
6965 error = scsidoinquiry(device, argc, argv, combinedopt,
6966 task_attr, retry_count, timeout);
6967 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
6968 struct ata_params *ident_buf;
6969 error = ata_do_identify(device, retry_count, timeout,
6972 printf("%s%d: ", device->device_name,
6973 device->dev_unit_num);
6974 ata_print_ident(ident_buf);
6981 warnx("sanitize: error sending inquiry");
6982 goto sanitize_bailout;
6987 if (!get_confirmation()) {
6989 goto sanitize_bailout;
6994 use_timeout = timeout;
6996 use_timeout = (immediate ? 10 : 10800) * 1000;
6998 if (immediate == 0 && quiet == 0) {
6999 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7000 use_timeout / 1000);
7004 * If the user hasn't disabled questions and didn't specify a
7005 * timeout on the command line, ask them if they want the current
7008 if (immediate == 0 && ycount == 0 && timeout == 0) {
7010 int new_timeout = 0;
7012 fprintf(stdout, "Enter new timeout in seconds or press\n"
7013 "return to keep the current timeout [%d] ",
7014 use_timeout / 1000);
7016 if (fgets(str, sizeof(str), stdin) != NULL) {
7018 new_timeout = atoi(str);
7021 if (new_timeout != 0) {
7022 use_timeout = new_timeout * 1000;
7023 fprintf(stdout, "Using new timeout value %d\n",
7024 use_timeout / 1000);
7028 if (dt == CC_DT_SCSI) {
7031 byte2 |= SSZ_UNRESTRICTED_EXIT;
7034 scsi_sanitize(&ccb->csio,
7035 /* retries */ retry_count,
7037 /* tag_action */ task_attr,
7040 /* data_ptr */ data_ptr,
7041 /* dxfer_len */ dxfer_len,
7042 /* sense_len */ SSD_FULL_SIZE,
7043 /* timeout */ use_timeout);
7045 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7046 if (arglist & CAM_ARG_ERR_RECOVER)
7047 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7048 if (cam_send_ccb(device, ccb) < 0) {
7049 warn("error sending sanitize command");
7051 goto sanitize_bailout;
7053 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7054 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7055 feature = 0x14; /* OVERWRITE EXT */
7056 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7057 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7059 count |= 0x80; /* INVERT PATTERN */
7061 count |= 0x10; /* FAILURE MODE */
7062 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7063 feature = 0x12; /* BLOCK ERASE EXT */
7064 lba = 0x0000426B4572;
7067 count |= 0x10; /* FAILURE MODE */
7068 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7069 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7070 lba = 0x000043727970;
7073 count |= 0x10; /* FAILURE MODE */
7074 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7075 feature = 0x00; /* SANITIZE STATUS EXT */
7077 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7080 goto sanitize_bailout;
7083 error = ata_do_cmd(device,
7086 /*flags*/CAM_DIR_NONE,
7087 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7089 /*tag_action*/MSG_SIMPLE_Q_TAG,
7090 /*command*/ATA_SANITIZE,
7091 /*features*/feature,
7093 /*sector_count*/count,
7096 /*timeout*/ use_timeout,
7100 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7101 struct scsi_sense_data *sense;
7102 int error_code, sense_key, asc, ascq;
7104 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7105 CAM_SCSI_STATUS_ERROR) {
7106 sense = &ccb->csio.sense_data;
7107 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7108 ccb->csio.sense_resid, &error_code, &sense_key,
7109 &asc, &ascq, /*show_errors*/ 1);
7111 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7112 asc == 0x20 && ascq == 0x00)
7113 warnx("sanitize is not supported by "
7116 warnx("error sanitizing this device");
7118 warnx("error sanitizing this device");
7120 if (arglist & CAM_ARG_VERBOSE) {
7121 cam_error_print(device, ccb, CAM_ESF_ALL,
7122 CAM_EPF_ALL, stderr);
7125 goto sanitize_bailout;
7129 * If we ran in non-immediate mode, we already checked for errors
7130 * above and printed out any necessary information. If we're in
7131 * immediate mode, we need to loop through and get status
7132 * information periodically.
7134 if (immediate == 0) {
7136 fprintf(stdout, "Sanitize Complete\n");
7138 goto sanitize_bailout;
7142 if (dt == CC_DT_SCSI) {
7143 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7144 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7145 error = sanitize_wait_ata(device, ccb, quiet, dt);
7148 if (error == 0 && quiet == 0)
7149 fprintf(stdout, "Sanitize Complete \n");
7154 if (data_ptr != NULL)
7162 scsireportluns(struct cam_device *device, int argc, char **argv,
7163 char *combinedopt, int task_attr, int retry_count, int timeout)
7166 int c, countonly, lunsonly;
7167 struct scsi_report_luns_data *lundata;
7169 uint8_t report_type;
7170 uint32_t list_len, i, j;
7175 report_type = RPL_REPORT_DEFAULT;
7176 ccb = cam_getccb(device);
7179 warnx("%s: error allocating ccb", __func__);
7186 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7195 if (strcasecmp(optarg, "default") == 0)
7196 report_type = RPL_REPORT_DEFAULT;
7197 else if (strcasecmp(optarg, "wellknown") == 0)
7198 report_type = RPL_REPORT_WELLKNOWN;
7199 else if (strcasecmp(optarg, "all") == 0)
7200 report_type = RPL_REPORT_ALL;
7202 warnx("%s: invalid report type \"%s\"",
7213 if ((countonly != 0)
7214 && (lunsonly != 0)) {
7215 warnx("%s: you can only specify one of -c or -l", __func__);
7220 * According to SPC-4, the allocation length must be at least 16
7221 * bytes -- enough for the header and one LUN.
7223 alloc_len = sizeof(*lundata) + 8;
7227 lundata = malloc(alloc_len);
7229 if (lundata == NULL) {
7230 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7235 scsi_report_luns(&ccb->csio,
7236 /*retries*/ retry_count,
7238 /*tag_action*/ task_attr,
7239 /*select_report*/ report_type,
7240 /*rpl_buf*/ lundata,
7241 /*alloc_len*/ alloc_len,
7242 /*sense_len*/ SSD_FULL_SIZE,
7243 /*timeout*/ timeout ? timeout : 5000);
7245 /* Disable freezing the device queue */
7246 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7248 if (arglist & CAM_ARG_ERR_RECOVER)
7249 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7251 if (cam_send_ccb(device, ccb) < 0) {
7252 warn("error sending REPORT LUNS command");
7257 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7258 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7264 list_len = scsi_4btoul(lundata->length);
7267 * If we need to list the LUNs, and our allocation
7268 * length was too short, reallocate and retry.
7270 if ((countonly == 0)
7271 && (list_len > (alloc_len - sizeof(*lundata)))) {
7272 alloc_len = list_len + sizeof(*lundata);
7278 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7279 ((list_len / 8) > 1) ? "s" : "");
7284 for (i = 0; i < (list_len / 8); i++) {
7288 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7290 fprintf(stdout, ",");
7291 switch (lundata->luns[i].lundata[j] &
7292 RPL_LUNDATA_ATYP_MASK) {
7293 case RPL_LUNDATA_ATYP_PERIPH:
7294 if ((lundata->luns[i].lundata[j] &
7295 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7296 fprintf(stdout, "%d:",
7297 lundata->luns[i].lundata[j] &
7298 RPL_LUNDATA_PERIPH_BUS_MASK);
7300 && ((lundata->luns[i].lundata[j+2] &
7301 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7304 fprintf(stdout, "%d",
7305 lundata->luns[i].lundata[j+1]);
7307 case RPL_LUNDATA_ATYP_FLAT: {
7309 tmplun[0] = lundata->luns[i].lundata[j] &
7310 RPL_LUNDATA_FLAT_LUN_MASK;
7311 tmplun[1] = lundata->luns[i].lundata[j+1];
7313 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7317 case RPL_LUNDATA_ATYP_LUN:
7318 fprintf(stdout, "%d:%d:%d",
7319 (lundata->luns[i].lundata[j+1] &
7320 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7321 lundata->luns[i].lundata[j] &
7322 RPL_LUNDATA_LUN_TARG_MASK,
7323 lundata->luns[i].lundata[j+1] &
7324 RPL_LUNDATA_LUN_LUN_MASK);
7326 case RPL_LUNDATA_ATYP_EXTLUN: {
7327 int field_len_code, eam_code;
7329 eam_code = lundata->luns[i].lundata[j] &
7330 RPL_LUNDATA_EXT_EAM_MASK;
7331 field_len_code = (lundata->luns[i].lundata[j] &
7332 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7334 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7335 && (field_len_code == 0x00)) {
7336 fprintf(stdout, "%d",
7337 lundata->luns[i].lundata[j+1]);
7338 } else if ((eam_code ==
7339 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7340 && (field_len_code == 0x03)) {
7344 * This format takes up all 8 bytes.
7345 * If we aren't starting at offset 0,
7349 fprintf(stdout, "Invalid "
7352 "specified format", j);
7356 bzero(tmp_lun, sizeof(tmp_lun));
7357 bcopy(&lundata->luns[i].lundata[j+1],
7358 &tmp_lun[1], sizeof(tmp_lun) - 1);
7359 fprintf(stdout, "%#jx",
7360 (intmax_t)scsi_8btou64(tmp_lun));
7363 fprintf(stderr, "Unknown Extended LUN"
7364 "Address method %#x, length "
7365 "code %#x", eam_code,
7372 fprintf(stderr, "Unknown LUN address method "
7373 "%#x\n", lundata->luns[i].lundata[0] &
7374 RPL_LUNDATA_ATYP_MASK);
7378 * For the flat addressing method, there are no
7379 * other levels after it.
7384 fprintf(stdout, "\n");
7397 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7398 char *combinedopt, int task_attr, int retry_count, int timeout)
7401 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7402 struct scsi_read_capacity_data rcap;
7403 struct scsi_read_capacity_data_long rcaplong;
7418 ccb = cam_getccb(device);
7421 warnx("%s: error allocating ccb", __func__);
7425 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7455 if ((blocksizeonly != 0)
7456 && (numblocks != 0)) {
7457 warnx("%s: you can only specify one of -b or -N", __func__);
7462 if ((blocksizeonly != 0)
7463 && (sizeonly != 0)) {
7464 warnx("%s: you can only specify one of -b or -s", __func__);
7471 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7477 && (blocksizeonly != 0)) {
7478 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7486 scsi_read_capacity(&ccb->csio,
7487 /*retries*/ retry_count,
7489 /*tag_action*/ task_attr,
7492 /*timeout*/ timeout ? timeout : 5000);
7494 /* Disable freezing the device queue */
7495 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7497 if (arglist & CAM_ARG_ERR_RECOVER)
7498 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7500 if (cam_send_ccb(device, ccb) < 0) {
7501 warn("error sending READ CAPACITY command");
7506 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7507 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7512 maxsector = scsi_4btoul(rcap.addr);
7513 block_len = scsi_4btoul(rcap.length);
7516 * A last block of 2^32-1 means that the true capacity is over 2TB,
7517 * and we need to issue the long READ CAPACITY to get the real
7518 * capacity. Otherwise, we're all set.
7520 if (maxsector != 0xffffffff)
7524 scsi_read_capacity_16(&ccb->csio,
7525 /*retries*/ retry_count,
7527 /*tag_action*/ task_attr,
7531 /*rcap_buf*/ (uint8_t *)&rcaplong,
7532 /*rcap_buf_len*/ sizeof(rcaplong),
7533 /*sense_len*/ SSD_FULL_SIZE,
7534 /*timeout*/ timeout ? timeout : 5000);
7536 /* Disable freezing the device queue */
7537 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7539 if (arglist & CAM_ARG_ERR_RECOVER)
7540 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7542 if (cam_send_ccb(device, ccb) < 0) {
7543 warn("error sending READ CAPACITY (16) command");
7548 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7549 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7554 maxsector = scsi_8btou64(rcaplong.addr);
7555 block_len = scsi_4btoul(rcaplong.length);
7558 if (blocksizeonly == 0) {
7560 * Humanize implies !quiet, and also implies numblocks.
7562 if (humanize != 0) {
7567 tmpbytes = (maxsector + 1) * block_len;
7568 ret = humanize_number(tmpstr, sizeof(tmpstr),
7569 tmpbytes, "", HN_AUTOSCALE,
7572 HN_DIVISOR_1000 : 0));
7574 warnx("%s: humanize_number failed!", __func__);
7578 fprintf(stdout, "Device Size: %s%s", tmpstr,
7579 (sizeonly == 0) ? ", " : "\n");
7580 } else if (numblocks != 0) {
7581 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7582 "Blocks: " : "", (uintmax_t)maxsector + 1,
7583 (sizeonly == 0) ? ", " : "\n");
7585 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7586 "Last Block: " : "", (uintmax_t)maxsector,
7587 (sizeonly == 0) ? ", " : "\n");
7591 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7592 "Block Length: " : "", block_len, (quiet == 0) ?
7601 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7602 int retry_count, int timeout)
7606 uint8_t *smp_request = NULL, *smp_response = NULL;
7607 int request_size = 0, response_size = 0;
7608 int fd_request = 0, fd_response = 0;
7609 char *datastr = NULL;
7610 struct get_hook hook;
7615 * Note that at the moment we don't support sending SMP CCBs to
7616 * devices that aren't probed by CAM.
7618 ccb = cam_getccb(device);
7620 warnx("%s: error allocating CCB", __func__);
7624 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7627 arglist |= CAM_ARG_CMD_IN;
7628 response_size = strtol(optarg, NULL, 0);
7629 if (response_size <= 0) {
7630 warnx("invalid number of response bytes %d",
7633 goto smpcmd_bailout;
7635 hook.argc = argc - optind;
7636 hook.argv = argv + optind;
7639 datastr = cget(&hook, NULL);
7641 * If the user supplied "-" instead of a format, he
7642 * wants the data to be written to stdout.
7644 if ((datastr != NULL)
7645 && (datastr[0] == '-'))
7648 smp_response = (u_int8_t *)malloc(response_size);
7649 if (smp_response == NULL) {
7650 warn("can't malloc memory for SMP response");
7652 goto smpcmd_bailout;
7656 arglist |= CAM_ARG_CMD_OUT;
7657 request_size = strtol(optarg, NULL, 0);
7658 if (request_size <= 0) {
7659 warnx("invalid number of request bytes %d",
7662 goto smpcmd_bailout;
7664 hook.argc = argc - optind;
7665 hook.argv = argv + optind;
7667 datastr = cget(&hook, NULL);
7668 smp_request = (u_int8_t *)malloc(request_size);
7669 if (smp_request == NULL) {
7670 warn("can't malloc memory for SMP request");
7672 goto smpcmd_bailout;
7674 bzero(smp_request, request_size);
7676 * If the user supplied "-" instead of a format, he
7677 * wants the data to be read from stdin.
7679 if ((datastr != NULL)
7680 && (datastr[0] == '-'))
7683 buff_encode_visit(smp_request, request_size,
7694 * If fd_data is set, and we're writing to the device, we need to
7695 * read the data the user wants written from stdin.
7697 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7699 int amt_to_read = request_size;
7700 u_int8_t *buf_ptr = smp_request;
7702 for (amt_read = 0; amt_to_read > 0;
7703 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7704 if (amt_read == -1) {
7705 warn("error reading data from stdin");
7707 goto smpcmd_bailout;
7709 amt_to_read -= amt_read;
7710 buf_ptr += amt_read;
7714 if (((arglist & CAM_ARG_CMD_IN) == 0)
7715 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7716 warnx("%s: need both the request (-r) and response (-R) "
7717 "arguments", __func__);
7719 goto smpcmd_bailout;
7722 flags |= CAM_DEV_QFRZDIS;
7724 cam_fill_smpio(&ccb->smpio,
7725 /*retries*/ retry_count,
7728 /*smp_request*/ smp_request,
7729 /*smp_request_len*/ request_size,
7730 /*smp_response*/ smp_response,
7731 /*smp_response_len*/ response_size,
7732 /*timeout*/ timeout ? timeout : 5000);
7734 ccb->smpio.flags = SMP_FLAG_NONE;
7736 if (((retval = cam_send_ccb(device, ccb)) < 0)
7737 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7738 const char warnstr[] = "error sending command";
7745 if (arglist & CAM_ARG_VERBOSE) {
7746 cam_error_print(device, ccb, CAM_ESF_ALL,
7747 CAM_EPF_ALL, stderr);
7751 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7752 && (response_size > 0)) {
7753 if (fd_response == 0) {
7754 buff_decode_visit(smp_response, response_size,
7755 datastr, arg_put, NULL);
7756 fprintf(stdout, "\n");
7758 ssize_t amt_written;
7759 int amt_to_write = response_size;
7760 u_int8_t *buf_ptr = smp_response;
7762 for (amt_written = 0; (amt_to_write > 0) &&
7763 (amt_written = write(STDOUT_FILENO, buf_ptr,
7764 amt_to_write)) > 0;){
7765 amt_to_write -= amt_written;
7766 buf_ptr += amt_written;
7768 if (amt_written == -1) {
7769 warn("error writing data to stdout");
7771 goto smpcmd_bailout;
7772 } else if ((amt_written == 0)
7773 && (amt_to_write > 0)) {
7774 warnx("only wrote %u bytes out of %u",
7775 response_size - amt_to_write,
7784 if (smp_request != NULL)
7787 if (smp_response != NULL)
7794 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7795 int retry_count, int timeout)
7799 int32_t mmc_opcode = 0, mmc_arg = 0;
7800 int32_t mmc_flags = -1;
7803 int is_bw_4 = 0, is_bw_1 = 0;
7804 int is_frequency = 0;
7805 int is_highspeed = 0, is_stdspeed = 0;
7806 int is_info_request = 0;
7808 uint8_t mmc_data_byte = 0;
7809 uint32_t mmc_frequency = 0;
7811 /* For IO_RW_EXTENDED command */
7812 uint8_t *mmc_data = NULL;
7813 struct mmc_data mmc_d;
7814 int mmc_data_len = 0;
7817 * Note that at the moment we don't support sending SMP CCBs to
7818 * devices that aren't probed by CAM.
7820 ccb = cam_getccb(device);
7822 warnx("%s: error allocating CCB", __func__);
7826 bzero(&(&ccb->ccb_h)[1],
7827 sizeof(union ccb) - sizeof(struct ccb_hdr));
7829 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7838 if (!strcmp(optarg, "high"))
7844 is_info_request = 1;
7848 mmc_frequency = strtol(optarg, NULL, 0);
7851 mmc_opcode = strtol(optarg, NULL, 0);
7852 if (mmc_opcode < 0) {
7853 warnx("invalid MMC opcode %d",
7856 goto mmccmd_bailout;
7860 mmc_arg = strtol(optarg, NULL, 0);
7862 warnx("invalid MMC arg %d",
7865 goto mmccmd_bailout;
7869 mmc_flags = strtol(optarg, NULL, 0);
7870 if (mmc_flags < 0) {
7871 warnx("invalid MMC flags %d",
7874 goto mmccmd_bailout;
7878 mmc_data_len = strtol(optarg, NULL, 0);
7879 if (mmc_data_len <= 0) {
7880 warnx("invalid MMC data len %d",
7883 goto mmccmd_bailout;
7890 mmc_data_byte = strtol(optarg, NULL, 0);
7896 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7898 /* If flags are left default, supply the right flags */
7900 switch (mmc_opcode) {
7901 case MMC_GO_IDLE_STATE:
7902 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7904 case IO_SEND_OP_COND:
7905 mmc_flags = MMC_RSP_R4;
7907 case SD_SEND_RELATIVE_ADDR:
7908 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7910 case MMC_SELECT_CARD:
7911 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7912 mmc_arg = mmc_arg << 16;
7914 case SD_IO_RW_DIRECT:
7915 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7916 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7918 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7920 case SD_IO_RW_EXTENDED:
7921 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7922 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7923 int len_arg = mmc_data_len;
7924 if (mmc_data_len == 512)
7928 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7930 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7933 mmc_flags = MMC_RSP_R1;
7937 // Switch bus width instead of sending IO command
7938 if (is_bw_4 || is_bw_1) {
7939 struct ccb_trans_settings_mmc *cts;
7940 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7941 ccb->ccb_h.flags = 0;
7942 cts = &ccb->cts.proto_specific.mmc;
7943 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7944 cts->ios_valid = MMC_BW;
7945 if (((retval = cam_send_ccb(device, ccb)) < 0)
7946 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7947 warn("Error sending command");
7949 printf("Parameters set OK\n");
7956 struct ccb_trans_settings_mmc *cts;
7957 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7958 ccb->ccb_h.flags = 0;
7959 cts = &ccb->cts.proto_specific.mmc;
7960 cts->ios.clock = mmc_frequency;
7961 cts->ios_valid = MMC_CLK;
7962 if (((retval = cam_send_ccb(device, ccb)) < 0)
7963 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7964 warn("Error sending command");
7966 printf("Parameters set OK\n");
7972 // Switch bus speed instead of sending IO command
7973 if (is_stdspeed || is_highspeed) {
7974 struct ccb_trans_settings_mmc *cts;
7975 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7976 ccb->ccb_h.flags = 0;
7977 cts = &ccb->cts.proto_specific.mmc;
7978 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7979 cts->ios_valid = MMC_BT;
7980 if (((retval = cam_send_ccb(device, ccb)) < 0)
7981 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7982 warn("Error sending command");
7984 printf("Speed set OK (HS: %d)\n", is_highspeed);
7990 // Get information about controller and its settings
7991 if (is_info_request) {
7992 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7993 ccb->ccb_h.flags = 0;
7994 struct ccb_trans_settings_mmc *cts;
7995 cts = &ccb->cts.proto_specific.mmc;
7996 if (((retval = cam_send_ccb(device, ccb)) < 0)
7997 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7998 warn("Error sending command");
8001 printf("Host controller information\n");
8002 printf("Host OCR: 0x%x\n", cts->host_ocr);
8003 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8004 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8005 printf("Supported bus width:\n");
8006 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8008 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8011 printf("Supported operating modes:\n");
8012 if (cts->host_caps & MMC_CAP_HSPEED)
8013 printf(" Can do High Speed transfers\n");
8014 if (cts->host_caps & MMC_CAP_UHS_SDR12)
8015 printf(" Can do UHS SDR12\n");
8016 if (cts->host_caps & MMC_CAP_UHS_SDR25)
8017 printf(" Can do UHS SDR25\n");
8018 if (cts->host_caps & MMC_CAP_UHS_SDR50)
8019 printf(" Can do UHS SDR50\n");
8020 if (cts->host_caps & MMC_CAP_UHS_SDR104)
8021 printf(" Can do UHS SDR104\n");
8022 if (cts->host_caps & MMC_CAP_UHS_DDR50)
8023 printf(" Can do UHS DDR50\n");
8024 if (cts->host_caps & MMC_CAP_MMC_DDR52_120)
8025 printf(" Can do eMMC DDR52 at 1.2V\n");
8026 if (cts->host_caps & MMC_CAP_MMC_DDR52_180)
8027 printf(" Can do eMMC DDR52 at 1.8V\n");
8028 if (cts->host_caps & MMC_CAP_MMC_HS200_120)
8029 printf(" Can do eMMC HS200 at 1.2V\n");
8030 if (cts->host_caps & MMC_CAP_MMC_HS200_180)
8031 printf(" Can do eMMC HS200 at 1.8V\n");
8032 if (cts->host_caps & MMC_CAP_MMC_HS400_120)
8033 printf(" Can do eMMC HS400 at 1.2V\n");
8034 if (cts->host_caps & MMC_CAP_MMC_HS400_180)
8035 printf(" Can do eMMC HS400 at 1.8V\n");
8037 printf("Supported VCCQ voltages:\n");
8038 if (cts->host_caps & MMC_CAP_SIGNALING_120)
8040 if (cts->host_caps & MMC_CAP_SIGNALING_180)
8042 if (cts->host_caps & MMC_CAP_SIGNALING_330)
8045 printf("Current settings:\n");
8046 printf(" Bus width: ");
8047 switch (cts->ios.bus_width) {
8058 printf(" Freq: %d.%03d MHz%s\n",
8059 cts->ios.clock / 1000000,
8060 (cts->ios.clock / 1000) % 1000,
8061 cts->ios.timing == bus_timing_hs ? " (high-speed timing)" : "");
8064 switch (cts->ios.vccq) {
8078 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8080 if (mmc_data_len > 0) {
8081 flags |= CAM_DIR_IN;
8082 mmc_data = malloc(mmc_data_len);
8083 memset(mmc_data, 0, mmc_data_len);
8084 memset(&mmc_d, 0, sizeof(mmc_d));
8085 mmc_d.len = mmc_data_len;
8086 mmc_d.data = mmc_data;
8087 mmc_d.flags = MMC_DATA_READ;
8088 } else flags |= CAM_DIR_NONE;
8090 cam_fill_mmcio(&ccb->mmcio,
8091 /*retries*/ retry_count,
8094 /*mmc_opcode*/ mmc_opcode,
8095 /*mmc_arg*/ mmc_arg,
8096 /*mmc_flags*/ mmc_flags,
8097 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8098 /*timeout*/ timeout ? timeout : 5000);
8100 if (((retval = cam_send_ccb(device, ccb)) < 0)
8101 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8102 const char warnstr[] = "error sending command";
8109 if (arglist & CAM_ARG_VERBOSE) {
8110 cam_error_print(device, ccb, CAM_ESF_ALL,
8111 CAM_EPF_ALL, stderr);
8115 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8116 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8117 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8118 ccb->mmcio.cmd.resp[1],
8119 ccb->mmcio.cmd.resp[2],
8120 ccb->mmcio.cmd.resp[3]);
8122 switch (mmc_opcode) {
8123 case SD_IO_RW_DIRECT:
8124 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8125 SD_R5_DATA(ccb->mmcio.cmd.resp),
8126 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8128 case SD_IO_RW_EXTENDED:
8129 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8130 hexdump(mmc_data, mmc_data_len, NULL, 0);
8132 case SD_SEND_RELATIVE_ADDR:
8133 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8136 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8137 if (mmc_data_len > 0)
8138 hexdump(mmc_data, mmc_data_len, NULL, 0);
8145 if (mmc_data_len > 0 && mmc_data != NULL)
8152 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8153 char *combinedopt, int retry_count, int timeout)
8156 struct smp_report_general_request *request = NULL;
8157 struct smp_report_general_response *response = NULL;
8158 struct sbuf *sb = NULL;
8160 int c, long_response = 0;
8164 * Note that at the moment we don't support sending SMP CCBs to
8165 * devices that aren't probed by CAM.
8167 ccb = cam_getccb(device);
8169 warnx("%s: error allocating CCB", __func__);
8173 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8182 request = malloc(sizeof(*request));
8183 if (request == NULL) {
8184 warn("%s: unable to allocate %zd bytes", __func__,
8190 response = malloc(sizeof(*response));
8191 if (response == NULL) {
8192 warn("%s: unable to allocate %zd bytes", __func__,
8199 smp_report_general(&ccb->smpio,
8203 /*request_len*/ sizeof(*request),
8204 (uint8_t *)response,
8205 /*response_len*/ sizeof(*response),
8206 /*long_response*/ long_response,
8209 if (((retval = cam_send_ccb(device, ccb)) < 0)
8210 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8211 const char warnstr[] = "error sending command";
8218 if (arglist & CAM_ARG_VERBOSE) {
8219 cam_error_print(device, ccb, CAM_ESF_ALL,
8220 CAM_EPF_ALL, stderr);
8227 * If the device supports the long response bit, try again and see
8228 * if we can get all of the data.
8230 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8231 && (long_response == 0)) {
8232 ccb->ccb_h.status = CAM_REQ_INPROG;
8233 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8239 * XXX KDM detect and decode SMP errors here.
8241 sb = sbuf_new_auto();
8243 warnx("%s: error allocating sbuf", __func__);
8247 smp_report_general_sbuf(response, sizeof(*response), sb);
8249 if (sbuf_finish(sb) != 0) {
8250 warnx("%s: sbuf_finish", __func__);
8254 printf("%s", sbuf_data(sb));
8260 if (request != NULL)
8263 if (response != NULL)
8272 static struct camcontrol_opts phy_ops[] = {
8273 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8274 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8275 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8276 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8277 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8278 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8279 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8280 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8281 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8286 smpphycontrol(struct cam_device *device, int argc, char **argv,
8287 char *combinedopt, int retry_count, int timeout)
8290 struct smp_phy_control_request *request = NULL;
8291 struct smp_phy_control_response *response = NULL;
8292 int long_response = 0;
8295 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8297 uint64_t attached_dev_name = 0;
8298 int dev_name_set = 0;
8299 uint32_t min_plr = 0, max_plr = 0;
8300 uint32_t pp_timeout_val = 0;
8301 int slumber_partial = 0;
8302 int set_pp_timeout_val = 0;
8306 * Note that at the moment we don't support sending SMP CCBs to
8307 * devices that aren't probed by CAM.
8309 ccb = cam_getccb(device);
8311 warnx("%s: error allocating CCB", __func__);
8315 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8323 if (strcasecmp(optarg, "enable") == 0)
8325 else if (strcasecmp(optarg, "disable") == 0)
8328 warnx("%s: Invalid argument %s", __func__,
8335 slumber_partial |= enable <<
8336 SMP_PC_SAS_SLUMBER_SHIFT;
8339 slumber_partial |= enable <<
8340 SMP_PC_SAS_PARTIAL_SHIFT;
8343 slumber_partial |= enable <<
8344 SMP_PC_SATA_SLUMBER_SHIFT;
8347 slumber_partial |= enable <<
8348 SMP_PC_SATA_PARTIAL_SHIFT;
8351 warnx("%s: programmer error", __func__);
8354 break; /*NOTREACHED*/
8359 attached_dev_name = (uintmax_t)strtoumax(optarg,
8368 * We don't do extensive checking here, so this
8369 * will continue to work when new speeds come out.
8371 min_plr = strtoul(optarg, NULL, 0);
8373 || (min_plr > 0xf)) {
8374 warnx("%s: invalid link rate %x",
8382 * We don't do extensive checking here, so this
8383 * will continue to work when new speeds come out.
8385 max_plr = strtoul(optarg, NULL, 0);
8387 || (max_plr > 0xf)) {
8388 warnx("%s: invalid link rate %x",
8395 camcontrol_optret optreturn;
8396 cam_argmask argnums;
8399 if (phy_op_set != 0) {
8400 warnx("%s: only one phy operation argument "
8401 "(-o) allowed", __func__);
8409 * Allow the user to specify the phy operation
8410 * numerically, as well as with a name. This will
8411 * future-proof it a bit, so options that are added
8412 * in future specs can be used.
8414 if (isdigit(optarg[0])) {
8415 phy_operation = strtoul(optarg, NULL, 0);
8416 if ((phy_operation == 0)
8417 || (phy_operation > 0xff)) {
8418 warnx("%s: invalid phy operation %#x",
8419 __func__, phy_operation);
8425 optreturn = getoption(phy_ops, optarg, &phy_operation,
8428 if (optreturn == CC_OR_AMBIGUOUS) {
8429 warnx("%s: ambiguous option %s", __func__,
8434 } else if (optreturn == CC_OR_NOT_FOUND) {
8435 warnx("%s: option %s not found", __func__,
8447 pp_timeout_val = strtoul(optarg, NULL, 0);
8448 if (pp_timeout_val > 15) {
8449 warnx("%s: invalid partial pathway timeout "
8450 "value %u, need a value less than 16",
8451 __func__, pp_timeout_val);
8455 set_pp_timeout_val = 1;
8463 warnx("%s: a PHY (-p phy) argument is required",__func__);
8468 if (((dev_name_set != 0)
8469 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8470 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8471 && (dev_name_set == 0))) {
8472 warnx("%s: -d name and -o setdevname arguments both "
8473 "required to set device name", __func__);
8478 request = malloc(sizeof(*request));
8479 if (request == NULL) {
8480 warn("%s: unable to allocate %zd bytes", __func__,
8486 response = malloc(sizeof(*response));
8487 if (response == NULL) {
8488 warn("%s: unable to allocate %zd bytes", __func__,
8494 smp_phy_control(&ccb->smpio,
8499 (uint8_t *)response,
8502 /*expected_exp_change_count*/ 0,
8505 (set_pp_timeout_val != 0) ? 1 : 0,
8513 if (((retval = cam_send_ccb(device, ccb)) < 0)
8514 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8515 const char warnstr[] = "error sending command";
8522 if (arglist & CAM_ARG_VERBOSE) {
8524 * Use CAM_EPF_NORMAL so we only get one line of
8525 * SMP command decoding.
8527 cam_error_print(device, ccb, CAM_ESF_ALL,
8528 CAM_EPF_NORMAL, stderr);
8534 /* XXX KDM print out something here for success? */
8539 if (request != NULL)
8542 if (response != NULL)
8549 smpmaninfo(struct cam_device *device, int argc, char **argv,
8550 char *combinedopt, int retry_count, int timeout)
8553 struct smp_report_manuf_info_request request;
8554 struct smp_report_manuf_info_response response;
8555 struct sbuf *sb = NULL;
8556 int long_response = 0;
8561 * Note that at the moment we don't support sending SMP CCBs to
8562 * devices that aren't probed by CAM.
8564 ccb = cam_getccb(device);
8566 warnx("%s: error allocating CCB", __func__);
8570 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8579 bzero(&request, sizeof(request));
8580 bzero(&response, sizeof(response));
8582 smp_report_manuf_info(&ccb->smpio,
8587 (uint8_t *)&response,
8592 if (((retval = cam_send_ccb(device, ccb)) < 0)
8593 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8594 const char warnstr[] = "error sending command";
8601 if (arglist & CAM_ARG_VERBOSE) {
8602 cam_error_print(device, ccb, CAM_ESF_ALL,
8603 CAM_EPF_ALL, stderr);
8609 sb = sbuf_new_auto();
8611 warnx("%s: error allocating sbuf", __func__);
8615 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8617 if (sbuf_finish(sb) != 0) {
8618 warnx("%s: sbuf_finish", __func__);
8622 printf("%s", sbuf_data(sb));
8636 getdevid(struct cam_devitem *item)
8639 union ccb *ccb = NULL;
8641 struct cam_device *dev;
8643 dev = cam_open_btl(item->dev_match.path_id,
8644 item->dev_match.target_id,
8645 item->dev_match.target_lun, O_RDWR, NULL);
8648 warnx("%s", cam_errbuf);
8653 item->device_id_len = 0;
8655 ccb = cam_getccb(dev);
8657 warnx("%s: error allocating CCB", __func__);
8663 * On the first try, we just probe for the size of the data, and
8664 * then allocate that much memory and try again.
8667 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8668 ccb->ccb_h.flags = CAM_DIR_IN;
8669 ccb->cdai.flags = CDAI_FLAG_NONE;
8670 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8671 ccb->cdai.bufsiz = item->device_id_len;
8672 if (item->device_id_len != 0)
8673 ccb->cdai.buf = (uint8_t *)item->device_id;
8675 if (cam_send_ccb(dev, ccb) < 0) {
8676 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8681 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8682 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8687 if (item->device_id_len == 0) {
8689 * This is our first time through. Allocate the buffer,
8690 * and then go back to get the data.
8692 if (ccb->cdai.provsiz == 0) {
8693 warnx("%s: invalid .provsiz field returned with "
8694 "XPT_GDEV_ADVINFO CCB", __func__);
8698 item->device_id_len = ccb->cdai.provsiz;
8699 item->device_id = malloc(item->device_id_len);
8700 if (item->device_id == NULL) {
8701 warn("%s: unable to allocate %d bytes", __func__,
8702 item->device_id_len);
8706 ccb->ccb_h.status = CAM_REQ_INPROG;
8712 cam_close_device(dev);
8721 * XXX KDM merge this code with getdevtree()?
8724 buildbusdevlist(struct cam_devlist *devlist)
8727 int bufsize, fd = -1;
8728 struct dev_match_pattern *patterns;
8729 struct cam_devitem *item = NULL;
8730 int skip_device = 0;
8733 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8734 warn("couldn't open %s", XPT_DEVICE);
8738 bzero(&ccb, sizeof(union ccb));
8740 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8741 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8742 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8744 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8745 bufsize = sizeof(struct dev_match_result) * 100;
8746 ccb.cdm.match_buf_len = bufsize;
8747 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8748 if (ccb.cdm.matches == NULL) {
8749 warnx("can't malloc memory for matches");
8753 ccb.cdm.num_matches = 0;
8754 ccb.cdm.num_patterns = 2;
8755 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8756 ccb.cdm.num_patterns;
8758 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8759 if (patterns == NULL) {
8760 warnx("can't malloc memory for patterns");
8765 ccb.cdm.patterns = patterns;
8766 bzero(patterns, ccb.cdm.pattern_buf_len);
8768 patterns[0].type = DEV_MATCH_DEVICE;
8769 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8770 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8771 patterns[1].type = DEV_MATCH_PERIPH;
8772 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8773 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8776 * We do the ioctl multiple times if necessary, in case there are
8777 * more than 100 nodes in the EDT.
8782 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8783 warn("error sending CAMIOCOMMAND ioctl");
8788 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8789 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8790 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8791 warnx("got CAM error %#x, CDM error %d\n",
8792 ccb.ccb_h.status, ccb.cdm.status);
8797 for (i = 0; i < ccb.cdm.num_matches; i++) {
8798 switch (ccb.cdm.matches[i].type) {
8799 case DEV_MATCH_DEVICE: {
8800 struct device_match_result *dev_result;
8803 &ccb.cdm.matches[i].result.device_result;
8805 if (dev_result->flags &
8806 DEV_RESULT_UNCONFIGURED) {
8812 item = malloc(sizeof(*item));
8814 warn("%s: unable to allocate %zd bytes",
8815 __func__, sizeof(*item));
8819 bzero(item, sizeof(*item));
8820 bcopy(dev_result, &item->dev_match,
8821 sizeof(*dev_result));
8822 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8825 if (getdevid(item) != 0) {
8831 case DEV_MATCH_PERIPH: {
8832 struct periph_match_result *periph_result;
8835 &ccb.cdm.matches[i].result.periph_result;
8837 if (skip_device != 0)
8839 item->num_periphs++;
8840 item->periph_matches = realloc(
8841 item->periph_matches,
8843 sizeof(struct periph_match_result));
8844 if (item->periph_matches == NULL) {
8845 warn("%s: error allocating periph "
8850 bcopy(periph_result, &item->periph_matches[
8851 item->num_periphs - 1],
8852 sizeof(*periph_result));
8856 fprintf(stderr, "%s: unexpected match "
8857 "type %d\n", __func__,
8858 ccb.cdm.matches[i].type);
8861 break; /*NOTREACHED*/
8864 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8865 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8873 free(ccb.cdm.matches);
8876 freebusdevlist(devlist);
8882 freebusdevlist(struct cam_devlist *devlist)
8884 struct cam_devitem *item, *item2;
8886 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8887 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8889 free(item->device_id);
8890 free(item->periph_matches);
8895 static struct cam_devitem *
8896 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8898 struct cam_devitem *item;
8900 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8901 struct scsi_vpd_id_descriptor *idd;
8904 * XXX KDM look for LUN IDs as well?
8906 idd = scsi_get_devid(item->device_id,
8907 item->device_id_len,
8908 scsi_devid_is_sas_target);
8912 if (scsi_8btou64(idd->identifier) == sasaddr)
8920 smpphylist(struct cam_device *device, int argc, char **argv,
8921 char *combinedopt, int retry_count, int timeout)
8923 struct smp_report_general_request *rgrequest = NULL;
8924 struct smp_report_general_response *rgresponse = NULL;
8925 struct smp_discover_request *disrequest = NULL;
8926 struct smp_discover_response *disresponse = NULL;
8927 struct cam_devlist devlist;
8929 int long_response = 0;
8936 * Note that at the moment we don't support sending SMP CCBs to
8937 * devices that aren't probed by CAM.
8939 ccb = cam_getccb(device);
8941 warnx("%s: error allocating CCB", __func__);
8945 STAILQ_INIT(&devlist.dev_queue);
8947 rgrequest = malloc(sizeof(*rgrequest));
8948 if (rgrequest == NULL) {
8949 warn("%s: unable to allocate %zd bytes", __func__,
8950 sizeof(*rgrequest));
8955 rgresponse = malloc(sizeof(*rgresponse));
8956 if (rgresponse == NULL) {
8957 warn("%s: unable to allocate %zd bytes", __func__,
8958 sizeof(*rgresponse));
8963 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8976 smp_report_general(&ccb->smpio,
8980 /*request_len*/ sizeof(*rgrequest),
8981 (uint8_t *)rgresponse,
8982 /*response_len*/ sizeof(*rgresponse),
8983 /*long_response*/ long_response,
8986 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8988 if (((retval = cam_send_ccb(device, ccb)) < 0)
8989 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8990 const char warnstr[] = "error sending command";
8997 if (arglist & CAM_ARG_VERBOSE) {
8998 cam_error_print(device, ccb, CAM_ESF_ALL,
8999 CAM_EPF_ALL, stderr);
9005 num_phys = rgresponse->num_phys;
9007 if (num_phys == 0) {
9009 fprintf(stdout, "%s: No Phys reported\n", __func__);
9014 devlist.path_id = device->path_id;
9016 retval = buildbusdevlist(&devlist);
9021 fprintf(stdout, "%d PHYs:\n", num_phys);
9022 fprintf(stdout, "PHY Attached SAS Address\n");
9025 disrequest = malloc(sizeof(*disrequest));
9026 if (disrequest == NULL) {
9027 warn("%s: unable to allocate %zd bytes", __func__,
9028 sizeof(*disrequest));
9033 disresponse = malloc(sizeof(*disresponse));
9034 if (disresponse == NULL) {
9035 warn("%s: unable to allocate %zd bytes", __func__,
9036 sizeof(*disresponse));
9041 for (i = 0; i < num_phys; i++) {
9042 struct cam_devitem *item;
9043 struct device_match_result *dev_match;
9044 char vendor[16], product[48], revision[16];
9048 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9050 ccb->ccb_h.status = CAM_REQ_INPROG;
9051 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9053 smp_discover(&ccb->smpio,
9057 sizeof(*disrequest),
9058 (uint8_t *)disresponse,
9059 sizeof(*disresponse),
9061 /*ignore_zone_group*/ 0,
9065 if (((retval = cam_send_ccb(device, ccb)) < 0)
9066 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9067 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9068 const char warnstr[] = "error sending command";
9075 if (arglist & CAM_ARG_VERBOSE) {
9076 cam_error_print(device, ccb, CAM_ESF_ALL,
9077 CAM_EPF_ALL, stderr);
9083 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9085 fprintf(stdout, "%3d <vacant>\n", i);
9089 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9092 item = findsasdevice(&devlist,
9093 scsi_8btou64(disresponse->attached_sas_address));
9097 || (item != NULL)) {
9098 fprintf(stdout, "%3d 0x%016jx", i,
9099 (uintmax_t)scsi_8btou64(
9100 disresponse->attached_sas_address));
9102 fprintf(stdout, "\n");
9105 } else if (quiet != 0)
9108 dev_match = &item->dev_match;
9110 if (dev_match->protocol == PROTO_SCSI) {
9111 cam_strvis(vendor, dev_match->inq_data.vendor,
9112 sizeof(dev_match->inq_data.vendor),
9114 cam_strvis(product, dev_match->inq_data.product,
9115 sizeof(dev_match->inq_data.product),
9117 cam_strvis(revision, dev_match->inq_data.revision,
9118 sizeof(dev_match->inq_data.revision),
9120 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9122 } else if ((dev_match->protocol == PROTO_ATA)
9123 || (dev_match->protocol == PROTO_SATAPM)) {
9124 cam_strvis(product, dev_match->ident_data.model,
9125 sizeof(dev_match->ident_data.model),
9127 cam_strvis(revision, dev_match->ident_data.revision,
9128 sizeof(dev_match->ident_data.revision),
9130 sprintf(tmpstr, "<%s %s>", product, revision);
9132 sprintf(tmpstr, "<>");
9134 fprintf(stdout, " %-33s ", tmpstr);
9137 * If we have 0 periphs, that's a bug...
9139 if (item->num_periphs == 0) {
9140 fprintf(stdout, "\n");
9144 fprintf(stdout, "(");
9145 for (j = 0; j < item->num_periphs; j++) {
9147 fprintf(stdout, ",");
9149 fprintf(stdout, "%s%d",
9150 item->periph_matches[j].periph_name,
9151 item->periph_matches[j].unit_number);
9154 fprintf(stdout, ")\n");
9168 freebusdevlist(&devlist);
9174 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9176 uint8_t error = 0, ata_device = 0, status = 0;
9181 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9184 if (arglist & CAM_ARG_VERBOSE) {
9185 cam_error_print(device, ccb, CAM_ESF_ALL,
9186 CAM_EPF_ALL, stderr);
9188 warnx("Can't get ATA command status");
9192 if (status & ATA_STATUS_ERROR) {
9193 cam_error_print(device, ccb, CAM_ESF_ALL,
9194 CAM_EPF_ALL, stderr);
9198 printf("%s%d: ", device->device_name, device->dev_unit_num);
9200 case ATA_PM_STANDBY:
9201 printf("Standby mode\n");
9203 case ATA_PM_STANDBY_Y:
9204 printf("Standby_y mode\n");
9206 case 0x40: /* obsolete since ACS-3 */
9207 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9209 case 0x41: /* obsolete since ACS-3 */
9210 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9213 printf("Idle mode\n");
9216 printf("Idle_a mode\n");
9219 printf("Idle_b mode\n");
9222 printf("Idle_c mode\n");
9224 case ATA_PM_ACTIVE_IDLE:
9225 printf("Active or Idle mode\n");
9228 printf("Unknown mode 0x%02x\n", count);
9236 atapm(struct cam_device *device, int argc, char **argv,
9237 char *combinedopt, int retry_count, int timeout)
9243 u_int8_t ata_flags = 0;
9246 ccb = cam_getccb(device);
9249 warnx("%s: error allocating ccb", __func__);
9253 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9262 if (strcmp(argv[1], "idle") == 0) {
9264 cmd = ATA_IDLE_IMMEDIATE;
9267 } else if (strcmp(argv[1], "standby") == 0) {
9269 cmd = ATA_STANDBY_IMMEDIATE;
9271 cmd = ATA_STANDBY_CMD;
9272 } else if (strcmp(argv[1], "powermode") == 0) {
9273 cmd = ATA_CHECK_POWER_MODE;
9274 ata_flags = AP_FLAG_CHK_COND;
9283 else if (t <= (240 * 5))
9285 else if (t <= (252 * 5))
9286 /* special encoding for 21 minutes */
9288 else if (t <= (11 * 30 * 60))
9289 sc = (t - 1) / (30 * 60) + 241;
9293 retval = ata_do_cmd(device,
9295 /*retries*/retry_count,
9296 /*flags*/CAM_DIR_NONE,
9297 /*protocol*/AP_PROTO_NON_DATA,
9298 /*ata_flags*/ata_flags,
9299 /*tag_action*/MSG_SIMPLE_Q_TAG,
9306 /*timeout*/timeout ? timeout : 30 * 1000,
9309 if (retval == 0 && cmd == ATA_CHECK_POWER_MODE)
9310 retval = atapm_proc_resp(device, ccb);
9317 ataaxm(struct cam_device *device, int argc, char **argv,
9318 char *combinedopt, int retry_count, int timeout)
9326 ccb = cam_getccb(device);
9329 warnx("%s: error allocating ccb", __func__);
9333 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9343 if (strcmp(argv[1], "apm") == 0) {
9359 retval = ata_do_cmd(device,
9361 /*retries*/retry_count,
9362 /*flags*/CAM_DIR_NONE,
9363 /*protocol*/AP_PROTO_NON_DATA,
9365 /*tag_action*/MSG_SIMPLE_Q_TAG,
9366 /*command*/ATA_SETFEATURES,
9372 /*timeout*/timeout ? timeout : 30 * 1000,
9380 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9381 int show_sa_errors, int sa_set, int service_action,
9382 int timeout_desc, int task_attr, int retry_count, int timeout,
9383 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9385 union ccb *ccb = NULL;
9386 uint8_t *buf = NULL;
9387 uint32_t alloc_len = 0, num_opcodes;
9388 uint32_t valid_len = 0;
9389 uint32_t avail_len = 0;
9390 struct scsi_report_supported_opcodes_all *all_hdr;
9391 struct scsi_report_supported_opcodes_one *one;
9396 * Make it clear that we haven't yet allocated or filled anything.
9401 ccb = cam_getccb(device);
9403 warnx("couldn't allocate CCB");
9408 if (opcode_set != 0) {
9409 options |= RSO_OPTIONS_OC;
9411 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9414 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9415 sizeof(struct scsi_report_supported_opcodes_descr));
9418 if (timeout_desc != 0) {
9419 options |= RSO_RCTD;
9420 alloc_len += num_opcodes *
9421 sizeof(struct scsi_report_supported_opcodes_timeout);
9425 options |= RSO_OPTIONS_OC_SA;
9426 if (show_sa_errors != 0)
9427 options &= ~RSO_OPTIONS_OC;
9436 buf = malloc(alloc_len);
9438 warn("Unable to allocate %u bytes", alloc_len);
9442 bzero(buf, alloc_len);
9444 scsi_report_supported_opcodes(&ccb->csio,
9445 /*retries*/ retry_count,
9447 /*tag_action*/ task_attr,
9448 /*options*/ options,
9449 /*req_opcode*/ opcode,
9450 /*req_service_action*/ service_action,
9452 /*dxfer_len*/ alloc_len,
9453 /*sense_len*/ SSD_FULL_SIZE,
9454 /*timeout*/ timeout ? timeout : 10000);
9456 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9458 if (retry_count != 0)
9459 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9461 if (cam_send_ccb(device, ccb) < 0) {
9462 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9467 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9468 if (verbosemode != 0)
9469 cam_error_print(device, ccb, CAM_ESF_ALL,
9470 CAM_EPF_ALL, stderr);
9475 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9477 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9478 && (valid_len >= sizeof(*all_hdr))) {
9479 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9480 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9481 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9482 && (valid_len >= sizeof(*one))) {
9483 uint32_t cdb_length;
9485 one = (struct scsi_report_supported_opcodes_one *)buf;
9486 cdb_length = scsi_2btoul(one->cdb_length);
9487 avail_len = sizeof(*one) + cdb_length;
9488 if (one->support & RSO_ONE_CTDP) {
9489 struct scsi_report_supported_opcodes_timeout *td;
9491 td = (struct scsi_report_supported_opcodes_timeout *)
9493 if (valid_len >= (avail_len + sizeof(td->length))) {
9494 avail_len += scsi_2btoul(td->length) +
9497 avail_len += sizeof(*td);
9503 * avail_len could be zero if we didn't get enough data back from
9504 * thet target to determine
9506 if ((avail_len != 0)
9507 && (avail_len > valid_len)) {
9508 alloc_len = avail_len;
9512 *fill_len = valid_len;
9524 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9525 int req_sa, uint8_t *buf, uint32_t valid_len)
9527 struct scsi_report_supported_opcodes_one *one;
9528 struct scsi_report_supported_opcodes_timeout *td;
9529 uint32_t cdb_len = 0, td_len = 0;
9530 const char *op_desc = NULL;
9534 one = (struct scsi_report_supported_opcodes_one *)buf;
9537 * If we don't have the full single opcode descriptor, no point in
9540 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9542 warnx("Only %u bytes returned, not enough to verify support",
9548 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9550 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9553 printf(", SA 0x%x", req_sa);
9556 switch (one->support & RSO_ONE_SUP_MASK) {
9557 case RSO_ONE_SUP_UNAVAIL:
9558 printf("No command support information currently available\n");
9560 case RSO_ONE_SUP_NOT_SUP:
9561 printf("Command not supported\n");
9564 break; /*NOTREACHED*/
9565 case RSO_ONE_SUP_AVAIL:
9566 printf("Command is supported, complies with a SCSI standard\n");
9568 case RSO_ONE_SUP_VENDOR:
9569 printf("Command is supported, vendor-specific "
9570 "implementation\n");
9573 printf("Unknown command support flags 0x%#x\n",
9574 one->support & RSO_ONE_SUP_MASK);
9579 * If we don't have the CDB length, it isn't exactly an error, the
9580 * command probably isn't supported.
9582 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9586 cdb_len = scsi_2btoul(one->cdb_length);
9589 * If our valid data doesn't include the full reported length,
9590 * return. The caller should have detected this and adjusted his
9591 * allocation length to get all of the available data.
9593 if (valid_len < sizeof(*one) + cdb_len) {
9599 * If all we have is the opcode, there is no point in printing out
9607 printf("CDB usage bitmap:");
9608 for (i = 0; i < cdb_len; i++) {
9609 printf(" %02x", one->cdb_usage[i]);
9614 * If we don't have a timeout descriptor, we're done.
9616 if ((one->support & RSO_ONE_CTDP) == 0)
9620 * If we don't have enough valid length to include the timeout
9621 * descriptor length, we're done.
9623 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9626 td = (struct scsi_report_supported_opcodes_timeout *)
9627 &buf[sizeof(*one) + cdb_len];
9628 td_len = scsi_2btoul(td->length);
9629 td_len += sizeof(td->length);
9632 * If we don't have the full timeout descriptor, we're done.
9634 if (td_len < sizeof(*td))
9638 * If we don't have enough valid length to contain the full timeout
9639 * descriptor, we're done.
9641 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9644 printf("Timeout information:\n");
9645 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9646 printf("Nominal timeout: %u seconds\n",
9647 scsi_4btoul(td->nominal_time));
9648 printf("Recommended timeout: %u seconds\n",
9649 scsi_4btoul(td->recommended_time));
9656 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9659 struct scsi_report_supported_opcodes_all *hdr;
9660 struct scsi_report_supported_opcodes_descr *desc;
9661 uint32_t avail_len = 0, used_len = 0;
9665 if (valid_len < sizeof(*hdr)) {
9666 warnx("%s: not enough returned data (%u bytes) opcode list",
9667 __func__, valid_len);
9671 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9672 avail_len = scsi_4btoul(hdr->length);
9673 avail_len += sizeof(hdr->length);
9675 * Take the lesser of the amount of data the drive claims is
9676 * available, and the amount of data the HBA says was returned.
9678 avail_len = MIN(avail_len, valid_len);
9680 used_len = sizeof(hdr->length);
9682 printf("%-6s %4s %8s ",
9683 "Opcode", "SA", "CDB len" );
9686 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9687 printf(" Description\n");
9689 while ((avail_len - used_len) > sizeof(*desc)) {
9690 struct scsi_report_supported_opcodes_timeout *td;
9692 const char *op_desc = NULL;
9694 cur_ptr = &buf[used_len];
9695 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9697 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9698 if (op_desc == NULL)
9699 op_desc = "UNKNOWN";
9701 printf("0x%02x %#4x %8u ", desc->opcode,
9702 scsi_2btoul(desc->service_action),
9703 scsi_2btoul(desc->cdb_length));
9705 used_len += sizeof(*desc);
9707 if ((desc->flags & RSO_CTDP) == 0) {
9708 printf(" %s\n", op_desc);
9713 * If we don't have enough space to fit a timeout
9714 * descriptor, then we're done.
9716 if (avail_len - used_len < sizeof(*td)) {
9717 used_len = avail_len;
9718 printf(" %s\n", op_desc);
9721 cur_ptr = &buf[used_len];
9722 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9723 td_len = scsi_2btoul(td->length);
9724 td_len += sizeof(td->length);
9728 * If the given timeout descriptor length is less than what
9729 * we understand, skip it.
9731 if (td_len < sizeof(*td)) {
9732 printf(" %s\n", op_desc);
9736 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9737 scsi_4btoul(td->nominal_time),
9738 scsi_4btoul(td->recommended_time), op_desc);
9745 scsiopcodes(struct cam_device *device, int argc, char **argv,
9746 char *combinedopt, int task_attr, int retry_count, int timeout,
9750 uint32_t opcode = 0, service_action = 0;
9751 int td_set = 0, opcode_set = 0, sa_set = 0;
9752 int show_sa_errors = 1;
9753 uint32_t valid_len = 0;
9754 uint8_t *buf = NULL;
9758 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9764 opcode = strtoul(optarg, &endptr, 0);
9765 if (*endptr != '\0') {
9766 warnx("Invalid opcode \"%s\", must be a number",
9771 if (opcode > 0xff) {
9772 warnx("Invalid opcode 0x%#x, must be between"
9773 "0 and 0xff inclusive", opcode);
9780 service_action = strtoul(optarg, &endptr, 0);
9781 if (*endptr != '\0') {
9782 warnx("Invalid service action \"%s\", must "
9783 "be a number", optarg);
9787 if (service_action > 0xffff) {
9788 warnx("Invalid service action 0x%#x, must "
9789 "be between 0 and 0xffff inclusive",
9804 && (opcode_set == 0)) {
9805 warnx("You must specify an opcode with -o if a service "
9810 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9811 sa_set, service_action, td_set, task_attr,
9812 retry_count, timeout, verbosemode, &valid_len,
9817 if ((opcode_set != 0)
9819 retval = scsiprintoneopcode(device, opcode, sa_set,
9820 service_action, buf, valid_len);
9822 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9833 reprobe(struct cam_device *device)
9838 ccb = cam_getccb(device);
9841 warnx("%s: error allocating ccb", __func__);
9845 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9847 if (cam_send_ccb(device, ccb) < 0) {
9848 warn("error sending XPT_REPROBE_LUN CCB");
9853 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9854 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9866 usage(int printlong)
9869 fprintf(printlong ? stdout : stderr,
9870 "usage: camcontrol <command> [device id][generic args][command args]\n"
9871 " camcontrol devlist [-b] [-v]\n"
9872 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9873 " camcontrol tur [dev_id][generic args]\n"
9874 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9875 " camcontrol identify [dev_id][generic args] [-v]\n"
9876 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9877 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9879 " camcontrol start [dev_id][generic args]\n"
9880 " camcontrol stop [dev_id][generic args]\n"
9881 " camcontrol load [dev_id][generic args]\n"
9882 " camcontrol eject [dev_id][generic args]\n"
9883 " camcontrol reprobe [dev_id][generic args]\n"
9884 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9885 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9886 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9887 " [-q][-s][-S offset][-X]\n"
9888 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9889 " [-P pagectl][-e | -b][-d]\n"
9890 " camcontrol cmd [dev_id][generic args]\n"
9891 " <-a cmd [args] | -c cmd [args]>\n"
9892 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9893 " camcontrol smpcmd [dev_id][generic args]\n"
9894 " <-r len fmt [args]> <-R len fmt [args]>\n"
9895 " camcontrol smprg [dev_id][generic args][-l]\n"
9896 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9897 " [-o operation][-d name][-m rate][-M rate]\n"
9898 " [-T pp_timeout][-a enable|disable]\n"
9899 " [-A enable|disable][-s enable|disable]\n"
9900 " [-S enable|disable]\n"
9901 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9902 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9903 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9904 " <all|dev_id|bus[:target[:lun]]|off>\n"
9905 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9906 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9907 " [-D <enable|disable>][-M mode][-O offset]\n"
9908 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9909 " [-U][-W bus_width]\n"
9910 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9911 " camcontrol sanitize [dev_id][generic args]\n"
9912 " [-a overwrite|block|crypto|exitfailure]\n"
9913 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9915 " camcontrol idle [dev_id][generic args][-t time]\n"
9916 " camcontrol standby [dev_id][generic args][-t time]\n"
9917 " camcontrol sleep [dev_id][generic args]\n"
9918 " camcontrol powermode [dev_id][generic args]\n"
9919 " camcontrol apm [dev_id][generic args][-l level]\n"
9920 " camcontrol aam [dev_id][generic args][-l level]\n"
9921 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9923 " camcontrol security [dev_id][generic args]\n"
9924 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9925 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9926 " [-U <user|master>] [-y]\n"
9927 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9928 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9929 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9930 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9931 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9932 " [-s scope][-S][-T type][-U]\n"
9933 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9934 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9935 " [-p part][-s start][-T type][-V vol]\n"
9936 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9938 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9939 " [-o rep_opts] [-P print_opts]\n"
9940 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9941 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9942 " [-S power_src] [-T timer]\n"
9943 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9944 " <-s <-f format -T time | -U >>\n"
9945 " camcontrol devtype [dev_id]\n"
9946 " camcontrol depop [dev_id] [-d | -l | -r] [-e element] [-c capacity]\n"
9947 " camcontrol mmcsdcmd [dev_id] [[-c mmc_opcode] [-a mmc_arg]\n"
9948 " [-f mmc_flags] [-l data_len]\n"
9949 " [-W [-b data_byte]]] |\n"
9950 " [-F frequency] |\n"
9953 " [-S high|normal]\n"
9955 " camcontrol help\n");
9959 "Specify one of the following options:\n"
9960 "devlist list all CAM devices\n"
9961 "periphlist list all CAM peripheral drivers attached to a device\n"
9962 "tur send a test unit ready to the named device\n"
9963 "inquiry send a SCSI inquiry command to the named device\n"
9964 "identify send a ATA identify command to the named device\n"
9965 "reportluns send a SCSI report luns command to the device\n"
9966 "readcap send a SCSI read capacity command to the device\n"
9967 "start send a Start Unit command to the device\n"
9968 "stop send a Stop Unit command to the device\n"
9969 "load send a Start Unit command to the device with the load bit set\n"
9970 "eject send a Stop Unit command to the device with the eject bit set\n"
9971 "reprobe update capacity information of the given device\n"
9972 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9973 "reset reset all buses, the given bus, bus:target:lun or device\n"
9974 "defects read the defect list of the specified device\n"
9975 "modepage display or edit (-e) the given mode page\n"
9976 "cmd send the given SCSI command, may need -i or -o as well\n"
9977 "smpcmd send the given SMP command, requires -o and -i\n"
9978 "smprg send the SMP Report General command\n"
9979 "smppc send the SMP PHY Control command, requires -p\n"
9980 "smpphylist display phys attached to a SAS expander\n"
9981 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9982 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9983 "tags report or set the number of transaction slots for a device\n"
9984 "negotiate report or set device negotiation parameters\n"
9985 "format send the SCSI FORMAT UNIT command to the named device\n"
9986 "sanitize send the SCSI SANITIZE command to the named device\n"
9987 "idle send the ATA IDLE command to the named device\n"
9988 "standby send the ATA STANDBY command to the named device\n"
9989 "sleep send the ATA SLEEP command to the named device\n"
9990 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9991 "fwdownload program firmware of the named device with the given image\n"
9992 "security report or send ATA security commands to the named device\n"
9993 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9994 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9995 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9996 "zone manage Zoned Block (Shingled) devices\n"
9997 "epc send ATA Extended Power Conditions commands\n"
9998 "timestamp report or set the device's timestamp\n"
9999 "devtype report the type of device\n"
10000 "depop manage drive storage elements\n"
10001 "mmcsdcmd send the given MMC command, needs -c and -a as well\n"
10002 "help this message\n"
10003 "Device Identifiers:\n"
10004 "bus:target specify the bus and target, lun defaults to 0\n"
10005 "bus:target:lun specify the bus, target and lun\n"
10006 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
10007 "Generic arguments:\n"
10008 "-v be verbose, print out sense information\n"
10009 "-t timeout command timeout in seconds, overrides default timeout\n"
10010 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
10011 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
10012 "-E have the kernel attempt to perform SCSI error recovery\n"
10013 "-C count specify the SCSI command retry count (needs -E to work)\n"
10014 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
10015 "modepage arguments:\n"
10016 "-l list all available mode pages\n"
10017 "-m page specify the mode page to view or edit\n"
10018 "-e edit the specified mode page\n"
10019 "-b force view to binary mode\n"
10020 "-d disable block descriptors for mode sense\n"
10021 "-P pgctl page control field 0-3\n"
10022 "defects arguments:\n"
10023 "-f format specify defect list format (block, bfi or phys)\n"
10024 "-G get the grown defect list\n"
10025 "-P get the permanent defect list\n"
10026 "inquiry arguments:\n"
10027 "-D get the standard inquiry data\n"
10028 "-S get the serial number\n"
10029 "-R get the transfer rate, etc.\n"
10030 "reportluns arguments:\n"
10031 "-c only report a count of available LUNs\n"
10032 "-l only print out luns, and not a count\n"
10033 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10034 "readcap arguments\n"
10035 "-b only report the blocksize\n"
10036 "-h human readable device size, base 2\n"
10037 "-H human readable device size, base 10\n"
10038 "-N print the number of blocks instead of last block\n"
10039 "-q quiet, print numbers only\n"
10040 "-s only report the last block/device size\n"
10042 "-c cdb [args] specify the SCSI CDB\n"
10043 "-i len fmt specify input data and input data format\n"
10044 "-o len fmt [args] specify output data and output data fmt\n"
10045 "smpcmd arguments:\n"
10046 "-r len fmt [args] specify the SMP command to be sent\n"
10047 "-R len fmt [args] specify SMP response format\n"
10048 "smprg arguments:\n"
10049 "-l specify the long response format\n"
10050 "smppc arguments:\n"
10051 "-p phy specify the PHY to operate on\n"
10052 "-l specify the long request/response format\n"
10053 "-o operation specify the phy control operation\n"
10054 "-d name set the attached device name\n"
10055 "-m rate set the minimum physical link rate\n"
10056 "-M rate set the maximum physical link rate\n"
10057 "-T pp_timeout set the partial pathway timeout value\n"
10058 "-a enable|disable enable or disable SATA slumber\n"
10059 "-A enable|disable enable or disable SATA partial phy power\n"
10060 "-s enable|disable enable or disable SAS slumber\n"
10061 "-S enable|disable enable or disable SAS partial phy power\n"
10062 "smpphylist arguments:\n"
10063 "-l specify the long response format\n"
10064 "-q only print phys with attached devices\n"
10065 "smpmaninfo arguments:\n"
10066 "-l specify the long response format\n"
10067 "debug arguments:\n"
10068 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10069 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10070 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10071 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10072 "tags arguments:\n"
10073 "-N tags specify the number of tags to use for this device\n"
10074 "-q be quiet, don't report the number of tags\n"
10075 "-v report a number of tag-related parameters\n"
10076 "negotiate arguments:\n"
10077 "-a send a test unit ready after negotiation\n"
10078 "-c report/set current negotiation settings\n"
10079 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10080 "-M mode set ATA mode\n"
10081 "-O offset set command delay offset\n"
10082 "-q be quiet, don't report anything\n"
10083 "-R syncrate synchronization rate in MHz\n"
10084 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10085 "-U report/set user negotiation settings\n"
10086 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10087 "-v also print a Path Inquiry CCB for the controller\n"
10088 "format arguments:\n"
10089 "-q be quiet, don't print status messages\n"
10090 "-r run in report only mode\n"
10091 "-w don't send immediate format command\n"
10092 "-y don't ask any questions\n"
10093 "sanitize arguments:\n"
10094 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10095 "-c passes overwrite passes to perform (1 to 31)\n"
10096 "-I invert overwrite pattern after each pass\n"
10097 "-P pattern path to overwrite pattern file\n"
10098 "-q be quiet, don't print status messages\n"
10099 "-r run in report only mode\n"
10100 "-U run operation in unrestricted completion exit mode\n"
10101 "-w don't send immediate sanitize command\n"
10102 "-y don't ask any questions\n"
10103 "idle/standby arguments:\n"
10104 "-t <arg> number of seconds before respective state.\n"
10105 "fwdownload arguments:\n"
10106 "-f fw_image path to firmware image file\n"
10107 "-q don't print informational messages, only errors\n"
10108 "-s run in simulation mode\n"
10109 "-v print info for every firmware segment sent to device\n"
10110 "-y don't ask any questions\n"
10111 "security arguments:\n"
10112 "-d pwd disable security using the given password for the selected\n"
10114 "-e pwd erase the device using the given pwd for the selected user\n"
10115 "-f freeze the security configuration of the specified device\n"
10116 "-h pwd enhanced erase the device using the given pwd for the\n"
10118 "-k pwd unlock the device using the given pwd for the selected\n"
10120 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10121 "-q be quiet, do not print any status messages\n"
10122 "-s pwd password the device (enable security) using the given\n"
10123 " pwd for the selected user\n"
10124 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10125 "-U <user|master> specifies which user to set: user or master\n"
10126 "-y don't ask any questions\n"
10128 "-f freeze the HPA configuration of the device\n"
10129 "-l lock the HPA configuration of the device\n"
10130 "-P make the HPA max sectors persist\n"
10131 "-p pwd Set the HPA configuration password required for unlock\n"
10133 "-q be quiet, do not print any status messages\n"
10134 "-s sectors configures the maximum user accessible sectors of the\n"
10136 "-U pwd unlock the HPA configuration of the device\n"
10137 "-y don't ask any questions\n"
10139 "-f freeze the AMA configuration of the device\n"
10140 "-q be quiet, do not print any status messages\n"
10141 "-s sectors configures the maximum user accessible sectors of the\n"
10143 "persist arguments:\n"
10144 "-i action specify read_keys, read_reservation, report_cap, or\n"
10145 " read_full_status\n"
10146 "-o action specify register, register_ignore, reserve, release,\n"
10147 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10148 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10149 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10150 "-k key specify the Reservation Key\n"
10151 "-K sa_key specify the Service Action Reservation Key\n"
10152 "-p set the Activate Persist Through Power Loss bit\n"
10153 "-R rtp specify the Relative Target Port\n"
10154 "-s scope specify the scope: lun, extent, element or a number\n"
10155 "-S specify Transport ID for register, requires -I\n"
10156 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10157 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10158 "-U unregister the current initiator for register_move\n"
10159 "attrib arguments:\n"
10160 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10162 "-w attr specify an attribute to write, one -w argument per attr\n"
10163 "-a attr_num only display this attribute number\n"
10164 "-c get cached attributes\n"
10165 "-e elem_addr request attributes for the given element in a changer\n"
10166 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10167 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10168 " field_none, field_desc, field_num, field_size, field_rw\n"
10169 "-p partition request attributes for the given partition\n"
10170 "-s start_attr request attributes starting at the given number\n"
10171 "-T elem_type specify the element type (used with -e)\n"
10172 "-V logical_vol specify the logical volume ID\n"
10173 "opcodes arguments:\n"
10174 "-o opcode specify the individual opcode to list\n"
10175 "-s service_action specify the service action for the opcode\n"
10176 "-N do not return SCSI error for unsupported SA\n"
10177 "-T request nominal and recommended timeout values\n"
10178 "zone arguments:\n"
10179 "-c cmd required: rz, open, close, finish, or rwp\n"
10180 "-a apply the action to all zones\n"
10181 "-l LBA specify the zone starting LBA\n"
10182 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10183 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10184 "-P print_opt report zones printing: normal, summary, script\n"
10186 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10187 " source, status, list\n"
10188 "-d disable power mode (timer, state)\n"
10189 "-D delayed entry (goto)\n"
10190 "-e enable power mode (timer, state)\n"
10191 "-H hold power mode (goto)\n"
10192 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10194 "-P only display power mode (status)\n"
10195 "-r rst_src restore settings from: default, saved (restore)\n"
10196 "-s save mode (timer, state, restore)\n"
10197 "-S power_src set power source: battery, nonbattery (source)\n"
10198 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10199 "timestamp arguments:\n"
10200 "-r report the timestamp of the device\n"
10201 "-f format report the timestamp of the device with the given\n"
10202 " strftime(3) format string\n"
10203 "-m report the timestamp of the device as milliseconds since\n"
10204 " January 1st, 1970\n"
10205 "-U report the time with UTC instead of the local time zone\n"
10206 "-s set the timestamp of the device\n"
10207 "-f format the format of the time string passed into strptime(3)\n"
10208 "-T time the time value passed into strptime(3)\n"
10209 "-U set the timestamp of the device to UTC time\n"
10210 "depop arguments:\n"
10211 "-d remove an element from service\n"
10212 "-l list status of all elements of drive\n"
10213 "-r restore all elements to service\n"
10214 "-e elm element to remove\n"
10215 "-c capacity requested new capacity\n"
10216 "mmcsdcmd arguments:\n"
10217 "-c mmc_cmd MMC command to send to the card\n"
10218 "-a mmc_arg Argument for the MMC command\n"
10219 "-f mmc_flag Flags to set for the MMC command\n"
10220 "-l data_len Expect data_len bytes of data in reply and display them\n"
10221 "-W Fill the data buffer before invoking the MMC command\n"
10222 "-b data_byte One byte of data to fill the data buffer with\n"
10223 "-F frequency Operating frequency to set on the controller\n"
10224 "-4 Set bus width to 4 bit\n"
10225 "-1 Set bus width to 8 bit\n"
10226 "-S high | std Set high-speed or standard timing\n"
10227 "-I Display various card and host controller information\n"
10232 main(int argc, char **argv)
10235 char *device = NULL;
10237 struct cam_device *cam_dev = NULL;
10238 int timeout = 0, retry_count = 1;
10239 camcontrol_optret optreturn;
10241 const char *mainopt = "C:En:Q:t:u:v";
10242 const char *subopt = NULL;
10243 char combinedopt[256];
10244 int error = 0, optstart = 2;
10245 int task_attr = MSG_SIMPLE_Q_TAG;
10249 target_id_t target;
10252 cmdlist = CAM_CMD_NONE;
10253 arglist = CAM_ARG_NONE;
10261 * Get the base option.
10263 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10265 if (optreturn == CC_OR_AMBIGUOUS) {
10266 warnx("ambiguous option %s", argv[1]);
10269 } else if (optreturn == CC_OR_NOT_FOUND) {
10270 warnx("option %s not found", argv[1]);
10276 * Ahh, getopt(3) is a pain.
10278 * This is a gross hack. There really aren't many other good
10279 * options (excuse the pun) for parsing options in a situation like
10280 * this. getopt is kinda braindead, so you end up having to run
10281 * through the options twice, and give each invocation of getopt
10282 * the option string for the other invocation.
10284 * You would think that you could just have two groups of options.
10285 * The first group would get parsed by the first invocation of
10286 * getopt, and the second group would get parsed by the second
10287 * invocation of getopt. It doesn't quite work out that way. When
10288 * the first invocation of getopt finishes, it leaves optind pointing
10289 * to the argument _after_ the first argument in the second group.
10290 * So when the second invocation of getopt comes around, it doesn't
10291 * recognize the first argument it gets and then bails out.
10293 * A nice alternative would be to have a flag for getopt that says
10294 * "just keep parsing arguments even when you encounter an unknown
10295 * argument", but there isn't one. So there's no real clean way to
10296 * easily parse two sets of arguments without having one invocation
10297 * of getopt know about the other.
10299 * Without this hack, the first invocation of getopt would work as
10300 * long as the generic arguments are first, but the second invocation
10301 * (in the subfunction) would fail in one of two ways. In the case
10302 * where you don't set optreset, it would fail because optind may be
10303 * pointing to the argument after the one it should be pointing at.
10304 * In the case where you do set optreset, and reset optind, it would
10305 * fail because getopt would run into the first set of options, which
10306 * it doesn't understand.
10308 * All of this would "sort of" work if you could somehow figure out
10309 * whether optind had been incremented one option too far. The
10310 * mechanics of that, however, are more daunting than just giving
10311 * both invocations all of the expect options for either invocation.
10313 * Needless to say, I wouldn't mind if someone invented a better
10314 * (non-GPL!) command line parsing interface than getopt. I
10315 * wouldn't mind if someone added more knobs to getopt to make it
10316 * work better. Who knows, I may talk myself into doing it someday,
10317 * if the standards weenies let me. As it is, it just leads to
10318 * hackery like this and causes people to avoid it in some cases.
10320 * KDM, September 8th, 1998
10322 if (subopt != NULL)
10323 sprintf(combinedopt, "%s%s", mainopt, subopt);
10325 sprintf(combinedopt, "%s", mainopt);
10328 * For these options we do not parse optional device arguments and
10329 * we do not open a passthrough device.
10331 if ((cmdlist == CAM_CMD_RESCAN)
10332 || (cmdlist == CAM_CMD_RESET)
10333 || (cmdlist == CAM_CMD_DEVTREE)
10334 || (cmdlist == CAM_CMD_USAGE)
10335 || (cmdlist == CAM_CMD_DEBUG))
10339 && (argc > 2 && argv[2][0] != '-')) {
10343 if (isdigit(argv[2][0])) {
10344 /* device specified as bus:target[:lun] */
10345 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10347 errx(1, "numeric device specification must "
10348 "be either bus:target, or "
10350 /* default to 0 if lun was not specified */
10351 if ((arglist & CAM_ARG_LUN) == 0) {
10353 arglist |= CAM_ARG_LUN;
10357 if (cam_get_device(argv[2], name, sizeof name, &unit)
10359 errx(1, "%s", cam_errbuf);
10360 device = strdup(name);
10361 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10366 * Start getopt processing at argv[2/3], since we've already
10367 * accepted argv[1..2] as the command name, and as a possible
10373 * Now we run through the argument list looking for generic
10374 * options, and ignoring options that possibly belong to
10377 while ((c = getopt(argc, argv, combinedopt))!= -1){
10380 retry_count = strtol(optarg, NULL, 0);
10381 if (retry_count < 0)
10382 errx(1, "retry count %d is < 0",
10384 arglist |= CAM_ARG_RETRIES;
10387 arglist |= CAM_ARG_ERR_RECOVER;
10390 arglist |= CAM_ARG_DEVICE;
10392 while (isspace(*tstr) && (*tstr != '\0'))
10394 device = (char *)strdup(tstr);
10398 int table_entry = 0;
10401 while (isspace(*tstr) && (*tstr != '\0'))
10403 if (isdigit(*tstr)) {
10404 task_attr = strtol(tstr, &endptr, 0);
10405 if (*endptr != '\0') {
10406 errx(1, "Invalid queue option "
10411 scsi_nv_status status;
10413 table_size = sizeof(task_attrs) /
10414 sizeof(task_attrs[0]);
10415 status = scsi_get_nv(task_attrs,
10416 table_size, tstr, &table_entry,
10417 SCSI_NV_FLAG_IG_CASE);
10418 if (status == SCSI_NV_FOUND)
10419 task_attr = task_attrs[
10420 table_entry].value;
10422 errx(1, "%s option %s",
10423 (status == SCSI_NV_AMBIGUOUS)?
10424 "ambiguous" : "invalid",
10431 timeout = strtol(optarg, NULL, 0);
10433 errx(1, "invalid timeout %d", timeout);
10434 /* Convert the timeout from seconds to ms */
10436 arglist |= CAM_ARG_TIMEOUT;
10439 arglist |= CAM_ARG_UNIT;
10440 unit = strtol(optarg, NULL, 0);
10443 arglist |= CAM_ARG_VERBOSE;
10451 * For most commands we'll want to open the passthrough device
10452 * associated with the specified device. In the case of the rescan
10453 * commands, we don't use a passthrough device at all, just the
10454 * transport layer device.
10456 if (devopen == 1) {
10457 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10458 && (((arglist & CAM_ARG_DEVICE) == 0)
10459 || ((arglist & CAM_ARG_UNIT) == 0))) {
10460 errx(1, "subcommand \"%s\" requires a valid device "
10461 "identifier", argv[1]);
10464 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10465 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10466 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10468 errx(1,"%s", cam_errbuf);
10472 * Reset optind to 2, and reset getopt, so these routines can parse
10473 * the arguments again.
10479 case CAM_CMD_DEVLIST:
10480 error = getdevlist(cam_dev);
10483 error = atahpa(cam_dev, retry_count, timeout,
10484 argc, argv, combinedopt);
10487 error = ataama(cam_dev, retry_count, timeout,
10488 argc, argv, combinedopt);
10490 case CAM_CMD_DEVTREE:
10491 error = getdevtree(argc, argv, combinedopt);
10493 case CAM_CMD_DEVTYPE:
10494 error = getdevtype(cam_dev);
10497 error = testunitready(cam_dev, task_attr, retry_count,
10500 case CAM_CMD_INQUIRY:
10501 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10502 task_attr, retry_count, timeout);
10504 case CAM_CMD_IDENTIFY:
10505 error = identify(cam_dev, retry_count, timeout);
10507 case CAM_CMD_STARTSTOP:
10508 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10509 arglist & CAM_ARG_EJECT, task_attr,
10510 retry_count, timeout);
10512 case CAM_CMD_RESCAN:
10513 error = dorescan_or_reset(argc, argv, 1);
10515 case CAM_CMD_RESET:
10516 error = dorescan_or_reset(argc, argv, 0);
10518 case CAM_CMD_READ_DEFECTS:
10519 error = readdefects(cam_dev, argc, argv, combinedopt,
10520 task_attr, retry_count, timeout);
10522 case CAM_CMD_MODE_PAGE:
10523 modepage(cam_dev, argc, argv, combinedopt,
10524 task_attr, retry_count, timeout);
10526 case CAM_CMD_SCSI_CMD:
10527 error = scsicmd(cam_dev, argc, argv, combinedopt,
10528 task_attr, retry_count, timeout);
10530 case CAM_CMD_MMCSD_CMD:
10531 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10532 retry_count, timeout);
10534 case CAM_CMD_SMP_CMD:
10535 error = smpcmd(cam_dev, argc, argv, combinedopt,
10536 retry_count, timeout);
10538 case CAM_CMD_SMP_RG:
10539 error = smpreportgeneral(cam_dev, argc, argv,
10540 combinedopt, retry_count,
10543 case CAM_CMD_SMP_PC:
10544 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10545 retry_count, timeout);
10547 case CAM_CMD_SMP_PHYLIST:
10548 error = smpphylist(cam_dev, argc, argv, combinedopt,
10549 retry_count, timeout);
10551 case CAM_CMD_SMP_MANINFO:
10552 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10553 retry_count, timeout);
10555 case CAM_CMD_DEBUG:
10556 error = camdebug(argc, argv, combinedopt);
10559 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10562 error = ratecontrol(cam_dev, task_attr, retry_count,
10563 timeout, argc, argv, combinedopt);
10565 case CAM_CMD_FORMAT:
10566 error = scsiformat(cam_dev, argc, argv,
10567 combinedopt, task_attr, retry_count,
10570 case CAM_CMD_REPORTLUNS:
10571 error = scsireportluns(cam_dev, argc, argv,
10572 combinedopt, task_attr,
10573 retry_count, timeout);
10575 case CAM_CMD_READCAP:
10576 error = scsireadcapacity(cam_dev, argc, argv,
10577 combinedopt, task_attr,
10578 retry_count, timeout);
10581 case CAM_CMD_STANDBY:
10582 case CAM_CMD_SLEEP:
10583 case CAM_CMD_POWER_MODE:
10584 error = atapm(cam_dev, argc, argv,
10585 combinedopt, retry_count, timeout);
10589 error = ataaxm(cam_dev, argc, argv,
10590 combinedopt, retry_count, timeout);
10592 case CAM_CMD_SECURITY:
10593 error = atasecurity(cam_dev, retry_count, timeout,
10594 argc, argv, combinedopt);
10596 case CAM_CMD_DOWNLOAD_FW:
10597 error = fwdownload(cam_dev, argc, argv, combinedopt,
10598 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10601 case CAM_CMD_SANITIZE:
10602 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10603 retry_count, timeout);
10605 case CAM_CMD_PERSIST:
10606 error = scsipersist(cam_dev, argc, argv, combinedopt,
10607 task_attr, retry_count, timeout,
10608 arglist & CAM_ARG_VERBOSE,
10609 arglist & CAM_ARG_ERR_RECOVER);
10611 case CAM_CMD_ATTRIB:
10612 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10613 task_attr, retry_count, timeout,
10614 arglist & CAM_ARG_VERBOSE,
10615 arglist & CAM_ARG_ERR_RECOVER);
10617 case CAM_CMD_OPCODES:
10618 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10619 task_attr, retry_count, timeout,
10620 arglist & CAM_ARG_VERBOSE);
10622 case CAM_CMD_REPROBE:
10623 error = reprobe(cam_dev);
10626 error = zone(cam_dev, argc, argv, combinedopt,
10627 task_attr, retry_count, timeout,
10628 arglist & CAM_ARG_VERBOSE);
10631 error = epc(cam_dev, argc, argv, combinedopt,
10632 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10634 case CAM_CMD_TIMESTAMP:
10635 error = timestamp(cam_dev, argc, argv, combinedopt,
10636 task_attr, retry_count, timeout,
10637 arglist & CAM_ARG_VERBOSE);
10639 case CAM_CMD_DEPOP:
10640 error = depop(cam_dev, argc, argv, combinedopt,
10641 task_attr, retry_count, timeout,
10642 arglist & CAM_ARG_VERBOSE);
10644 case CAM_CMD_USAGE:
10653 if (cam_dev != NULL)
10654 cam_close_device(cam_dev);