2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
53 #include <cam/cam_debug.h>
54 #include <cam/cam_ccb.h>
55 #include <cam/scsi/scsi_all.h>
56 #include <cam/scsi/scsi_da.h>
57 #include <cam/scsi/scsi_pass.h>
58 #include <cam/scsi/scsi_message.h>
59 #include <cam/scsi/smp_all.h>
60 #include <cam/ata/ata_all.h>
61 #include <cam/mmc/mmc_all.h>
63 #include "camcontrol.h"
65 #include "nvmecontrol_ext.h"
118 CAM_ARG_NONE = 0x00000000,
119 CAM_ARG_VERBOSE = 0x00000001,
120 CAM_ARG_DEVICE = 0x00000002,
121 CAM_ARG_BUS = 0x00000004,
122 CAM_ARG_TARGET = 0x00000008,
123 CAM_ARG_LUN = 0x00000010,
124 CAM_ARG_EJECT = 0x00000020,
125 CAM_ARG_UNIT = 0x00000040,
126 /* unused 0x00000080 */
127 /* unused 0x00000100 */
128 /* unused 0x00000200 */
129 CAM_ARG_PLIST = 0x00000400,
130 CAM_ARG_GLIST = 0x00000800,
131 CAM_ARG_GET_SERIAL = 0x00001000,
132 CAM_ARG_GET_STDINQ = 0x00002000,
133 CAM_ARG_GET_XFERRATE = 0x00004000,
134 CAM_ARG_INQ_MASK = 0x00007000,
135 /* unused 0x00008000 */
136 /* unused 0x00010000 */
137 CAM_ARG_TIMEOUT = 0x00020000,
138 CAM_ARG_CMD_IN = 0x00040000,
139 CAM_ARG_CMD_OUT = 0x00080000,
140 /* unused 0x00100000 */
141 CAM_ARG_ERR_RECOVER = 0x00200000,
142 CAM_ARG_RETRIES = 0x00400000,
143 CAM_ARG_START_UNIT = 0x00800000,
144 CAM_ARG_DEBUG_INFO = 0x01000000,
145 CAM_ARG_DEBUG_TRACE = 0x02000000,
146 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
147 CAM_ARG_DEBUG_CDB = 0x08000000,
148 CAM_ARG_DEBUG_XPT = 0x10000000,
149 CAM_ARG_DEBUG_PERIPH = 0x20000000,
150 CAM_ARG_DEBUG_PROBE = 0x40000000,
151 /* unused 0x80000000 */
154 struct camcontrol_opts {
161 struct ata_set_max_pwd
164 u_int8_t password[32];
165 u_int16_t reserved2[239];
168 static struct scsi_nv task_attrs[] = {
169 { "simple", MSG_SIMPLE_Q_TAG },
170 { "head", MSG_HEAD_OF_Q_TAG },
171 { "ordered", MSG_ORDERED_Q_TAG },
172 { "iwr", MSG_IGN_WIDE_RESIDUE },
173 { "aca", MSG_ACA_TASK }
176 static const char scsicmd_opts[] = "a:c:dfi:o:r";
177 static const char readdefect_opts[] = "f:GPqsS:X";
178 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
179 static const char smprg_opts[] = "l";
180 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
181 static const char smpphylist_opts[] = "lq";
184 static struct camcontrol_opts option_table[] = {
185 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
186 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
187 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
188 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
189 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
190 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
191 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
192 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
193 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
194 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
195 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
196 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
197 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
198 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:F:f:Wb:l:41S:I"},
199 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
200 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
201 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
202 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
203 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
204 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
205 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
206 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
207 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
208 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
209 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
210 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
211 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
212 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
213 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm:DLP:"},
214 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
215 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
216 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
217 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
218 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
219 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
220 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
221 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
222 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
223 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
224 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
225 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
226 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
227 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
228 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
229 {"ama", CAM_CMD_AMA, CAM_ARG_NONE, "fqs:"},
230 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
231 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
232 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
233 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
234 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
235 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
236 {"depop", CAM_CMD_DEPOP, CAM_ARG_NONE, "ac:de:ls"},
237 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
238 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
239 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
244 struct device_match_result dev_match;
246 struct periph_match_result *periph_matches;
247 struct scsi_vpd_device_id *device_id;
249 STAILQ_ENTRY(cam_devitem) links;
253 STAILQ_HEAD(, cam_devitem) dev_queue;
257 static cam_argmask arglist;
259 static const char *devtype_names[] = {
269 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
270 uint32_t *cmdnum, cam_argmask *argnum,
271 const char **subopt);
272 static int getdevlist(struct cam_device *device);
273 static int getdevtree(int argc, char **argv, char *combinedopt);
274 static int getdevtype(struct cam_device *device);
275 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
276 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
277 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
278 static int print_dev_mmcsd(struct device_match_result *dev_result,
281 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
283 static int testunitready(struct cam_device *device, int task_attr,
284 int retry_count, int timeout, int quiet);
285 static int scsistart(struct cam_device *device, int startstop, int loadeject,
286 int task_attr, int retry_count, int timeout);
287 static int scsiinquiry(struct cam_device *device, int task_attr,
288 int retry_count, int timeout);
289 static int scsiserial(struct cam_device *device, int task_attr,
290 int retry_count, int timeout);
291 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
292 lun_id_t *lun, cam_argmask *arglst);
293 static int reprobe(struct cam_device *device);
294 static int dorescan_or_reset(int argc, char **argv, int rescan);
295 static int rescan_or_reset_bus(path_id_t bus, int rescan);
296 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
297 lun_id_t lun, int scan);
298 static int readdefects(struct cam_device *device, int argc, char **argv,
299 char *combinedopt, int task_attr, int retry_count,
301 static void modepage(struct cam_device *device, int argc, char **argv,
302 char *combinedopt, int task_attr, int retry_count,
304 static int scsicmd(struct cam_device *device, int argc, char **argv,
305 char *combinedopt, int task_attr, int retry_count,
307 static int smpcmd(struct cam_device *device, int argc, char **argv,
308 char *combinedopt, int retry_count, int timeout);
309 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
310 char *combinedopt, int retry_count, int timeout);
311 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
312 char *combinedopt, int retry_count, int timeout);
313 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
314 char *combinedopt, int retry_count, int timeout);
315 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
316 char *combinedopt, int retry_count, int timeout);
317 static int getdevid(struct cam_devitem *item);
318 static int buildbusdevlist(struct cam_devlist *devlist);
319 static void freebusdevlist(struct cam_devlist *devlist);
320 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
322 static int smpphylist(struct cam_device *device, int argc, char **argv,
323 char *combinedopt, int retry_count, int timeout);
324 static int tagcontrol(struct cam_device *device, int argc, char **argv,
326 static void cts_print(struct cam_device *device,
327 struct ccb_trans_settings *cts);
328 static void cpi_print(struct ccb_pathinq *cpi);
329 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
330 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
331 static int get_print_cts(struct cam_device *device, int user_settings,
332 int quiet, struct ccb_trans_settings *cts);
333 static int ratecontrol(struct cam_device *device, int task_attr,
334 int retry_count, int timeout, int argc, char **argv,
336 static int scsiformat(struct cam_device *device, int argc, char **argv,
337 char *combinedopt, int task_attr, int retry_count,
339 static int sanitize(struct cam_device *device, int argc, char **argv,
340 char *combinedopt, int task_attr, int retry_count,
342 static int scsireportluns(struct cam_device *device, int argc, char **argv,
343 char *combinedopt, int task_attr, int retry_count,
345 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
346 char *combinedopt, int task_attr, int retry_count,
348 static int atapm(struct cam_device *device, int argc, char **argv,
349 char *combinedopt, int retry_count, int timeout);
350 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
351 int argc, char **argv, char *combinedopt);
352 static int atahpa(struct cam_device *device, int retry_count, int timeout,
353 int argc, char **argv, char *combinedopt);
354 static int ataama(struct cam_device *device, int retry_count, int timeout,
355 int argc, char **argv, char *combinedopt);
356 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
357 int sa_set, int req_sa, uint8_t *buf,
359 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
361 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
362 char *combinedopt, int task_attr, int retry_count,
363 int timeout, int verbose);
366 #define min(a,b) (((a)<(b))?(a):(b))
369 #define max(a,b) (((a)>(b))?(a):(b))
373 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
374 cam_argmask *argnum, const char **subopt)
376 struct camcontrol_opts *opts;
379 for (opts = table; (opts != NULL) && (opts->optname != NULL);
381 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
382 *cmdnum = opts->cmdnum;
383 *argnum = opts->argnum;
384 *subopt = opts->subopt;
385 if (++num_matches > 1)
386 return (CC_OR_AMBIGUOUS);
391 return (CC_OR_FOUND);
393 return (CC_OR_NOT_FOUND);
397 getdevlist(struct cam_device *device)
403 ccb = cam_getccb(device);
405 ccb->ccb_h.func_code = XPT_GDEVLIST;
406 ccb->ccb_h.flags = CAM_DIR_NONE;
407 ccb->ccb_h.retry_count = 1;
409 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
410 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
411 if (cam_send_ccb(device, ccb) < 0) {
412 warn("error getting device list");
419 switch (ccb->cgdl.status) {
420 case CAM_GDEVLIST_MORE_DEVS:
421 strcpy(status, "MORE");
423 case CAM_GDEVLIST_LAST_DEVICE:
424 strcpy(status, "LAST");
426 case CAM_GDEVLIST_LIST_CHANGED:
427 strcpy(status, "CHANGED");
429 case CAM_GDEVLIST_ERROR:
430 strcpy(status, "ERROR");
435 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
436 ccb->cgdl.periph_name,
437 ccb->cgdl.unit_number,
438 ccb->cgdl.generation,
443 * If the list has changed, we need to start over from the
446 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
456 getdevtree(int argc, char **argv, char *combinedopt)
467 while ((c = getopt(argc, argv, combinedopt)) != -1) {
470 if ((arglist & CAM_ARG_VERBOSE) == 0)
478 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
479 warn("couldn't open %s", XPT_DEVICE);
483 bzero(&ccb, sizeof(union ccb));
485 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
486 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
487 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
489 ccb.ccb_h.func_code = XPT_DEV_MATCH;
490 bufsize = sizeof(struct dev_match_result) * 100;
491 ccb.cdm.match_buf_len = bufsize;
492 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
493 if (ccb.cdm.matches == NULL) {
494 warnx("can't malloc memory for matches");
498 ccb.cdm.num_matches = 0;
501 * We fetch all nodes, since we display most of them in the default
502 * case, and all in the verbose case.
504 ccb.cdm.num_patterns = 0;
505 ccb.cdm.pattern_buf_len = 0;
508 * We do the ioctl multiple times if necessary, in case there are
509 * more than 100 nodes in the EDT.
512 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
513 warn("error sending CAMIOCOMMAND ioctl");
518 if ((ccb.ccb_h.status != CAM_REQ_CMP)
519 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
520 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
521 warnx("got CAM error %#x, CDM error %d\n",
522 ccb.ccb_h.status, ccb.cdm.status);
527 for (i = 0; i < ccb.cdm.num_matches; i++) {
528 switch (ccb.cdm.matches[i].type) {
529 case DEV_MATCH_BUS: {
530 struct bus_match_result *bus_result;
533 * Only print the bus information if the
534 * user turns on the verbose flag.
536 if ((busonly == 0) &&
537 (arglist & CAM_ARG_VERBOSE) == 0)
541 &ccb.cdm.matches[i].result.bus_result;
544 fprintf(stdout, ")\n");
548 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
550 bus_result->dev_name,
551 bus_result->unit_number,
553 (busonly ? "" : ":"));
556 case DEV_MATCH_DEVICE: {
557 struct device_match_result *dev_result;
564 &ccb.cdm.matches[i].result.device_result;
566 if ((dev_result->flags
567 & DEV_RESULT_UNCONFIGURED)
568 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
574 if (dev_result->protocol == PROTO_SCSI) {
575 if (print_dev_scsi(dev_result,
580 } else if (dev_result->protocol == PROTO_ATA ||
581 dev_result->protocol == PROTO_SATAPM) {
582 if (print_dev_ata(dev_result,
587 } else if (dev_result->protocol == PROTO_MMCSD){
588 if (print_dev_mmcsd(dev_result,
593 } else if (dev_result->protocol == PROTO_SEMB) {
594 if (print_dev_semb(dev_result,
600 } else if (dev_result->protocol == PROTO_NVME) {
601 if (print_dev_nvme(dev_result,
608 sprintf(tmpstr, "<>");
611 fprintf(stdout, ")\n");
615 fprintf(stdout, "%-33s at scbus%d "
616 "target %d lun %jx (",
619 dev_result->target_id,
620 (uintmax_t)dev_result->target_lun);
626 case DEV_MATCH_PERIPH: {
627 struct periph_match_result *periph_result;
630 &ccb.cdm.matches[i].result.periph_result;
632 if (busonly || skip_device != 0)
636 fprintf(stdout, ",");
638 fprintf(stdout, "%s%d",
639 periph_result->periph_name,
640 periph_result->unit_number);
646 fprintf(stdout, "unknown match type\n");
651 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
652 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
655 fprintf(stdout, ")\n");
663 getdevtype(struct cam_device *cam_dev)
665 camcontrol_devtype dt;
669 * Get the device type and report it, request no I/O be done to do this.
671 error = get_device_type(cam_dev, -1, 0, 0, &dt);
672 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
673 fprintf(stdout, "illegal\n");
676 fprintf(stdout, "%s\n", devtype_names[dt]);
681 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
683 char vendor[16], product[48], revision[16];
685 cam_strvis(vendor, dev_result->inq_data.vendor,
686 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
687 cam_strvis(product, dev_result->inq_data.product,
688 sizeof(dev_result->inq_data.product), sizeof(product));
689 cam_strvis(revision, dev_result->inq_data.revision,
690 sizeof(dev_result->inq_data.revision), sizeof(revision));
691 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
697 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
699 char product[48], revision[16];
701 cam_strvis(product, dev_result->ident_data.model,
702 sizeof(dev_result->ident_data.model), sizeof(product));
703 cam_strvis(revision, dev_result->ident_data.revision,
704 sizeof(dev_result->ident_data.revision), sizeof(revision));
705 sprintf(tmpstr, "<%s %s>", product, revision);
711 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
713 struct sep_identify_data *sid;
714 char vendor[16], product[48], revision[16], fw[5];
716 sid = (struct sep_identify_data *)&dev_result->ident_data;
717 cam_strvis(vendor, sid->vendor_id,
718 sizeof(sid->vendor_id), sizeof(vendor));
719 cam_strvis(product, sid->product_id,
720 sizeof(sid->product_id), sizeof(product));
721 cam_strvis(revision, sid->product_rev,
722 sizeof(sid->product_rev), sizeof(revision));
723 cam_strvis(fw, sid->firmware_rev,
724 sizeof(sid->firmware_rev), sizeof(fw));
725 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
731 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
734 struct ccb_dev_advinfo *advi;
735 struct cam_device *dev;
736 struct mmc_params mmc_ident_data;
738 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
739 dev_result->target_lun, O_RDWR, NULL);
741 warnx("%s", cam_errbuf);
745 ccb = cam_getccb(dev);
747 warnx("couldn't allocate CCB");
748 cam_close_device(dev);
753 advi->ccb_h.flags = CAM_DIR_IN;
754 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
755 advi->flags = CDAI_FLAG_NONE;
756 advi->buftype = CDAI_TYPE_MMC_PARAMS;
757 advi->bufsiz = sizeof(struct mmc_params);
758 advi->buf = (uint8_t *)&mmc_ident_data;
760 if (cam_send_ccb(dev, ccb) < 0) {
761 warn("error sending XPT_DEV_ADVINFO CCB");
763 cam_close_device(dev);
767 if (strlen(mmc_ident_data.model) > 0) {
768 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
770 sprintf(tmpstr, "<%s card>",
771 mmc_ident_data.card_features &
772 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
776 cam_close_device(dev);
782 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
785 struct ccb_dev_advinfo *advi;
787 ccb = cam_getccb(dev);
789 warnx("couldn't allocate CCB");
790 cam_close_device(dev);
795 advi->ccb_h.flags = CAM_DIR_IN;
796 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
797 advi->flags = CDAI_FLAG_NONE;
798 advi->buftype = CDAI_TYPE_NVME_CNTRL;
799 advi->bufsiz = sizeof(struct nvme_controller_data);
800 advi->buf = (uint8_t *)cdata;
802 if (cam_send_ccb(dev, ccb) < 0) {
803 warn("error sending XPT_DEV_ADVINFO CCB");
805 cam_close_device(dev);
808 if (advi->ccb_h.status != CAM_REQ_CMP) {
809 warnx("got CAM error %#x", advi->ccb_h.status);
811 cam_close_device(dev);
819 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
821 struct cam_device *dev;
822 struct nvme_controller_data cdata;
823 char vendor[64], product[64];
825 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
826 dev_result->target_lun, O_RDWR, NULL);
828 warnx("%s", cam_errbuf);
832 if (nvme_get_cdata(dev, &cdata))
835 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
836 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
837 sprintf(tmpstr, "<%s %s>", vendor, product);
839 cam_close_device(dev);
845 testunitready(struct cam_device *device, int task_attr, int retry_count,
846 int timeout, int quiet)
851 ccb = cam_getccb(device);
853 scsi_test_unit_ready(&ccb->csio,
854 /* retries */ retry_count,
856 /* tag_action */ task_attr,
857 /* sense_len */ SSD_FULL_SIZE,
858 /* timeout */ timeout ? timeout : 5000);
860 /* Disable freezing the device queue */
861 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
863 if (arglist & CAM_ARG_ERR_RECOVER)
864 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
866 if (cam_send_ccb(device, ccb) < 0) {
868 warn("error sending TEST UNIT READY command");
873 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
875 fprintf(stdout, "Unit is ready\n");
878 fprintf(stdout, "Unit is not ready\n");
881 if (arglist & CAM_ARG_VERBOSE) {
882 cam_error_print(device, ccb, CAM_ESF_ALL,
883 CAM_EPF_ALL, stderr);
893 scsistart(struct cam_device *device, int startstop, int loadeject,
894 int task_attr, int retry_count, int timeout)
899 ccb = cam_getccb(device);
902 * If we're stopping, send an ordered tag so the drive in question
903 * will finish any previously queued writes before stopping. If
904 * the device isn't capable of tagged queueing, or if tagged
905 * queueing is turned off, the tag action is a no-op. We override
906 * the default simple tag, although this also has the effect of
907 * overriding the user's wishes if he wanted to specify a simple
911 && (task_attr == MSG_SIMPLE_Q_TAG))
912 task_attr = MSG_ORDERED_Q_TAG;
914 scsi_start_stop(&ccb->csio,
915 /* retries */ retry_count,
917 /* tag_action */ task_attr,
918 /* start/stop */ startstop,
919 /* load_eject */ loadeject,
921 /* sense_len */ SSD_FULL_SIZE,
922 /* timeout */ timeout ? timeout : 120000);
924 /* Disable freezing the device queue */
925 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
927 if (arglist & CAM_ARG_ERR_RECOVER)
928 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
930 if (cam_send_ccb(device, ccb) < 0) {
931 warn("error sending START STOP UNIT command");
936 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
938 fprintf(stdout, "Unit started successfully");
940 fprintf(stdout,", Media loaded\n");
942 fprintf(stdout,"\n");
944 fprintf(stdout, "Unit stopped successfully");
946 fprintf(stdout, ", Media ejected\n");
948 fprintf(stdout, "\n");
954 "Error received from start unit command\n");
957 "Error received from stop unit command\n");
959 if (arglist & CAM_ARG_VERBOSE) {
960 cam_error_print(device, ccb, CAM_ESF_ALL,
961 CAM_EPF_ALL, stderr);
971 scsidoinquiry(struct cam_device *device, int argc, char **argv,
972 char *combinedopt, int task_attr, int retry_count, int timeout)
977 while ((c = getopt(argc, argv, combinedopt)) != -1) {
980 arglist |= CAM_ARG_GET_STDINQ;
983 arglist |= CAM_ARG_GET_XFERRATE;
986 arglist |= CAM_ARG_GET_SERIAL;
994 * If the user didn't specify any inquiry options, he wants all of
997 if ((arglist & CAM_ARG_INQ_MASK) == 0)
998 arglist |= CAM_ARG_INQ_MASK;
1000 if (arglist & CAM_ARG_GET_STDINQ)
1001 error = scsiinquiry(device, task_attr, retry_count, timeout);
1006 if (arglist & CAM_ARG_GET_SERIAL)
1007 scsiserial(device, task_attr, retry_count, timeout);
1009 if (arglist & CAM_ARG_GET_XFERRATE)
1010 error = camxferrate(device);
1016 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1020 struct scsi_inquiry_data *inq_buf;
1023 ccb = cam_getccb(device);
1026 warnx("couldn't allocate CCB");
1030 inq_buf = (struct scsi_inquiry_data *)malloc(
1031 sizeof(struct scsi_inquiry_data));
1033 if (inq_buf == NULL) {
1035 warnx("can't malloc memory for inquiry\n");
1038 bzero(inq_buf, sizeof(*inq_buf));
1041 * Note that although the size of the inquiry buffer is the full
1042 * 256 bytes specified in the SCSI spec, we only tell the device
1043 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1044 * two reasons for this:
1046 * - The SCSI spec says that when a length field is only 1 byte,
1047 * a value of 0 will be interpreted as 256. Therefore
1048 * scsi_inquiry() will convert an inq_len (which is passed in as
1049 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1050 * to 0. Evidently, very few devices meet the spec in that
1051 * regard. Some devices, like many Seagate disks, take the 0 as
1052 * 0, and don't return any data. One Pioneer DVD-R drive
1053 * returns more data than the command asked for.
1055 * So, since there are numerous devices that just don't work
1056 * right with the full inquiry size, we don't send the full size.
1058 * - The second reason not to use the full inquiry data length is
1059 * that we don't need it here. The only reason we issue a
1060 * standard inquiry is to get the vendor name, device name,
1061 * and revision so scsi_print_inquiry() can print them.
1063 * If, at some point in the future, more inquiry data is needed for
1064 * some reason, this code should use a procedure similar to the
1065 * probe code. i.e., issue a short inquiry, and determine from
1066 * the additional length passed back from the device how much
1067 * inquiry data the device supports. Once the amount the device
1068 * supports is determined, issue an inquiry for that amount and no
1073 scsi_inquiry(&ccb->csio,
1074 /* retries */ retry_count,
1076 /* tag_action */ task_attr,
1077 /* inq_buf */ (u_int8_t *)inq_buf,
1078 /* inq_len */ SHORT_INQUIRY_LENGTH,
1081 /* sense_len */ SSD_FULL_SIZE,
1082 /* timeout */ timeout ? timeout : 5000);
1084 /* Disable freezing the device queue */
1085 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1087 if (arglist & CAM_ARG_ERR_RECOVER)
1088 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1090 if (cam_send_ccb(device, ccb) < 0) {
1091 warn("error sending INQUIRY command");
1096 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1099 if (arglist & CAM_ARG_VERBOSE) {
1100 cam_error_print(device, ccb, CAM_ESF_ALL,
1101 CAM_EPF_ALL, stderr);
1112 fprintf(stdout, "%s%d: ", device->device_name,
1113 device->dev_unit_num);
1114 scsi_print_inquiry(inq_buf);
1122 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1126 struct scsi_vpd_unit_serial_number *serial_buf;
1127 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1130 ccb = cam_getccb(device);
1133 warnx("couldn't allocate CCB");
1137 serial_buf = (struct scsi_vpd_unit_serial_number *)
1138 malloc(sizeof(*serial_buf));
1140 if (serial_buf == NULL) {
1142 warnx("can't malloc memory for serial number");
1146 scsi_inquiry(&ccb->csio,
1147 /*retries*/ retry_count,
1149 /* tag_action */ task_attr,
1150 /* inq_buf */ (u_int8_t *)serial_buf,
1151 /* inq_len */ sizeof(*serial_buf),
1153 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1154 /* sense_len */ SSD_FULL_SIZE,
1155 /* timeout */ timeout ? timeout : 5000);
1157 /* Disable freezing the device queue */
1158 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1160 if (arglist & CAM_ARG_ERR_RECOVER)
1161 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1163 if (cam_send_ccb(device, ccb) < 0) {
1164 warn("error sending INQUIRY command");
1170 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1173 if (arglist & CAM_ARG_VERBOSE) {
1174 cam_error_print(device, ccb, CAM_ESF_ALL,
1175 CAM_EPF_ALL, stderr);
1186 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1187 serial_num[serial_buf->length] = '\0';
1189 if ((arglist & CAM_ARG_GET_STDINQ)
1190 || (arglist & CAM_ARG_GET_XFERRATE))
1191 fprintf(stdout, "%s%d: Serial Number ",
1192 device->device_name, device->dev_unit_num);
1194 fprintf(stdout, "%.60s\n", serial_num);
1202 camxferrate(struct cam_device *device)
1204 struct ccb_pathinq cpi;
1206 u_int32_t speed = 0;
1211 if ((retval = get_cpi(device, &cpi)) != 0)
1214 ccb = cam_getccb(device);
1217 warnx("couldn't allocate CCB");
1221 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1222 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1224 if (((retval = cam_send_ccb(device, ccb)) < 0)
1225 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1226 const char error_string[] = "error getting transfer settings";
1231 warnx(error_string);
1233 if (arglist & CAM_ARG_VERBOSE)
1234 cam_error_print(device, ccb, CAM_ESF_ALL,
1235 CAM_EPF_ALL, stderr);
1239 goto xferrate_bailout;
1243 speed = cpi.base_transfer_speed;
1245 if (ccb->cts.transport == XPORT_SPI) {
1246 struct ccb_trans_settings_spi *spi =
1247 &ccb->cts.xport_specific.spi;
1249 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1250 freq = scsi_calc_syncsrate(spi->sync_period);
1253 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1254 speed *= (0x01 << spi->bus_width);
1256 } else if (ccb->cts.transport == XPORT_FC) {
1257 struct ccb_trans_settings_fc *fc =
1258 &ccb->cts.xport_specific.fc;
1260 if (fc->valid & CTS_FC_VALID_SPEED)
1261 speed = fc->bitrate;
1262 } else if (ccb->cts.transport == XPORT_SAS) {
1263 struct ccb_trans_settings_sas *sas =
1264 &ccb->cts.xport_specific.sas;
1266 if (sas->valid & CTS_SAS_VALID_SPEED)
1267 speed = sas->bitrate;
1268 } else if (ccb->cts.transport == XPORT_ATA) {
1269 struct ccb_trans_settings_pata *pata =
1270 &ccb->cts.xport_specific.ata;
1272 if (pata->valid & CTS_ATA_VALID_MODE)
1273 speed = ata_mode2speed(pata->mode);
1274 } else if (ccb->cts.transport == XPORT_SATA) {
1275 struct ccb_trans_settings_sata *sata =
1276 &ccb->cts.xport_specific.sata;
1278 if (sata->valid & CTS_SATA_VALID_REVISION)
1279 speed = ata_revision2speed(sata->revision);
1284 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1285 device->device_name, device->dev_unit_num,
1288 fprintf(stdout, "%s%d: %dKB/s transfers",
1289 device->device_name, device->dev_unit_num,
1293 if (ccb->cts.transport == XPORT_SPI) {
1294 struct ccb_trans_settings_spi *spi =
1295 &ccb->cts.xport_specific.spi;
1297 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1298 && (spi->sync_offset != 0))
1299 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1300 freq % 1000, spi->sync_offset);
1302 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1303 && (spi->bus_width > 0)) {
1304 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1305 && (spi->sync_offset != 0)) {
1306 fprintf(stdout, ", ");
1308 fprintf(stdout, " (");
1310 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1311 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1312 && (spi->sync_offset != 0)) {
1313 fprintf(stdout, ")");
1315 } else if (ccb->cts.transport == XPORT_ATA) {
1316 struct ccb_trans_settings_pata *pata =
1317 &ccb->cts.xport_specific.ata;
1320 if (pata->valid & CTS_ATA_VALID_MODE)
1321 printf("%s, ", ata_mode2string(pata->mode));
1322 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1323 printf("ATAPI %dbytes, ", pata->atapi);
1324 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1325 printf("PIO %dbytes", pata->bytecount);
1327 } else if (ccb->cts.transport == XPORT_SATA) {
1328 struct ccb_trans_settings_sata *sata =
1329 &ccb->cts.xport_specific.sata;
1332 if (sata->valid & CTS_SATA_VALID_REVISION)
1333 printf("SATA %d.x, ", sata->revision);
1336 if (sata->valid & CTS_SATA_VALID_MODE)
1337 printf("%s, ", ata_mode2string(sata->mode));
1338 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1339 printf("ATAPI %dbytes, ", sata->atapi);
1340 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1341 printf("PIO %dbytes", sata->bytecount);
1345 if (ccb->cts.protocol == PROTO_SCSI) {
1346 struct ccb_trans_settings_scsi *scsi =
1347 &ccb->cts.proto_specific.scsi;
1348 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1349 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1350 fprintf(stdout, ", Command Queueing Enabled");
1355 fprintf(stdout, "\n");
1365 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1367 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1368 ((u_int32_t)parm->lba_size_2 << 16);
1370 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1371 ((u_int64_t)parm->lba_size48_2 << 16) |
1372 ((u_int64_t)parm->lba_size48_3 << 32) |
1373 ((u_int64_t)parm->lba_size48_4 << 48);
1377 "Support Enabled Value\n");
1380 printf("Host Protected Area (HPA) ");
1381 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1382 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1383 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1386 printf("HPA - Security ");
1387 if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY)
1388 printf("yes %s\n", (parm->enabled.command2 &
1389 ATA_SUPPORT_MAXSECURITY) ? "yes" : "no ");
1398 ataama_print(struct ata_params *parm, u_int64_t nativesize, int header)
1400 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1401 ((u_int32_t)parm->lba_size_2 << 16);
1403 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1404 ((u_int64_t)parm->lba_size48_2 << 16) |
1405 ((u_int64_t)parm->lba_size48_3 << 32) |
1406 ((u_int64_t)parm->lba_size48_4 << 48);
1410 "Support Enabled Value\n");
1413 printf("Accessible Max Address Config ");
1414 if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) {
1415 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1416 printf("yes %s %ju/%ju\n",
1417 (nativesize > lba) ? "yes" : "no ", lba, nativesize);
1424 atasata(struct ata_params *parm)
1428 if (parm->satacapabilities != 0xffff &&
1429 parm->satacapabilities != 0x0000)
1436 atacapprint(struct ata_params *parm)
1439 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1440 ((u_int32_t)parm->lba_size_2 << 16);
1442 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1443 ((u_int64_t)parm->lba_size48_2 << 16) |
1444 ((u_int64_t)parm->lba_size48_3 << 32) |
1445 ((u_int64_t)parm->lba_size48_4 << 48);
1448 printf("protocol ");
1449 proto = (parm->config == ATA_PROTO_CFA) ? "CFA" :
1450 (parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
1451 if (ata_version(parm->version_major) == 0) {
1452 printf("%s", proto);
1453 } else if (ata_version(parm->version_major) <= 7) {
1454 printf("%s-%d", proto,
1455 ata_version(parm->version_major));
1456 } else if (ata_version(parm->version_major) == 8) {
1457 printf("%s8-ACS", proto);
1460 ata_version(parm->version_major) - 7, proto);
1462 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1463 if (parm->satacapabilities & ATA_SATA_GEN3)
1464 printf(" SATA 3.x\n");
1465 else if (parm->satacapabilities & ATA_SATA_GEN2)
1466 printf(" SATA 2.x\n");
1467 else if (parm->satacapabilities & ATA_SATA_GEN1)
1468 printf(" SATA 1.x\n");
1474 printf("device model %.40s\n", parm->model);
1475 printf("firmware revision %.8s\n", parm->revision);
1476 printf("serial number %.20s\n", parm->serial);
1477 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1478 printf("WWN %04x%04x%04x%04x\n",
1479 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1481 printf("additional product id %.8s\n", parm->product_id);
1482 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1483 printf("media serial number %.30s\n",
1484 parm->media_serial);
1487 printf("cylinders %d\n", parm->cylinders);
1488 printf("heads %d\n", parm->heads);
1489 printf("sectors/track %d\n", parm->sectors);
1490 printf("sector size logical %u, physical %lu, offset %lu\n",
1491 ata_logical_sector_size(parm),
1492 (unsigned long)ata_physical_sector_size(parm),
1493 (unsigned long)ata_logical_sector_offset(parm));
1495 if (parm->config == ATA_PROTO_CFA ||
1496 (parm->support.command2 & ATA_SUPPORT_CFA))
1497 printf("CFA supported\n");
1499 printf("LBA%ssupported ",
1500 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1502 printf("%d sectors\n", lbasize);
1506 printf("LBA48%ssupported ",
1507 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1509 printf("%ju sectors\n", (uintmax_t)lbasize48);
1513 printf("PIO supported PIO");
1514 switch (ata_max_pmode(parm)) {
1530 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1531 printf(" w/o IORDY");
1534 printf("DMA%ssupported ",
1535 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1536 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1537 if (parm->mwdmamodes & 0xff) {
1539 if (parm->mwdmamodes & 0x04)
1541 else if (parm->mwdmamodes & 0x02)
1543 else if (parm->mwdmamodes & 0x01)
1547 if ((parm->atavalid & ATA_FLAG_88) &&
1548 (parm->udmamodes & 0xff)) {
1550 if (parm->udmamodes & 0x40)
1552 else if (parm->udmamodes & 0x20)
1554 else if (parm->udmamodes & 0x10)
1556 else if (parm->udmamodes & 0x08)
1558 else if (parm->udmamodes & 0x04)
1560 else if (parm->udmamodes & 0x02)
1562 else if (parm->udmamodes & 0x01)
1569 if (parm->media_rotation_rate == 1) {
1570 printf("media RPM non-rotating\n");
1571 } else if (parm->media_rotation_rate >= 0x0401 &&
1572 parm->media_rotation_rate <= 0xFFFE) {
1573 printf("media RPM %d\n",
1574 parm->media_rotation_rate);
1577 printf("Zoned-Device Commands ");
1578 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1579 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1580 printf("device managed\n");
1582 case ATA_SUPPORT_ZONE_HOST_AWARE:
1583 printf("host aware\n");
1590 "Support Enabled Value Vendor\n");
1591 printf("read ahead %s %s\n",
1592 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1593 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1594 printf("write cache %s %s\n",
1595 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1596 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1597 printf("flush cache %s %s\n",
1598 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1599 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1600 printf("Native Command Queuing (NCQ) ");
1601 if (atasata(parm) && (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1602 printf("yes %d tags\n",
1603 ATA_QUEUE_LEN(parm->queue) + 1);
1604 printf("NCQ Priority Information %s\n",
1605 parm->satacapabilities & ATA_SUPPORT_NCQ_PRIO ?
1607 printf("NCQ Non-Data Command %s\n",
1608 parm->satacapabilities2 & ATA_SUPPORT_NCQ_NON_DATA ?
1610 printf("NCQ Streaming %s\n",
1611 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1613 printf("Receive & Send FPDMA Queued %s\n",
1614 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1616 printf("NCQ Autosense %s\n",
1617 parm->satasupport & ATA_SUPPORT_NCQ_AUTOSENSE ?
1622 printf("SMART %s %s\n",
1623 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1624 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1625 printf("security %s %s\n",
1626 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1627 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1628 printf("power management %s %s\n",
1629 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1630 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1631 printf("microcode download %s %s\n",
1632 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1633 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1634 printf("advanced power management %s %s",
1635 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1636 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1637 if (parm->support.command2 & ATA_SUPPORT_APM) {
1638 printf(" %d/0x%02X\n",
1639 parm->apm_value & 0xff, parm->apm_value & 0xff);
1642 printf("automatic acoustic management %s %s",
1643 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1644 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1645 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1646 printf(" %d/0x%02X %d/0x%02X\n",
1647 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1648 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1649 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1650 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1653 printf("media status notification %s %s\n",
1654 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1655 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1656 printf("power-up in Standby %s %s\n",
1657 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1658 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1659 printf("write-read-verify %s %s",
1660 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1661 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1662 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1663 printf(" %d/0x%x\n",
1664 parm->wrv_mode, parm->wrv_mode);
1667 printf("unload %s %s\n",
1668 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1669 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1670 printf("general purpose logging %s %s\n",
1671 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1672 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1673 printf("free-fall %s %s\n",
1674 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1675 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1676 printf("sense data reporting %s %s\n",
1677 parm->support2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no",
1678 parm->enabled2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no");
1679 printf("extended power conditions %s %s\n",
1680 parm->support2 & ATA_SUPPORT_EPC ? "yes" : "no",
1681 parm->enabled2 & ATA_SUPPORT_EPC ? "yes" : "no");
1682 printf("device statistics notification %s %s\n",
1683 parm->support2 & ATA_SUPPORT_DSN ? "yes" : "no",
1684 parm->enabled2 & ATA_SUPPORT_DSN ? "yes" : "no");
1685 printf("Data Set Management (DSM/TRIM) ");
1686 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1688 printf("DSM - max 512byte blocks ");
1689 if (parm->max_dsm_blocks == 0x00)
1690 printf("yes not specified\n");
1693 parm->max_dsm_blocks);
1695 printf("DSM - deterministic read ");
1696 if (parm->support3 & ATA_SUPPORT_DRAT) {
1697 if (parm->support3 & ATA_SUPPORT_RZAT)
1698 printf("yes zeroed\n");
1700 printf("yes any value\n");
1707 printf("Trusted Computing %s\n",
1708 ((parm->tcg & 0xc000) == 0x4000) && (parm->tcg & ATA_SUPPORT_TCG) ?
1710 printf("encrypts all user data %s\n",
1711 parm->support3 & ATA_ENCRYPTS_ALL_USER_DATA ? "yes" : "no");
1712 printf("Sanitize ");
1713 if (parm->multi & ATA_SUPPORT_SANITIZE) {
1714 printf("yes\t\t%s%s%s\n",
1715 parm->multi & ATA_SUPPORT_BLOCK_ERASE_EXT ? "block, " : "",
1716 parm->multi & ATA_SUPPORT_OVERWRITE_EXT ? "overwrite, " : "",
1717 parm->multi & ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT ? "crypto" : "");
1718 printf("Sanitize - commands allowed %s\n",
1719 parm->multi & ATA_SUPPORT_SANITIZE_ALLOWED ? "yes" : "no");
1720 printf("Sanitize - antifreeze lock %s\n",
1721 parm->multi & ATA_SUPPORT_ANTIFREEZE_LOCK_EXT ? "yes" : "no");
1728 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb)
1730 struct ata_pass_16 *ata_pass_16;
1731 struct ata_cmd ata_cmd;
1733 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1734 ata_cmd.command = ata_pass_16->command;
1735 ata_cmd.control = ata_pass_16->control;
1736 ata_cmd.features = ata_pass_16->features;
1738 if (arglist & CAM_ARG_VERBOSE) {
1739 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1740 ata_op_string(&ata_cmd),
1741 ccb->csio.ccb_h.timeout);
1744 /* Disable freezing the device queue */
1745 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1747 if (arglist & CAM_ARG_ERR_RECOVER)
1748 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1750 if (cam_send_ccb(device, ccb) < 0) {
1751 warn("error sending ATA %s via pass_16", ata_op_string(&ata_cmd));
1756 * Consider any non-CAM_REQ_CMP status as error and report it here,
1757 * unless caller set AP_FLAG_CHK_COND, in which case it is responsible.
1759 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1760 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1761 warnx("ATA %s via pass_16 failed", ata_op_string(&ata_cmd));
1762 if (arglist & CAM_ARG_VERBOSE) {
1763 cam_error_print(device, ccb, CAM_ESF_ALL,
1764 CAM_EPF_ALL, stderr);
1774 ata_cam_send(struct cam_device *device, union ccb *ccb)
1776 if (arglist & CAM_ARG_VERBOSE) {
1777 warnx("sending ATA %s with timeout of %u msecs",
1778 ata_op_string(&(ccb->ataio.cmd)),
1779 ccb->ataio.ccb_h.timeout);
1782 /* Disable freezing the device queue */
1783 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1785 if (arglist & CAM_ARG_ERR_RECOVER)
1786 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1788 if (cam_send_ccb(device, ccb) < 0) {
1789 warn("error sending ATA %s", ata_op_string(&(ccb->ataio.cmd)));
1794 * Consider any non-CAM_REQ_CMP status as error and report it here,
1795 * unless caller set AP_FLAG_CHK_COND, in which case it is responsible.
1797 if (!(ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT) &&
1798 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1799 warnx("ATA %s failed", ata_op_string(&(ccb->ataio.cmd)));
1800 if (arglist & CAM_ARG_VERBOSE) {
1801 cam_error_print(device, ccb, CAM_ESF_ALL,
1802 CAM_EPF_ALL, stderr);
1811 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1812 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1813 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1814 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1815 u_int16_t dxfer_len, int timeout)
1817 if (data_ptr != NULL) {
1818 if (flags & CAM_DIR_OUT)
1819 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1821 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1823 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1826 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1828 scsi_ata_pass_16(&ccb->csio,
1842 /*sense_len*/SSD_FULL_SIZE,
1845 return scsi_cam_pass_16_send(device, ccb);
1849 ata_try_pass_16(struct cam_device *device)
1851 struct ccb_pathinq cpi;
1853 if (get_cpi(device, &cpi) != 0) {
1854 warnx("couldn't get CPI");
1858 if (cpi.protocol == PROTO_SCSI) {
1859 /* possibly compatible with pass_16 */
1863 /* likely not compatible with pass_16 */
1868 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1869 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1870 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1871 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1872 u_int16_t dxfer_len, int timeout, int force48bit)
1876 retval = ata_try_pass_16(device);
1881 return (ata_do_pass_16(device, ccb, retries, flags, protocol,
1882 ata_flags, tag_action, command, features,
1883 lba, sector_count, data_ptr, dxfer_len,
1887 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1888 cam_fill_ataio(&ccb->ataio,
1897 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1898 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1900 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1902 if (ata_flags & AP_FLAG_CHK_COND)
1903 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1905 return ata_cam_send(device, ccb);
1909 dump_data(uint16_t *ptr, uint32_t len)
1913 for (i = 0; i < len / 2; i++) {
1915 printf(" %3d: ", i);
1916 printf("%04hx ", ptr[i]);
1925 atahpa_proc_resp(struct cam_device *device, union ccb *ccb, u_int64_t *hpasize)
1927 uint8_t error = 0, ata_device = 0, status = 0;
1932 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
1935 if (arglist & CAM_ARG_VERBOSE) {
1936 cam_error_print(device, ccb, CAM_ESF_ALL,
1937 CAM_EPF_ALL, stderr);
1939 warnx("Can't get ATA command status");
1943 if (status & ATA_STATUS_ERROR) {
1944 if (arglist & CAM_ARG_VERBOSE) {
1945 cam_error_print(device, ccb, CAM_ESF_ALL,
1946 CAM_EPF_ALL, stderr);
1949 if (error & ATA_ERROR_ID_NOT_FOUND) {
1950 warnx("Max address has already been set since "
1951 "last power-on or hardware reset");
1952 } else if (hpasize == NULL)
1953 warnx("Command failed with ATA error");
1958 if (hpasize != NULL) {
1959 if (retval == 2 || retval == 6)
1968 ata_read_native_max(struct cam_device *device, int retry_count,
1969 u_int32_t timeout, union ccb *ccb,
1970 struct ata_params *parm, u_int64_t *hpasize)
1976 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1977 protocol = AP_PROTO_NON_DATA;
1980 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1981 protocol |= AP_EXTEND;
1983 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1986 error = ata_do_cmd(device,
1989 /*flags*/CAM_DIR_NONE,
1990 /*protocol*/protocol,
1991 /*ata_flags*/AP_FLAG_CHK_COND,
1992 /*tag_action*/MSG_SIMPLE_Q_TAG,
1999 timeout ? timeout : 5000,
2005 return atahpa_proc_resp(device, ccb, hpasize);
2009 atahpa_set_max(struct cam_device *device, int retry_count,
2010 u_int32_t timeout, union ccb *ccb,
2011 int is48bit, u_int64_t maxsize, int persist)
2017 protocol = AP_PROTO_NON_DATA;
2020 cmd = ATA_SET_MAX_ADDRESS48;
2021 protocol |= AP_EXTEND;
2023 cmd = ATA_SET_MAX_ADDRESS;
2026 /* lba's are zero indexed so the max lba is requested max - 1 */
2030 error = ata_do_cmd(device,
2033 /*flags*/CAM_DIR_NONE,
2034 /*protocol*/protocol,
2035 /*ata_flags*/AP_FLAG_CHK_COND,
2036 /*tag_action*/MSG_SIMPLE_Q_TAG,
2038 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2040 /*sector_count*/persist,
2043 timeout ? timeout : 1000,
2049 return atahpa_proc_resp(device, ccb, NULL);
2053 atahpa_password(struct cam_device *device, int retry_count,
2054 u_int32_t timeout, union ccb *ccb,
2055 int is48bit, struct ata_set_max_pwd *pwd)
2060 protocol = AP_PROTO_PIO_OUT;
2061 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2063 return (ata_do_cmd(device,
2066 /*flags*/CAM_DIR_OUT,
2067 /*protocol*/protocol,
2068 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2069 AP_FLAG_TLEN_SECT_CNT,
2070 /*tag_action*/MSG_SIMPLE_Q_TAG,
2072 /*features*/ATA_HPA_FEAT_SET_PWD,
2074 /*sector_count*/sizeof(*pwd) / 512,
2075 /*data_ptr*/(u_int8_t*)pwd,
2076 /*dxfer_len*/sizeof(*pwd),
2077 timeout ? timeout : 1000,
2082 atahpa_lock(struct cam_device *device, int retry_count,
2083 u_int32_t timeout, union ccb *ccb, int is48bit)
2088 protocol = AP_PROTO_NON_DATA;
2089 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2091 return (ata_do_cmd(device,
2094 /*flags*/CAM_DIR_NONE,
2095 /*protocol*/protocol,
2097 /*tag_action*/MSG_SIMPLE_Q_TAG,
2099 /*features*/ATA_HPA_FEAT_LOCK,
2104 timeout ? timeout : 1000,
2109 atahpa_unlock(struct cam_device *device, int retry_count,
2110 u_int32_t timeout, union ccb *ccb,
2111 int is48bit, struct ata_set_max_pwd *pwd)
2116 protocol = AP_PROTO_PIO_OUT;
2117 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2119 return (ata_do_cmd(device,
2122 /*flags*/CAM_DIR_OUT,
2123 /*protocol*/protocol,
2124 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2125 AP_FLAG_TLEN_SECT_CNT,
2126 /*tag_action*/MSG_SIMPLE_Q_TAG,
2128 /*features*/ATA_HPA_FEAT_UNLOCK,
2130 /*sector_count*/sizeof(*pwd) / 512,
2131 /*data_ptr*/(u_int8_t*)pwd,
2132 /*dxfer_len*/sizeof(*pwd),
2133 timeout ? timeout : 1000,
2138 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2139 u_int32_t timeout, union ccb *ccb, int is48bit)
2144 protocol = AP_PROTO_NON_DATA;
2145 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2147 return (ata_do_cmd(device,
2150 /*flags*/CAM_DIR_NONE,
2151 /*protocol*/protocol,
2153 /*tag_action*/MSG_SIMPLE_Q_TAG,
2155 /*features*/ATA_HPA_FEAT_FREEZE,
2160 timeout ? timeout : 1000,
2165 ata_get_native_max(struct cam_device *device, int retry_count,
2166 u_int32_t timeout, union ccb *ccb,
2167 u_int64_t *nativesize)
2171 error = ata_do_cmd(device,
2174 /*flags*/CAM_DIR_NONE,
2175 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2176 /*ata_flags*/AP_FLAG_CHK_COND,
2177 /*tag_action*/MSG_SIMPLE_Q_TAG,
2178 /*command*/ATA_AMAX_ADDR,
2179 /*features*/ATA_AMAX_ADDR_GET,
2184 timeout ? timeout : 30 * 1000,
2190 return atahpa_proc_resp(device, ccb, nativesize);
2194 ataama_set(struct cam_device *device, int retry_count,
2195 u_int32_t timeout, union ccb *ccb, u_int64_t maxsize)
2199 /* lba's are zero indexed so the max lba is requested max - 1 */
2203 error = ata_do_cmd(device,
2206 /*flags*/CAM_DIR_NONE,
2207 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2208 /*ata_flags*/AP_FLAG_CHK_COND,
2209 /*tag_action*/MSG_SIMPLE_Q_TAG,
2210 /*command*/ATA_AMAX_ADDR,
2211 /*features*/ATA_AMAX_ADDR_SET,
2216 timeout ? timeout : 30 * 1000,
2222 return atahpa_proc_resp(device, ccb, NULL);
2226 ataama_freeze(struct cam_device *device, int retry_count,
2227 u_int32_t timeout, union ccb *ccb)
2230 return (ata_do_cmd(device,
2233 /*flags*/CAM_DIR_NONE,
2234 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2236 /*tag_action*/MSG_SIMPLE_Q_TAG,
2237 /*command*/ATA_AMAX_ADDR,
2238 /*features*/ATA_AMAX_ADDR_FREEZE,
2243 timeout ? timeout : 30 * 1000,
2248 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2249 union ccb *ccb, struct ata_params** ident_bufp)
2251 struct ata_params *ident_buf;
2252 struct ccb_pathinq cpi;
2253 struct ccb_getdev cgd;
2256 u_int8_t command, retry_command;
2258 if (get_cpi(device, &cpi) != 0) {
2259 warnx("couldn't get CPI");
2263 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2264 if (cpi.protocol == PROTO_ATA) {
2265 if (get_cgd(device, &cgd) != 0) {
2266 warnx("couldn't get CGD");
2270 command = (cgd.protocol == PROTO_ATA) ?
2271 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2274 /* We don't know which for sure so try both */
2275 command = ATA_ATA_IDENTIFY;
2276 retry_command = ATA_ATAPI_IDENTIFY;
2279 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2281 warnx("can't calloc memory for identify\n");
2286 error = ata_do_cmd(device,
2288 /*retries*/retry_count,
2289 /*flags*/CAM_DIR_IN,
2290 /*protocol*/AP_PROTO_PIO_IN,
2291 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2292 AP_FLAG_TLEN_SECT_CNT,
2293 /*tag_action*/MSG_SIMPLE_Q_TAG,
2297 /*sector_count*/sizeof(struct ata_params) / 512,
2298 /*data_ptr*/(u_int8_t *)ptr,
2299 /*dxfer_len*/sizeof(struct ata_params),
2300 /*timeout*/timeout ? timeout : 30 * 1000,
2304 if (retry_command != 0) {
2305 command = retry_command;
2313 ident_buf = (struct ata_params *)ptr;
2314 ata_param_fixup(ident_buf);
2317 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2322 /* check for invalid (all zero) response */
2324 warnx("Invalid identify response detected");
2329 *ident_bufp = ident_buf;
2336 ataidentify(struct cam_device *device, int retry_count, int timeout)
2339 struct ata_params *ident_buf;
2340 u_int64_t hpasize = 0, nativesize = 0;
2342 if ((ccb = cam_getccb(device)) == NULL) {
2343 warnx("couldn't allocate CCB");
2347 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2352 if (arglist & CAM_ARG_VERBOSE) {
2353 printf("%s%d: Raw identify data:\n",
2354 device->device_name, device->dev_unit_num);
2355 dump_data((uint16_t *)ident_buf, sizeof(struct ata_params));
2358 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2359 ata_read_native_max(device, retry_count, timeout, ccb,
2360 ident_buf, &hpasize);
2362 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2363 ata_get_native_max(device, retry_count, timeout, ccb,
2367 printf("%s%d: ", device->device_name, device->dev_unit_num);
2368 ata_print_ident(ident_buf);
2369 camxferrate(device);
2370 atacapprint(ident_buf);
2371 atahpa_print(ident_buf, hpasize, 0);
2372 ataama_print(ident_buf, nativesize, 0);
2382 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2384 struct nvme_controller_data cdata;
2386 if (nvme_get_cdata(device, &cdata))
2388 nvme_print_controller(&cdata);
2395 identify(struct cam_device *device, int retry_count, int timeout)
2398 struct ccb_pathinq cpi;
2400 if (get_cpi(device, &cpi) != 0) {
2401 warnx("couldn't get CPI");
2405 if (cpi.protocol == PROTO_NVME) {
2406 return (nvmeidentify(device, retry_count, timeout));
2409 return (ataidentify(device, retry_count, timeout));
2414 ATA_SECURITY_ACTION_PRINT,
2415 ATA_SECURITY_ACTION_FREEZE,
2416 ATA_SECURITY_ACTION_UNLOCK,
2417 ATA_SECURITY_ACTION_DISABLE,
2418 ATA_SECURITY_ACTION_ERASE,
2419 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2420 ATA_SECURITY_ACTION_SET_PASSWORD
2424 atasecurity_print_time(u_int16_t tw)
2428 printf("unspecified");
2430 printf("> 508 min");
2432 printf("%i min", 2 * tw);
2436 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2440 return 2 * 3600 * 1000; /* default: two hours */
2441 else if (timeout > 255)
2442 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2444 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2449 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2453 bzero(&cmd, sizeof(cmd));
2454 cmd.command = command;
2455 printf("Issuing %s", ata_op_string(&cmd));
2458 /* pwd->password may not be null terminated */
2459 char pass[sizeof(pwd->password)+1];
2461 strlcpy(pass, pwd->password, sizeof(pass));
2462 printf(" password='%s', user='%s'",
2464 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2467 if (command == ATA_SECURITY_SET_PASSWORD) {
2468 printf(", mode='%s'",
2469 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2470 "maximum" : "high");
2478 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2479 int retry_count, u_int32_t timeout, int quiet)
2483 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2485 return ata_do_cmd(device,
2488 /*flags*/CAM_DIR_NONE,
2489 /*protocol*/AP_PROTO_NON_DATA,
2491 /*tag_action*/MSG_SIMPLE_Q_TAG,
2492 /*command*/ATA_SECURITY_FREEZE_LOCK,
2503 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2504 int retry_count, u_int32_t timeout,
2505 struct ata_security_password *pwd, int quiet)
2509 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2511 return ata_do_cmd(device,
2514 /*flags*/CAM_DIR_OUT,
2515 /*protocol*/AP_PROTO_PIO_OUT,
2516 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2517 AP_FLAG_TLEN_SECT_CNT,
2518 /*tag_action*/MSG_SIMPLE_Q_TAG,
2519 /*command*/ATA_SECURITY_UNLOCK,
2522 /*sector_count*/sizeof(*pwd) / 512,
2523 /*data_ptr*/(u_int8_t *)pwd,
2524 /*dxfer_len*/sizeof(*pwd),
2530 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2531 int retry_count, u_int32_t timeout,
2532 struct ata_security_password *pwd, int quiet)
2536 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2537 return ata_do_cmd(device,
2540 /*flags*/CAM_DIR_OUT,
2541 /*protocol*/AP_PROTO_PIO_OUT,
2542 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2543 AP_FLAG_TLEN_SECT_CNT,
2544 /*tag_action*/MSG_SIMPLE_Q_TAG,
2545 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2548 /*sector_count*/sizeof(*pwd) / 512,
2549 /*data_ptr*/(u_int8_t *)pwd,
2550 /*dxfer_len*/sizeof(*pwd),
2557 atasecurity_erase_confirm(struct cam_device *device,
2558 struct ata_params* ident_buf)
2561 printf("\nYou are about to ERASE ALL DATA from the following"
2562 " device:\n%s%d,%s%d: ", device->device_name,
2563 device->dev_unit_num, device->given_dev_name,
2564 device->given_unit_number);
2565 ata_print_ident(ident_buf);
2569 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2571 if (fgets(str, sizeof(str), stdin) != NULL) {
2572 if (strncasecmp(str, "yes", 3) == 0) {
2574 } else if (strncasecmp(str, "no", 2) == 0) {
2577 printf("Please answer \"yes\" or "
2588 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2589 int retry_count, u_int32_t timeout,
2590 u_int32_t erase_timeout,
2591 struct ata_security_password *pwd, int quiet)
2596 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2598 error = ata_do_cmd(device,
2601 /*flags*/CAM_DIR_NONE,
2602 /*protocol*/AP_PROTO_NON_DATA,
2604 /*tag_action*/MSG_SIMPLE_Q_TAG,
2605 /*command*/ATA_SECURITY_ERASE_PREPARE,
2618 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2620 error = ata_do_cmd(device,
2623 /*flags*/CAM_DIR_OUT,
2624 /*protocol*/AP_PROTO_PIO_OUT,
2625 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2626 AP_FLAG_TLEN_SECT_CNT,
2627 /*tag_action*/MSG_SIMPLE_Q_TAG,
2628 /*command*/ATA_SECURITY_ERASE_UNIT,
2631 /*sector_count*/sizeof(*pwd) / 512,
2632 /*data_ptr*/(u_int8_t *)pwd,
2633 /*dxfer_len*/sizeof(*pwd),
2634 /*timeout*/erase_timeout,
2637 if (error == 0 && quiet == 0)
2638 printf("\nErase Complete\n");
2644 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2645 int retry_count, u_int32_t timeout,
2646 struct ata_security_password *pwd, int quiet)
2650 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2652 return ata_do_cmd(device,
2655 /*flags*/CAM_DIR_OUT,
2656 /*protocol*/AP_PROTO_PIO_OUT,
2657 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2658 AP_FLAG_TLEN_SECT_CNT,
2659 /*tag_action*/MSG_SIMPLE_Q_TAG,
2660 /*command*/ATA_SECURITY_SET_PASSWORD,
2663 /*sector_count*/sizeof(*pwd) / 512,
2664 /*data_ptr*/(u_int8_t *)pwd,
2665 /*dxfer_len*/sizeof(*pwd),
2671 atasecurity_print(struct ata_params *parm)
2674 printf("\nSecurity Option Value\n");
2675 if (arglist & CAM_ARG_VERBOSE) {
2676 printf("status %04x\n",
2677 parm->security_status);
2679 printf("supported %s\n",
2680 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2681 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2683 printf("enabled %s\n",
2684 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2685 printf("drive locked %s\n",
2686 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2687 printf("security config frozen %s\n",
2688 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2689 printf("count expired %s\n",
2690 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2691 printf("security level %s\n",
2692 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2693 printf("enhanced erase supported %s\n",
2694 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2695 printf("erase time ");
2696 atasecurity_print_time(parm->erase_time);
2698 printf("enhanced erase time ");
2699 atasecurity_print_time(parm->enhanced_erase_time);
2701 printf("master password rev %04x%s\n",
2702 parm->master_passwd_revision,
2703 parm->master_passwd_revision == 0x0000 ||
2704 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2708 * Validates and copies the password in optarg to the passed buffer.
2709 * If the password in optarg is the same length as the buffer then
2710 * the data will still be copied but no null termination will occur.
2713 ata_getpwd(u_int8_t *passwd, int max, char opt)
2717 len = strlen(optarg);
2719 warnx("-%c password is too long", opt);
2721 } else if (len == 0) {
2722 warnx("-%c password is missing", opt);
2724 } else if (optarg[0] == '-'){
2725 warnx("-%c password starts with '-' (generic arg?)", opt);
2727 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2728 warnx("-%c password conflicts with existing password from -%c",
2733 /* Callers pass in a buffer which does NOT need to be terminated */
2734 strncpy(passwd, optarg, max);
2741 ATA_HPA_ACTION_PRINT,
2742 ATA_HPA_ACTION_SET_MAX,
2743 ATA_HPA_ACTION_SET_PWD,
2744 ATA_HPA_ACTION_LOCK,
2745 ATA_HPA_ACTION_UNLOCK,
2746 ATA_HPA_ACTION_FREEZE_LOCK
2750 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2751 u_int64_t maxsize, int persist)
2753 printf("\nYou are about to configure HPA to limit the user accessible\n"
2754 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2755 persist ? "persistently" : "temporarily",
2756 device->device_name, device->dev_unit_num,
2757 device->given_dev_name, device->given_unit_number);
2758 ata_print_ident(ident_buf);
2762 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2764 if (NULL != fgets(str, sizeof(str), stdin)) {
2765 if (0 == strncasecmp(str, "yes", 3)) {
2767 } else if (0 == strncasecmp(str, "no", 2)) {
2770 printf("Please answer \"yes\" or "
2781 atahpa(struct cam_device *device, int retry_count, int timeout,
2782 int argc, char **argv, char *combinedopt)
2785 struct ata_params *ident_buf;
2786 struct ccb_getdev cgd;
2787 struct ata_set_max_pwd pwd;
2788 int error, confirm, quiet, c, action, actions, persist;
2789 int security, is48bit, pwdsize;
2790 u_int64_t hpasize, maxsize;
2799 memset(&pwd, 0, sizeof(pwd));
2801 /* default action is to print hpa information */
2802 action = ATA_HPA_ACTION_PRINT;
2803 pwdsize = sizeof(pwd.password);
2805 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2808 action = ATA_HPA_ACTION_SET_MAX;
2809 maxsize = strtoumax(optarg, NULL, 0);
2814 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2816 action = ATA_HPA_ACTION_SET_PWD;
2822 action = ATA_HPA_ACTION_LOCK;
2828 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2830 action = ATA_HPA_ACTION_UNLOCK;
2836 action = ATA_HPA_ACTION_FREEZE_LOCK;
2856 warnx("too many hpa actions specified");
2860 if (get_cgd(device, &cgd) != 0) {
2861 warnx("couldn't get CGD");
2865 ccb = cam_getccb(device);
2867 warnx("couldn't allocate CCB");
2871 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2878 printf("%s%d: ", device->device_name, device->dev_unit_num);
2879 ata_print_ident(ident_buf);
2880 camxferrate(device);
2883 if (action == ATA_HPA_ACTION_PRINT) {
2885 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2886 ata_read_native_max(device, retry_count, timeout, ccb,
2887 ident_buf, &hpasize);
2888 atahpa_print(ident_buf, hpasize, 1);
2895 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2896 warnx("HPA is not supported by this device");
2902 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
2903 warnx("HPA Security is not supported by this device");
2909 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2912 * The ATA spec requires:
2913 * 1. Read native max addr is called directly before set max addr
2914 * 2. Read native max addr is NOT called before any other set max call
2917 case ATA_HPA_ACTION_SET_MAX:
2919 atahpa_set_confirm(device, ident_buf, maxsize,
2926 error = ata_read_native_max(device, retry_count, timeout,
2927 ccb, ident_buf, &hpasize);
2929 error = atahpa_set_max(device, retry_count, timeout,
2930 ccb, is48bit, maxsize, persist);
2933 /* redo identify to get new values */
2934 error = ata_do_identify(device,
2935 retry_count, timeout, ccb,
2937 atahpa_print(ident_buf, hpasize, 1);
2939 /* Hint CAM to reprobe the device. */
2945 case ATA_HPA_ACTION_SET_PWD:
2946 error = atahpa_password(device, retry_count, timeout,
2947 ccb, is48bit, &pwd);
2948 if (error == 0 && quiet == 0)
2949 printf("HPA password has been set\n");
2952 case ATA_HPA_ACTION_LOCK:
2953 error = atahpa_lock(device, retry_count, timeout,
2955 if (error == 0 && quiet == 0)
2956 printf("HPA has been locked\n");
2959 case ATA_HPA_ACTION_UNLOCK:
2960 error = atahpa_unlock(device, retry_count, timeout,
2961 ccb, is48bit, &pwd);
2962 if (error == 0 && quiet == 0)
2963 printf("HPA has been unlocked\n");
2966 case ATA_HPA_ACTION_FREEZE_LOCK:
2967 error = atahpa_freeze_lock(device, retry_count, timeout,
2969 if (error == 0 && quiet == 0)
2970 printf("HPA has been frozen\n");
2974 errx(1, "Option currently not supported");
2984 ATA_AMA_ACTION_PRINT,
2985 ATA_AMA_ACTION_SET_MAX,
2986 ATA_AMA_ACTION_FREEZE_LOCK
2990 ataama(struct cam_device *device, int retry_count, int timeout,
2991 int argc, char **argv, char *combinedopt)
2994 struct ata_params *ident_buf;
2995 struct ccb_getdev cgd;
2996 int error, quiet, c, action, actions;
2997 u_int64_t nativesize, maxsize;
3003 /* default action is to print AMA information */
3004 action = ATA_AMA_ACTION_PRINT;
3006 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3009 action = ATA_AMA_ACTION_SET_MAX;
3010 maxsize = strtoumax(optarg, NULL, 0);
3015 action = ATA_AMA_ACTION_FREEZE_LOCK;
3026 warnx("too many AMA actions specified");
3030 if (get_cgd(device, &cgd) != 0) {
3031 warnx("couldn't get CGD");
3035 ccb = cam_getccb(device);
3037 warnx("couldn't allocate CCB");
3041 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3048 printf("%s%d: ", device->device_name, device->dev_unit_num);
3049 ata_print_ident(ident_buf);
3050 camxferrate(device);
3053 if (action == ATA_AMA_ACTION_PRINT) {
3055 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3056 ata_get_native_max(device, retry_count, timeout, ccb,
3058 ataama_print(ident_buf, nativesize, 1);
3065 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3066 warnx("Accessible Max Address is not supported by this device");
3073 case ATA_AMA_ACTION_SET_MAX:
3074 error = ata_get_native_max(device, retry_count, timeout, ccb,
3077 error = ataama_set(device, retry_count, timeout,
3081 /* redo identify to get new values */
3082 error = ata_do_identify(device,
3083 retry_count, timeout, ccb,
3085 ataama_print(ident_buf, nativesize, 1);
3087 /* Hint CAM to reprobe the device. */
3093 case ATA_AMA_ACTION_FREEZE_LOCK:
3094 error = ataama_freeze(device, retry_count, timeout,
3096 if (error == 0 && quiet == 0)
3097 printf("Accessible Max Address has been frozen\n");
3101 errx(1, "Option currently not supported");
3111 atasecurity(struct cam_device *device, int retry_count, int timeout,
3112 int argc, char **argv, char *combinedopt)
3115 struct ata_params *ident_buf;
3116 int error, confirm, quiet, c, action, actions, setpwd;
3117 int security_enabled, erase_timeout, pwdsize;
3118 struct ata_security_password pwd;
3126 memset(&pwd, 0, sizeof(pwd));
3128 /* default action is to print security information */
3129 action = ATA_SECURITY_ACTION_PRINT;
3131 /* user is master by default as its safer that way */
3132 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3133 pwdsize = sizeof(pwd.password);
3135 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3138 action = ATA_SECURITY_ACTION_FREEZE;
3143 if (strcasecmp(optarg, "user") == 0) {
3144 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3145 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3146 } else if (strcasecmp(optarg, "master") == 0) {
3147 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3148 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3150 warnx("-U argument '%s' is invalid (must be "
3151 "'user' or 'master')", optarg);
3157 if (strcasecmp(optarg, "high") == 0) {
3158 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3159 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3160 } else if (strcasecmp(optarg, "maximum") == 0) {
3161 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3162 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3164 warnx("-l argument '%s' is unknown (must be "
3165 "'high' or 'maximum')", optarg);
3171 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3173 action = ATA_SECURITY_ACTION_UNLOCK;
3178 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3180 action = ATA_SECURITY_ACTION_DISABLE;
3185 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3187 action = ATA_SECURITY_ACTION_ERASE;
3192 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3194 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3195 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3200 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3203 if (action == ATA_SECURITY_ACTION_PRINT)
3204 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3206 * Don't increment action as this can be combined
3207 * with other actions.
3220 erase_timeout = atoi(optarg) * 1000;
3226 warnx("too many security actions specified");
3230 if ((ccb = cam_getccb(device)) == NULL) {
3231 warnx("couldn't allocate CCB");
3235 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3242 printf("%s%d: ", device->device_name, device->dev_unit_num);
3243 ata_print_ident(ident_buf);
3244 camxferrate(device);
3247 if (action == ATA_SECURITY_ACTION_PRINT) {
3248 atasecurity_print(ident_buf);
3254 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3255 warnx("Security not supported");
3261 /* default timeout 15 seconds the same as linux hdparm */
3262 timeout = timeout ? timeout : 15 * 1000;
3264 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3266 /* first set the password if requested */
3268 /* confirm we can erase before setting the password if erasing */
3270 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3271 action == ATA_SECURITY_ACTION_ERASE) &&
3272 atasecurity_erase_confirm(device, ident_buf) == 0) {
3278 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3279 pwd.revision = ident_buf->master_passwd_revision;
3280 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3281 --pwd.revision == 0) {
3282 pwd.revision = 0xfffe;
3285 error = atasecurity_set_password(device, ccb, retry_count,
3286 timeout, &pwd, quiet);
3292 security_enabled = 1;
3296 case ATA_SECURITY_ACTION_FREEZE:
3297 error = atasecurity_freeze(device, ccb, retry_count,
3301 case ATA_SECURITY_ACTION_UNLOCK:
3302 if (security_enabled) {
3303 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3304 error = atasecurity_unlock(device, ccb,
3305 retry_count, timeout, &pwd, quiet);
3307 warnx("Can't unlock, drive is not locked");
3311 warnx("Can't unlock, security is disabled");
3316 case ATA_SECURITY_ACTION_DISABLE:
3317 if (security_enabled) {
3318 /* First unlock the drive if its locked */
3319 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3320 error = atasecurity_unlock(device, ccb,
3328 error = atasecurity_disable(device,
3336 warnx("Can't disable security (already disabled)");
3341 case ATA_SECURITY_ACTION_ERASE:
3342 if (security_enabled) {
3343 if (erase_timeout == 0) {
3344 erase_timeout = atasecurity_erase_timeout_msecs(
3345 ident_buf->erase_time);
3348 error = atasecurity_erase(device, ccb, retry_count,
3349 timeout, erase_timeout, &pwd, quiet);
3351 warnx("Can't secure erase (security is disabled)");
3356 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3357 if (security_enabled) {
3358 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3359 if (erase_timeout == 0) {
3361 atasecurity_erase_timeout_msecs(
3362 ident_buf->enhanced_erase_time);
3365 error = atasecurity_erase(device, ccb,
3366 retry_count, timeout,
3367 erase_timeout, &pwd,
3370 warnx("Enhanced erase is not supported");
3374 warnx("Can't secure erase (enhanced), "
3375 "(security is disabled)");
3388 * Convert periph name into a bus, target and lun.
3390 * Returns the number of parsed components, or 0.
3393 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3394 cam_argmask *arglst)
3399 bzero(&ccb, sizeof(ccb));
3400 ccb.ccb_h.func_code = XPT_GDEVLIST;
3401 if (cam_get_device(tstr, ccb.cgdl.periph_name,
3402 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3403 warnx("%s", cam_errbuf);
3408 * Attempt to get the passthrough device. This ioctl will
3409 * fail if the device name is null, if the device doesn't
3410 * exist, or if the passthrough driver isn't in the kernel.
3412 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3413 warn("Unable to open %s", XPT_DEVICE);
3416 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3417 warn("Unable to find bus:target:lun for device %s%d",
3418 ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3423 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3424 const struct cam_status_entry *entry;
3426 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3427 warnx("Unable to find bus:target_lun for device %s%d, "
3428 "CAM status: %s (%#x)",
3429 ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3430 entry ? entry->status_text : "Unknown",
3436 * The kernel fills in the bus/target/lun. We don't
3437 * need the passthrough device name and unit number since
3438 * we aren't going to open it.
3440 *bus = ccb.ccb_h.path_id;
3441 *target = ccb.ccb_h.target_id;
3442 *lun = ccb.ccb_h.target_lun;
3443 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3448 * Parse out a bus, or a bus, target and lun in the following
3454 * Returns the number of parsed components, or 0.
3457 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3458 cam_argmask *arglst)
3463 *bus = CAM_BUS_WILDCARD;
3464 *target = CAM_TARGET_WILDCARD;
3465 *lun = CAM_LUN_WILDCARD;
3467 while (isspace(*tstr) && (*tstr != '\0'))
3470 if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3471 arglist |= CAM_ARG_BUS;
3475 if (!isdigit(*tstr))
3476 return (parse_btl_name(tstr, bus, target, lun, arglst));
3478 tmpstr = strsep(&tstr, ":");
3479 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3480 *bus = strtol(tmpstr, &end, 0);
3483 *arglst |= CAM_ARG_BUS;
3485 tmpstr = strsep(&tstr, ":");
3486 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3487 *target = strtol(tmpstr, &end, 0);
3490 *arglst |= CAM_ARG_TARGET;
3492 tmpstr = strsep(&tstr, ":");
3493 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3494 *lun = strtoll(tmpstr, &end, 0);
3497 *arglst |= CAM_ARG_LUN;
3507 dorescan_or_reset(int argc, char **argv, int rescan)
3509 static const char must[] =
3510 "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3512 path_id_t bus = CAM_BUS_WILDCARD;
3513 target_id_t target = CAM_TARGET_WILDCARD;
3514 lun_id_t lun = CAM_LUN_WILDCARD;
3518 warnx(must, rescan? "rescan" : "reset");
3522 tstr = argv[optind];
3523 while (isspace(*tstr) && (*tstr != '\0'))
3525 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3526 arglist |= CAM_ARG_BUS;
3528 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3529 if (rv != 1 && rv != 3) {
3530 warnx(must, rescan ? "rescan" : "reset");
3535 if (arglist & CAM_ARG_LUN)
3536 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3538 error = rescan_or_reset_bus(bus, rescan);
3544 rescan_or_reset_bus(path_id_t bus, int rescan)
3546 union ccb *ccb = NULL, *matchccb = NULL;
3547 int fd = -1, retval;
3552 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3553 warnx("error opening transport layer device %s", XPT_DEVICE);
3554 warn("%s", XPT_DEVICE);
3558 ccb = malloc(sizeof(*ccb));
3560 warn("failed to allocate CCB");
3564 bzero(ccb, sizeof(*ccb));
3566 if (bus != CAM_BUS_WILDCARD) {
3567 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3568 ccb->ccb_h.path_id = bus;
3569 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3570 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3571 ccb->crcn.flags = CAM_FLAG_NONE;
3573 /* run this at a low priority */
3574 ccb->ccb_h.pinfo.priority = 5;
3576 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3577 warn("CAMIOCOMMAND ioctl failed");
3582 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3583 fprintf(stdout, "%s of bus %d was successful\n",
3584 rescan ? "Re-scan" : "Reset", bus);
3586 fprintf(stdout, "%s of bus %d returned error %#x\n",
3587 rescan ? "Re-scan" : "Reset", bus,
3588 ccb->ccb_h.status & CAM_STATUS_MASK);
3597 * The right way to handle this is to modify the xpt so that it can
3598 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3599 * that isn't implemented, so instead we enumerate the buses and
3600 * send the rescan or reset to those buses in the case where the
3601 * given bus is -1 (wildcard). We don't send a rescan or reset
3602 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3603 * no-op, sending a rescan to the xpt bus would result in a status of
3606 matchccb = malloc(sizeof(*matchccb));
3607 if (matchccb == NULL) {
3608 warn("failed to allocate CCB");
3612 bzero(matchccb, sizeof(*matchccb));
3613 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3614 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3615 bufsize = sizeof(struct dev_match_result) * 20;
3616 matchccb->cdm.match_buf_len = bufsize;
3617 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3618 if (matchccb->cdm.matches == NULL) {
3619 warnx("can't malloc memory for matches");
3623 matchccb->cdm.num_matches = 0;
3625 matchccb->cdm.num_patterns = 1;
3626 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3628 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3629 matchccb->cdm.pattern_buf_len);
3630 if (matchccb->cdm.patterns == NULL) {
3631 warnx("can't malloc memory for patterns");
3635 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3636 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3641 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3642 warn("CAMIOCOMMAND ioctl failed");
3647 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3648 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3649 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3650 warnx("got CAM error %#x, CDM error %d\n",
3651 matchccb->ccb_h.status, matchccb->cdm.status);
3656 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3657 struct bus_match_result *bus_result;
3659 /* This shouldn't happen. */
3660 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3663 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3666 * We don't want to rescan or reset the xpt bus.
3669 if (bus_result->path_id == CAM_XPT_PATH_ID)
3672 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3674 ccb->ccb_h.path_id = bus_result->path_id;
3675 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3676 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3677 ccb->crcn.flags = CAM_FLAG_NONE;
3679 /* run this at a low priority */
3680 ccb->ccb_h.pinfo.priority = 5;
3682 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3683 warn("CAMIOCOMMAND ioctl failed");
3688 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3689 fprintf(stdout, "%s of bus %d was successful\n",
3690 rescan? "Re-scan" : "Reset",
3691 bus_result->path_id);
3694 * Don't bail out just yet, maybe the other
3695 * rescan or reset commands will complete
3698 fprintf(stderr, "%s of bus %d returned error "
3699 "%#x\n", rescan? "Re-scan" : "Reset",
3700 bus_result->path_id,
3701 ccb->ccb_h.status & CAM_STATUS_MASK);
3705 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3706 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3713 if (matchccb != NULL) {
3714 free(matchccb->cdm.patterns);
3715 free(matchccb->cdm.matches);
3724 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3727 struct cam_device *device;
3732 if (bus == CAM_BUS_WILDCARD) {
3733 warnx("invalid bus number %d", bus);
3737 if (target == CAM_TARGET_WILDCARD) {
3738 warnx("invalid target number %d", target);
3742 if (lun == CAM_LUN_WILDCARD) {
3743 warnx("invalid lun number %jx", (uintmax_t)lun);
3749 bzero(&ccb, sizeof(union ccb));
3752 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3753 warnx("error opening transport layer device %s\n",
3755 warn("%s", XPT_DEVICE);
3759 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3760 if (device == NULL) {
3761 warnx("%s", cam_errbuf);
3766 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3767 ccb.ccb_h.path_id = bus;
3768 ccb.ccb_h.target_id = target;
3769 ccb.ccb_h.target_lun = lun;
3770 ccb.ccb_h.timeout = 5000;
3771 ccb.crcn.flags = CAM_FLAG_NONE;
3773 /* run this at a low priority */
3774 ccb.ccb_h.pinfo.priority = 5;
3777 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3778 warn("CAMIOCOMMAND ioctl failed");
3783 if (cam_send_ccb(device, &ccb) < 0) {
3784 warn("error sending XPT_RESET_DEV CCB");
3785 cam_close_device(device);
3793 cam_close_device(device);
3796 * An error code of CAM_BDR_SENT is normal for a BDR request.
3798 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3800 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3801 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3802 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3805 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3806 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3807 ccb.ccb_h.status & CAM_STATUS_MASK);
3813 static struct scsi_nv defect_list_type_map[] = {
3814 { "block", SRDD10_BLOCK_FORMAT },
3815 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3816 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3817 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3818 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3819 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3823 readdefects(struct cam_device *device, int argc, char **argv,
3824 char *combinedopt, int task_attr, int retry_count, int timeout)
3826 union ccb *ccb = NULL;
3827 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3828 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3829 size_t hdr_size = 0, entry_size = 0;
3832 u_int8_t *defect_list = NULL;
3833 u_int8_t list_format = 0;
3834 int list_type_set = 0;
3835 u_int32_t dlist_length = 0;
3836 u_int32_t returned_length = 0, valid_len = 0;
3837 u_int32_t num_returned = 0, num_valid = 0;
3838 u_int32_t max_possible_size = 0, hdr_max = 0;
3839 u_int32_t starting_offset = 0;
3840 u_int8_t returned_format, returned_type;
3842 int summary = 0, quiet = 0;
3844 int lists_specified = 0;
3845 int get_length = 1, first_pass = 1;
3848 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3852 scsi_nv_status status;
3855 status = scsi_get_nv(defect_list_type_map,
3856 sizeof(defect_list_type_map) /
3857 sizeof(defect_list_type_map[0]), optarg,
3858 &entry_num, SCSI_NV_FLAG_IG_CASE);
3860 if (status == SCSI_NV_FOUND) {
3861 list_format = defect_list_type_map[
3865 warnx("%s: %s %s option %s", __func__,
3866 (status == SCSI_NV_AMBIGUOUS) ?
3867 "ambiguous" : "invalid", "defect list type",
3870 goto defect_bailout;
3875 arglist |= CAM_ARG_GLIST;
3878 arglist |= CAM_ARG_PLIST;
3889 starting_offset = strtoul(optarg, &endptr, 0);
3890 if (*endptr != '\0') {
3892 warnx("invalid starting offset %s", optarg);
3893 goto defect_bailout;
3905 if (list_type_set == 0) {
3907 warnx("no defect list format specified");
3908 goto defect_bailout;
3911 if (arglist & CAM_ARG_PLIST) {
3912 list_format |= SRDD10_PLIST;
3916 if (arglist & CAM_ARG_GLIST) {
3917 list_format |= SRDD10_GLIST;
3922 * This implies a summary, and was the previous behavior.
3924 if (lists_specified == 0)
3927 ccb = cam_getccb(device);
3932 * We start off asking for just the header to determine how much
3933 * defect data is available. Some Hitachi drives return an error
3934 * if you ask for more data than the drive has. Once we know the
3935 * length, we retry the command with the returned length.
3937 if (use_12byte == 0)
3938 dlist_length = sizeof(*hdr10);
3940 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;
3986 if (use_12byte == 0) {
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;
4040 if (get_length != 0) {
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)) {
4062 if ((use_12byte == 0)
4063 && (returned_length >= max_possible_size)) {
4068 dlist_length = returned_length + hdr_size;
4069 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4070 && (asc == 0x1f) && (ascq == 0x00)
4071 && (returned_length > 0)) {
4072 /* Partial defect list transfer */
4074 * Hitachi drives return this error
4075 * along with a partial defect list if they
4076 * have more defects than the 10 byte
4077 * command can support. Retry with the 12
4080 if (use_12byte == 0) {
4085 dlist_length = returned_length + hdr_size;
4086 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4087 && (asc == 0x24) && (ascq == 0x00)) {
4088 /* Invalid field in CDB */
4090 * SBC-3 says that if the drive has more
4091 * defects than can be reported with the
4092 * 10 byte command, it should return this
4093 * error and no data. Retry with the 12
4096 if (use_12byte == 0) {
4101 dlist_length = returned_length + hdr_size;
4104 * If we got a SCSI error and no valid length,
4105 * just use the 10 byte maximum. The 12
4106 * byte maximum is too large.
4108 if (returned_length == 0)
4109 dlist_length = SRDD10_MAX_LENGTH;
4111 if ((use_12byte == 0)
4112 && (returned_length >=
4113 max_possible_size)) {
4118 dlist_length = returned_length +
4122 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4125 warnx("Error reading defect header");
4126 if (arglist & CAM_ARG_VERBOSE)
4127 cam_error_print(device, ccb, CAM_ESF_ALL,
4128 CAM_EPF_ALL, stderr);
4129 goto defect_bailout;
4131 if ((use_12byte == 0)
4132 && (returned_length >= max_possible_size)) {
4137 dlist_length = returned_length + hdr_size;
4140 fprintf(stdout, "%u", num_returned);
4142 fprintf(stdout, " defect%s",
4143 (num_returned != 1) ? "s" : "");
4145 fprintf(stdout, "\n");
4147 goto defect_bailout;
4151 * We always limit the list length to the 10-byte maximum
4152 * length (0xffff). The reason is that some controllers
4153 * can't handle larger I/Os, and we can transfer the entire
4154 * 10 byte list in one shot. For drives that support the 12
4155 * byte read defects command, we'll step through the list
4156 * by specifying a starting offset. For drives that don't
4157 * support the 12 byte command's starting offset, we'll
4158 * just display the first 64K.
4160 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4166 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4167 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4168 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4169 struct scsi_sense_data *sense;
4170 int error_code, sense_key, asc, ascq;
4172 sense = &ccb->csio.sense_data;
4173 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4174 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4175 &ascq, /*show_errors*/ 1);
4178 * According to the SCSI spec, if the disk doesn't support
4179 * the requested format, it will generally return a sense
4180 * key of RECOVERED ERROR, and an additional sense code
4181 * of "DEFECT LIST NOT FOUND". HGST drives also return
4182 * Primary/Grown defect list not found errors. So just
4183 * check for an ASC of 0x1c.
4185 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4187 const char *format_str;
4189 format_str = scsi_nv_to_str(defect_list_type_map,
4190 sizeof(defect_list_type_map) /
4191 sizeof(defect_list_type_map[0]),
4192 list_format & SRDD10_DLIST_FORMAT_MASK);
4193 warnx("requested defect format %s not available",
4194 format_str ? format_str : "unknown");
4196 format_str = scsi_nv_to_str(defect_list_type_map,
4197 sizeof(defect_list_type_map) /
4198 sizeof(defect_list_type_map[0]), returned_type);
4199 if (format_str != NULL) {
4200 warnx("Device returned %s format",
4204 warnx("Device returned unknown defect"
4205 " data format %#x", returned_type);
4206 goto defect_bailout;
4210 warnx("Error returned from read defect data command");
4211 if (arglist & CAM_ARG_VERBOSE)
4212 cam_error_print(device, ccb, CAM_ESF_ALL,
4213 CAM_EPF_ALL, stderr);
4214 goto defect_bailout;
4216 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4218 warnx("Error returned from read defect data command");
4219 if (arglist & CAM_ARG_VERBOSE)
4220 cam_error_print(device, ccb, CAM_ESF_ALL,
4221 CAM_EPF_ALL, stderr);
4222 goto defect_bailout;
4225 if (first_pass != 0) {
4226 fprintf(stderr, "Got %d defect", num_returned);
4228 if ((lists_specified == 0) || (num_returned == 0)) {
4229 fprintf(stderr, "s.\n");
4230 goto defect_bailout;
4231 } else if (num_returned == 1)
4232 fprintf(stderr, ":\n");
4234 fprintf(stderr, "s:\n");
4240 * XXX KDM I should probably clean up the printout format for the
4243 switch (returned_type) {
4244 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4245 case SRDD10_EXT_PHYS_FORMAT:
4247 struct scsi_defect_desc_phys_sector *dlist;
4249 dlist = (struct scsi_defect_desc_phys_sector *)
4250 (defect_list + hdr_size);
4252 for (i = 0; i < num_valid; i++) {
4255 sector = scsi_4btoul(dlist[i].sector);
4256 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4257 mads = (sector & SDD_EXT_PHYS_MADS) ?
4259 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4261 if (hex_format == 0)
4262 fprintf(stdout, "%d:%d:%d%s",
4263 scsi_3btoul(dlist[i].cylinder),
4265 scsi_4btoul(dlist[i].sector),
4266 mads ? " - " : "\n");
4268 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4269 scsi_3btoul(dlist[i].cylinder),
4271 scsi_4btoul(dlist[i].sector),
4272 mads ? " - " : "\n");
4275 if (num_valid < num_returned) {
4276 starting_offset += num_valid;
4281 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4282 case SRDD10_EXT_BFI_FORMAT:
4284 struct scsi_defect_desc_bytes_from_index *dlist;
4286 dlist = (struct scsi_defect_desc_bytes_from_index *)
4287 (defect_list + hdr_size);
4289 for (i = 0; i < num_valid; i++) {
4292 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4293 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4294 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4295 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4297 if (hex_format == 0)
4298 fprintf(stdout, "%d:%d:%d%s",
4299 scsi_3btoul(dlist[i].cylinder),
4301 scsi_4btoul(dlist[i].bytes_from_index),
4302 mads ? " - " : "\n");
4304 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4305 scsi_3btoul(dlist[i].cylinder),
4307 scsi_4btoul(dlist[i].bytes_from_index),
4308 mads ? " - " : "\n");
4312 if (num_valid < num_returned) {
4313 starting_offset += num_valid;
4318 case SRDDH10_BLOCK_FORMAT:
4320 struct scsi_defect_desc_block *dlist;
4322 dlist = (struct scsi_defect_desc_block *)
4323 (defect_list + hdr_size);
4325 for (i = 0; i < num_valid; i++) {
4326 if (hex_format == 0)
4327 fprintf(stdout, "%u\n",
4328 scsi_4btoul(dlist[i].address));
4330 fprintf(stdout, "0x%x\n",
4331 scsi_4btoul(dlist[i].address));
4334 if (num_valid < num_returned) {
4335 starting_offset += num_valid;
4341 case SRDD10_LONG_BLOCK_FORMAT:
4343 struct scsi_defect_desc_long_block *dlist;
4345 dlist = (struct scsi_defect_desc_long_block *)
4346 (defect_list + hdr_size);
4348 for (i = 0; i < num_valid; i++) {
4349 if (hex_format == 0)
4350 fprintf(stdout, "%ju\n",
4351 (uintmax_t)scsi_8btou64(
4354 fprintf(stdout, "0x%jx\n",
4355 (uintmax_t)scsi_8btou64(
4359 if (num_valid < num_returned) {
4360 starting_offset += num_valid;
4366 fprintf(stderr, "Unknown defect format 0x%x\n",
4373 if (defect_list != NULL)
4384 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4388 ccb = cam_getccb(device);
4395 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4396 int page, int subpage, int task_attr, int retry_count, int timeout,
4397 u_int8_t *data, int datalen)
4400 int error_code, sense_key, asc, ascq;
4402 ccb = cam_getccb(device);
4404 errx(1, "mode_sense: couldn't allocate CCB");
4408 * MODE SENSE(6) can't handle more then 255 bytes. If there are more,
4409 * device must return error, so we should not get truncated data.
4411 if (*cdb_len == 6 && datalen > 255)
4414 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4416 scsi_mode_sense_subpage(&ccb->csio,
4417 /* retries */ retry_count,
4419 /* tag_action */ task_attr,
4423 /* subpage */ subpage,
4424 /* param_buf */ data,
4425 /* param_len */ datalen,
4426 /* minimum_cmd_size */ *cdb_len,
4427 /* sense_len */ SSD_FULL_SIZE,
4428 /* timeout */ timeout ? timeout : 5000);
4429 if (llbaa && ccb->csio.cdb_len == 10) {
4430 struct scsi_mode_sense_10 *cdb =
4431 (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4432 cdb->byte2 |= SMS10_LLBAA;
4435 /* Record what CDB size the above function really set. */
4436 *cdb_len = ccb->csio.cdb_len;
4438 if (arglist & CAM_ARG_ERR_RECOVER)
4439 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4441 /* Disable freezing the device queue */
4442 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4444 if (cam_send_ccb(device, ccb) < 0)
4445 err(1, "error sending mode sense command");
4447 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4448 if (*cdb_len != 6 &&
4449 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4450 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4451 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4456 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4457 if (arglist & CAM_ARG_VERBOSE) {
4458 cam_error_print(device, ccb, CAM_ESF_ALL,
4459 CAM_EPF_ALL, stderr);
4462 cam_close_device(device);
4463 errx(1, "mode sense command returned error");
4470 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4471 int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4476 ccb = cam_getccb(device);
4479 errx(1, "mode_select: couldn't allocate CCB");
4481 scsi_mode_select_len(&ccb->csio,
4482 /* retries */ retry_count,
4484 /* tag_action */ task_attr,
4485 /* scsi_page_fmt */ 1,
4486 /* save_pages */ save_pages,
4487 /* param_buf */ data,
4488 /* param_len */ datalen,
4489 /* minimum_cmd_size */ cdb_len,
4490 /* sense_len */ SSD_FULL_SIZE,
4491 /* timeout */ timeout ? timeout : 5000);
4493 if (arglist & CAM_ARG_ERR_RECOVER)
4494 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4496 /* Disable freezing the device queue */
4497 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4499 if (((retval = cam_send_ccb(device, ccb)) < 0)
4500 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4501 if (arglist & CAM_ARG_VERBOSE) {
4502 cam_error_print(device, ccb, CAM_ESF_ALL,
4503 CAM_EPF_ALL, stderr);
4506 cam_close_device(device);
4509 err(1, "error sending mode select command");
4511 errx(1, "error sending mode select command");
4519 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4520 int task_attr, int retry_count, int timeout)
4523 int c, page = -1, subpage = 0, pc = 0, llbaa = 0;
4524 int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4526 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4544 str_subpage = optarg;
4545 strsep(&str_subpage, ",");
4546 page = strtol(optarg, NULL, 0);
4548 subpage = strtol(str_subpage, NULL, 0);
4549 if (page < 0 || page > 0x3f)
4550 errx(1, "invalid mode page %d", page);
4551 if (subpage < 0 || subpage > 0xff)
4552 errx(1, "invalid mode subpage %d", subpage);
4561 pc = strtol(optarg, NULL, 0);
4562 if ((pc < 0) || (pc > 3))
4563 errx(1, "invalid page control field %d", pc);
4570 if (desc && page == -1)
4571 page = SMS_ALL_PAGES_PAGE;
4573 if (page == -1 && list == 0)
4574 errx(1, "you must specify a mode page!");
4577 errx(1, "-d and -D are incompatible!");
4579 if (llbaa && cdb_len != 10)
4580 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4583 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4584 retry_count, timeout);
4586 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4587 edit, binary, task_attr, retry_count, timeout);
4592 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4593 int task_attr, int retry_count, int timeout)
4596 u_int32_t flags = CAM_DIR_NONE;
4597 u_int8_t *data_ptr = NULL;
4599 u_int8_t atacmd[12];
4600 struct get_hook hook;
4601 int c, data_bytes = 0, valid_bytes;
4607 char *datastr = NULL, *tstr, *resstr = NULL;
4609 int fd_data = 0, fd_res = 0;
4612 ccb = cam_getccb(device);
4615 warnx("scsicmd: error allocating ccb");
4619 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4623 while (isspace(*tstr) && (*tstr != '\0'))
4625 hook.argc = argc - optind;
4626 hook.argv = argv + optind;
4628 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4631 * Increment optind by the number of arguments the
4632 * encoding routine processed. After each call to
4633 * getopt(3), optind points to the argument that
4634 * getopt should process _next_. In this case,
4635 * that means it points to the first command string
4636 * argument, if there is one. Once we increment
4637 * this, it should point to either the next command
4638 * line argument, or it should be past the end of
4645 while (isspace(*tstr) && (*tstr != '\0'))
4647 hook.argc = argc - optind;
4648 hook.argv = argv + optind;
4650 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4653 * Increment optind by the number of arguments the
4654 * encoding routine processed. After each call to
4655 * getopt(3), optind points to the argument that
4656 * getopt should process _next_. In this case,
4657 * that means it points to the first command string
4658 * argument, if there is one. Once we increment
4659 * this, it should point to either the next command
4660 * line argument, or it should be past the end of
4672 if (arglist & CAM_ARG_CMD_OUT) {
4673 warnx("command must either be "
4674 "read or write, not both");
4676 goto scsicmd_bailout;
4678 arglist |= CAM_ARG_CMD_IN;
4680 data_bytes = strtol(optarg, NULL, 0);
4681 if (data_bytes <= 0) {
4682 warnx("invalid number of input bytes %d",
4685 goto scsicmd_bailout;
4687 hook.argc = argc - optind;
4688 hook.argv = argv + optind;
4691 datastr = cget(&hook, NULL);
4693 * If the user supplied "-" instead of a format, he
4694 * wants the data to be written to stdout.
4696 if ((datastr != NULL)
4697 && (datastr[0] == '-'))
4700 data_ptr = (u_int8_t *)malloc(data_bytes);
4701 if (data_ptr == NULL) {
4702 warnx("can't malloc memory for data_ptr");
4704 goto scsicmd_bailout;
4708 if (arglist & CAM_ARG_CMD_IN) {
4709 warnx("command must either be "
4710 "read or write, not both");
4712 goto scsicmd_bailout;
4714 arglist |= CAM_ARG_CMD_OUT;
4715 flags = CAM_DIR_OUT;
4716 data_bytes = strtol(optarg, NULL, 0);
4717 if (data_bytes <= 0) {
4718 warnx("invalid number of output bytes %d",
4721 goto scsicmd_bailout;
4723 hook.argc = argc - optind;
4724 hook.argv = argv + optind;
4726 datastr = cget(&hook, NULL);
4727 data_ptr = (u_int8_t *)malloc(data_bytes);
4728 if (data_ptr == NULL) {
4729 warnx("can't malloc memory for data_ptr");
4731 goto scsicmd_bailout;
4733 bzero(data_ptr, data_bytes);
4735 * If the user supplied "-" instead of a format, he
4736 * wants the data to be read from stdin.
4738 if ((datastr != NULL)
4739 && (datastr[0] == '-'))
4742 buff_encode_visit(data_ptr, data_bytes, datastr,
4748 hook.argc = argc - optind;
4749 hook.argv = argv + optind;
4751 resstr = cget(&hook, NULL);
4752 if ((resstr != NULL) && (resstr[0] == '-'))
4762 * If fd_data is set, and we're writing to the device, we need to
4763 * read the data the user wants written from stdin.
4765 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4767 int amt_to_read = data_bytes;
4768 u_int8_t *buf_ptr = data_ptr;
4770 for (amt_read = 0; amt_to_read > 0;
4771 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4772 if (amt_read == -1) {
4773 warn("error reading data from stdin");
4775 goto scsicmd_bailout;
4777 amt_to_read -= amt_read;
4778 buf_ptr += amt_read;
4782 if (arglist & CAM_ARG_ERR_RECOVER)
4783 flags |= CAM_PASS_ERR_RECOVER;
4785 /* Disable freezing the device queue */
4786 flags |= CAM_DEV_QFRZDIS;
4790 * This is taken from the SCSI-3 draft spec.
4791 * (T10/1157D revision 0.3)
4792 * The top 3 bits of an opcode are the group code.
4793 * The next 5 bits are the command code.
4794 * Group 0: six byte commands
4795 * Group 1: ten byte commands
4796 * Group 2: ten byte commands
4798 * Group 4: sixteen byte commands
4799 * Group 5: twelve byte commands
4800 * Group 6: vendor specific
4801 * Group 7: vendor specific
4803 switch((cdb[0] >> 5) & 0x7) {
4814 /* computed by buff_encode_visit */
4825 * We should probably use csio_build_visit or something like that
4826 * here, but it's easier to encode arguments as you go. The
4827 * alternative would be skipping the CDB argument and then encoding
4828 * it here, since we've got the data buffer argument by now.
4830 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4832 cam_fill_csio(&ccb->csio,
4833 /*retries*/ retry_count,
4836 /*tag_action*/ task_attr,
4837 /*data_ptr*/ data_ptr,
4838 /*dxfer_len*/ data_bytes,
4839 /*sense_len*/ SSD_FULL_SIZE,
4840 /*cdb_len*/ cdb_len,
4841 /*timeout*/ timeout ? timeout : 5000);
4844 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4846 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4848 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4850 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4852 cam_fill_ataio(&ccb->ataio,
4853 /*retries*/ retry_count,
4857 /*data_ptr*/ data_ptr,
4858 /*dxfer_len*/ data_bytes,
4859 /*timeout*/ timeout ? timeout : 5000);
4862 if (((retval = cam_send_ccb(device, ccb)) < 0)
4863 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4864 const char warnstr[] = "error sending command";
4871 if (arglist & CAM_ARG_VERBOSE) {
4872 cam_error_print(device, ccb, CAM_ESF_ALL,
4873 CAM_EPF_ALL, stderr);
4877 goto scsicmd_bailout;
4880 if (atacmd_len && need_res) {
4882 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4884 fprintf(stdout, "\n");
4887 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4888 ccb->ataio.res.status,
4889 ccb->ataio.res.error,
4890 ccb->ataio.res.lba_low,
4891 ccb->ataio.res.lba_mid,
4892 ccb->ataio.res.lba_high,
4893 ccb->ataio.res.device,
4894 ccb->ataio.res.lba_low_exp,
4895 ccb->ataio.res.lba_mid_exp,
4896 ccb->ataio.res.lba_high_exp,
4897 ccb->ataio.res.sector_count,
4898 ccb->ataio.res.sector_count_exp);
4904 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4906 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4907 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4908 && (arglist & CAM_ARG_CMD_IN)
4909 && (valid_bytes > 0)) {
4911 buff_decode_visit(data_ptr, valid_bytes, datastr,
4913 fprintf(stdout, "\n");
4915 ssize_t amt_written;
4916 int amt_to_write = valid_bytes;
4917 u_int8_t *buf_ptr = data_ptr;
4919 for (amt_written = 0; (amt_to_write > 0) &&
4920 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4921 amt_to_write -= amt_written;
4922 buf_ptr += amt_written;
4924 if (amt_written == -1) {
4925 warn("error writing data to stdout");
4927 goto scsicmd_bailout;
4928 } else if ((amt_written == 0)
4929 && (amt_to_write > 0)) {
4930 warnx("only wrote %u bytes out of %u",
4931 valid_bytes - amt_to_write, valid_bytes);
4938 if ((data_bytes > 0) && (data_ptr != NULL))
4947 camdebug(int argc, char **argv, char *combinedopt)
4950 path_id_t bus = CAM_BUS_WILDCARD;
4951 target_id_t target = CAM_TARGET_WILDCARD;
4952 lun_id_t lun = CAM_LUN_WILDCARD;
4957 bzero(&ccb, sizeof(union ccb));
4959 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4962 arglist |= CAM_ARG_DEBUG_INFO;
4963 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4966 arglist |= CAM_ARG_DEBUG_PERIPH;
4967 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4970 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4971 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4974 arglist |= CAM_ARG_DEBUG_TRACE;
4975 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4978 arglist |= CAM_ARG_DEBUG_XPT;
4979 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4982 arglist |= CAM_ARG_DEBUG_CDB;
4983 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4986 arglist |= CAM_ARG_DEBUG_PROBE;
4987 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4998 warnx("you must specify \"off\", \"all\" or a bus,");
4999 warnx("bus:target, bus:target:lun or periph");
5004 while (isspace(*tstr) && (*tstr != '\0'))
5007 if (strncmp(tstr, "off", 3) == 0) {
5008 ccb.cdbg.flags = CAM_DEBUG_NONE;
5009 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5010 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5011 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5013 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5015 warnx("you must specify \"all\", \"off\", or a bus,");
5016 warnx("bus:target, bus:target:lun or periph to debug");
5021 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5022 warnx("error opening transport layer device %s", XPT_DEVICE);
5023 warn("%s", XPT_DEVICE);
5027 ccb.ccb_h.func_code = XPT_DEBUG;
5028 ccb.ccb_h.path_id = bus;
5029 ccb.ccb_h.target_id = target;
5030 ccb.ccb_h.target_lun = lun;
5032 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5033 warn("CAMIOCOMMAND ioctl failed");
5036 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5037 CAM_FUNC_NOTAVAIL) {
5038 warnx("CAM debugging not available");
5039 warnx("you need to put options CAMDEBUG in"
5040 " your kernel config file!");
5042 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5044 warnx("XPT_DEBUG CCB failed with status %#x",
5048 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5050 "Debugging turned off\n");
5053 "Debugging enabled for "
5055 bus, target, (uintmax_t)lun);
5065 tagcontrol(struct cam_device *device, int argc, char **argv,
5075 ccb = cam_getccb(device);
5078 warnx("tagcontrol: error allocating ccb");
5082 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5085 numtags = strtol(optarg, NULL, 0);
5087 warnx("tag count %d is < 0", numtags);
5089 goto tagcontrol_bailout;
5100 cam_path_string(device, pathstr, sizeof(pathstr));
5103 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5104 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5105 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5106 ccb->crs.openings = numtags;
5109 if (cam_send_ccb(device, ccb) < 0) {
5110 warn("error sending XPT_REL_SIMQ CCB");
5112 goto tagcontrol_bailout;
5115 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5116 warnx("XPT_REL_SIMQ CCB failed");
5117 cam_error_print(device, ccb, CAM_ESF_ALL,
5118 CAM_EPF_ALL, stderr);
5120 goto tagcontrol_bailout;
5125 fprintf(stdout, "%stagged openings now %d\n",
5126 pathstr, ccb->crs.openings);
5129 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5131 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5133 if (cam_send_ccb(device, ccb) < 0) {
5134 warn("error sending XPT_GDEV_STATS CCB");
5136 goto tagcontrol_bailout;
5139 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5140 warnx("XPT_GDEV_STATS CCB failed");
5141 cam_error_print(device, ccb, CAM_ESF_ALL,
5142 CAM_EPF_ALL, stderr);
5144 goto tagcontrol_bailout;
5147 if (arglist & CAM_ARG_VERBOSE) {
5148 fprintf(stdout, "%s", pathstr);
5149 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5150 fprintf(stdout, "%s", pathstr);
5151 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5152 fprintf(stdout, "%s", pathstr);
5153 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5154 fprintf(stdout, "%s", pathstr);
5155 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5156 fprintf(stdout, "%s", pathstr);
5157 fprintf(stdout, "held %d\n", ccb->cgds.held);
5158 fprintf(stdout, "%s", pathstr);
5159 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5160 fprintf(stdout, "%s", pathstr);
5161 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5164 fprintf(stdout, "%s", pathstr);
5165 fprintf(stdout, "device openings: ");
5167 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5168 ccb->cgds.dev_active);
5178 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5182 cam_path_string(device, pathstr, sizeof(pathstr));
5184 if (cts->transport == XPORT_SPI) {
5185 struct ccb_trans_settings_spi *spi =
5186 &cts->xport_specific.spi;
5188 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5190 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5193 if (spi->sync_offset != 0) {
5196 freq = scsi_calc_syncsrate(spi->sync_period);
5197 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5198 pathstr, freq / 1000, freq % 1000);
5202 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5203 fprintf(stdout, "%soffset: %d\n", pathstr,
5207 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5208 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5209 (0x01 << spi->bus_width) * 8);
5212 if (spi->valid & CTS_SPI_VALID_DISC) {
5213 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5214 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5215 "enabled" : "disabled");
5218 if (cts->transport == XPORT_FC) {
5219 struct ccb_trans_settings_fc *fc =
5220 &cts->xport_specific.fc;
5222 if (fc->valid & CTS_FC_VALID_WWNN)
5223 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5224 (long long) fc->wwnn);
5225 if (fc->valid & CTS_FC_VALID_WWPN)
5226 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5227 (long long) fc->wwpn);
5228 if (fc->valid & CTS_FC_VALID_PORT)
5229 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5230 if (fc->valid & CTS_FC_VALID_SPEED)
5231 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5232 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5234 if (cts->transport == XPORT_SAS) {
5235 struct ccb_trans_settings_sas *sas =
5236 &cts->xport_specific.sas;
5238 if (sas->valid & CTS_SAS_VALID_SPEED)
5239 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5240 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5242 if (cts->transport == XPORT_ATA) {
5243 struct ccb_trans_settings_pata *pata =
5244 &cts->xport_specific.ata;
5246 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5247 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5248 ata_mode2string(pata->mode));
5250 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5251 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5254 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5255 fprintf(stdout, "%sPIO transaction length: %d\n",
5256 pathstr, pata->bytecount);
5259 if (cts->transport == XPORT_SATA) {
5260 struct ccb_trans_settings_sata *sata =
5261 &cts->xport_specific.sata;
5263 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5264 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5267 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5268 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5269 ata_mode2string(sata->mode));
5271 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5272 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5275 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5276 fprintf(stdout, "%sPIO transaction length: %d\n",
5277 pathstr, sata->bytecount);
5279 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5280 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5283 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5284 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5287 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5288 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5292 if (cts->protocol == PROTO_ATA) {
5293 struct ccb_trans_settings_ata *ata=
5294 &cts->proto_specific.ata;
5296 if (ata->valid & CTS_ATA_VALID_TQ) {
5297 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5298 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5299 "enabled" : "disabled");
5302 if (cts->protocol == PROTO_SCSI) {
5303 struct ccb_trans_settings_scsi *scsi=
5304 &cts->proto_specific.scsi;
5306 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5307 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5308 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5309 "enabled" : "disabled");
5313 if (cts->protocol == PROTO_NVME) {
5314 struct ccb_trans_settings_nvme *nvmex =
5315 &cts->xport_specific.nvme;
5317 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5318 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5319 NVME_MAJOR(nvmex->spec),
5320 NVME_MINOR(nvmex->spec));
5322 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5323 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5324 nvmex->lanes, nvmex->max_lanes);
5325 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5326 nvmex->speed, nvmex->max_speed);
5333 * Get a path inquiry CCB for the specified device.
5336 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5341 ccb = cam_getccb(device);
5343 warnx("get_cpi: couldn't allocate CCB");
5346 ccb->ccb_h.func_code = XPT_PATH_INQ;
5347 if (cam_send_ccb(device, ccb) < 0) {
5348 warn("get_cpi: error sending Path Inquiry CCB");
5350 goto get_cpi_bailout;
5352 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5353 if (arglist & CAM_ARG_VERBOSE)
5354 cam_error_print(device, ccb, CAM_ESF_ALL,
5355 CAM_EPF_ALL, stderr);
5357 goto get_cpi_bailout;
5359 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5367 * Get a get device CCB for the specified device.
5370 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5375 ccb = cam_getccb(device);
5377 warnx("get_cgd: couldn't allocate CCB");
5380 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5381 if (cam_send_ccb(device, ccb) < 0) {
5382 warn("get_cgd: error sending Get type information CCB");
5384 goto get_cgd_bailout;
5386 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5387 if (arglist & CAM_ARG_VERBOSE)
5388 cam_error_print(device, ccb, CAM_ESF_ALL,
5389 CAM_EPF_ALL, stderr);
5391 goto get_cgd_bailout;
5393 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5401 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5405 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5406 int timeout, int verbosemode)
5408 union ccb *ccb = NULL;
5409 struct scsi_vpd_supported_page_list sup_pages;
5413 ccb = cam_getccb(dev);
5415 warn("Unable to allocate CCB");
5420 bzero(&sup_pages, sizeof(sup_pages));
5422 scsi_inquiry(&ccb->csio,
5423 /*retries*/ retry_count,
5425 /* tag_action */ MSG_SIMPLE_Q_TAG,
5426 /* inq_buf */ (u_int8_t *)&sup_pages,
5427 /* inq_len */ sizeof(sup_pages),
5429 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5430 /* sense_len */ SSD_FULL_SIZE,
5431 /* timeout */ timeout ? timeout : 5000);
5433 /* Disable freezing the device queue */
5434 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5436 if (retry_count != 0)
5437 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5439 if (cam_send_ccb(dev, ccb) < 0) {
5446 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5447 if (verbosemode != 0)
5448 cam_error_print(dev, ccb, CAM_ESF_ALL,
5449 CAM_EPF_ALL, stderr);
5454 for (i = 0; i < sup_pages.length; i++) {
5455 if (sup_pages.list[i] == page_id) {
5468 * devtype is filled in with the type of device.
5469 * Returns 0 for success, non-zero for failure.
5472 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5473 int verbosemode, camcontrol_devtype *devtype)
5475 struct ccb_getdev cgd;
5478 retval = get_cgd(dev, &cgd);
5482 switch (cgd.protocol) {
5488 *devtype = CC_DT_ATA;
5490 break; /*NOTREACHED*/
5492 *devtype = CC_DT_NVME;
5494 break; /*NOTREACHED*/
5496 *devtype = CC_DT_MMCSD;
5498 break; /*NOTREACHED*/
5500 *devtype = CC_DT_UNKNOWN;
5502 break; /*NOTREACHED*/
5505 if (retry_count == -1) {
5507 * For a retry count of -1, used only the cached data to avoid
5508 * I/O to the drive. Sending the identify command to the drive
5509 * can cause issues for SATL attachaed drives since identify is
5510 * not an NCQ command. We check for the strings that windows
5511 * displays since those will not be NULs (they are supposed
5512 * to be space padded). We could check other bits, but anything
5513 * non-zero implies SATL.
5515 if (cgd.ident_data.serial[0] != 0 ||
5516 cgd.ident_data.revision[0] != 0 ||
5517 cgd.ident_data.model[0] != 0)
5518 *devtype = CC_DT_SATL;
5520 *devtype = CC_DT_SCSI;
5523 * Check for the ATA Information VPD page (0x89). If this is an
5524 * ATA device behind a SCSI to ATA translation layer (SATL),
5525 * this VPD page should be present.
5527 * If that VPD page isn't present, or we get an error back from
5528 * the INQUIRY command, we'll just treat it as a normal SCSI
5531 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5532 timeout, verbosemode);
5534 *devtype = CC_DT_SATL;
5536 *devtype = CC_DT_SCSI;
5545 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5546 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5547 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5548 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5549 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5550 int is48bit, camcontrol_devtype devtype)
5554 if (devtype == CC_DT_ATA) {
5555 cam_fill_ataio(&ccb->ataio,
5556 /*retries*/ retry_count,
5559 /*tag_action*/ tag_action,
5560 /*data_ptr*/ data_ptr,
5561 /*dxfer_len*/ dxfer_len,
5562 /*timeout*/ timeout);
5563 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5564 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5567 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5570 if (auxiliary != 0) {
5571 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5572 ccb->ataio.aux = auxiliary;
5575 if (ata_flags & AP_FLAG_CHK_COND)
5576 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5578 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5579 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5580 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5581 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5583 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5584 protocol |= AP_EXTEND;
5586 retval = scsi_ata_pass(&ccb->csio,
5587 /*retries*/ retry_count,
5590 /*tag_action*/ tag_action,
5591 /*protocol*/ protocol,
5592 /*ata_flags*/ ata_flags,
5593 /*features*/ features,
5594 /*sector_count*/ sector_count,
5596 /*command*/ command,
5599 /*auxiliary*/ auxiliary,
5601 /*data_ptr*/ data_ptr,
5602 /*dxfer_len*/ dxfer_len,
5603 /*cdb_storage*/ cdb_storage,
5604 /*cdb_storage_len*/ cdb_storage_len,
5605 /*minimum_cmd_size*/ 0,
5606 /*sense_len*/ sense_len,
5607 /*timeout*/ timeout);
5614 * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5615 * 4 -- count truncated, 6 -- lba and count truncated.
5618 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5619 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5623 switch (ccb->ccb_h.func_code) {
5626 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5630 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5631 * or 16 byte, and need to see what
5633 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5634 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5636 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5637 if ((opcode != ATA_PASS_12)
5638 && (opcode != ATA_PASS_16)) {
5639 warnx("%s: unsupported opcode %02x", __func__, opcode);
5643 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5645 /* Note: the _ccb() variant returns 0 for an error */
5649 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5650 switch (error_code) {
5651 case SSD_DESC_CURRENT_ERROR:
5652 case SSD_DESC_DEFERRED_ERROR: {
5653 struct scsi_sense_data_desc *sense;
5654 struct scsi_sense_ata_ret_desc *desc;
5657 sense = (struct scsi_sense_data_desc *)
5658 &ccb->csio.sense_data;
5660 desc_ptr = scsi_find_desc(sense, sense_len,
5662 if (desc_ptr == NULL) {
5663 cam_error_print(dev, ccb, CAM_ESF_ALL,
5664 CAM_EPF_ALL, stderr);
5667 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5669 *error = desc->error;
5670 *count = (desc->count_15_8 << 8) |
5672 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5673 ((uint64_t)desc->lba_39_32 << 32) |
5674 ((uint64_t)desc->lba_31_24 << 24) |
5675 (desc->lba_23_16 << 16) |
5676 (desc->lba_15_8 << 8) |
5678 *device = desc->device;
5679 *status = desc->status;
5682 * If the extend bit isn't set, the result is for a
5683 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5684 * command without the extend bit set. This means
5685 * that the device is supposed to return 28-bit
5686 * status. The count field is only 8 bits, and the
5687 * LBA field is only 8 bits.
5689 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5695 case SSD_CURRENT_ERROR:
5696 case SSD_DEFERRED_ERROR: {
5700 * In my understanding of SAT-5 specification, saying:
5701 * "without interpreting the contents of the STATUS",
5702 * this should not happen if CK_COND was set, but it
5703 * does at least for some devices, so try to revert.
5705 if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5706 (asc == 0) && (ascq == 0)) {
5707 *status = ATA_STATUS_ERROR;
5708 *error = ATA_ERROR_ABORT;
5715 if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5716 (asc != 0x00) || (ascq != 0x1d))
5720 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5721 SSD_DESC_INFO, &val, NULL);
5722 *error = (val >> 24) & 0xff;
5723 *status = (val >> 16) & 0xff;
5724 *device = (val >> 8) & 0xff;
5725 *count = val & 0xff;
5728 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5729 SSD_DESC_COMMAND, &val, NULL);
5730 *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5731 ((val & 0xff) << 16);
5733 /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5734 return ((val >> 28) & 0x06);
5743 struct ata_res *res;
5745 /* Only some statuses return ATA result register set. */
5746 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5747 cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5750 res = &ccb->ataio.res;
5751 *error = res->error;
5752 *status = res->status;
5753 *device = res->device;
5754 *count = res->sector_count;
5755 *lba = (res->lba_high << 16) |
5756 (res->lba_mid << 8) |
5758 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5759 *count |= (res->sector_count_exp << 8);
5760 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5761 ((uint64_t)res->lba_mid_exp << 32) |
5762 ((uint64_t)res->lba_high_exp << 40);
5764 *lba |= (res->device & 0xf) << 24;
5775 cpi_print(struct ccb_pathinq *cpi)
5777 char adapter_str[1024];
5780 snprintf(adapter_str, sizeof(adapter_str),
5781 "%s%d:", cpi->dev_name, cpi->unit_number);
5783 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5786 for (i = 1; i < UINT8_MAX; i = i << 1) {
5789 if ((i & cpi->hba_inquiry) == 0)
5792 fprintf(stdout, "%s supports ", adapter_str);
5796 str = "MDP message";
5799 str = "32 bit wide SCSI";
5802 str = "16 bit wide SCSI";
5805 str = "SDTR message";
5808 str = "linked CDBs";
5811 str = "tag queue messages";
5814 str = "soft reset alternative";
5817 str = "SATA Port Multiplier";
5820 str = "unknown PI bit set";
5823 fprintf(stdout, "%s\n", str);
5826 for (i = 1; i < UINT32_MAX; i = i << 1) {
5829 if ((i & cpi->hba_misc) == 0)
5832 fprintf(stdout, "%s ", adapter_str);
5836 str = "can understand ata_ext requests";
5839 str = "64bit extended LUNs supported";
5842 str = "bus scans from high ID to low ID";
5845 str = "removable devices not included in scan";
5847 case PIM_NOINITIATOR:
5848 str = "initiator role not supported";
5850 case PIM_NOBUSRESET:
5851 str = "user has disabled initial BUS RESET or"
5852 " controller is in target/mixed mode";
5855 str = "do not send 6-byte commands";
5858 str = "scan bus sequentially";
5861 str = "unmapped I/O supported";
5864 str = "does its own scanning";
5867 str = "unknown PIM bit set";
5870 fprintf(stdout, "%s\n", str);
5873 for (i = 1; i < UINT16_MAX; i = i << 1) {
5876 if ((i & cpi->target_sprt) == 0)
5879 fprintf(stdout, "%s supports ", adapter_str);
5882 str = "target mode processor mode";
5885 str = "target mode phase cog. mode";
5887 case PIT_DISCONNECT:
5888 str = "disconnects in target mode";
5891 str = "terminate I/O message in target mode";
5894 str = "group 6 commands in target mode";
5897 str = "group 7 commands in target mode";
5900 str = "unknown PIT bit set";
5904 fprintf(stdout, "%s\n", str);
5906 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5908 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5910 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5912 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5913 adapter_str, cpi->hpath_id);
5914 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5916 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5917 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5918 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5919 adapter_str, cpi->hba_vendor);
5920 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5921 adapter_str, cpi->hba_device);
5922 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5923 adapter_str, cpi->hba_subvendor);
5924 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5925 adapter_str, cpi->hba_subdevice);
5926 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5927 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5928 if (cpi->base_transfer_speed > 1000)
5929 fprintf(stdout, "%d.%03dMB/sec\n",
5930 cpi->base_transfer_speed / 1000,
5931 cpi->base_transfer_speed % 1000);
5933 fprintf(stdout, "%dKB/sec\n",
5934 (cpi->base_transfer_speed % 1000) * 1000);
5935 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5936 adapter_str, cpi->maxio);
5940 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5941 struct ccb_trans_settings *cts)
5947 ccb = cam_getccb(device);
5950 warnx("get_print_cts: error allocating ccb");
5954 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5956 if (user_settings == 0)
5957 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5959 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5961 if (cam_send_ccb(device, ccb) < 0) {
5962 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
5964 goto get_print_cts_bailout;
5967 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5968 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5969 if (arglist & CAM_ARG_VERBOSE)
5970 cam_error_print(device, ccb, CAM_ESF_ALL,
5971 CAM_EPF_ALL, stderr);
5973 goto get_print_cts_bailout;
5977 cts_print(device, &ccb->cts);
5980 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5982 get_print_cts_bailout:
5990 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5991 int timeout, int argc, char **argv, char *combinedopt)
5995 int user_settings = 0;
5997 int disc_enable = -1, tag_enable = -1;
6000 double syncrate = -1;
6003 int change_settings = 0, send_tur = 0;
6004 struct ccb_pathinq cpi;
6006 ccb = cam_getccb(device);
6008 warnx("ratecontrol: error allocating ccb");
6011 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6020 if (strncasecmp(optarg, "enable", 6) == 0)
6022 else if (strncasecmp(optarg, "disable", 7) == 0)
6025 warnx("-D argument \"%s\" is unknown", optarg);
6027 goto ratecontrol_bailout;
6029 change_settings = 1;
6032 mode = ata_string2mode(optarg);
6034 warnx("unknown mode '%s'", optarg);
6036 goto ratecontrol_bailout;
6038 change_settings = 1;
6041 offset = strtol(optarg, NULL, 0);
6043 warnx("offset value %d is < 0", offset);
6045 goto ratecontrol_bailout;
6047 change_settings = 1;
6053 syncrate = atof(optarg);
6055 warnx("sync rate %f is < 0", syncrate);
6057 goto ratecontrol_bailout;
6059 change_settings = 1;
6062 if (strncasecmp(optarg, "enable", 6) == 0)
6064 else if (strncasecmp(optarg, "disable", 7) == 0)
6067 warnx("-T argument \"%s\" is unknown", optarg);
6069 goto ratecontrol_bailout;
6071 change_settings = 1;
6077 bus_width = strtol(optarg, NULL, 0);
6078 if (bus_width < 0) {
6079 warnx("bus width %d is < 0", bus_width);
6081 goto ratecontrol_bailout;
6083 change_settings = 1;
6090 * Grab path inquiry information, so we can determine whether
6091 * or not the initiator is capable of the things that the user
6094 if ((retval = get_cpi(device, &cpi)) != 0)
6095 goto ratecontrol_bailout;
6097 fprintf(stdout, "%s parameters:\n",
6098 user_settings ? "User" : "Current");
6100 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6102 goto ratecontrol_bailout;
6104 if (arglist & CAM_ARG_VERBOSE)
6107 if (change_settings) {
6108 int didsettings = 0;
6109 struct ccb_trans_settings_spi *spi = NULL;
6110 struct ccb_trans_settings_pata *pata = NULL;
6111 struct ccb_trans_settings_sata *sata = NULL;
6112 struct ccb_trans_settings_ata *ata = NULL;
6113 struct ccb_trans_settings_scsi *scsi = NULL;
6115 if (ccb->cts.transport == XPORT_SPI)
6116 spi = &ccb->cts.xport_specific.spi;
6117 if (ccb->cts.transport == XPORT_ATA)
6118 pata = &ccb->cts.xport_specific.ata;
6119 if (ccb->cts.transport == XPORT_SATA)
6120 sata = &ccb->cts.xport_specific.sata;
6121 if (ccb->cts.protocol == PROTO_ATA)
6122 ata = &ccb->cts.proto_specific.ata;
6123 if (ccb->cts.protocol == PROTO_SCSI)
6124 scsi = &ccb->cts.proto_specific.scsi;
6125 ccb->cts.xport_specific.valid = 0;
6126 ccb->cts.proto_specific.valid = 0;
6127 if (spi && disc_enable != -1) {
6128 spi->valid |= CTS_SPI_VALID_DISC;
6129 if (disc_enable == 0)
6130 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6132 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6135 if (tag_enable != -1) {
6136 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6137 warnx("HBA does not support tagged queueing, "
6138 "so you cannot modify tag settings");
6140 goto ratecontrol_bailout;
6143 ata->valid |= CTS_SCSI_VALID_TQ;
6144 if (tag_enable == 0)
6145 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6147 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6150 scsi->valid |= CTS_SCSI_VALID_TQ;
6151 if (tag_enable == 0)
6152 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6154 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6158 if (spi && offset != -1) {
6159 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6160 warnx("HBA is not capable of changing offset");
6162 goto ratecontrol_bailout;
6164 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6165 spi->sync_offset = offset;
6168 if (spi && syncrate != -1) {
6169 int prelim_sync_period;
6171 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6172 warnx("HBA is not capable of changing "
6175 goto ratecontrol_bailout;
6177 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6179 * The sync rate the user gives us is in MHz.
6180 * We need to translate it into KHz for this
6185 * Next, we calculate a "preliminary" sync period
6186 * in tenths of a nanosecond.
6189 prelim_sync_period = 0;
6191 prelim_sync_period = 10000000 / syncrate;
6193 scsi_calc_syncparam(prelim_sync_period);
6196 if (sata && syncrate != -1) {
6197 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6198 warnx("HBA is not capable of changing "
6201 goto ratecontrol_bailout;
6203 if (!user_settings) {
6204 warnx("You can modify only user rate "
6205 "settings for SATA");
6207 goto ratecontrol_bailout;
6209 sata->revision = ata_speed2revision(syncrate * 100);
6210 if (sata->revision < 0) {
6211 warnx("Invalid rate %f", syncrate);
6213 goto ratecontrol_bailout;
6215 sata->valid |= CTS_SATA_VALID_REVISION;
6218 if ((pata || sata) && mode != -1) {
6219 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6220 warnx("HBA is not capable of changing "
6223 goto ratecontrol_bailout;
6225 if (!user_settings) {
6226 warnx("You can modify only user mode "
6227 "settings for ATA/SATA");
6229 goto ratecontrol_bailout;
6233 pata->valid |= CTS_ATA_VALID_MODE;
6236 sata->valid |= CTS_SATA_VALID_MODE;
6241 * The bus_width argument goes like this:
6245 * Therefore, if you shift the number of bits given on the
6246 * command line right by 4, you should get the correct
6249 if (spi && bus_width != -1) {
6251 * We might as well validate things here with a
6252 * decipherable error message, rather than what
6253 * will probably be an indecipherable error message
6254 * by the time it gets back to us.
6256 if ((bus_width == 16)
6257 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6258 warnx("HBA does not support 16 bit bus width");
6260 goto ratecontrol_bailout;
6261 } else if ((bus_width == 32)
6262 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6263 warnx("HBA does not support 32 bit bus width");
6265 goto ratecontrol_bailout;
6266 } else if ((bus_width != 8)
6267 && (bus_width != 16)
6268 && (bus_width != 32)) {
6269 warnx("Invalid bus width %d", bus_width);
6271 goto ratecontrol_bailout;
6273 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6274 spi->bus_width = bus_width >> 4;
6277 if (didsettings == 0) {
6278 goto ratecontrol_bailout;
6280 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6281 if (cam_send_ccb(device, ccb) < 0) {
6282 warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6284 goto ratecontrol_bailout;
6286 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6287 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6288 if (arglist & CAM_ARG_VERBOSE) {
6289 cam_error_print(device, ccb, CAM_ESF_ALL,
6290 CAM_EPF_ALL, stderr);
6293 goto ratecontrol_bailout;
6297 retval = testunitready(device, task_attr, retry_count, timeout,
6298 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6300 * If the TUR didn't succeed, just bail.
6304 fprintf(stderr, "Test Unit Ready failed\n");
6305 goto ratecontrol_bailout;
6308 if ((change_settings || send_tur) && !quiet &&
6309 (ccb->cts.transport == XPORT_ATA ||
6310 ccb->cts.transport == XPORT_SATA || send_tur)) {
6311 fprintf(stdout, "New parameters:\n");
6312 retval = get_print_cts(device, user_settings, 0, NULL);
6315 ratecontrol_bailout:
6321 scsiformat(struct cam_device *device, int argc, char **argv,
6322 char *combinedopt, int task_attr, int retry_count, int timeout)
6326 int ycount = 0, quiet = 0;
6327 int error = 0, retval = 0;
6328 int use_timeout = 10800 * 1000;
6330 struct format_defect_list_header fh;
6331 u_int8_t *data_ptr = NULL;
6332 u_int32_t dxfer_len = 0;
6334 int num_warnings = 0;
6337 ccb = cam_getccb(device);
6340 warnx("scsiformat: error allocating ccb");
6344 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6364 if (quiet == 0 && ycount == 0) {
6365 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6366 "following device:\n");
6368 error = scsidoinquiry(device, argc, argv, combinedopt,
6369 task_attr, retry_count, timeout);
6372 warnx("scsiformat: error sending inquiry");
6373 goto scsiformat_bailout;
6378 if (!get_confirmation()) {
6380 goto scsiformat_bailout;
6385 use_timeout = timeout;
6388 fprintf(stdout, "Current format timeout is %d seconds\n",
6389 use_timeout / 1000);
6393 * If the user hasn't disabled questions and didn't specify a
6394 * timeout on the command line, ask them if they want the current
6398 && (timeout == 0)) {
6400 int new_timeout = 0;
6402 fprintf(stdout, "Enter new timeout in seconds or press\n"
6403 "return to keep the current timeout [%d] ",
6404 use_timeout / 1000);
6406 if (fgets(str, sizeof(str), stdin) != NULL) {
6408 new_timeout = atoi(str);
6411 if (new_timeout != 0) {
6412 use_timeout = new_timeout * 1000;
6413 fprintf(stdout, "Using new timeout value %d\n",
6414 use_timeout / 1000);
6419 * Keep this outside the if block below to silence any unused
6420 * variable warnings.
6422 bzero(&fh, sizeof(fh));
6425 * If we're in immediate mode, we've got to include the format
6428 if (immediate != 0) {
6429 fh.byte2 = FU_DLH_IMMED;
6430 data_ptr = (u_int8_t *)&fh;
6431 dxfer_len = sizeof(fh);
6432 byte2 = FU_FMT_DATA;
6433 } else if (quiet == 0) {
6434 fprintf(stdout, "Formatting...");
6438 scsi_format_unit(&ccb->csio,
6439 /* retries */ retry_count,
6441 /* tag_action */ task_attr,
6444 /* data_ptr */ data_ptr,
6445 /* dxfer_len */ dxfer_len,
6446 /* sense_len */ SSD_FULL_SIZE,
6447 /* timeout */ use_timeout);
6449 /* Disable freezing the device queue */
6450 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6452 if (arglist & CAM_ARG_ERR_RECOVER)
6453 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6455 if (((retval = cam_send_ccb(device, ccb)) < 0)
6456 || ((immediate == 0)
6457 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6458 const char errstr[] = "error sending format command";
6465 if (arglist & CAM_ARG_VERBOSE) {
6466 cam_error_print(device, ccb, CAM_ESF_ALL,
6467 CAM_EPF_ALL, stderr);
6470 goto scsiformat_bailout;
6474 * If we ran in non-immediate mode, we already checked for errors
6475 * above and printed out any necessary information. If we're in
6476 * immediate mode, we need to loop through and get status
6477 * information periodically.
6479 if (immediate == 0) {
6481 fprintf(stdout, "Format Complete\n");
6483 goto scsiformat_bailout;
6490 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6493 * There's really no need to do error recovery or
6494 * retries here, since we're just going to sit in a
6495 * loop and wait for the device to finish formatting.
6497 scsi_test_unit_ready(&ccb->csio,
6500 /* tag_action */ task_attr,
6501 /* sense_len */ SSD_FULL_SIZE,
6502 /* timeout */ 5000);
6504 /* Disable freezing the device queue */
6505 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6507 retval = cam_send_ccb(device, ccb);
6510 * If we get an error from the ioctl, bail out. SCSI
6511 * errors are expected.
6514 warn("error sending TEST UNIT READY command");
6516 goto scsiformat_bailout;
6519 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6521 if ((status != CAM_REQ_CMP)
6522 && (status == CAM_SCSI_STATUS_ERROR)
6523 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6524 struct scsi_sense_data *sense;
6525 int error_code, sense_key, asc, ascq;
6527 sense = &ccb->csio.sense_data;
6528 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6529 ccb->csio.sense_resid, &error_code, &sense_key,
6530 &asc, &ascq, /*show_errors*/ 1);
6533 * According to the SCSI-2 and SCSI-3 specs, a
6534 * drive that is in the middle of a format should
6535 * return NOT READY with an ASC of "logical unit
6536 * not ready, format in progress". The sense key
6537 * specific bytes will then be a progress indicator.
6539 if ((sense_key == SSD_KEY_NOT_READY)
6540 && (asc == 0x04) && (ascq == 0x04)) {
6543 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6544 ccb->csio.sense_resid, sks) == 0)
6547 u_int64_t percentage;
6549 val = scsi_2btoul(&sks[1]);
6550 percentage = 10000ull * val;
6553 "\rFormatting: %ju.%02u %% "
6555 (uintmax_t)(percentage /
6557 (unsigned)((percentage /
6561 } else if ((quiet == 0)
6562 && (++num_warnings <= 1)) {
6563 warnx("Unexpected SCSI Sense Key "
6564 "Specific value returned "
6566 scsi_sense_print(device, &ccb->csio,
6568 warnx("Unable to print status "
6569 "information, but format will "
6571 warnx("will exit when format is "
6576 warnx("Unexpected SCSI error during format");
6577 cam_error_print(device, ccb, CAM_ESF_ALL,
6578 CAM_EPF_ALL, stderr);
6580 goto scsiformat_bailout;
6583 } else if (status != CAM_REQ_CMP) {
6584 warnx("Unexpected CAM status %#x", status);
6585 if (arglist & CAM_ARG_VERBOSE)
6586 cam_error_print(device, ccb, CAM_ESF_ALL,
6587 CAM_EPF_ALL, stderr);
6589 goto scsiformat_bailout;
6592 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6595 fprintf(stdout, "\nFormat Complete\n");
6605 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6606 camcontrol_devtype devtype)
6609 uint8_t error = 0, ata_device = 0, status = 0;
6615 retval = build_ata_cmd(ccb,
6617 /*flags*/ CAM_DIR_NONE,
6618 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6619 /*protocol*/ AP_PROTO_NON_DATA,
6620 /*ata_flags*/ AP_FLAG_CHK_COND,
6621 /*features*/ 0x00, /* SANITIZE STATUS EXT */
6624 /*command*/ ATA_SANITIZE,
6628 /*cdb_storage*/ NULL,
6629 /*cdb_storage_len*/ 0,
6630 /*sense_len*/ SSD_FULL_SIZE,
6633 /*devtype*/ devtype);
6635 warnx("%s: build_ata_cmd() failed, likely "
6636 "programmer error", __func__);
6640 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6641 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6642 retval = cam_send_ccb(device, ccb);
6644 warn("error sending SANITIZE STATUS EXT command");
6648 retval = get_ata_status(device, ccb, &error, &count, &lba,
6649 &ata_device, &status);
6651 warnx("Can't get SANITIZE STATUS EXT status, "
6652 "sanitize may still run.");
6655 if (status & ATA_STATUS_ERROR) {
6656 if (error & ATA_ERROR_ABORT) {
6657 switch (lba & 0xff) {
6659 warnx("Reason not reported or sanitize failed.");
6662 warnx("Sanitize command unsuccessful. ");
6665 warnx("Unsupported sanitize device command. ");
6668 warnx("Device is in sanitize frozen state. ");
6671 warnx("Sanitize antifreeze lock is enabled. ");
6675 warnx("SANITIZE STATUS EXT failed, "
6676 "sanitize may still run.");
6679 if (count & 0x4000) {
6684 "Sanitizing: %u.%02u%% (%d/%d)\r",
6685 (perc / (0x10000 * 100)),
6686 ((perc / 0x10000) % 100),
6698 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6700 int warnings = 0, retval;
6705 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6708 * There's really no need to do error recovery or
6709 * retries here, since we're just going to sit in a
6710 * loop and wait for the device to finish sanitizing.
6712 scsi_test_unit_ready(&ccb->csio,
6715 /* tag_action */ task_attr,
6716 /* sense_len */ SSD_FULL_SIZE,
6717 /* timeout */ 5000);
6719 /* Disable freezing the device queue */
6720 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6722 retval = cam_send_ccb(device, ccb);
6725 * If we get an error from the ioctl, bail out. SCSI
6726 * errors are expected.
6729 warn("error sending TEST UNIT READY command");
6733 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6734 if ((status == CAM_SCSI_STATUS_ERROR) &&
6735 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6736 struct scsi_sense_data *sense;
6737 int error_code, sense_key, asc, ascq;
6739 sense = &ccb->csio.sense_data;
6740 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6741 ccb->csio.sense_resid, &error_code, &sense_key,
6742 &asc, &ascq, /*show_errors*/ 1);
6745 * According to the SCSI-3 spec, a drive that is in the
6746 * middle of a sanitize should return NOT READY with an
6747 * ASC of "logical unit not ready, sanitize in
6748 * progress". The sense key specific bytes will then
6749 * be a progress indicator.
6751 if ((sense_key == SSD_KEY_NOT_READY)
6752 && (asc == 0x04) && (ascq == 0x1b)) {
6755 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6756 ccb->csio.sense_resid, sks) == 0)
6758 val = scsi_2btoul(&sks[1]);
6761 "Sanitizing: %u.%02u%% (%d/%d)\r",
6762 (perc / (0x10000 * 100)),
6763 ((perc / 0x10000) % 100),
6766 } else if ((quiet == 0) && (++warnings <= 1)) {
6767 warnx("Unexpected SCSI Sense Key "
6768 "Specific value returned "
6769 "during sanitize:");
6770 scsi_sense_print(device, &ccb->csio,
6772 warnx("Unable to print status "
6773 "information, but sanitze will "
6775 warnx("will exit when sanitize is "
6780 warnx("Unexpected SCSI error during sanitize");
6781 cam_error_print(device, ccb, CAM_ESF_ALL,
6782 CAM_EPF_ALL, stderr);
6786 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6787 warnx("Unexpected CAM status %#x", status);
6788 if (arglist & CAM_ARG_VERBOSE)
6789 cam_error_print(device, ccb, CAM_ESF_ALL,
6790 CAM_EPF_ALL, stderr);
6793 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6798 sanitize(struct cam_device *device, int argc, char **argv,
6799 char *combinedopt, int task_attr, int retry_count, int timeout)
6802 u_int8_t action = 0;
6804 int ycount = 0, quiet = 0;
6812 const char *pattern = NULL;
6813 u_int8_t *data_ptr = NULL;
6814 u_int32_t dxfer_len = 0;
6816 uint16_t feature, count;
6819 camcontrol_devtype dt;
6822 * Get the device type, request no I/O be done to do this.
6824 error = get_device_type(device, -1, 0, 0, &dt);
6825 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6826 warnx("sanitize: can't get device type");
6830 ccb = cam_getccb(device);
6833 warnx("sanitize: error allocating ccb");
6837 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6840 if (strcasecmp(optarg, "overwrite") == 0)
6841 action = SSZ_SERVICE_ACTION_OVERWRITE;
6842 else if (strcasecmp(optarg, "block") == 0)
6843 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6844 else if (strcasecmp(optarg, "crypto") == 0)
6845 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6846 else if (strcasecmp(optarg, "exitfailure") == 0)
6847 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6849 warnx("invalid service operation \"%s\"",
6852 goto sanitize_bailout;
6856 passes = strtol(optarg, NULL, 0);
6857 if (passes < 1 || passes > 31) {
6858 warnx("invalid passes value %d", passes);
6860 goto sanitize_bailout;
6879 /* ATA supports only immediate commands. */
6880 if (dt == CC_DT_SCSI)
6893 warnx("an action is required");
6895 goto sanitize_bailout;
6896 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6897 struct scsi_sanitize_parameter_list *pl;
6901 if (pattern == NULL) {
6902 warnx("overwrite action requires -P argument");
6904 goto sanitize_bailout;
6906 fd = open(pattern, O_RDONLY);
6908 warn("cannot open pattern file %s", pattern);
6910 goto sanitize_bailout;
6912 if (fstat(fd, &sb) < 0) {
6913 warn("cannot stat pattern file %s", pattern);
6915 goto sanitize_bailout;
6918 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6919 warnx("pattern file size exceeds maximum value %d",
6920 SSZPL_MAX_PATTERN_LENGTH);
6922 goto sanitize_bailout;
6924 dxfer_len = sizeof(*pl) + sz;
6925 data_ptr = calloc(1, dxfer_len);
6926 if (data_ptr == NULL) {
6927 warnx("cannot allocate parameter list buffer");
6929 goto sanitize_bailout;
6932 amt = read(fd, data_ptr + sizeof(*pl), sz);
6934 warn("cannot read pattern file");
6936 goto sanitize_bailout;
6937 } else if (amt != sz) {
6938 warnx("short pattern file read");
6940 goto sanitize_bailout;
6943 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6949 pl->byte1 |= SSZPL_INVERT;
6950 scsi_ulto2b(sz, pl->length);
6956 else if (invert != 0)
6958 else if (pattern != NULL)
6963 warnx("%s argument only valid with overwrite "
6966 goto sanitize_bailout;
6970 if (quiet == 0 && ycount == 0) {
6971 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6972 "following device:\n");
6974 if (dt == CC_DT_SCSI) {
6975 error = scsidoinquiry(device, argc, argv, combinedopt,
6976 task_attr, retry_count, timeout);
6977 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
6978 struct ata_params *ident_buf;
6979 error = ata_do_identify(device, retry_count, timeout,
6982 printf("%s%d: ", device->device_name,
6983 device->dev_unit_num);
6984 ata_print_ident(ident_buf);
6991 warnx("sanitize: error sending inquiry");
6992 goto sanitize_bailout;
6997 if (!get_confirmation()) {
6999 goto sanitize_bailout;
7004 use_timeout = timeout;
7006 use_timeout = (immediate ? 10 : 10800) * 1000;
7008 if (immediate == 0 && quiet == 0) {
7009 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7010 use_timeout / 1000);
7014 * If the user hasn't disabled questions and didn't specify a
7015 * timeout on the command line, ask them if they want the current
7018 if (immediate == 0 && ycount == 0 && timeout == 0) {
7020 int new_timeout = 0;
7022 fprintf(stdout, "Enter new timeout in seconds or press\n"
7023 "return to keep the current timeout [%d] ",
7024 use_timeout / 1000);
7026 if (fgets(str, sizeof(str), stdin) != NULL) {
7028 new_timeout = atoi(str);
7031 if (new_timeout != 0) {
7032 use_timeout = new_timeout * 1000;
7033 fprintf(stdout, "Using new timeout value %d\n",
7034 use_timeout / 1000);
7038 if (dt == CC_DT_SCSI) {
7041 byte2 |= SSZ_UNRESTRICTED_EXIT;
7044 scsi_sanitize(&ccb->csio,
7045 /* retries */ retry_count,
7047 /* tag_action */ task_attr,
7050 /* data_ptr */ data_ptr,
7051 /* dxfer_len */ dxfer_len,
7052 /* sense_len */ SSD_FULL_SIZE,
7053 /* timeout */ use_timeout);
7055 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7056 if (arglist & CAM_ARG_ERR_RECOVER)
7057 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7058 if (cam_send_ccb(device, ccb) < 0) {
7059 warn("error sending sanitize command");
7061 goto sanitize_bailout;
7063 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7064 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7065 feature = 0x14; /* OVERWRITE EXT */
7066 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7067 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7069 count |= 0x80; /* INVERT PATTERN */
7071 count |= 0x10; /* FAILURE MODE */
7072 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7073 feature = 0x12; /* BLOCK ERASE EXT */
7074 lba = 0x0000426B4572;
7077 count |= 0x10; /* FAILURE MODE */
7078 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7079 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7080 lba = 0x000043727970;
7083 count |= 0x10; /* FAILURE MODE */
7084 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7085 feature = 0x00; /* SANITIZE STATUS EXT */
7087 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7090 goto sanitize_bailout;
7093 error = ata_do_cmd(device,
7096 /*flags*/CAM_DIR_NONE,
7097 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7099 /*tag_action*/MSG_SIMPLE_Q_TAG,
7100 /*command*/ATA_SANITIZE,
7101 /*features*/feature,
7103 /*sector_count*/count,
7106 /*timeout*/ use_timeout,
7110 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7111 struct scsi_sense_data *sense;
7112 int error_code, sense_key, asc, ascq;
7114 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7115 CAM_SCSI_STATUS_ERROR) {
7116 sense = &ccb->csio.sense_data;
7117 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7118 ccb->csio.sense_resid, &error_code, &sense_key,
7119 &asc, &ascq, /*show_errors*/ 1);
7121 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7122 asc == 0x20 && ascq == 0x00)
7123 warnx("sanitize is not supported by "
7126 warnx("error sanitizing this device");
7128 warnx("error sanitizing this device");
7130 if (arglist & CAM_ARG_VERBOSE) {
7131 cam_error_print(device, ccb, CAM_ESF_ALL,
7132 CAM_EPF_ALL, stderr);
7135 goto sanitize_bailout;
7139 * If we ran in non-immediate mode, we already checked for errors
7140 * above and printed out any necessary information. If we're in
7141 * immediate mode, we need to loop through and get status
7142 * information periodically.
7144 if (immediate == 0) {
7146 fprintf(stdout, "Sanitize Complete\n");
7148 goto sanitize_bailout;
7152 if (dt == CC_DT_SCSI) {
7153 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7154 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7155 error = sanitize_wait_ata(device, ccb, quiet, dt);
7158 if (error == 0 && quiet == 0)
7159 fprintf(stdout, "Sanitize Complete \n");
7164 if (data_ptr != NULL)
7172 scsireportluns(struct cam_device *device, int argc, char **argv,
7173 char *combinedopt, int task_attr, int retry_count, int timeout)
7176 int c, countonly, lunsonly;
7177 struct scsi_report_luns_data *lundata;
7179 uint8_t report_type;
7180 uint32_t list_len, i, j;
7185 report_type = RPL_REPORT_DEFAULT;
7186 ccb = cam_getccb(device);
7189 warnx("%s: error allocating ccb", __func__);
7196 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7205 if (strcasecmp(optarg, "default") == 0)
7206 report_type = RPL_REPORT_DEFAULT;
7207 else if (strcasecmp(optarg, "wellknown") == 0)
7208 report_type = RPL_REPORT_WELLKNOWN;
7209 else if (strcasecmp(optarg, "all") == 0)
7210 report_type = RPL_REPORT_ALL;
7212 warnx("%s: invalid report type \"%s\"",
7223 if ((countonly != 0)
7224 && (lunsonly != 0)) {
7225 warnx("%s: you can only specify one of -c or -l", __func__);
7230 * According to SPC-4, the allocation length must be at least 16
7231 * bytes -- enough for the header and one LUN.
7233 alloc_len = sizeof(*lundata) + 8;
7237 lundata = malloc(alloc_len);
7239 if (lundata == NULL) {
7240 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7245 scsi_report_luns(&ccb->csio,
7246 /*retries*/ retry_count,
7248 /*tag_action*/ task_attr,
7249 /*select_report*/ report_type,
7250 /*rpl_buf*/ lundata,
7251 /*alloc_len*/ alloc_len,
7252 /*sense_len*/ SSD_FULL_SIZE,
7253 /*timeout*/ timeout ? timeout : 5000);
7255 /* Disable freezing the device queue */
7256 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7258 if (arglist & CAM_ARG_ERR_RECOVER)
7259 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7261 if (cam_send_ccb(device, ccb) < 0) {
7262 warn("error sending REPORT LUNS command");
7267 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7268 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7274 list_len = scsi_4btoul(lundata->length);
7277 * If we need to list the LUNs, and our allocation
7278 * length was too short, reallocate and retry.
7280 if ((countonly == 0)
7281 && (list_len > (alloc_len - sizeof(*lundata)))) {
7282 alloc_len = list_len + sizeof(*lundata);
7288 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7289 ((list_len / 8) > 1) ? "s" : "");
7294 for (i = 0; i < (list_len / 8); i++) {
7298 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7300 fprintf(stdout, ",");
7301 switch (lundata->luns[i].lundata[j] &
7302 RPL_LUNDATA_ATYP_MASK) {
7303 case RPL_LUNDATA_ATYP_PERIPH:
7304 if ((lundata->luns[i].lundata[j] &
7305 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7306 fprintf(stdout, "%d:",
7307 lundata->luns[i].lundata[j] &
7308 RPL_LUNDATA_PERIPH_BUS_MASK);
7310 && ((lundata->luns[i].lundata[j+2] &
7311 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7314 fprintf(stdout, "%d",
7315 lundata->luns[i].lundata[j+1]);
7317 case RPL_LUNDATA_ATYP_FLAT: {
7319 tmplun[0] = lundata->luns[i].lundata[j] &
7320 RPL_LUNDATA_FLAT_LUN_MASK;
7321 tmplun[1] = lundata->luns[i].lundata[j+1];
7323 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7327 case RPL_LUNDATA_ATYP_LUN:
7328 fprintf(stdout, "%d:%d:%d",
7329 (lundata->luns[i].lundata[j+1] &
7330 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7331 lundata->luns[i].lundata[j] &
7332 RPL_LUNDATA_LUN_TARG_MASK,
7333 lundata->luns[i].lundata[j+1] &
7334 RPL_LUNDATA_LUN_LUN_MASK);
7336 case RPL_LUNDATA_ATYP_EXTLUN: {
7337 int field_len_code, eam_code;
7339 eam_code = lundata->luns[i].lundata[j] &
7340 RPL_LUNDATA_EXT_EAM_MASK;
7341 field_len_code = (lundata->luns[i].lundata[j] &
7342 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7344 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7345 && (field_len_code == 0x00)) {
7346 fprintf(stdout, "%d",
7347 lundata->luns[i].lundata[j+1]);
7348 } else if ((eam_code ==
7349 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7350 && (field_len_code == 0x03)) {
7354 * This format takes up all 8 bytes.
7355 * If we aren't starting at offset 0,
7359 fprintf(stdout, "Invalid "
7362 "specified format", j);
7366 bzero(tmp_lun, sizeof(tmp_lun));
7367 bcopy(&lundata->luns[i].lundata[j+1],
7368 &tmp_lun[1], sizeof(tmp_lun) - 1);
7369 fprintf(stdout, "%#jx",
7370 (intmax_t)scsi_8btou64(tmp_lun));
7373 fprintf(stderr, "Unknown Extended LUN"
7374 "Address method %#x, length "
7375 "code %#x", eam_code,
7382 fprintf(stderr, "Unknown LUN address method "
7383 "%#x\n", lundata->luns[i].lundata[0] &
7384 RPL_LUNDATA_ATYP_MASK);
7388 * For the flat addressing method, there are no
7389 * other levels after it.
7394 fprintf(stdout, "\n");
7407 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7408 char *combinedopt, int task_attr, int retry_count, int timeout)
7411 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7412 struct scsi_read_capacity_data rcap;
7413 struct scsi_read_capacity_data_long rcaplong;
7428 ccb = cam_getccb(device);
7431 warnx("%s: error allocating ccb", __func__);
7435 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7465 if ((blocksizeonly != 0)
7466 && (numblocks != 0)) {
7467 warnx("%s: you can only specify one of -b or -N", __func__);
7472 if ((blocksizeonly != 0)
7473 && (sizeonly != 0)) {
7474 warnx("%s: you can only specify one of -b or -s", __func__);
7481 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7487 && (blocksizeonly != 0)) {
7488 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7496 scsi_read_capacity(&ccb->csio,
7497 /*retries*/ retry_count,
7499 /*tag_action*/ task_attr,
7502 /*timeout*/ timeout ? timeout : 5000);
7504 /* Disable freezing the device queue */
7505 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7507 if (arglist & CAM_ARG_ERR_RECOVER)
7508 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7510 if (cam_send_ccb(device, ccb) < 0) {
7511 warn("error sending READ CAPACITY command");
7516 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7517 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7522 maxsector = scsi_4btoul(rcap.addr);
7523 block_len = scsi_4btoul(rcap.length);
7526 * A last block of 2^32-1 means that the true capacity is over 2TB,
7527 * and we need to issue the long READ CAPACITY to get the real
7528 * capacity. Otherwise, we're all set.
7530 if (maxsector != 0xffffffff)
7534 scsi_read_capacity_16(&ccb->csio,
7535 /*retries*/ retry_count,
7537 /*tag_action*/ task_attr,
7541 /*rcap_buf*/ (uint8_t *)&rcaplong,
7542 /*rcap_buf_len*/ sizeof(rcaplong),
7543 /*sense_len*/ SSD_FULL_SIZE,
7544 /*timeout*/ timeout ? timeout : 5000);
7546 /* Disable freezing the device queue */
7547 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7549 if (arglist & CAM_ARG_ERR_RECOVER)
7550 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7552 if (cam_send_ccb(device, ccb) < 0) {
7553 warn("error sending READ CAPACITY (16) command");
7558 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7559 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7564 maxsector = scsi_8btou64(rcaplong.addr);
7565 block_len = scsi_4btoul(rcaplong.length);
7568 if (blocksizeonly == 0) {
7570 * Humanize implies !quiet, and also implies numblocks.
7572 if (humanize != 0) {
7577 tmpbytes = (maxsector + 1) * block_len;
7578 ret = humanize_number(tmpstr, sizeof(tmpstr),
7579 tmpbytes, "", HN_AUTOSCALE,
7582 HN_DIVISOR_1000 : 0));
7584 warnx("%s: humanize_number failed!", __func__);
7588 fprintf(stdout, "Device Size: %s%s", tmpstr,
7589 (sizeonly == 0) ? ", " : "\n");
7590 } else if (numblocks != 0) {
7591 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7592 "Blocks: " : "", (uintmax_t)maxsector + 1,
7593 (sizeonly == 0) ? ", " : "\n");
7595 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7596 "Last Block: " : "", (uintmax_t)maxsector,
7597 (sizeonly == 0) ? ", " : "\n");
7601 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7602 "Block Length: " : "", block_len, (quiet == 0) ?
7611 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7612 int retry_count, int timeout)
7616 uint8_t *smp_request = NULL, *smp_response = NULL;
7617 int request_size = 0, response_size = 0;
7618 int fd_request = 0, fd_response = 0;
7619 char *datastr = NULL;
7620 struct get_hook hook;
7625 * Note that at the moment we don't support sending SMP CCBs to
7626 * devices that aren't probed by CAM.
7628 ccb = cam_getccb(device);
7630 warnx("%s: error allocating CCB", __func__);
7634 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7637 arglist |= CAM_ARG_CMD_IN;
7638 response_size = strtol(optarg, NULL, 0);
7639 if (response_size <= 0) {
7640 warnx("invalid number of response bytes %d",
7643 goto smpcmd_bailout;
7645 hook.argc = argc - optind;
7646 hook.argv = argv + optind;
7649 datastr = cget(&hook, NULL);
7651 * If the user supplied "-" instead of a format, he
7652 * wants the data to be written to stdout.
7654 if ((datastr != NULL)
7655 && (datastr[0] == '-'))
7658 smp_response = (u_int8_t *)malloc(response_size);
7659 if (smp_response == NULL) {
7660 warn("can't malloc memory for SMP response");
7662 goto smpcmd_bailout;
7666 arglist |= CAM_ARG_CMD_OUT;
7667 request_size = strtol(optarg, NULL, 0);
7668 if (request_size <= 0) {
7669 warnx("invalid number of request bytes %d",
7672 goto smpcmd_bailout;
7674 hook.argc = argc - optind;
7675 hook.argv = argv + optind;
7677 datastr = cget(&hook, NULL);
7678 smp_request = (u_int8_t *)malloc(request_size);
7679 if (smp_request == NULL) {
7680 warn("can't malloc memory for SMP request");
7682 goto smpcmd_bailout;
7684 bzero(smp_request, request_size);
7686 * If the user supplied "-" instead of a format, he
7687 * wants the data to be read from stdin.
7689 if ((datastr != NULL)
7690 && (datastr[0] == '-'))
7693 buff_encode_visit(smp_request, request_size,
7704 * If fd_data is set, and we're writing to the device, we need to
7705 * read the data the user wants written from stdin.
7707 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7709 int amt_to_read = request_size;
7710 u_int8_t *buf_ptr = smp_request;
7712 for (amt_read = 0; amt_to_read > 0;
7713 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7714 if (amt_read == -1) {
7715 warn("error reading data from stdin");
7717 goto smpcmd_bailout;
7719 amt_to_read -= amt_read;
7720 buf_ptr += amt_read;
7724 if (((arglist & CAM_ARG_CMD_IN) == 0)
7725 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7726 warnx("%s: need both the request (-r) and response (-R) "
7727 "arguments", __func__);
7729 goto smpcmd_bailout;
7732 flags |= CAM_DEV_QFRZDIS;
7734 cam_fill_smpio(&ccb->smpio,
7735 /*retries*/ retry_count,
7738 /*smp_request*/ smp_request,
7739 /*smp_request_len*/ request_size,
7740 /*smp_response*/ smp_response,
7741 /*smp_response_len*/ response_size,
7742 /*timeout*/ timeout ? timeout : 5000);
7744 ccb->smpio.flags = SMP_FLAG_NONE;
7746 if (((retval = cam_send_ccb(device, ccb)) < 0)
7747 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7748 const char warnstr[] = "error sending command";
7755 if (arglist & CAM_ARG_VERBOSE) {
7756 cam_error_print(device, ccb, CAM_ESF_ALL,
7757 CAM_EPF_ALL, stderr);
7761 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7762 && (response_size > 0)) {
7763 if (fd_response == 0) {
7764 buff_decode_visit(smp_response, response_size,
7765 datastr, arg_put, NULL);
7766 fprintf(stdout, "\n");
7768 ssize_t amt_written;
7769 int amt_to_write = response_size;
7770 u_int8_t *buf_ptr = smp_response;
7772 for (amt_written = 0; (amt_to_write > 0) &&
7773 (amt_written = write(STDOUT_FILENO, buf_ptr,
7774 amt_to_write)) > 0;){
7775 amt_to_write -= amt_written;
7776 buf_ptr += amt_written;
7778 if (amt_written == -1) {
7779 warn("error writing data to stdout");
7781 goto smpcmd_bailout;
7782 } else if ((amt_written == 0)
7783 && (amt_to_write > 0)) {
7784 warnx("only wrote %u bytes out of %u",
7785 response_size - amt_to_write,
7794 if (smp_request != NULL)
7797 if (smp_response != NULL)
7804 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7805 int retry_count, int timeout)
7809 int32_t mmc_opcode = 0, mmc_arg = 0;
7810 int32_t mmc_flags = -1;
7813 int is_bw_4 = 0, is_bw_1 = 0;
7814 int is_frequency = 0;
7815 int is_highspeed = 0, is_stdspeed = 0;
7816 int is_info_request = 0;
7818 uint8_t mmc_data_byte = 0;
7819 uint32_t mmc_frequency = 0;
7821 /* For IO_RW_EXTENDED command */
7822 uint8_t *mmc_data = NULL;
7823 struct mmc_data mmc_d;
7824 int mmc_data_len = 0;
7827 * Note that at the moment we don't support sending SMP CCBs to
7828 * devices that aren't probed by CAM.
7830 ccb = cam_getccb(device);
7832 warnx("%s: error allocating CCB", __func__);
7836 bzero(&(&ccb->ccb_h)[1],
7837 sizeof(union ccb) - sizeof(struct ccb_hdr));
7839 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7848 if (!strcmp(optarg, "high"))
7854 is_info_request = 1;
7858 mmc_frequency = strtol(optarg, NULL, 0);
7861 mmc_opcode = strtol(optarg, NULL, 0);
7862 if (mmc_opcode < 0) {
7863 warnx("invalid MMC opcode %d",
7866 goto mmccmd_bailout;
7870 mmc_arg = strtol(optarg, NULL, 0);
7872 warnx("invalid MMC arg %d",
7875 goto mmccmd_bailout;
7879 mmc_flags = strtol(optarg, NULL, 0);
7880 if (mmc_flags < 0) {
7881 warnx("invalid MMC flags %d",
7884 goto mmccmd_bailout;
7888 mmc_data_len = strtol(optarg, NULL, 0);
7889 if (mmc_data_len <= 0) {
7890 warnx("invalid MMC data len %d",
7893 goto mmccmd_bailout;
7900 mmc_data_byte = strtol(optarg, NULL, 0);
7906 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7908 /* If flags are left default, supply the right flags */
7910 switch (mmc_opcode) {
7911 case MMC_GO_IDLE_STATE:
7912 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7914 case IO_SEND_OP_COND:
7915 mmc_flags = MMC_RSP_R4;
7917 case SD_SEND_RELATIVE_ADDR:
7918 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7920 case MMC_SELECT_CARD:
7921 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7922 mmc_arg = mmc_arg << 16;
7924 case SD_IO_RW_DIRECT:
7925 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7926 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7928 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7930 case SD_IO_RW_EXTENDED:
7931 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7932 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7933 int len_arg = mmc_data_len;
7934 if (mmc_data_len == 512)
7938 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7940 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7943 mmc_flags = MMC_RSP_R1;
7947 // Switch bus width instead of sending IO command
7948 if (is_bw_4 || is_bw_1) {
7949 struct ccb_trans_settings_mmc *cts;
7950 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7951 ccb->ccb_h.flags = 0;
7952 cts = &ccb->cts.proto_specific.mmc;
7953 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7954 cts->ios_valid = MMC_BW;
7955 if (((retval = cam_send_ccb(device, ccb)) < 0)
7956 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7957 warn("Error sending command");
7959 printf("Parameters set OK\n");
7966 struct ccb_trans_settings_mmc *cts;
7967 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7968 ccb->ccb_h.flags = 0;
7969 cts = &ccb->cts.proto_specific.mmc;
7970 cts->ios.clock = mmc_frequency;
7971 cts->ios_valid = MMC_CLK;
7972 if (((retval = cam_send_ccb(device, ccb)) < 0)
7973 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7974 warn("Error sending command");
7976 printf("Parameters set OK\n");
7982 // Switch bus speed instead of sending IO command
7983 if (is_stdspeed || is_highspeed) {
7984 struct ccb_trans_settings_mmc *cts;
7985 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7986 ccb->ccb_h.flags = 0;
7987 cts = &ccb->cts.proto_specific.mmc;
7988 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7989 cts->ios_valid = MMC_BT;
7990 if (((retval = cam_send_ccb(device, ccb)) < 0)
7991 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7992 warn("Error sending command");
7994 printf("Speed set OK (HS: %d)\n", is_highspeed);
8000 // Get information about controller and its settings
8001 if (is_info_request) {
8002 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8003 ccb->ccb_h.flags = 0;
8004 struct ccb_trans_settings_mmc *cts;
8005 cts = &ccb->cts.proto_specific.mmc;
8006 if (((retval = cam_send_ccb(device, ccb)) < 0)
8007 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8008 warn("Error sending command");
8011 printf("Host controller information\n");
8012 printf("Host OCR: 0x%x\n", cts->host_ocr);
8013 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8014 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8015 printf("Supported bus width:\n");
8016 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8018 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8021 printf("Supported operating modes:\n");
8022 if (cts->host_caps & MMC_CAP_HSPEED)
8023 printf(" Can do High Speed transfers\n");
8024 if (cts->host_caps & MMC_CAP_UHS_SDR12)
8025 printf(" Can do UHS SDR12\n");
8026 if (cts->host_caps & MMC_CAP_UHS_SDR25)
8027 printf(" Can do UHS SDR25\n");
8028 if (cts->host_caps & MMC_CAP_UHS_SDR50)
8029 printf(" Can do UHS SDR50\n");
8030 if (cts->host_caps & MMC_CAP_UHS_SDR104)
8031 printf(" Can do UHS SDR104\n");
8032 if (cts->host_caps & MMC_CAP_UHS_DDR50)
8033 printf(" Can do UHS DDR50\n");
8034 if (cts->host_caps & MMC_CAP_MMC_DDR52_120)
8035 printf(" Can do eMMC DDR52 at 1.2V\n");
8036 if (cts->host_caps & MMC_CAP_MMC_DDR52_180)
8037 printf(" Can do eMMC DDR52 at 1.8V\n");
8038 if (cts->host_caps & MMC_CAP_MMC_HS200_120)
8039 printf(" Can do eMMC HS200 at 1.2V\n");
8040 if (cts->host_caps & MMC_CAP_MMC_HS200_180)
8041 printf(" Can do eMMC HS200 at 1.8V\n");
8042 if (cts->host_caps & MMC_CAP_MMC_HS400_120)
8043 printf(" Can do eMMC HS400 at 1.2V\n");
8044 if (cts->host_caps & MMC_CAP_MMC_HS400_180)
8045 printf(" Can do eMMC HS400 at 1.8V\n");
8047 printf("Supported VCCQ voltages:\n");
8048 if (cts->host_caps & MMC_CAP_SIGNALING_120)
8050 if (cts->host_caps & MMC_CAP_SIGNALING_180)
8052 if (cts->host_caps & MMC_CAP_SIGNALING_330)
8055 printf("Current settings:\n");
8056 printf(" Bus width: ");
8057 switch (cts->ios.bus_width) {
8068 printf(" Freq: %d.%03d MHz%s\n",
8069 cts->ios.clock / 1000000,
8070 (cts->ios.clock / 1000) % 1000,
8071 cts->ios.timing == bus_timing_hs ? " (high-speed timing)" : "");
8074 switch (cts->ios.vccq) {
8088 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8090 if (mmc_data_len > 0) {
8091 flags |= CAM_DIR_IN;
8092 mmc_data = malloc(mmc_data_len);
8093 memset(mmc_data, 0, mmc_data_len);
8094 memset(&mmc_d, 0, sizeof(mmc_d));
8095 mmc_d.len = mmc_data_len;
8096 mmc_d.data = mmc_data;
8097 mmc_d.flags = MMC_DATA_READ;
8098 } else flags |= CAM_DIR_NONE;
8100 cam_fill_mmcio(&ccb->mmcio,
8101 /*retries*/ retry_count,
8104 /*mmc_opcode*/ mmc_opcode,
8105 /*mmc_arg*/ mmc_arg,
8106 /*mmc_flags*/ mmc_flags,
8107 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8108 /*timeout*/ timeout ? timeout : 5000);
8110 if (((retval = cam_send_ccb(device, ccb)) < 0)
8111 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8112 const char warnstr[] = "error sending command";
8119 if (arglist & CAM_ARG_VERBOSE) {
8120 cam_error_print(device, ccb, CAM_ESF_ALL,
8121 CAM_EPF_ALL, stderr);
8125 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8126 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8127 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8128 ccb->mmcio.cmd.resp[1],
8129 ccb->mmcio.cmd.resp[2],
8130 ccb->mmcio.cmd.resp[3]);
8132 switch (mmc_opcode) {
8133 case SD_IO_RW_DIRECT:
8134 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8135 SD_R5_DATA(ccb->mmcio.cmd.resp),
8136 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8138 case SD_IO_RW_EXTENDED:
8139 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8140 hexdump(mmc_data, mmc_data_len, NULL, 0);
8142 case SD_SEND_RELATIVE_ADDR:
8143 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8146 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8147 if (mmc_data_len > 0)
8148 hexdump(mmc_data, mmc_data_len, NULL, 0);
8155 if (mmc_data_len > 0 && mmc_data != NULL)
8162 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8163 char *combinedopt, int retry_count, int timeout)
8166 struct smp_report_general_request *request = NULL;
8167 struct smp_report_general_response *response = NULL;
8168 struct sbuf *sb = NULL;
8170 int c, long_response = 0;
8174 * Note that at the moment we don't support sending SMP CCBs to
8175 * devices that aren't probed by CAM.
8177 ccb = cam_getccb(device);
8179 warnx("%s: error allocating CCB", __func__);
8183 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8192 request = malloc(sizeof(*request));
8193 if (request == NULL) {
8194 warn("%s: unable to allocate %zd bytes", __func__,
8200 response = malloc(sizeof(*response));
8201 if (response == NULL) {
8202 warn("%s: unable to allocate %zd bytes", __func__,
8209 smp_report_general(&ccb->smpio,
8213 /*request_len*/ sizeof(*request),
8214 (uint8_t *)response,
8215 /*response_len*/ sizeof(*response),
8216 /*long_response*/ long_response,
8219 if (((retval = cam_send_ccb(device, ccb)) < 0)
8220 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8221 const char warnstr[] = "error sending command";
8228 if (arglist & CAM_ARG_VERBOSE) {
8229 cam_error_print(device, ccb, CAM_ESF_ALL,
8230 CAM_EPF_ALL, stderr);
8237 * If the device supports the long response bit, try again and see
8238 * if we can get all of the data.
8240 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8241 && (long_response == 0)) {
8242 ccb->ccb_h.status = CAM_REQ_INPROG;
8243 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8249 * XXX KDM detect and decode SMP errors here.
8251 sb = sbuf_new_auto();
8253 warnx("%s: error allocating sbuf", __func__);
8257 smp_report_general_sbuf(response, sizeof(*response), sb);
8259 if (sbuf_finish(sb) != 0) {
8260 warnx("%s: sbuf_finish", __func__);
8264 printf("%s", sbuf_data(sb));
8270 if (request != NULL)
8273 if (response != NULL)
8282 static struct camcontrol_opts phy_ops[] = {
8283 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8284 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8285 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8286 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8287 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8288 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8289 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8290 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8291 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8296 smpphycontrol(struct cam_device *device, int argc, char **argv,
8297 char *combinedopt, int retry_count, int timeout)
8300 struct smp_phy_control_request *request = NULL;
8301 struct smp_phy_control_response *response = NULL;
8302 int long_response = 0;
8305 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8307 uint64_t attached_dev_name = 0;
8308 int dev_name_set = 0;
8309 uint32_t min_plr = 0, max_plr = 0;
8310 uint32_t pp_timeout_val = 0;
8311 int slumber_partial = 0;
8312 int set_pp_timeout_val = 0;
8316 * Note that at the moment we don't support sending SMP CCBs to
8317 * devices that aren't probed by CAM.
8319 ccb = cam_getccb(device);
8321 warnx("%s: error allocating CCB", __func__);
8325 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8333 if (strcasecmp(optarg, "enable") == 0)
8335 else if (strcasecmp(optarg, "disable") == 0)
8338 warnx("%s: Invalid argument %s", __func__,
8345 slumber_partial |= enable <<
8346 SMP_PC_SAS_SLUMBER_SHIFT;
8349 slumber_partial |= enable <<
8350 SMP_PC_SAS_PARTIAL_SHIFT;
8353 slumber_partial |= enable <<
8354 SMP_PC_SATA_SLUMBER_SHIFT;
8357 slumber_partial |= enable <<
8358 SMP_PC_SATA_PARTIAL_SHIFT;
8361 warnx("%s: programmer error", __func__);
8364 break; /*NOTREACHED*/
8369 attached_dev_name = (uintmax_t)strtoumax(optarg,
8378 * We don't do extensive checking here, so this
8379 * will continue to work when new speeds come out.
8381 min_plr = strtoul(optarg, NULL, 0);
8383 || (min_plr > 0xf)) {
8384 warnx("%s: invalid link rate %x",
8392 * We don't do extensive checking here, so this
8393 * will continue to work when new speeds come out.
8395 max_plr = strtoul(optarg, NULL, 0);
8397 || (max_plr > 0xf)) {
8398 warnx("%s: invalid link rate %x",
8405 camcontrol_optret optreturn;
8406 cam_argmask argnums;
8409 if (phy_op_set != 0) {
8410 warnx("%s: only one phy operation argument "
8411 "(-o) allowed", __func__);
8419 * Allow the user to specify the phy operation
8420 * numerically, as well as with a name. This will
8421 * future-proof it a bit, so options that are added
8422 * in future specs can be used.
8424 if (isdigit(optarg[0])) {
8425 phy_operation = strtoul(optarg, NULL, 0);
8426 if ((phy_operation == 0)
8427 || (phy_operation > 0xff)) {
8428 warnx("%s: invalid phy operation %#x",
8429 __func__, phy_operation);
8435 optreturn = getoption(phy_ops, optarg, &phy_operation,
8438 if (optreturn == CC_OR_AMBIGUOUS) {
8439 warnx("%s: ambiguous option %s", __func__,
8444 } else if (optreturn == CC_OR_NOT_FOUND) {
8445 warnx("%s: option %s not found", __func__,
8457 pp_timeout_val = strtoul(optarg, NULL, 0);
8458 if (pp_timeout_val > 15) {
8459 warnx("%s: invalid partial pathway timeout "
8460 "value %u, need a value less than 16",
8461 __func__, pp_timeout_val);
8465 set_pp_timeout_val = 1;
8473 warnx("%s: a PHY (-p phy) argument is required",__func__);
8478 if (((dev_name_set != 0)
8479 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8480 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8481 && (dev_name_set == 0))) {
8482 warnx("%s: -d name and -o setdevname arguments both "
8483 "required to set device name", __func__);
8488 request = malloc(sizeof(*request));
8489 if (request == NULL) {
8490 warn("%s: unable to allocate %zd bytes", __func__,
8496 response = malloc(sizeof(*response));
8497 if (response == NULL) {
8498 warn("%s: unable to allocate %zd bytes", __func__,
8504 smp_phy_control(&ccb->smpio,
8509 (uint8_t *)response,
8512 /*expected_exp_change_count*/ 0,
8515 (set_pp_timeout_val != 0) ? 1 : 0,
8523 if (((retval = cam_send_ccb(device, ccb)) < 0)
8524 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8525 const char warnstr[] = "error sending command";
8532 if (arglist & CAM_ARG_VERBOSE) {
8534 * Use CAM_EPF_NORMAL so we only get one line of
8535 * SMP command decoding.
8537 cam_error_print(device, ccb, CAM_ESF_ALL,
8538 CAM_EPF_NORMAL, stderr);
8544 /* XXX KDM print out something here for success? */
8549 if (request != NULL)
8552 if (response != NULL)
8559 smpmaninfo(struct cam_device *device, int argc, char **argv,
8560 char *combinedopt, int retry_count, int timeout)
8563 struct smp_report_manuf_info_request request;
8564 struct smp_report_manuf_info_response response;
8565 struct sbuf *sb = NULL;
8566 int long_response = 0;
8571 * Note that at the moment we don't support sending SMP CCBs to
8572 * devices that aren't probed by CAM.
8574 ccb = cam_getccb(device);
8576 warnx("%s: error allocating CCB", __func__);
8580 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8589 bzero(&request, sizeof(request));
8590 bzero(&response, sizeof(response));
8592 smp_report_manuf_info(&ccb->smpio,
8597 (uint8_t *)&response,
8602 if (((retval = cam_send_ccb(device, ccb)) < 0)
8603 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8604 const char warnstr[] = "error sending command";
8611 if (arglist & CAM_ARG_VERBOSE) {
8612 cam_error_print(device, ccb, CAM_ESF_ALL,
8613 CAM_EPF_ALL, stderr);
8619 sb = sbuf_new_auto();
8621 warnx("%s: error allocating sbuf", __func__);
8625 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8627 if (sbuf_finish(sb) != 0) {
8628 warnx("%s: sbuf_finish", __func__);
8632 printf("%s", sbuf_data(sb));
8646 getdevid(struct cam_devitem *item)
8649 union ccb *ccb = NULL;
8651 struct cam_device *dev;
8653 dev = cam_open_btl(item->dev_match.path_id,
8654 item->dev_match.target_id,
8655 item->dev_match.target_lun, O_RDWR, NULL);
8658 warnx("%s", cam_errbuf);
8663 item->device_id_len = 0;
8665 ccb = cam_getccb(dev);
8667 warnx("%s: error allocating CCB", __func__);
8673 * On the first try, we just probe for the size of the data, and
8674 * then allocate that much memory and try again.
8677 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8678 ccb->ccb_h.flags = CAM_DIR_IN;
8679 ccb->cdai.flags = CDAI_FLAG_NONE;
8680 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8681 ccb->cdai.bufsiz = item->device_id_len;
8682 if (item->device_id_len != 0)
8683 ccb->cdai.buf = (uint8_t *)item->device_id;
8685 if (cam_send_ccb(dev, ccb) < 0) {
8686 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8691 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8692 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8697 if (item->device_id_len == 0) {
8699 * This is our first time through. Allocate the buffer,
8700 * and then go back to get the data.
8702 if (ccb->cdai.provsiz == 0) {
8703 warnx("%s: invalid .provsiz field returned with "
8704 "XPT_GDEV_ADVINFO CCB", __func__);
8708 item->device_id_len = ccb->cdai.provsiz;
8709 item->device_id = malloc(item->device_id_len);
8710 if (item->device_id == NULL) {
8711 warn("%s: unable to allocate %d bytes", __func__,
8712 item->device_id_len);
8716 ccb->ccb_h.status = CAM_REQ_INPROG;
8722 cam_close_device(dev);
8731 * XXX KDM merge this code with getdevtree()?
8734 buildbusdevlist(struct cam_devlist *devlist)
8737 int bufsize, fd = -1;
8738 struct dev_match_pattern *patterns;
8739 struct cam_devitem *item = NULL;
8740 int skip_device = 0;
8743 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8744 warn("couldn't open %s", XPT_DEVICE);
8748 bzero(&ccb, sizeof(union ccb));
8750 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8751 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8752 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8754 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8755 bufsize = sizeof(struct dev_match_result) * 100;
8756 ccb.cdm.match_buf_len = bufsize;
8757 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8758 if (ccb.cdm.matches == NULL) {
8759 warnx("can't malloc memory for matches");
8763 ccb.cdm.num_matches = 0;
8764 ccb.cdm.num_patterns = 2;
8765 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8766 ccb.cdm.num_patterns;
8768 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8769 if (patterns == NULL) {
8770 warnx("can't malloc memory for patterns");
8775 ccb.cdm.patterns = patterns;
8776 bzero(patterns, ccb.cdm.pattern_buf_len);
8778 patterns[0].type = DEV_MATCH_DEVICE;
8779 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8780 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8781 patterns[1].type = DEV_MATCH_PERIPH;
8782 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8783 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8786 * We do the ioctl multiple times if necessary, in case there are
8787 * more than 100 nodes in the EDT.
8792 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8793 warn("error sending CAMIOCOMMAND ioctl");
8798 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8799 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8800 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8801 warnx("got CAM error %#x, CDM error %d\n",
8802 ccb.ccb_h.status, ccb.cdm.status);
8807 for (i = 0; i < ccb.cdm.num_matches; i++) {
8808 switch (ccb.cdm.matches[i].type) {
8809 case DEV_MATCH_DEVICE: {
8810 struct device_match_result *dev_result;
8813 &ccb.cdm.matches[i].result.device_result;
8815 if (dev_result->flags &
8816 DEV_RESULT_UNCONFIGURED) {
8822 item = malloc(sizeof(*item));
8824 warn("%s: unable to allocate %zd bytes",
8825 __func__, sizeof(*item));
8829 bzero(item, sizeof(*item));
8830 bcopy(dev_result, &item->dev_match,
8831 sizeof(*dev_result));
8832 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8835 if (getdevid(item) != 0) {
8841 case DEV_MATCH_PERIPH: {
8842 struct periph_match_result *periph_result;
8845 &ccb.cdm.matches[i].result.periph_result;
8847 if (skip_device != 0)
8849 item->num_periphs++;
8850 item->periph_matches = realloc(
8851 item->periph_matches,
8853 sizeof(struct periph_match_result));
8854 if (item->periph_matches == NULL) {
8855 warn("%s: error allocating periph "
8860 bcopy(periph_result, &item->periph_matches[
8861 item->num_periphs - 1],
8862 sizeof(*periph_result));
8866 fprintf(stderr, "%s: unexpected match "
8867 "type %d\n", __func__,
8868 ccb.cdm.matches[i].type);
8871 break; /*NOTREACHED*/
8874 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8875 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8883 free(ccb.cdm.matches);
8886 freebusdevlist(devlist);
8892 freebusdevlist(struct cam_devlist *devlist)
8894 struct cam_devitem *item, *item2;
8896 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8897 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8899 free(item->device_id);
8900 free(item->periph_matches);
8905 static struct cam_devitem *
8906 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8908 struct cam_devitem *item;
8910 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8911 struct scsi_vpd_id_descriptor *idd;
8914 * XXX KDM look for LUN IDs as well?
8916 idd = scsi_get_devid(item->device_id,
8917 item->device_id_len,
8918 scsi_devid_is_sas_target);
8922 if (scsi_8btou64(idd->identifier) == sasaddr)
8930 smpphylist(struct cam_device *device, int argc, char **argv,
8931 char *combinedopt, int retry_count, int timeout)
8933 struct smp_report_general_request *rgrequest = NULL;
8934 struct smp_report_general_response *rgresponse = NULL;
8935 struct smp_discover_request *disrequest = NULL;
8936 struct smp_discover_response *disresponse = NULL;
8937 struct cam_devlist devlist;
8939 int long_response = 0;
8946 * Note that at the moment we don't support sending SMP CCBs to
8947 * devices that aren't probed by CAM.
8949 ccb = cam_getccb(device);
8951 warnx("%s: error allocating CCB", __func__);
8955 STAILQ_INIT(&devlist.dev_queue);
8957 rgrequest = malloc(sizeof(*rgrequest));
8958 if (rgrequest == NULL) {
8959 warn("%s: unable to allocate %zd bytes", __func__,
8960 sizeof(*rgrequest));
8965 rgresponse = malloc(sizeof(*rgresponse));
8966 if (rgresponse == NULL) {
8967 warn("%s: unable to allocate %zd bytes", __func__,
8968 sizeof(*rgresponse));
8973 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8986 smp_report_general(&ccb->smpio,
8990 /*request_len*/ sizeof(*rgrequest),
8991 (uint8_t *)rgresponse,
8992 /*response_len*/ sizeof(*rgresponse),
8993 /*long_response*/ long_response,
8996 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8998 if (((retval = cam_send_ccb(device, ccb)) < 0)
8999 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
9000 const char warnstr[] = "error sending command";
9007 if (arglist & CAM_ARG_VERBOSE) {
9008 cam_error_print(device, ccb, CAM_ESF_ALL,
9009 CAM_EPF_ALL, stderr);
9015 num_phys = rgresponse->num_phys;
9017 if (num_phys == 0) {
9019 fprintf(stdout, "%s: No Phys reported\n", __func__);
9024 devlist.path_id = device->path_id;
9026 retval = buildbusdevlist(&devlist);
9031 fprintf(stdout, "%d PHYs:\n", num_phys);
9032 fprintf(stdout, "PHY Attached SAS Address\n");
9035 disrequest = malloc(sizeof(*disrequest));
9036 if (disrequest == NULL) {
9037 warn("%s: unable to allocate %zd bytes", __func__,
9038 sizeof(*disrequest));
9043 disresponse = malloc(sizeof(*disresponse));
9044 if (disresponse == NULL) {
9045 warn("%s: unable to allocate %zd bytes", __func__,
9046 sizeof(*disresponse));
9051 for (i = 0; i < num_phys; i++) {
9052 struct cam_devitem *item;
9053 struct device_match_result *dev_match;
9054 char vendor[16], product[48], revision[16];
9058 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9060 ccb->ccb_h.status = CAM_REQ_INPROG;
9061 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9063 smp_discover(&ccb->smpio,
9067 sizeof(*disrequest),
9068 (uint8_t *)disresponse,
9069 sizeof(*disresponse),
9071 /*ignore_zone_group*/ 0,
9075 if (((retval = cam_send_ccb(device, ccb)) < 0)
9076 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9077 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9078 const char warnstr[] = "error sending command";
9085 if (arglist & CAM_ARG_VERBOSE) {
9086 cam_error_print(device, ccb, CAM_ESF_ALL,
9087 CAM_EPF_ALL, stderr);
9093 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9095 fprintf(stdout, "%3d <vacant>\n", i);
9099 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9102 item = findsasdevice(&devlist,
9103 scsi_8btou64(disresponse->attached_sas_address));
9107 || (item != NULL)) {
9108 fprintf(stdout, "%3d 0x%016jx", i,
9109 (uintmax_t)scsi_8btou64(
9110 disresponse->attached_sas_address));
9112 fprintf(stdout, "\n");
9115 } else if (quiet != 0)
9118 dev_match = &item->dev_match;
9120 if (dev_match->protocol == PROTO_SCSI) {
9121 cam_strvis(vendor, dev_match->inq_data.vendor,
9122 sizeof(dev_match->inq_data.vendor),
9124 cam_strvis(product, dev_match->inq_data.product,
9125 sizeof(dev_match->inq_data.product),
9127 cam_strvis(revision, dev_match->inq_data.revision,
9128 sizeof(dev_match->inq_data.revision),
9130 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9132 } else if ((dev_match->protocol == PROTO_ATA)
9133 || (dev_match->protocol == PROTO_SATAPM)) {
9134 cam_strvis(product, dev_match->ident_data.model,
9135 sizeof(dev_match->ident_data.model),
9137 cam_strvis(revision, dev_match->ident_data.revision,
9138 sizeof(dev_match->ident_data.revision),
9140 sprintf(tmpstr, "<%s %s>", product, revision);
9142 sprintf(tmpstr, "<>");
9144 fprintf(stdout, " %-33s ", tmpstr);
9147 * If we have 0 periphs, that's a bug...
9149 if (item->num_periphs == 0) {
9150 fprintf(stdout, "\n");
9154 fprintf(stdout, "(");
9155 for (j = 0; j < item->num_periphs; j++) {
9157 fprintf(stdout, ",");
9159 fprintf(stdout, "%s%d",
9160 item->periph_matches[j].periph_name,
9161 item->periph_matches[j].unit_number);
9164 fprintf(stdout, ")\n");
9178 freebusdevlist(&devlist);
9184 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9186 uint8_t error = 0, ata_device = 0, status = 0;
9191 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9194 if (arglist & CAM_ARG_VERBOSE) {
9195 cam_error_print(device, ccb, CAM_ESF_ALL,
9196 CAM_EPF_ALL, stderr);
9198 warnx("Can't get ATA command status");
9202 if (status & ATA_STATUS_ERROR) {
9203 cam_error_print(device, ccb, CAM_ESF_ALL,
9204 CAM_EPF_ALL, stderr);
9208 printf("%s%d: ", device->device_name, device->dev_unit_num);
9210 case ATA_PM_STANDBY:
9211 printf("Standby mode\n");
9213 case ATA_PM_STANDBY_Y:
9214 printf("Standby_y mode\n");
9216 case 0x40: /* obsolete since ACS-3 */
9217 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9219 case 0x41: /* obsolete since ACS-3 */
9220 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9223 printf("Idle mode\n");
9226 printf("Idle_a mode\n");
9229 printf("Idle_b mode\n");
9232 printf("Idle_c mode\n");
9234 case ATA_PM_ACTIVE_IDLE:
9235 printf("Active or Idle mode\n");
9238 printf("Unknown mode 0x%02x\n", count);
9246 atapm(struct cam_device *device, int argc, char **argv,
9247 char *combinedopt, int retry_count, int timeout)
9253 u_int8_t ata_flags = 0;
9256 ccb = cam_getccb(device);
9259 warnx("%s: error allocating ccb", __func__);
9263 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9272 if (strcmp(argv[1], "idle") == 0) {
9274 cmd = ATA_IDLE_IMMEDIATE;
9277 } else if (strcmp(argv[1], "standby") == 0) {
9279 cmd = ATA_STANDBY_IMMEDIATE;
9281 cmd = ATA_STANDBY_CMD;
9282 } else if (strcmp(argv[1], "powermode") == 0) {
9283 cmd = ATA_CHECK_POWER_MODE;
9284 ata_flags = AP_FLAG_CHK_COND;
9293 else if (t <= (240 * 5))
9295 else if (t <= (252 * 5))
9296 /* special encoding for 21 minutes */
9298 else if (t <= (11 * 30 * 60))
9299 sc = (t - 1) / (30 * 60) + 241;
9303 retval = ata_do_cmd(device,
9305 /*retries*/retry_count,
9306 /*flags*/CAM_DIR_NONE,
9307 /*protocol*/AP_PROTO_NON_DATA,
9308 /*ata_flags*/ata_flags,
9309 /*tag_action*/MSG_SIMPLE_Q_TAG,
9316 /*timeout*/timeout ? timeout : 30 * 1000,
9319 if (retval == 0 && cmd == ATA_CHECK_POWER_MODE)
9320 retval = atapm_proc_resp(device, ccb);
9327 ataaxm(struct cam_device *device, int argc, char **argv,
9328 char *combinedopt, int retry_count, int timeout)
9336 ccb = cam_getccb(device);
9339 warnx("%s: error allocating ccb", __func__);
9343 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9353 if (strcmp(argv[1], "apm") == 0) {
9369 retval = ata_do_cmd(device,
9371 /*retries*/retry_count,
9372 /*flags*/CAM_DIR_NONE,
9373 /*protocol*/AP_PROTO_NON_DATA,
9375 /*tag_action*/MSG_SIMPLE_Q_TAG,
9376 /*command*/ATA_SETFEATURES,
9382 /*timeout*/timeout ? timeout : 30 * 1000,
9390 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9391 int show_sa_errors, int sa_set, int service_action,
9392 int timeout_desc, int task_attr, int retry_count, int timeout,
9393 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9395 union ccb *ccb = NULL;
9396 uint8_t *buf = NULL;
9397 uint32_t alloc_len = 0, num_opcodes;
9398 uint32_t valid_len = 0;
9399 uint32_t avail_len = 0;
9400 struct scsi_report_supported_opcodes_all *all_hdr;
9401 struct scsi_report_supported_opcodes_one *one;
9406 * Make it clear that we haven't yet allocated or filled anything.
9411 ccb = cam_getccb(device);
9413 warnx("couldn't allocate CCB");
9418 if (opcode_set != 0) {
9419 options |= RSO_OPTIONS_OC;
9421 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9424 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9425 sizeof(struct scsi_report_supported_opcodes_descr));
9428 if (timeout_desc != 0) {
9429 options |= RSO_RCTD;
9430 alloc_len += num_opcodes *
9431 sizeof(struct scsi_report_supported_opcodes_timeout);
9435 options |= RSO_OPTIONS_OC_SA;
9436 if (show_sa_errors != 0)
9437 options &= ~RSO_OPTIONS_OC;
9446 buf = malloc(alloc_len);
9448 warn("Unable to allocate %u bytes", alloc_len);
9452 bzero(buf, alloc_len);
9454 scsi_report_supported_opcodes(&ccb->csio,
9455 /*retries*/ retry_count,
9457 /*tag_action*/ task_attr,
9458 /*options*/ options,
9459 /*req_opcode*/ opcode,
9460 /*req_service_action*/ service_action,
9462 /*dxfer_len*/ alloc_len,
9463 /*sense_len*/ SSD_FULL_SIZE,
9464 /*timeout*/ timeout ? timeout : 10000);
9466 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9468 if (retry_count != 0)
9469 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9471 if (cam_send_ccb(device, ccb) < 0) {
9472 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9477 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9478 if (verbosemode != 0)
9479 cam_error_print(device, ccb, CAM_ESF_ALL,
9480 CAM_EPF_ALL, stderr);
9485 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9487 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9488 && (valid_len >= sizeof(*all_hdr))) {
9489 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9490 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9491 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9492 && (valid_len >= sizeof(*one))) {
9493 uint32_t cdb_length;
9495 one = (struct scsi_report_supported_opcodes_one *)buf;
9496 cdb_length = scsi_2btoul(one->cdb_length);
9497 avail_len = sizeof(*one) + cdb_length;
9498 if (one->support & RSO_ONE_CTDP) {
9499 struct scsi_report_supported_opcodes_timeout *td;
9501 td = (struct scsi_report_supported_opcodes_timeout *)
9503 if (valid_len >= (avail_len + sizeof(td->length))) {
9504 avail_len += scsi_2btoul(td->length) +
9507 avail_len += sizeof(*td);
9513 * avail_len could be zero if we didn't get enough data back from
9514 * thet target to determine
9516 if ((avail_len != 0)
9517 && (avail_len > valid_len)) {
9518 alloc_len = avail_len;
9522 *fill_len = valid_len;
9534 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9535 int req_sa, uint8_t *buf, uint32_t valid_len)
9537 struct scsi_report_supported_opcodes_one *one;
9538 struct scsi_report_supported_opcodes_timeout *td;
9539 uint32_t cdb_len = 0, td_len = 0;
9540 const char *op_desc = NULL;
9544 one = (struct scsi_report_supported_opcodes_one *)buf;
9547 * If we don't have the full single opcode descriptor, no point in
9550 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9552 warnx("Only %u bytes returned, not enough to verify support",
9558 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9560 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9563 printf(", SA 0x%x", req_sa);
9566 switch (one->support & RSO_ONE_SUP_MASK) {
9567 case RSO_ONE_SUP_UNAVAIL:
9568 printf("No command support information currently available\n");
9570 case RSO_ONE_SUP_NOT_SUP:
9571 printf("Command not supported\n");
9574 break; /*NOTREACHED*/
9575 case RSO_ONE_SUP_AVAIL:
9576 printf("Command is supported, complies with a SCSI standard\n");
9578 case RSO_ONE_SUP_VENDOR:
9579 printf("Command is supported, vendor-specific "
9580 "implementation\n");
9583 printf("Unknown command support flags 0x%#x\n",
9584 one->support & RSO_ONE_SUP_MASK);
9589 * If we don't have the CDB length, it isn't exactly an error, the
9590 * command probably isn't supported.
9592 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9596 cdb_len = scsi_2btoul(one->cdb_length);
9599 * If our valid data doesn't include the full reported length,
9600 * return. The caller should have detected this and adjusted his
9601 * allocation length to get all of the available data.
9603 if (valid_len < sizeof(*one) + cdb_len) {
9609 * If all we have is the opcode, there is no point in printing out
9617 printf("CDB usage bitmap:");
9618 for (i = 0; i < cdb_len; i++) {
9619 printf(" %02x", one->cdb_usage[i]);
9624 * If we don't have a timeout descriptor, we're done.
9626 if ((one->support & RSO_ONE_CTDP) == 0)
9630 * If we don't have enough valid length to include the timeout
9631 * descriptor length, we're done.
9633 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9636 td = (struct scsi_report_supported_opcodes_timeout *)
9637 &buf[sizeof(*one) + cdb_len];
9638 td_len = scsi_2btoul(td->length);
9639 td_len += sizeof(td->length);
9642 * If we don't have the full timeout descriptor, we're done.
9644 if (td_len < sizeof(*td))
9648 * If we don't have enough valid length to contain the full timeout
9649 * descriptor, we're done.
9651 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9654 printf("Timeout information:\n");
9655 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9656 printf("Nominal timeout: %u seconds\n",
9657 scsi_4btoul(td->nominal_time));
9658 printf("Recommended timeout: %u seconds\n",
9659 scsi_4btoul(td->recommended_time));
9666 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9669 struct scsi_report_supported_opcodes_all *hdr;
9670 struct scsi_report_supported_opcodes_descr *desc;
9671 uint32_t avail_len = 0, used_len = 0;
9675 if (valid_len < sizeof(*hdr)) {
9676 warnx("%s: not enough returned data (%u bytes) opcode list",
9677 __func__, valid_len);
9681 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9682 avail_len = scsi_4btoul(hdr->length);
9683 avail_len += sizeof(hdr->length);
9685 * Take the lesser of the amount of data the drive claims is
9686 * available, and the amount of data the HBA says was returned.
9688 avail_len = MIN(avail_len, valid_len);
9690 used_len = sizeof(hdr->length);
9692 printf("%-6s %4s %8s ",
9693 "Opcode", "SA", "CDB len" );
9696 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9697 printf(" Description\n");
9699 while ((avail_len - used_len) > sizeof(*desc)) {
9700 struct scsi_report_supported_opcodes_timeout *td;
9702 const char *op_desc = NULL;
9704 cur_ptr = &buf[used_len];
9705 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9707 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9708 if (op_desc == NULL)
9709 op_desc = "UNKNOWN";
9711 printf("0x%02x %#4x %8u ", desc->opcode,
9712 scsi_2btoul(desc->service_action),
9713 scsi_2btoul(desc->cdb_length));
9715 used_len += sizeof(*desc);
9717 if ((desc->flags & RSO_CTDP) == 0) {
9718 printf(" %s\n", op_desc);
9723 * If we don't have enough space to fit a timeout
9724 * descriptor, then we're done.
9726 if (avail_len - used_len < sizeof(*td)) {
9727 used_len = avail_len;
9728 printf(" %s\n", op_desc);
9731 cur_ptr = &buf[used_len];
9732 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9733 td_len = scsi_2btoul(td->length);
9734 td_len += sizeof(td->length);
9738 * If the given timeout descriptor length is less than what
9739 * we understand, skip it.
9741 if (td_len < sizeof(*td)) {
9742 printf(" %s\n", op_desc);
9746 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9747 scsi_4btoul(td->nominal_time),
9748 scsi_4btoul(td->recommended_time), op_desc);
9755 scsiopcodes(struct cam_device *device, int argc, char **argv,
9756 char *combinedopt, int task_attr, int retry_count, int timeout,
9760 uint32_t opcode = 0, service_action = 0;
9761 int td_set = 0, opcode_set = 0, sa_set = 0;
9762 int show_sa_errors = 1;
9763 uint32_t valid_len = 0;
9764 uint8_t *buf = NULL;
9768 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9774 opcode = strtoul(optarg, &endptr, 0);
9775 if (*endptr != '\0') {
9776 warnx("Invalid opcode \"%s\", must be a number",
9781 if (opcode > 0xff) {
9782 warnx("Invalid opcode 0x%#x, must be between"
9783 "0 and 0xff inclusive", opcode);
9790 service_action = strtoul(optarg, &endptr, 0);
9791 if (*endptr != '\0') {
9792 warnx("Invalid service action \"%s\", must "
9793 "be a number", optarg);
9797 if (service_action > 0xffff) {
9798 warnx("Invalid service action 0x%#x, must "
9799 "be between 0 and 0xffff inclusive",
9814 && (opcode_set == 0)) {
9815 warnx("You must specify an opcode with -o if a service "
9820 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9821 sa_set, service_action, td_set, task_attr,
9822 retry_count, timeout, verbosemode, &valid_len,
9827 if ((opcode_set != 0)
9829 retval = scsiprintoneopcode(device, opcode, sa_set,
9830 service_action, buf, valid_len);
9832 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9843 reprobe(struct cam_device *device)
9848 ccb = cam_getccb(device);
9851 warnx("%s: error allocating ccb", __func__);
9855 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9857 if (cam_send_ccb(device, ccb) < 0) {
9858 warn("error sending XPT_REPROBE_LUN CCB");
9863 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9864 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9876 usage(int printlong)
9879 fprintf(printlong ? stdout : stderr,
9880 "usage: camcontrol <command> [device id][generic args][command args]\n"
9881 " camcontrol devlist [-b] [-v]\n"
9882 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9883 " camcontrol tur [dev_id][generic args]\n"
9884 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9885 " camcontrol identify [dev_id][generic args] [-v]\n"
9886 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9887 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9889 " camcontrol start [dev_id][generic args]\n"
9890 " camcontrol stop [dev_id][generic args]\n"
9891 " camcontrol load [dev_id][generic args]\n"
9892 " camcontrol eject [dev_id][generic args]\n"
9893 " camcontrol reprobe [dev_id][generic args]\n"
9894 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9895 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9896 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9897 " [-q][-s][-S offset][-X]\n"
9898 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9899 " [-P pagectl][-e | -b][-d]\n"
9900 " camcontrol cmd [dev_id][generic args]\n"
9901 " <-a cmd [args] | -c cmd [args]>\n"
9902 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9903 " camcontrol smpcmd [dev_id][generic args]\n"
9904 " <-r len fmt [args]> <-R len fmt [args]>\n"
9905 " camcontrol smprg [dev_id][generic args][-l]\n"
9906 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9907 " [-o operation][-d name][-m rate][-M rate]\n"
9908 " [-T pp_timeout][-a enable|disable]\n"
9909 " [-A enable|disable][-s enable|disable]\n"
9910 " [-S enable|disable]\n"
9911 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9912 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9913 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9914 " <all|dev_id|bus[:target[:lun]]|off>\n"
9915 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9916 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9917 " [-D <enable|disable>][-M mode][-O offset]\n"
9918 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9919 " [-U][-W bus_width]\n"
9920 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9921 " camcontrol sanitize [dev_id][generic args]\n"
9922 " [-a overwrite|block|crypto|exitfailure]\n"
9923 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9925 " camcontrol idle [dev_id][generic args][-t time]\n"
9926 " camcontrol standby [dev_id][generic args][-t time]\n"
9927 " camcontrol sleep [dev_id][generic args]\n"
9928 " camcontrol powermode [dev_id][generic args]\n"
9929 " camcontrol apm [dev_id][generic args][-l level]\n"
9930 " camcontrol aam [dev_id][generic args][-l level]\n"
9931 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9933 " camcontrol security [dev_id][generic args]\n"
9934 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9935 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9936 " [-U <user|master>] [-y]\n"
9937 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9938 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9939 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9940 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9941 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9942 " [-s scope][-S][-T type][-U]\n"
9943 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9944 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9945 " [-p part][-s start][-T type][-V vol]\n"
9946 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9948 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9949 " [-o rep_opts] [-P print_opts]\n"
9950 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9951 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9952 " [-S power_src] [-T timer]\n"
9953 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9954 " <-s <-f format -T time | -U >>\n"
9955 " camcontrol devtype [dev_id]\n"
9956 " camcontrol depop [dev_id] [-d | -l | -r] [-e element] [-c capacity]\n"
9957 " camcontrol mmcsdcmd [dev_id] [[-c mmc_opcode] [-a mmc_arg]\n"
9958 " [-f mmc_flags] [-l data_len]\n"
9959 " [-W [-b data_byte]]] |\n"
9960 " [-F frequency] |\n"
9963 " [-S high|normal]\n"
9965 " camcontrol help\n");
9969 "Specify one of the following options:\n"
9970 "devlist list all CAM devices\n"
9971 "periphlist list all CAM peripheral drivers attached to a device\n"
9972 "tur send a test unit ready to the named device\n"
9973 "inquiry send a SCSI inquiry command to the named device\n"
9974 "identify send a ATA identify command to the named device\n"
9975 "reportluns send a SCSI report luns command to the device\n"
9976 "readcap send a SCSI read capacity command to the device\n"
9977 "start send a Start Unit command to the device\n"
9978 "stop send a Stop Unit command to the device\n"
9979 "load send a Start Unit command to the device with the load bit set\n"
9980 "eject send a Stop Unit command to the device with the eject bit set\n"
9981 "reprobe update capacity information of the given device\n"
9982 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9983 "reset reset all buses, the given bus, bus:target:lun or device\n"
9984 "defects read the defect list of the specified device\n"
9985 "modepage display or edit (-e) the given mode page\n"
9986 "cmd send the given SCSI command, may need -i or -o as well\n"
9987 "smpcmd send the given SMP command, requires -o and -i\n"
9988 "smprg send the SMP Report General command\n"
9989 "smppc send the SMP PHY Control command, requires -p\n"
9990 "smpphylist display phys attached to a SAS expander\n"
9991 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9992 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9993 "tags report or set the number of transaction slots for a device\n"
9994 "negotiate report or set device negotiation parameters\n"
9995 "format send the SCSI FORMAT UNIT command to the named device\n"
9996 "sanitize send the SCSI SANITIZE command to the named device\n"
9997 "idle send the ATA IDLE command to the named device\n"
9998 "standby send the ATA STANDBY command to the named device\n"
9999 "sleep send the ATA SLEEP command to the named device\n"
10000 "powermode send the ATA CHECK POWER MODE command to the named device\n"
10001 "fwdownload program firmware of the named device with the given image\n"
10002 "security report or send ATA security commands to the named device\n"
10003 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
10004 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
10005 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
10006 "zone manage Zoned Block (Shingled) devices\n"
10007 "epc send ATA Extended Power Conditions commands\n"
10008 "timestamp report or set the device's timestamp\n"
10009 "devtype report the type of device\n"
10010 "depop manage drive storage elements\n"
10011 "mmcsdcmd send the given MMC command, needs -c and -a as well\n"
10012 "help this message\n"
10013 "Device Identifiers:\n"
10014 "bus:target specify the bus and target, lun defaults to 0\n"
10015 "bus:target:lun specify the bus, target and lun\n"
10016 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
10017 "Generic arguments:\n"
10018 "-v be verbose, print out sense information\n"
10019 "-t timeout command timeout in seconds, overrides default timeout\n"
10020 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
10021 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
10022 "-E have the kernel attempt to perform SCSI error recovery\n"
10023 "-C count specify the SCSI command retry count (needs -E to work)\n"
10024 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
10025 "modepage arguments:\n"
10026 "-l list all available mode pages\n"
10027 "-m page specify the mode page to view or edit\n"
10028 "-e edit the specified mode page\n"
10029 "-b force view to binary mode\n"
10030 "-d disable block descriptors for mode sense\n"
10031 "-P pgctl page control field 0-3\n"
10032 "defects arguments:\n"
10033 "-f format specify defect list format (block, bfi or phys)\n"
10034 "-G get the grown defect list\n"
10035 "-P get the permanent defect list\n"
10036 "inquiry arguments:\n"
10037 "-D get the standard inquiry data\n"
10038 "-S get the serial number\n"
10039 "-R get the transfer rate, etc.\n"
10040 "reportluns arguments:\n"
10041 "-c only report a count of available LUNs\n"
10042 "-l only print out luns, and not a count\n"
10043 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10044 "readcap arguments\n"
10045 "-b only report the blocksize\n"
10046 "-h human readable device size, base 2\n"
10047 "-H human readable device size, base 10\n"
10048 "-N print the number of blocks instead of last block\n"
10049 "-q quiet, print numbers only\n"
10050 "-s only report the last block/device size\n"
10052 "-c cdb [args] specify the SCSI CDB\n"
10053 "-i len fmt specify input data and input data format\n"
10054 "-o len fmt [args] specify output data and output data fmt\n"
10055 "smpcmd arguments:\n"
10056 "-r len fmt [args] specify the SMP command to be sent\n"
10057 "-R len fmt [args] specify SMP response format\n"
10058 "smprg arguments:\n"
10059 "-l specify the long response format\n"
10060 "smppc arguments:\n"
10061 "-p phy specify the PHY to operate on\n"
10062 "-l specify the long request/response format\n"
10063 "-o operation specify the phy control operation\n"
10064 "-d name set the attached device name\n"
10065 "-m rate set the minimum physical link rate\n"
10066 "-M rate set the maximum physical link rate\n"
10067 "-T pp_timeout set the partial pathway timeout value\n"
10068 "-a enable|disable enable or disable SATA slumber\n"
10069 "-A enable|disable enable or disable SATA partial phy power\n"
10070 "-s enable|disable enable or disable SAS slumber\n"
10071 "-S enable|disable enable or disable SAS partial phy power\n"
10072 "smpphylist arguments:\n"
10073 "-l specify the long response format\n"
10074 "-q only print phys with attached devices\n"
10075 "smpmaninfo arguments:\n"
10076 "-l specify the long response format\n"
10077 "debug arguments:\n"
10078 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10079 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10080 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10081 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10082 "tags arguments:\n"
10083 "-N tags specify the number of tags to use for this device\n"
10084 "-q be quiet, don't report the number of tags\n"
10085 "-v report a number of tag-related parameters\n"
10086 "negotiate arguments:\n"
10087 "-a send a test unit ready after negotiation\n"
10088 "-c report/set current negotiation settings\n"
10089 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10090 "-M mode set ATA mode\n"
10091 "-O offset set command delay offset\n"
10092 "-q be quiet, don't report anything\n"
10093 "-R syncrate synchronization rate in MHz\n"
10094 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10095 "-U report/set user negotiation settings\n"
10096 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10097 "-v also print a Path Inquiry CCB for the controller\n"
10098 "format arguments:\n"
10099 "-q be quiet, don't print status messages\n"
10100 "-r run in report only mode\n"
10101 "-w don't send immediate format command\n"
10102 "-y don't ask any questions\n"
10103 "sanitize arguments:\n"
10104 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10105 "-c passes overwrite passes to perform (1 to 31)\n"
10106 "-I invert overwrite pattern after each pass\n"
10107 "-P pattern path to overwrite pattern file\n"
10108 "-q be quiet, don't print status messages\n"
10109 "-r run in report only mode\n"
10110 "-U run operation in unrestricted completion exit mode\n"
10111 "-w don't send immediate sanitize command\n"
10112 "-y don't ask any questions\n"
10113 "idle/standby arguments:\n"
10114 "-t <arg> number of seconds before respective state.\n"
10115 "fwdownload arguments:\n"
10116 "-f fw_image path to firmware image file\n"
10117 "-q don't print informational messages, only errors\n"
10118 "-s run in simulation mode\n"
10119 "-v print info for every firmware segment sent to device\n"
10120 "-y don't ask any questions\n"
10121 "security arguments:\n"
10122 "-d pwd disable security using the given password for the selected\n"
10124 "-e pwd erase the device using the given pwd for the selected user\n"
10125 "-f freeze the security configuration of the specified device\n"
10126 "-h pwd enhanced erase the device using the given pwd for the\n"
10128 "-k pwd unlock the device using the given pwd for the selected\n"
10130 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10131 "-q be quiet, do not print any status messages\n"
10132 "-s pwd password the device (enable security) using the given\n"
10133 " pwd for the selected user\n"
10134 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10135 "-U <user|master> specifies which user to set: user or master\n"
10136 "-y don't ask any questions\n"
10138 "-f freeze the HPA configuration of the device\n"
10139 "-l lock the HPA configuration of the device\n"
10140 "-P make the HPA max sectors persist\n"
10141 "-p pwd Set the HPA configuration password required for unlock\n"
10143 "-q be quiet, do not print any status messages\n"
10144 "-s sectors configures the maximum user accessible sectors of the\n"
10146 "-U pwd unlock the HPA configuration of the device\n"
10147 "-y don't ask any questions\n"
10149 "-f freeze the AMA configuration of the device\n"
10150 "-q be quiet, do not print any status messages\n"
10151 "-s sectors configures the maximum user accessible sectors of the\n"
10153 "persist arguments:\n"
10154 "-i action specify read_keys, read_reservation, report_cap, or\n"
10155 " read_full_status\n"
10156 "-o action specify register, register_ignore, reserve, release,\n"
10157 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10158 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10159 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10160 "-k key specify the Reservation Key\n"
10161 "-K sa_key specify the Service Action Reservation Key\n"
10162 "-p set the Activate Persist Through Power Loss bit\n"
10163 "-R rtp specify the Relative Target Port\n"
10164 "-s scope specify the scope: lun, extent, element or a number\n"
10165 "-S specify Transport ID for register, requires -I\n"
10166 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10167 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10168 "-U unregister the current initiator for register_move\n"
10169 "attrib arguments:\n"
10170 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10172 "-w attr specify an attribute to write, one -w argument per attr\n"
10173 "-a attr_num only display this attribute number\n"
10174 "-c get cached attributes\n"
10175 "-e elem_addr request attributes for the given element in a changer\n"
10176 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10177 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10178 " field_none, field_desc, field_num, field_size, field_rw\n"
10179 "-p partition request attributes for the given partition\n"
10180 "-s start_attr request attributes starting at the given number\n"
10181 "-T elem_type specify the element type (used with -e)\n"
10182 "-V logical_vol specify the logical volume ID\n"
10183 "opcodes arguments:\n"
10184 "-o opcode specify the individual opcode to list\n"
10185 "-s service_action specify the service action for the opcode\n"
10186 "-N do not return SCSI error for unsupported SA\n"
10187 "-T request nominal and recommended timeout values\n"
10188 "zone arguments:\n"
10189 "-c cmd required: rz, open, close, finish, or rwp\n"
10190 "-a apply the action to all zones\n"
10191 "-l LBA specify the zone starting LBA\n"
10192 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10193 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10194 "-P print_opt report zones printing: normal, summary, script\n"
10196 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10197 " source, status, list\n"
10198 "-d disable power mode (timer, state)\n"
10199 "-D delayed entry (goto)\n"
10200 "-e enable power mode (timer, state)\n"
10201 "-H hold power mode (goto)\n"
10202 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10204 "-P only display power mode (status)\n"
10205 "-r rst_src restore settings from: default, saved (restore)\n"
10206 "-s save mode (timer, state, restore)\n"
10207 "-S power_src set power source: battery, nonbattery (source)\n"
10208 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10209 "timestamp arguments:\n"
10210 "-r report the timestamp of the device\n"
10211 "-f format report the timestamp of the device with the given\n"
10212 " strftime(3) format string\n"
10213 "-m report the timestamp of the device as milliseconds since\n"
10214 " January 1st, 1970\n"
10215 "-U report the time with UTC instead of the local time zone\n"
10216 "-s set the timestamp of the device\n"
10217 "-f format the format of the time string passed into strptime(3)\n"
10218 "-T time the time value passed into strptime(3)\n"
10219 "-U set the timestamp of the device to UTC time\n"
10220 "depop arguments:\n"
10221 "-d remove an element from service\n"
10222 "-l list status of all elements of drive\n"
10223 "-r restore all elements to service\n"
10224 "-e elm element to remove\n"
10225 "-c capacity requested new capacity\n"
10226 "mmcsdcmd arguments:\n"
10227 "-c mmc_cmd MMC command to send to the card\n"
10228 "-a mmc_arg Argument for the MMC command\n"
10229 "-f mmc_flag Flags to set for the MMC command\n"
10230 "-l data_len Expect data_len bytes of data in reply and display them\n"
10231 "-W Fill the data buffer before invoking the MMC command\n"
10232 "-b data_byte One byte of data to fill the data buffer with\n"
10233 "-F frequency Operating frequency to set on the controller\n"
10234 "-4 Set bus width to 4 bit\n"
10235 "-1 Set bus width to 8 bit\n"
10236 "-S high | std Set high-speed or standard timing\n"
10237 "-I Display various card and host controller information\n"
10242 main(int argc, char **argv)
10245 char *device = NULL;
10247 struct cam_device *cam_dev = NULL;
10248 int timeout = 0, retry_count = 1;
10249 camcontrol_optret optreturn;
10251 const char *mainopt = "C:En:Q:t:u:v";
10252 const char *subopt = NULL;
10253 char combinedopt[256];
10254 int error = 0, optstart = 2;
10255 int task_attr = MSG_SIMPLE_Q_TAG;
10259 target_id_t target;
10262 cmdlist = CAM_CMD_NONE;
10263 arglist = CAM_ARG_NONE;
10271 * Get the base option.
10273 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10275 if (optreturn == CC_OR_AMBIGUOUS) {
10276 warnx("ambiguous option %s", argv[1]);
10279 } else if (optreturn == CC_OR_NOT_FOUND) {
10280 warnx("option %s not found", argv[1]);
10286 * Ahh, getopt(3) is a pain.
10288 * This is a gross hack. There really aren't many other good
10289 * options (excuse the pun) for parsing options in a situation like
10290 * this. getopt is kinda braindead, so you end up having to run
10291 * through the options twice, and give each invocation of getopt
10292 * the option string for the other invocation.
10294 * You would think that you could just have two groups of options.
10295 * The first group would get parsed by the first invocation of
10296 * getopt, and the second group would get parsed by the second
10297 * invocation of getopt. It doesn't quite work out that way. When
10298 * the first invocation of getopt finishes, it leaves optind pointing
10299 * to the argument _after_ the first argument in the second group.
10300 * So when the second invocation of getopt comes around, it doesn't
10301 * recognize the first argument it gets and then bails out.
10303 * A nice alternative would be to have a flag for getopt that says
10304 * "just keep parsing arguments even when you encounter an unknown
10305 * argument", but there isn't one. So there's no real clean way to
10306 * easily parse two sets of arguments without having one invocation
10307 * of getopt know about the other.
10309 * Without this hack, the first invocation of getopt would work as
10310 * long as the generic arguments are first, but the second invocation
10311 * (in the subfunction) would fail in one of two ways. In the case
10312 * where you don't set optreset, it would fail because optind may be
10313 * pointing to the argument after the one it should be pointing at.
10314 * In the case where you do set optreset, and reset optind, it would
10315 * fail because getopt would run into the first set of options, which
10316 * it doesn't understand.
10318 * All of this would "sort of" work if you could somehow figure out
10319 * whether optind had been incremented one option too far. The
10320 * mechanics of that, however, are more daunting than just giving
10321 * both invocations all of the expect options for either invocation.
10323 * Needless to say, I wouldn't mind if someone invented a better
10324 * (non-GPL!) command line parsing interface than getopt. I
10325 * wouldn't mind if someone added more knobs to getopt to make it
10326 * work better. Who knows, I may talk myself into doing it someday,
10327 * if the standards weenies let me. As it is, it just leads to
10328 * hackery like this and causes people to avoid it in some cases.
10330 * KDM, September 8th, 1998
10332 if (subopt != NULL)
10333 sprintf(combinedopt, "%s%s", mainopt, subopt);
10335 sprintf(combinedopt, "%s", mainopt);
10338 * For these options we do not parse optional device arguments and
10339 * we do not open a passthrough device.
10341 if ((cmdlist == CAM_CMD_RESCAN)
10342 || (cmdlist == CAM_CMD_RESET)
10343 || (cmdlist == CAM_CMD_DEVTREE)
10344 || (cmdlist == CAM_CMD_USAGE)
10345 || (cmdlist == CAM_CMD_DEBUG))
10349 && (argc > 2 && argv[2][0] != '-')) {
10353 if (isdigit(argv[2][0])) {
10354 /* device specified as bus:target[:lun] */
10355 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10357 errx(1, "numeric device specification must "
10358 "be either bus:target, or "
10360 /* default to 0 if lun was not specified */
10361 if ((arglist & CAM_ARG_LUN) == 0) {
10363 arglist |= CAM_ARG_LUN;
10367 if (cam_get_device(argv[2], name, sizeof name, &unit)
10369 errx(1, "%s", cam_errbuf);
10370 device = strdup(name);
10371 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10376 * Start getopt processing at argv[2/3], since we've already
10377 * accepted argv[1..2] as the command name, and as a possible
10383 * Now we run through the argument list looking for generic
10384 * options, and ignoring options that possibly belong to
10387 while ((c = getopt(argc, argv, combinedopt))!= -1){
10390 retry_count = strtol(optarg, NULL, 0);
10391 if (retry_count < 0)
10392 errx(1, "retry count %d is < 0",
10394 arglist |= CAM_ARG_RETRIES;
10397 arglist |= CAM_ARG_ERR_RECOVER;
10400 arglist |= CAM_ARG_DEVICE;
10402 while (isspace(*tstr) && (*tstr != '\0'))
10404 device = (char *)strdup(tstr);
10408 int table_entry = 0;
10411 while (isspace(*tstr) && (*tstr != '\0'))
10413 if (isdigit(*tstr)) {
10414 task_attr = strtol(tstr, &endptr, 0);
10415 if (*endptr != '\0') {
10416 errx(1, "Invalid queue option "
10421 scsi_nv_status status;
10423 table_size = sizeof(task_attrs) /
10424 sizeof(task_attrs[0]);
10425 status = scsi_get_nv(task_attrs,
10426 table_size, tstr, &table_entry,
10427 SCSI_NV_FLAG_IG_CASE);
10428 if (status == SCSI_NV_FOUND)
10429 task_attr = task_attrs[
10430 table_entry].value;
10432 errx(1, "%s option %s",
10433 (status == SCSI_NV_AMBIGUOUS)?
10434 "ambiguous" : "invalid",
10441 timeout = strtol(optarg, NULL, 0);
10443 errx(1, "invalid timeout %d", timeout);
10444 /* Convert the timeout from seconds to ms */
10446 arglist |= CAM_ARG_TIMEOUT;
10449 arglist |= CAM_ARG_UNIT;
10450 unit = strtol(optarg, NULL, 0);
10453 arglist |= CAM_ARG_VERBOSE;
10461 * For most commands we'll want to open the passthrough device
10462 * associated with the specified device. In the case of the rescan
10463 * commands, we don't use a passthrough device at all, just the
10464 * transport layer device.
10466 if (devopen == 1) {
10467 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10468 && (((arglist & CAM_ARG_DEVICE) == 0)
10469 || ((arglist & CAM_ARG_UNIT) == 0))) {
10470 errx(1, "subcommand \"%s\" requires a valid device "
10471 "identifier", argv[1]);
10474 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10475 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10476 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10478 errx(1,"%s", cam_errbuf);
10482 * Reset optind to 2, and reset getopt, so these routines can parse
10483 * the arguments again.
10489 case CAM_CMD_DEVLIST:
10490 error = getdevlist(cam_dev);
10493 error = atahpa(cam_dev, retry_count, timeout,
10494 argc, argv, combinedopt);
10497 error = ataama(cam_dev, retry_count, timeout,
10498 argc, argv, combinedopt);
10500 case CAM_CMD_DEVTREE:
10501 error = getdevtree(argc, argv, combinedopt);
10503 case CAM_CMD_DEVTYPE:
10504 error = getdevtype(cam_dev);
10507 error = testunitready(cam_dev, task_attr, retry_count,
10510 case CAM_CMD_INQUIRY:
10511 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10512 task_attr, retry_count, timeout);
10514 case CAM_CMD_IDENTIFY:
10515 error = identify(cam_dev, retry_count, timeout);
10517 case CAM_CMD_STARTSTOP:
10518 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10519 arglist & CAM_ARG_EJECT, task_attr,
10520 retry_count, timeout);
10522 case CAM_CMD_RESCAN:
10523 error = dorescan_or_reset(argc, argv, 1);
10525 case CAM_CMD_RESET:
10526 error = dorescan_or_reset(argc, argv, 0);
10528 case CAM_CMD_READ_DEFECTS:
10529 error = readdefects(cam_dev, argc, argv, combinedopt,
10530 task_attr, retry_count, timeout);
10532 case CAM_CMD_MODE_PAGE:
10533 modepage(cam_dev, argc, argv, combinedopt,
10534 task_attr, retry_count, timeout);
10536 case CAM_CMD_SCSI_CMD:
10537 error = scsicmd(cam_dev, argc, argv, combinedopt,
10538 task_attr, retry_count, timeout);
10540 case CAM_CMD_MMCSD_CMD:
10541 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10542 retry_count, timeout);
10544 case CAM_CMD_SMP_CMD:
10545 error = smpcmd(cam_dev, argc, argv, combinedopt,
10546 retry_count, timeout);
10548 case CAM_CMD_SMP_RG:
10549 error = smpreportgeneral(cam_dev, argc, argv,
10550 combinedopt, retry_count,
10553 case CAM_CMD_SMP_PC:
10554 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10555 retry_count, timeout);
10557 case CAM_CMD_SMP_PHYLIST:
10558 error = smpphylist(cam_dev, argc, argv, combinedopt,
10559 retry_count, timeout);
10561 case CAM_CMD_SMP_MANINFO:
10562 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10563 retry_count, timeout);
10565 case CAM_CMD_DEBUG:
10566 error = camdebug(argc, argv, combinedopt);
10569 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10572 error = ratecontrol(cam_dev, task_attr, retry_count,
10573 timeout, argc, argv, combinedopt);
10575 case CAM_CMD_FORMAT:
10576 error = scsiformat(cam_dev, argc, argv,
10577 combinedopt, task_attr, retry_count,
10580 case CAM_CMD_REPORTLUNS:
10581 error = scsireportluns(cam_dev, argc, argv,
10582 combinedopt, task_attr,
10583 retry_count, timeout);
10585 case CAM_CMD_READCAP:
10586 error = scsireadcapacity(cam_dev, argc, argv,
10587 combinedopt, task_attr,
10588 retry_count, timeout);
10591 case CAM_CMD_STANDBY:
10592 case CAM_CMD_SLEEP:
10593 case CAM_CMD_POWER_MODE:
10594 error = atapm(cam_dev, argc, argv,
10595 combinedopt, retry_count, timeout);
10599 error = ataaxm(cam_dev, argc, argv,
10600 combinedopt, retry_count, timeout);
10602 case CAM_CMD_SECURITY:
10603 error = atasecurity(cam_dev, retry_count, timeout,
10604 argc, argv, combinedopt);
10606 case CAM_CMD_DOWNLOAD_FW:
10607 error = fwdownload(cam_dev, argc, argv, combinedopt,
10608 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10611 case CAM_CMD_SANITIZE:
10612 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10613 retry_count, timeout);
10615 case CAM_CMD_PERSIST:
10616 error = scsipersist(cam_dev, argc, argv, combinedopt,
10617 task_attr, retry_count, timeout,
10618 arglist & CAM_ARG_VERBOSE,
10619 arglist & CAM_ARG_ERR_RECOVER);
10621 case CAM_CMD_ATTRIB:
10622 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10623 task_attr, retry_count, timeout,
10624 arglist & CAM_ARG_VERBOSE,
10625 arglist & CAM_ARG_ERR_RECOVER);
10627 case CAM_CMD_OPCODES:
10628 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10629 task_attr, retry_count, timeout,
10630 arglist & CAM_ARG_VERBOSE);
10632 case CAM_CMD_REPROBE:
10633 error = reprobe(cam_dev);
10636 error = zone(cam_dev, argc, argv, combinedopt,
10637 task_attr, retry_count, timeout,
10638 arglist & CAM_ARG_VERBOSE);
10641 error = epc(cam_dev, argc, argv, combinedopt,
10642 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10644 case CAM_CMD_TIMESTAMP:
10645 error = timestamp(cam_dev, argc, argv, combinedopt,
10646 task_attr, retry_count, timeout,
10647 arglist & CAM_ARG_VERBOSE);
10649 case CAM_CMD_DEPOP:
10650 error = depop(cam_dev, argc, argv, combinedopt,
10651 task_attr, retry_count, timeout,
10652 arglist & CAM_ARG_VERBOSE);
10654 case CAM_CMD_USAGE:
10663 if (cam_dev != NULL)
10664 cam_close_device(cam_dev);