xref: /freebsd/sbin/camcontrol/camcontrol.c (revision a0ca4af9455b844c5e094fc1b09b1390ffa979fc)
1 /*
2  * Copyright (c) 1997-2007 Kenneth D. Merry
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
15  *
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
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 #include <sys/ioctl.h>
31 #include <sys/stdint.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/endian.h>
35 #include <sys/sbuf.h>
36 
37 #include <stdbool.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <inttypes.h>
43 #include <limits.h>
44 #include <fcntl.h>
45 #include <ctype.h>
46 #include <err.h>
47 #include <libnvmf.h>
48 #include <libutil.h>
49 #include <limits.h>
50 #include <inttypes.h>
51 
52 #include <cam/cam.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>
62 #include <camlib.h>
63 #include "camcontrol.h"
64 #include "nvmecontrol_ext.h"
65 
66 typedef enum {
67 	CAM_CMD_NONE,
68 	CAM_CMD_DEVLIST,
69 	CAM_CMD_TUR,
70 	CAM_CMD_INQUIRY,
71 	CAM_CMD_STARTSTOP,
72 	CAM_CMD_RESCAN,
73 	CAM_CMD_READ_DEFECTS,
74 	CAM_CMD_MODE_PAGE,
75 	CAM_CMD_SCSI_CMD,
76 	CAM_CMD_DEVTREE,
77 	CAM_CMD_USAGE,
78 	CAM_CMD_DEBUG,
79 	CAM_CMD_RESET,
80 	CAM_CMD_FORMAT,
81 	CAM_CMD_TAG,
82 	CAM_CMD_RATE,
83 	CAM_CMD_DETACH,
84 	CAM_CMD_REPORTLUNS,
85 	CAM_CMD_READCAP,
86 	CAM_CMD_IDENTIFY,
87 	CAM_CMD_IDLE,
88 	CAM_CMD_STANDBY,
89 	CAM_CMD_SLEEP,
90 	CAM_CMD_SMP_CMD,
91 	CAM_CMD_SMP_RG,
92 	CAM_CMD_SMP_PC,
93 	CAM_CMD_SMP_PHYLIST,
94 	CAM_CMD_SMP_MANINFO,
95 	CAM_CMD_DOWNLOAD_FW,
96 	CAM_CMD_SECURITY,
97 	CAM_CMD_HPA,
98 	CAM_CMD_SANITIZE,
99 	CAM_CMD_PERSIST,
100 	CAM_CMD_APM,
101 	CAM_CMD_AAM,
102 	CAM_CMD_ATTRIB,
103 	CAM_CMD_OPCODES,
104 	CAM_CMD_REPROBE,
105 	CAM_CMD_ZONE,
106 	CAM_CMD_EPC,
107 	CAM_CMD_TIMESTAMP,
108 	CAM_CMD_MMCSD_CMD,
109 	CAM_CMD_POWER_MODE,
110 	CAM_CMD_DEVTYPE,
111 	CAM_CMD_AMA,
112 	CAM_CMD_DEPOP,
113 	CAM_CMD_REQSENSE
114 } cam_cmd;
115 
116 typedef enum {
117 	CAM_ARG_NONE		= 0x00000000,
118 	CAM_ARG_VERBOSE		= 0x00000001,
119 	CAM_ARG_DEVICE		= 0x00000002,
120 	CAM_ARG_BUS		= 0x00000004,
121 	CAM_ARG_TARGET		= 0x00000008,
122 	CAM_ARG_LUN		= 0x00000010,
123 	CAM_ARG_EJECT		= 0x00000020,
124 	CAM_ARG_UNIT		= 0x00000040,
125 			/* unused 0x00000080 */
126 			/* unused 0x00000100 */
127 			/* unused 0x00000200 */
128 			/* unused 0x00000400 */
129 			/* unused 0x00000800 */
130 	CAM_ARG_GET_SERIAL	= 0x00001000,
131 	CAM_ARG_GET_STDINQ	= 0x00002000,
132 	CAM_ARG_GET_XFERRATE	= 0x00004000,
133 	CAM_ARG_INQ_MASK	= 0x00007000,
134 			/* unused 0x00008000 */
135 			/* unused 0x00010000 */
136 	CAM_ARG_TIMEOUT		= 0x00020000,
137 	CAM_ARG_CMD_IN		= 0x00040000,
138 	CAM_ARG_CMD_OUT		= 0x00080000,
139 			/* unused 0x00100000 */
140 	CAM_ARG_ERR_RECOVER	= 0x00200000,
141 	CAM_ARG_RETRIES		= 0x00400000,
142 	CAM_ARG_START_UNIT	= 0x00800000,
143 	CAM_ARG_DEBUG_INFO	= 0x01000000,
144 	CAM_ARG_DEBUG_TRACE	= 0x02000000,
145 	CAM_ARG_DEBUG_SUBTRACE	= 0x04000000,
146 	CAM_ARG_DEBUG_CDB	= 0x08000000,
147 	CAM_ARG_DEBUG_XPT	= 0x10000000,
148 	CAM_ARG_DEBUG_PERIPH	= 0x20000000,
149 	CAM_ARG_DEBUG_PROBE	= 0x40000000,
150 			/* unused 0x80000000 */
151 } cam_argmask;
152 
153 struct camcontrol_opts {
154 	const char	*optname;
155 	uint32_t	cmdnum;
156 	cam_argmask	argnum;
157 	const char	*subopt;
158 };
159 
160 struct ata_set_max_pwd
161 {
162 	uint16_t reserved1;
163 	uint8_t password[32];
164 	uint16_t reserved2[239];
165 };
166 
167 static struct scsi_nv task_attrs[] = {
168 	{ "simple", MSG_SIMPLE_Q_TAG },
169 	{ "head", MSG_HEAD_OF_Q_TAG },
170 	{ "ordered", MSG_ORDERED_Q_TAG },
171 	{ "iwr", MSG_IGN_WIDE_RESIDUE },
172 	{ "aca", MSG_ACA_TASK }
173 };
174 
175 static const char scsicmd_opts[] = "a:c:dfi:o:r";
176 static const char readdefect_opts[] = "f:GPqsS:X";
177 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
178 static const char smprg_opts[] = "l";
179 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
180 static const char smpphylist_opts[] = "lq";
181 static char pwd_opt;
182 
183 static struct camcontrol_opts option_table[] = {
184 	{"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
185 	{"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
186 	{"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
187 	{"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
188 	{"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
189 	{"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
190 	{"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
191 	{"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
192 	{"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
193 	{"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
194 	{"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
195 	{"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
196 	{"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
197 	{"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:F:f:Wb:l:41S:I"},
198 	{"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
199 	{"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
200 	{"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
201 	{"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
202 	{"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
203 	{"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
204 	{"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
205 	{"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
206 	{"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
207 	{"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
208 	{"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
209 	{"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
210 	{"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
211 	{"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
212 	{"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm:DLP:"},
213 	{"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
214 	{"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
215 	{"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
216 	{"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
217 	{"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
218 	{"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
219 	{"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
220 	{"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
221 	{"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
222 	{"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
223 	{"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
224 	{"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
225 	{"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
226 	{"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
227 	{"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
228 	{"ama", CAM_CMD_AMA, CAM_ARG_NONE, "fqs:"},
229 	{"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
230 	{"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
231 	{"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
232 	{"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
233 	{"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
234 	{"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
235 	{"depop", CAM_CMD_DEPOP, CAM_ARG_NONE, "ac:de:ls"},
236 	{"sense", CAM_CMD_REQSENSE, CAM_ARG_NONE, "Dx"},
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},
240 	{NULL, 0, 0, NULL}
241 };
242 
243 struct cam_devitem {
244 	struct device_match_result dev_match;
245 	int num_periphs;
246 	struct periph_match_result *periph_matches;
247 	struct scsi_vpd_device_id *device_id;
248 	int device_id_len;
249 	STAILQ_ENTRY(cam_devitem) links;
250 };
251 
252 struct cam_devlist {
253 	STAILQ_HEAD(, cam_devitem) dev_queue;
254 	path_id_t path_id;
255 };
256 
257 static cam_argmask arglist;
258 
259 static const char *devtype_names[] = {
260 	"none",
261 	"scsi",
262 	"satl",
263 	"ata",
264 	"nvme",
265 	"mmcsd",
266 	"unknown",
267 };
268 
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,
279     char *tmpstr);
280 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
281 static int requestsense(struct cam_device *device, int argc, char **argv,
282 			char *combinedopt, int task_attr, int retry_count,
283 			int timeout);
284 static int testunitready(struct cam_device *device, int task_attr,
285 			 int retry_count, int timeout, int quiet);
286 static int scsistart(struct cam_device *device, int startstop, int loadeject,
287 		     int task_attr, int retry_count, int timeout);
288 static int scsiinquiry(struct cam_device *device, int task_attr,
289 		       int retry_count, int timeout);
290 static int scsiserial(struct cam_device *device, int task_attr,
291 		      int retry_count, int timeout);
292 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
293 		     lun_id_t *lun, cam_argmask *arglst);
294 static int reprobe(struct cam_device *device);
295 static int dorescan_or_reset(int argc, char **argv, int rescan);
296 static int rescan_or_reset_bus(path_id_t bus, int rescan);
297 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
298     lun_id_t lun, int scan);
299 static int readdefects(struct cam_device *device, int argc, char **argv,
300 		       char *combinedopt, int task_attr, int retry_count,
301 		       int timeout);
302 static void modepage(struct cam_device *device, int argc, char **argv,
303 		     char *combinedopt, int task_attr, int retry_count,
304 		     int timeout);
305 static int scsicmd(struct cam_device *device, int argc, char **argv,
306 		   char *combinedopt, int task_attr, int retry_count,
307 		   int timeout);
308 static int smpcmd(struct cam_device *device, int argc, char **argv,
309 		  char *combinedopt, int retry_count, int timeout);
310 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
311 		  char *combinedopt, int retry_count, int timeout);
312 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
313 			    char *combinedopt, int retry_count, int timeout);
314 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
315 			 char *combinedopt, int retry_count, int timeout);
316 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
317 		      char *combinedopt, int retry_count, int timeout);
318 static int getdevid(struct cam_devitem *item);
319 static int buildbusdevlist(struct cam_devlist *devlist);
320 static void freebusdevlist(struct cam_devlist *devlist);
321 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
322 					 uint64_t sasaddr);
323 static int smpphylist(struct cam_device *device, int argc, char **argv,
324 		      char *combinedopt, int retry_count, int timeout);
325 static int tagcontrol(struct cam_device *device, int argc, char **argv,
326 		      char *combinedopt);
327 static void cts_print(struct cam_device *device,
328 		      struct ccb_trans_settings *cts);
329 static void cpi_print(struct ccb_pathinq *cpi);
330 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
331 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
332 static int get_print_cts(struct cam_device *device, int user_settings,
333 			 int quiet, struct ccb_trans_settings *cts);
334 static int ratecontrol(struct cam_device *device, int task_attr,
335 		       int retry_count, int timeout, int argc, char **argv,
336 		       char *combinedopt);
337 static int scsiformat(struct cam_device *device, int argc, char **argv,
338 		      char *combinedopt, int task_attr, int retry_count,
339 		      int timeout);
340 static int sanitize(struct cam_device *device, int argc, char **argv,
341 			char *combinedopt, int task_attr, int retry_count,
342 			int timeout);
343 static int scsireportluns(struct cam_device *device, int argc, char **argv,
344 			  char *combinedopt, int task_attr, int retry_count,
345 			  int timeout);
346 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
347 			    char *combinedopt, int task_attr, int retry_count,
348 			    int timeout);
349 static int atapm(struct cam_device *device, int argc, char **argv,
350 		 char *combinedopt, int retry_count, int timeout);
351 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
352 		       int argc, char **argv, char *combinedopt);
353 static int atahpa(struct cam_device *device, int retry_count, int timeout,
354 		  int argc, char **argv, char *combinedopt);
355 static int ataama(struct cam_device *device, int retry_count, int timeout,
356 		  int argc, char **argv, char *combinedopt);
357 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
358 			      int sa_set, int req_sa, uint8_t *buf,
359 			      uint32_t valid_len);
360 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
361 			    uint32_t valid_len);
362 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
363 		       char *combinedopt, int task_attr, int retry_count,
364 		       int timeout, int verbose);
365 
366 #ifndef min
367 #define min(a,b) (((a)<(b))?(a):(b))
368 #endif
369 #ifndef max
370 #define max(a,b) (((a)>(b))?(a):(b))
371 #endif
372 
373 camcontrol_optret
374 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
375 	  cam_argmask *argnum, const char **subopt)
376 {
377 	struct camcontrol_opts *opts;
378 	int num_matches = 0;
379 
380 	for (opts = table; (opts != NULL) && (opts->optname != NULL);
381 	     opts++) {
382 		if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
383 			*cmdnum = opts->cmdnum;
384 			*argnum = opts->argnum;
385 			*subopt = opts->subopt;
386 			if (++num_matches > 1)
387 				return (CC_OR_AMBIGUOUS);
388 		}
389 	}
390 
391 	if (num_matches > 0)
392 		return (CC_OR_FOUND);
393 	else
394 		return (CC_OR_NOT_FOUND);
395 }
396 
397 static int
398 getdevlist(struct cam_device *device)
399 {
400 	union ccb *ccb;
401 	char status[32];
402 	int error = 0;
403 
404 	ccb = cam_getccb(device);
405 
406 	ccb->ccb_h.func_code = XPT_GDEVLIST;
407 	ccb->ccb_h.flags = CAM_DIR_NONE;
408 	ccb->ccb_h.retry_count = 1;
409 	ccb->cgdl.index = 0;
410 	ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
411 	while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
412 		if (cam_send_ccb(device, ccb) < 0) {
413 			warn("error getting device list");
414 			cam_freeccb(ccb);
415 			return (1);
416 		}
417 
418 		status[0] = '\0';
419 
420 		switch (ccb->cgdl.status) {
421 			case CAM_GDEVLIST_MORE_DEVS:
422 				strcpy(status, "MORE");
423 				break;
424 			case CAM_GDEVLIST_LAST_DEVICE:
425 				strcpy(status, "LAST");
426 				break;
427 			case CAM_GDEVLIST_LIST_CHANGED:
428 				strcpy(status, "CHANGED");
429 				break;
430 			case CAM_GDEVLIST_ERROR:
431 				strcpy(status, "ERROR");
432 				error = 1;
433 				break;
434 		}
435 
436 		fprintf(stdout, "%s%d:  generation: %d index: %d status: %s\n",
437 			ccb->cgdl.periph_name,
438 			ccb->cgdl.unit_number,
439 			ccb->cgdl.generation,
440 			ccb->cgdl.index,
441 			status);
442 
443 		/*
444 		 * If the list has changed, we need to start over from the
445 		 * beginning.
446 		 */
447 		if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
448 			ccb->cgdl.index = 0;
449 	}
450 
451 	cam_freeccb(ccb);
452 
453 	return (error);
454 }
455 
456 static int
457 getdevtree(int argc, char **argv, char *combinedopt)
458 {
459 	union ccb ccb;
460 	int bufsize, fd;
461 	unsigned int i;
462 	int need_close = 0;
463 	int error = 0;
464 	int skip_device = 0;
465 	int busonly = 0;
466 	int c;
467 
468 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
469 		switch(c) {
470 		case 'b':
471 			if ((arglist & CAM_ARG_VERBOSE) == 0)
472 				busonly = 1;
473 			break;
474 		default:
475 			break;
476 		}
477 	}
478 
479 	if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
480 		warn("couldn't open %s", XPT_DEVICE);
481 		return (1);
482 	}
483 
484 	bzero(&ccb, sizeof(union ccb));
485 
486 	ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
487 	ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
488 	ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
489 
490 	ccb.ccb_h.func_code = XPT_DEV_MATCH;
491 	bufsize = sizeof(struct dev_match_result) * 100;
492 	ccb.cdm.match_buf_len = bufsize;
493 	ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
494 	if (ccb.cdm.matches == NULL) {
495 		warnx("can't malloc memory for matches");
496 		close(fd);
497 		return (1);
498 	}
499 	ccb.cdm.num_matches = 0;
500 
501 	/*
502 	 * We fetch all nodes, since we display most of them in the default
503 	 * case, and all in the verbose case.
504 	 */
505 	ccb.cdm.num_patterns = 0;
506 	ccb.cdm.pattern_buf_len = 0;
507 
508 	/*
509 	 * We do the ioctl multiple times if necessary, in case there are
510 	 * more than 100 nodes in the EDT.
511 	 */
512 	do {
513 		if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
514 			warn("error sending CAMIOCOMMAND ioctl");
515 			error = 1;
516 			break;
517 		}
518 
519 		if ((ccb.ccb_h.status != CAM_REQ_CMP)
520 		 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
521 		    && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
522 			warnx("got CAM error %#x, CDM error %d\n",
523 			      ccb.ccb_h.status, ccb.cdm.status);
524 			error = 1;
525 			break;
526 		}
527 
528 		for (i = 0; i < ccb.cdm.num_matches; i++) {
529 			switch (ccb.cdm.matches[i].type) {
530 			case DEV_MATCH_BUS: {
531 				struct bus_match_result *bus_result;
532 
533 				/*
534 				 * Only print the bus information if the
535 				 * user turns on the verbose flag.
536 				 */
537 				if ((busonly == 0) &&
538 				    (arglist & CAM_ARG_VERBOSE) == 0)
539 					break;
540 
541 				bus_result =
542 					&ccb.cdm.matches[i].result.bus_result;
543 
544 				if (need_close) {
545 					fprintf(stdout, ")\n");
546 					need_close = 0;
547 				}
548 
549 				fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
550 					bus_result->path_id,
551 					bus_result->dev_name,
552 					bus_result->unit_number,
553 					bus_result->bus_id,
554 					(busonly ? "" : ":"));
555 				break;
556 			}
557 			case DEV_MATCH_DEVICE: {
558 				struct device_match_result *dev_result;
559 				char tmpstr[256];
560 
561 				if (busonly == 1)
562 					break;
563 
564 				dev_result =
565 				     &ccb.cdm.matches[i].result.device_result;
566 
567 				if ((dev_result->flags
568 				     & DEV_RESULT_UNCONFIGURED)
569 				 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
570 					skip_device = 1;
571 					break;
572 				} else
573 					skip_device = 0;
574 
575 				if (dev_result->protocol == PROTO_SCSI) {
576 					if (print_dev_scsi(dev_result,
577 					    &tmpstr[0]) != 0) {
578 						skip_device = 1;
579 						break;
580 					}
581 				} else if (dev_result->protocol == PROTO_ATA ||
582 				    dev_result->protocol == PROTO_SATAPM) {
583 					if (print_dev_ata(dev_result,
584 					    &tmpstr[0]) != 0) {
585 						skip_device = 1;
586 						break;
587 					}
588 				} else if (dev_result->protocol == PROTO_MMCSD){
589 					if (print_dev_mmcsd(dev_result,
590 					    &tmpstr[0]) != 0) {
591 						skip_device = 1;
592 						break;
593 					}
594 				} else if (dev_result->protocol == PROTO_SEMB) {
595 					if (print_dev_semb(dev_result,
596 					    &tmpstr[0]) != 0) {
597 						skip_device = 1;
598 						break;
599 					}
600 				} else if (dev_result->protocol == PROTO_NVME) {
601 					if (print_dev_nvme(dev_result,
602 					    &tmpstr[0]) != 0) {
603 						skip_device = 1;
604 						break;
605 					}
606 				} else {
607 				    sprintf(tmpstr, "<>");
608 				}
609 				if (need_close) {
610 					fprintf(stdout, ")\n");
611 					need_close = 0;
612 				}
613 
614 				fprintf(stdout, "%-33s  at scbus%d "
615 					"target %d lun %jx (",
616 					tmpstr,
617 					dev_result->path_id,
618 					dev_result->target_id,
619 					(uintmax_t)dev_result->target_lun);
620 
621 				need_close = 1;
622 
623 				break;
624 			}
625 			case DEV_MATCH_PERIPH: {
626 				struct periph_match_result *periph_result;
627 
628 				periph_result =
629 				      &ccb.cdm.matches[i].result.periph_result;
630 
631 				if (busonly || skip_device != 0)
632 					break;
633 
634 				if (need_close > 1)
635 					fprintf(stdout, ",");
636 
637 				fprintf(stdout, "%s%d",
638 					periph_result->periph_name,
639 					periph_result->unit_number);
640 
641 				need_close++;
642 				break;
643 			}
644 			default:
645 				fprintf(stdout, "unknown match type\n");
646 				break;
647 			}
648 		}
649 
650 	} while ((ccb.ccb_h.status == CAM_REQ_CMP)
651 		&& (ccb.cdm.status == CAM_DEV_MATCH_MORE));
652 
653 	if (need_close)
654 		fprintf(stdout, ")\n");
655 
656 	close(fd);
657 
658 	return (error);
659 }
660 
661 static int
662 getdevtype(struct cam_device *cam_dev)
663 {
664 	camcontrol_devtype dt;
665 	int error;
666 
667 	/*
668 	 * Get the device type and report it, request no I/O be done to do this.
669 	 */
670 	error = get_device_type(cam_dev, -1, 0, 0, &dt);
671 	if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
672 		fprintf(stdout, "illegal\n");
673 		return (1);
674 	}
675 	fprintf(stdout, "%s\n", devtype_names[dt]);
676 	return (0);
677 }
678 
679 static int
680 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
681 {
682 	char vendor[16], product[48], revision[16];
683 
684 	cam_strvis(vendor, dev_result->inq_data.vendor,
685 	    sizeof(dev_result->inq_data.vendor), sizeof(vendor));
686 	cam_strvis(product, dev_result->inq_data.product,
687 	    sizeof(dev_result->inq_data.product), sizeof(product));
688 	cam_strvis(revision, dev_result->inq_data.revision,
689 	    sizeof(dev_result->inq_data.revision), sizeof(revision));
690 	sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
691 
692 	return (0);
693 }
694 
695 static int
696 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
697 {
698 	char product[48], revision[16];
699 
700 	cam_strvis(product, dev_result->ident_data.model,
701 	    sizeof(dev_result->ident_data.model), sizeof(product));
702 	cam_strvis(revision, dev_result->ident_data.revision,
703 	    sizeof(dev_result->ident_data.revision), sizeof(revision));
704 	sprintf(tmpstr, "<%s %s>", product, revision);
705 
706 	return (0);
707 }
708 
709 static int
710 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
711 {
712 	struct sep_identify_data *sid;
713 	char vendor[16], product[48], revision[16], fw[5];
714 
715 	sid = (struct sep_identify_data *)&dev_result->ident_data;
716 	cam_strvis(vendor, sid->vendor_id,
717 	    sizeof(sid->vendor_id), sizeof(vendor));
718 	cam_strvis(product, sid->product_id,
719 	    sizeof(sid->product_id), sizeof(product));
720 	cam_strvis(revision, sid->product_rev,
721 	    sizeof(sid->product_rev), sizeof(revision));
722 	cam_strvis(fw, sid->firmware_rev,
723 	    sizeof(sid->firmware_rev), sizeof(fw));
724 	sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
725 
726 	return (0);
727 }
728 
729 static int
730 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
731 {
732 	union ccb *ccb;
733 	struct ccb_dev_advinfo *advi;
734 	struct cam_device *dev;
735 	struct mmc_params mmc_ident_data;
736 
737 	dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
738 	    dev_result->target_lun, O_RDWR, NULL);
739 	if (dev == NULL) {
740 		warnx("%s", cam_errbuf);
741 		return (1);
742 	}
743 
744 	ccb = cam_getccb(dev);
745 	if (ccb == NULL) {
746 		warnx("couldn't allocate CCB");
747 		cam_close_device(dev);
748 		return (1);
749 	}
750 
751 	advi = &ccb->cdai;
752 	advi->ccb_h.flags = CAM_DIR_IN;
753 	advi->ccb_h.func_code = XPT_DEV_ADVINFO;
754 	advi->flags = CDAI_FLAG_NONE;
755 	advi->buftype = CDAI_TYPE_MMC_PARAMS;
756 	advi->bufsiz = sizeof(struct mmc_params);
757 	advi->buf = (uint8_t *)&mmc_ident_data;
758 
759 	if (cam_send_ccb(dev, ccb) < 0) {
760 		warn("error sending XPT_DEV_ADVINFO CCB");
761 		cam_freeccb(ccb);
762 		cam_close_device(dev);
763 		return (1);
764 	}
765 
766 	if (strlen(mmc_ident_data.model) > 0) {
767 		sprintf(tmpstr, "<%s>", mmc_ident_data.model);
768 	} else {
769 		sprintf(tmpstr, "<%s card>",
770 		    mmc_ident_data.card_features &
771 		    CARD_FEATURE_SDIO ? "SDIO" : "unknown");
772 	}
773 
774 	cam_freeccb(ccb);
775 	cam_close_device(dev);
776 	return (0);
777 }
778 
779 static int
780 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
781 {
782 	union ccb *ccb;
783 	struct ccb_dev_advinfo *advi;
784 
785 	ccb = cam_getccb(dev);
786 	if (ccb == NULL) {
787 		warnx("couldn't allocate CCB");
788 		cam_close_device(dev);
789 		return (1);
790 	}
791 
792 	advi = &ccb->cdai;
793 	advi->ccb_h.flags = CAM_DIR_IN;
794 	advi->ccb_h.func_code = XPT_DEV_ADVINFO;
795 	advi->flags = CDAI_FLAG_NONE;
796 	advi->buftype = CDAI_TYPE_NVME_CNTRL;
797 	advi->bufsiz = sizeof(struct nvme_controller_data);
798 	advi->buf = (uint8_t *)cdata;
799 
800 	if (cam_send_ccb(dev, ccb) < 0) {
801 		warn("error sending XPT_DEV_ADVINFO CCB");
802 		cam_freeccb(ccb);
803 		cam_close_device(dev);
804 		return(1);
805 	}
806 	if (advi->ccb_h.status != CAM_REQ_CMP) {
807 		warnx("got CAM error %#x", advi->ccb_h.status);
808 		cam_freeccb(ccb);
809 		cam_close_device(dev);
810 		return(1);
811 	}
812 	cam_freeccb(ccb);
813 	return 0;
814 }
815 
816 static int
817 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
818 {
819 	struct cam_device *dev;
820 	struct nvme_controller_data cdata;
821 	char vendor[64], product[64];
822 
823 	dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
824 	    dev_result->target_lun, O_RDWR, NULL);
825 	if (dev == NULL) {
826 		warnx("%s", cam_errbuf);
827 		return (1);
828 	}
829 
830 	if (nvme_get_cdata(dev, &cdata))
831 		return (1);
832 
833 	cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
834 	cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
835 	sprintf(tmpstr, "<%s %s>", vendor, product);
836 
837 	cam_close_device(dev);
838 	return (0);
839 }
840 
841 static int
842 requestsense(struct cam_device *device, int argc, char **argv,
843 	     char *combinedopt, int task_attr, int retry_count, int timeout)
844 {
845 	int c;
846 	int descriptor_sense = 0;
847 	int do_hexdump = 0;
848 	struct scsi_sense_data sense;
849 	union ccb *ccb = NULL;
850 	int error = 0;
851 	size_t returned_bytes;
852 
853 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
854 		switch (c) {
855 		case 'D':
856 			descriptor_sense = 1;
857 			break;
858 		case 'x':
859 			do_hexdump = 1;
860 			break;
861 		default:
862 			break;
863 		}
864 	}
865 
866 	ccb = cam_getccb(device);
867 	if (ccb == NULL) {
868 		warnx("couldn't allocate CCB");
869 		return (1);
870 	}
871 
872 	/* cam_getccb cleans up the header, caller has to zero the payload */
873 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
874 
875 	bzero(&sense, sizeof(sense));
876 
877 	scsi_request_sense(&ccb->csio,
878 			   /*retries*/ retry_count,
879 			   /*cbfcnp*/ NULL,
880 			   /*data_ptr*/ (void *)&sense,
881 			   /*dxfer_len*/ sizeof(sense),
882 			   /*tag_action*/ task_attr,
883 			   /*sense_len*/ SSD_FULL_SIZE,
884 			   /*timeout*/ timeout ? timeout : 60000);
885 
886 	if (descriptor_sense != 0) {
887 		struct scsi_request_sense *cdb;
888 
889 		cdb = (struct scsi_request_sense *)&ccb->csio.cdb_io.cdb_bytes;
890 		cdb->byte2 |= SRS_DESC;
891 	}
892 
893 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
894 
895 	if (arglist & CAM_ARG_ERR_RECOVER)
896 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
897 
898 	if (cam_send_ccb(device, ccb) < 0) {
899 		warn("error sending REQUEST SENSE command");
900 		cam_freeccb(ccb);
901 		error = 1;
902 		goto bailout;
903 	}
904 
905 	/*
906 	 * REQUEST SENSE is not generally supposed to fail.  But there can
907 	 * be transport or other errors that might cause it to fail.  It
908 	 * may also fail if the user asks for descriptor sense and the
909 	 * device doesn't support it.  So we check the CCB status here to see.
910 	 */
911 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
912 		warnx("REQUEST SENSE failed");
913 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
914 		error = 1;
915 		goto bailout;
916 	}
917 
918 	returned_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
919 
920 	if (do_hexdump != 0) {
921 		hexdump(&sense, returned_bytes, NULL, 0);
922 	} else {
923 		char path_str[80];
924 		struct sbuf *sb;
925 
926 		cam_path_string(device, path_str, sizeof(path_str));
927 		sb = sbuf_new_auto();
928 		if (sb == NULL) {
929 			warnx("%s: cannot allocate sbuf", __func__);
930 			error = 1;
931 			goto bailout;
932 		}
933 
934 		scsi_sense_only_sbuf(&sense, returned_bytes, sb, path_str,
935 		    &device->inq_data, scsiio_cdb_ptr(&ccb->csio),
936 		    ccb->csio.cdb_len);
937 
938 		sbuf_finish(sb);
939 		printf("%s", sbuf_data(sb));
940 		sbuf_delete(sb);
941 	}
942 bailout:
943 	if (ccb != NULL)
944 		cam_freeccb(ccb);
945 
946 	return (error);
947 }
948 
949 static int
950 testunitready(struct cam_device *device, int task_attr, int retry_count,
951 	      int timeout, int quiet)
952 {
953 	int error = 0;
954 	union ccb *ccb;
955 
956 	ccb = cam_getccb(device);
957 
958 	scsi_test_unit_ready(&ccb->csio,
959 			     /* retries */ retry_count,
960 			     /* cbfcnp */ NULL,
961 			     /* tag_action */ task_attr,
962 			     /* sense_len */ SSD_FULL_SIZE,
963 			     /* timeout */ timeout ? timeout : 5000);
964 
965 	/* Disable freezing the device queue */
966 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
967 
968 	if (arglist & CAM_ARG_ERR_RECOVER)
969 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
970 
971 	if (cam_send_ccb(device, ccb) < 0) {
972 		if (quiet == 0)
973 			warn("error sending TEST UNIT READY command");
974 		cam_freeccb(ccb);
975 		return (1);
976 	}
977 
978 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
979 		if (quiet == 0)
980 			fprintf(stdout, "Unit is ready\n");
981 	} else {
982 		if (quiet == 0)
983 			fprintf(stdout, "Unit is not ready\n");
984 		error = 1;
985 
986 		if (arglist & CAM_ARG_VERBOSE) {
987 			cam_error_print(device, ccb, CAM_ESF_ALL,
988 					CAM_EPF_ALL, stderr);
989 		}
990 	}
991 
992 	cam_freeccb(ccb);
993 
994 	return (error);
995 }
996 
997 static int
998 scsistart(struct cam_device *device, int startstop, int loadeject,
999 	  int task_attr, int retry_count, int timeout)
1000 {
1001 	union ccb *ccb;
1002 	int error = 0;
1003 
1004 	ccb = cam_getccb(device);
1005 
1006 	/*
1007 	 * If we're stopping, send an ordered tag so the drive in question
1008 	 * will finish any previously queued writes before stopping.  If
1009 	 * the device isn't capable of tagged queueing, or if tagged
1010 	 * queueing is turned off, the tag action is a no-op.  We override
1011 	 * the default simple tag, although this also has the effect of
1012 	 * overriding the user's wishes if he wanted to specify a simple
1013 	 * tag.
1014 	 */
1015 	if ((startstop == 0)
1016 	 && (task_attr == MSG_SIMPLE_Q_TAG))
1017 		task_attr = MSG_ORDERED_Q_TAG;
1018 
1019 	scsi_start_stop(&ccb->csio,
1020 			/* retries */ retry_count,
1021 			/* cbfcnp */ NULL,
1022 			/* tag_action */ task_attr,
1023 			/* start/stop */ startstop,
1024 			/* load_eject */ loadeject,
1025 			/* immediate */ 0,
1026 			/* sense_len */ SSD_FULL_SIZE,
1027 			/* timeout */ timeout ? timeout : 120000);
1028 
1029 	/* Disable freezing the device queue */
1030 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1031 
1032 	if (arglist & CAM_ARG_ERR_RECOVER)
1033 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1034 
1035 	if (cam_send_ccb(device, ccb) < 0) {
1036 		warn("error sending START STOP UNIT command");
1037 		cam_freeccb(ccb);
1038 		return (1);
1039 	}
1040 
1041 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
1042 		if (startstop) {
1043 			fprintf(stdout, "Unit started successfully");
1044 			if (loadeject)
1045 				fprintf(stdout,", Media loaded\n");
1046 			else
1047 				fprintf(stdout,"\n");
1048 		} else {
1049 			fprintf(stdout, "Unit stopped successfully");
1050 			if (loadeject)
1051 				fprintf(stdout, ", Media ejected\n");
1052 			else
1053 				fprintf(stdout, "\n");
1054 		}
1055 	else {
1056 		error = 1;
1057 		if (startstop)
1058 			fprintf(stdout,
1059 				"Error received from start unit command\n");
1060 		else
1061 			fprintf(stdout,
1062 				"Error received from stop unit command\n");
1063 
1064 		if (arglist & CAM_ARG_VERBOSE) {
1065 			cam_error_print(device, ccb, CAM_ESF_ALL,
1066 					CAM_EPF_ALL, stderr);
1067 		}
1068 	}
1069 
1070 	cam_freeccb(ccb);
1071 
1072 	return (error);
1073 }
1074 
1075 int
1076 scsidoinquiry(struct cam_device *device, int argc, char **argv,
1077 	      char *combinedopt, int task_attr, int retry_count, int timeout)
1078 {
1079 	int c;
1080 	int error = 0;
1081 
1082 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
1083 		switch(c) {
1084 		case 'D':
1085 			arglist |= CAM_ARG_GET_STDINQ;
1086 			break;
1087 		case 'R':
1088 			arglist |= CAM_ARG_GET_XFERRATE;
1089 			break;
1090 		case 'S':
1091 			arglist |= CAM_ARG_GET_SERIAL;
1092 			break;
1093 		default:
1094 			break;
1095 		}
1096 	}
1097 
1098 	/*
1099 	 * If the user didn't specify any inquiry options, he wants all of
1100 	 * them.
1101 	 */
1102 	if ((arglist & CAM_ARG_INQ_MASK) == 0)
1103 		arglist |= CAM_ARG_INQ_MASK;
1104 
1105 	if (arglist & CAM_ARG_GET_STDINQ)
1106 		error = scsiinquiry(device, task_attr, retry_count, timeout);
1107 
1108 	if (error != 0)
1109 		return (error);
1110 
1111 	if (arglist & CAM_ARG_GET_SERIAL)
1112 		scsiserial(device, task_attr, retry_count, timeout);
1113 
1114 	if (arglist & CAM_ARG_GET_XFERRATE)
1115 		error = camxferrate(device);
1116 
1117 	return (error);
1118 }
1119 
1120 static int
1121 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1122 	    int timeout)
1123 {
1124 	union ccb *ccb;
1125 	struct scsi_inquiry_data *inq_buf;
1126 	int error = 0;
1127 
1128 	ccb = cam_getccb(device);
1129 
1130 	if (ccb == NULL) {
1131 		warnx("couldn't allocate CCB");
1132 		return (1);
1133 	}
1134 
1135 	inq_buf = (struct scsi_inquiry_data *)malloc(
1136 		sizeof(struct scsi_inquiry_data));
1137 
1138 	if (inq_buf == NULL) {
1139 		cam_freeccb(ccb);
1140 		warnx("can't malloc memory for inquiry\n");
1141 		return (1);
1142 	}
1143 	bzero(inq_buf, sizeof(*inq_buf));
1144 
1145 	/*
1146 	 * Note that although the size of the inquiry buffer is the full
1147 	 * 256 bytes specified in the SCSI spec, we only tell the device
1148 	 * that we have allocated SHORT_INQUIRY_LENGTH bytes.  There are
1149 	 * two reasons for this:
1150 	 *
1151 	 *  - The SCSI spec says that when a length field is only 1 byte,
1152 	 *    a value of 0 will be interpreted as 256.  Therefore
1153 	 *    scsi_inquiry() will convert an inq_len (which is passed in as
1154 	 *    a uint32_t, but the field in the CDB is only 1 byte) of 256
1155 	 *    to 0.  Evidently, very few devices meet the spec in that
1156 	 *    regard.  Some devices, like many Seagate disks, take the 0 as
1157 	 *    0, and don't return any data.  One Pioneer DVD-R drive
1158 	 *    returns more data than the command asked for.
1159 	 *
1160 	 *    So, since there are numerous devices that just don't work
1161 	 *    right with the full inquiry size, we don't send the full size.
1162 	 *
1163 	 *  - The second reason not to use the full inquiry data length is
1164 	 *    that we don't need it here.  The only reason we issue a
1165 	 *    standard inquiry is to get the vendor name, device name,
1166 	 *    and revision so scsi_print_inquiry() can print them.
1167 	 *
1168 	 * If, at some point in the future, more inquiry data is needed for
1169 	 * some reason, this code should use a procedure similar to the
1170 	 * probe code.  i.e., issue a short inquiry, and determine from
1171 	 * the additional length passed back from the device how much
1172 	 * inquiry data the device supports.  Once the amount the device
1173 	 * supports is determined, issue an inquiry for that amount and no
1174 	 * more.
1175 	 *
1176 	 * KDM, 2/18/2000
1177 	 */
1178 	scsi_inquiry(&ccb->csio,
1179 		     /* retries */ retry_count,
1180 		     /* cbfcnp */ NULL,
1181 		     /* tag_action */ task_attr,
1182 		     /* inq_buf */ (uint8_t *)inq_buf,
1183 		     /* inq_len */ SHORT_INQUIRY_LENGTH,
1184 		     /* evpd */ 0,
1185 		     /* page_code */ 0,
1186 		     /* sense_len */ SSD_FULL_SIZE,
1187 		     /* timeout */ timeout ? timeout : 5000);
1188 
1189 	/* Disable freezing the device queue */
1190 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1191 
1192 	if (arglist & CAM_ARG_ERR_RECOVER)
1193 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1194 
1195 	if (cam_send_ccb(device, ccb) < 0) {
1196 		warn("error sending INQUIRY command");
1197 		cam_freeccb(ccb);
1198 		return (1);
1199 	}
1200 
1201 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1202 		error = 1;
1203 
1204 		if (arglist & CAM_ARG_VERBOSE) {
1205 			cam_error_print(device, ccb, CAM_ESF_ALL,
1206 					CAM_EPF_ALL, stderr);
1207 		}
1208 	}
1209 
1210 	cam_freeccb(ccb);
1211 
1212 	if (error != 0) {
1213 		free(inq_buf);
1214 		return (error);
1215 	}
1216 
1217 	fprintf(stdout, "%s%d: ", device->device_name,
1218 		device->dev_unit_num);
1219 	scsi_print_inquiry(inq_buf);
1220 
1221 	free(inq_buf);
1222 
1223 	return (0);
1224 }
1225 
1226 static int
1227 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1228 	   int timeout)
1229 {
1230 	union ccb *ccb;
1231 	struct scsi_vpd_unit_serial_number *serial_buf;
1232 	char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1233 	int error = 0;
1234 
1235 	ccb = cam_getccb(device);
1236 
1237 	if (ccb == NULL) {
1238 		warnx("couldn't allocate CCB");
1239 		return (1);
1240 	}
1241 
1242 	serial_buf = (struct scsi_vpd_unit_serial_number *)
1243 		malloc(sizeof(*serial_buf));
1244 
1245 	if (serial_buf == NULL) {
1246 		cam_freeccb(ccb);
1247 		warnx("can't malloc memory for serial number");
1248 		return (1);
1249 	}
1250 
1251 	scsi_inquiry(&ccb->csio,
1252 		     /*retries*/ retry_count,
1253 		     /*cbfcnp*/ NULL,
1254 		     /* tag_action */ task_attr,
1255 		     /* inq_buf */ (uint8_t *)serial_buf,
1256 		     /* inq_len */ sizeof(*serial_buf),
1257 		     /* evpd */ 1,
1258 		     /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1259 		     /* sense_len */ SSD_FULL_SIZE,
1260 		     /* timeout */ timeout ? timeout : 5000);
1261 
1262 	/* Disable freezing the device queue */
1263 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1264 
1265 	if (arglist & CAM_ARG_ERR_RECOVER)
1266 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1267 
1268 	if (cam_send_ccb(device, ccb) < 0) {
1269 		warn("error sending INQUIRY command");
1270 		cam_freeccb(ccb);
1271 		free(serial_buf);
1272 		return (1);
1273 	}
1274 
1275 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1276 		error = 1;
1277 
1278 		if (arglist & CAM_ARG_VERBOSE) {
1279 			cam_error_print(device, ccb, CAM_ESF_ALL,
1280 					CAM_EPF_ALL, stderr);
1281 		}
1282 	}
1283 
1284 	cam_freeccb(ccb);
1285 
1286 	if (error != 0) {
1287 		free(serial_buf);
1288 		return (error);
1289 	}
1290 
1291 	bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1292 	serial_num[serial_buf->length] = '\0';
1293 
1294 	if ((arglist & CAM_ARG_GET_STDINQ)
1295 	 || (arglist & CAM_ARG_GET_XFERRATE))
1296 		fprintf(stdout, "%s%d: Serial Number ",
1297 			device->device_name, device->dev_unit_num);
1298 
1299 	fprintf(stdout, "%.60s\n", serial_num);
1300 
1301 	free(serial_buf);
1302 
1303 	return (0);
1304 }
1305 
1306 int
1307 camxferrate(struct cam_device *device)
1308 {
1309 	struct ccb_pathinq cpi;
1310 	uint32_t freq = 0;
1311 	uint32_t speed = 0;
1312 	union ccb *ccb;
1313 	u_int mb;
1314 	int retval = 0;
1315 
1316 	if ((retval = get_cpi(device, &cpi)) != 0)
1317 		return (1);
1318 
1319 	ccb = cam_getccb(device);
1320 
1321 	if (ccb == NULL) {
1322 		warnx("couldn't allocate CCB");
1323 		return (1);
1324 	}
1325 
1326 	ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1327 	ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1328 
1329 	if (((retval = cam_send_ccb(device, ccb)) < 0)
1330 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1331 		const char error_string[] = "error getting transfer settings";
1332 
1333 		if (retval < 0)
1334 			warn(error_string);
1335 		else
1336 			warnx(error_string);
1337 
1338 		if (arglist & CAM_ARG_VERBOSE)
1339 			cam_error_print(device, ccb, CAM_ESF_ALL,
1340 					CAM_EPF_ALL, stderr);
1341 
1342 		retval = 1;
1343 
1344 		goto xferrate_bailout;
1345 
1346 	}
1347 
1348 	speed = cpi.base_transfer_speed;
1349 	freq = 0;
1350 	if (ccb->cts.transport == XPORT_SPI) {
1351 		struct ccb_trans_settings_spi *spi =
1352 		    &ccb->cts.xport_specific.spi;
1353 
1354 		if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1355 			freq = scsi_calc_syncsrate(spi->sync_period);
1356 			speed = freq;
1357 		}
1358 		if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1359 			speed *= (0x01 << spi->bus_width);
1360 		}
1361 	} else if (ccb->cts.transport == XPORT_FC) {
1362 		struct ccb_trans_settings_fc *fc =
1363 		    &ccb->cts.xport_specific.fc;
1364 
1365 		if (fc->valid & CTS_FC_VALID_SPEED)
1366 			speed = fc->bitrate;
1367 	} else if (ccb->cts.transport == XPORT_SAS) {
1368 		struct ccb_trans_settings_sas *sas =
1369 		    &ccb->cts.xport_specific.sas;
1370 
1371 		if (sas->valid & CTS_SAS_VALID_SPEED)
1372 			speed = sas->bitrate;
1373 	} else if (ccb->cts.transport == XPORT_ATA) {
1374 		struct ccb_trans_settings_pata *pata =
1375 		    &ccb->cts.xport_specific.ata;
1376 
1377 		if (pata->valid & CTS_ATA_VALID_MODE)
1378 			speed = ata_mode2speed(pata->mode);
1379 	} else if (ccb->cts.transport == XPORT_SATA) {
1380 		struct	ccb_trans_settings_sata *sata =
1381 		    &ccb->cts.xport_specific.sata;
1382 
1383 		if (sata->valid & CTS_SATA_VALID_REVISION)
1384 			speed = ata_revision2speed(sata->revision);
1385 	}
1386 
1387 	mb = speed / 1000;
1388 	if (mb > 0) {
1389 		fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1390 			device->device_name, device->dev_unit_num,
1391 			mb, speed % 1000);
1392 	} else {
1393 		fprintf(stdout, "%s%d: %dKB/s transfers",
1394 			device->device_name, device->dev_unit_num,
1395 			speed);
1396 	}
1397 
1398 	if (ccb->cts.transport == XPORT_SPI) {
1399 		struct ccb_trans_settings_spi *spi =
1400 		    &ccb->cts.xport_specific.spi;
1401 
1402 		if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1403 		 && (spi->sync_offset != 0))
1404 			fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1405 				freq % 1000, spi->sync_offset);
1406 
1407 		if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1408 		 && (spi->bus_width > 0)) {
1409 			if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1410 			 && (spi->sync_offset != 0)) {
1411 				fprintf(stdout, ", ");
1412 			} else {
1413 				fprintf(stdout, " (");
1414 			}
1415 			fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1416 		} else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1417 		 && (spi->sync_offset != 0)) {
1418 			fprintf(stdout, ")");
1419 		}
1420 	} else if (ccb->cts.transport == XPORT_ATA) {
1421 		struct ccb_trans_settings_pata *pata =
1422 		    &ccb->cts.xport_specific.ata;
1423 
1424 		printf(" (");
1425 		if (pata->valid & CTS_ATA_VALID_MODE)
1426 			printf("%s, ", ata_mode2string(pata->mode));
1427 		if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1428 			printf("ATAPI %dbytes, ", pata->atapi);
1429 		if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1430 			printf("PIO %dbytes", pata->bytecount);
1431 		printf(")");
1432 	} else if (ccb->cts.transport == XPORT_SATA) {
1433 		struct ccb_trans_settings_sata *sata =
1434 		    &ccb->cts.xport_specific.sata;
1435 
1436 		printf(" (");
1437 		if (sata->valid & CTS_SATA_VALID_REVISION)
1438 			printf("SATA %d.x, ", sata->revision);
1439 		else
1440 			printf("SATA, ");
1441 		if (sata->valid & CTS_SATA_VALID_MODE)
1442 			printf("%s, ", ata_mode2string(sata->mode));
1443 		if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1444 			printf("ATAPI %dbytes, ", sata->atapi);
1445 		if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1446 			printf("PIO %dbytes", sata->bytecount);
1447 		printf(")");
1448 	}
1449 
1450 	if (ccb->cts.protocol == PROTO_SCSI) {
1451 		struct ccb_trans_settings_scsi *scsi =
1452 		    &ccb->cts.proto_specific.scsi;
1453 		if (scsi->valid & CTS_SCSI_VALID_TQ) {
1454 			if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1455 				fprintf(stdout, ", Command Queueing Enabled");
1456 			}
1457 		}
1458 	}
1459 
1460 	fprintf(stdout, "\n");
1461 
1462 xferrate_bailout:
1463 
1464 	cam_freeccb(ccb);
1465 
1466 	return (retval);
1467 }
1468 
1469 static void
1470 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1471 {
1472 	uint32_t lbasize = (uint32_t)parm->lba_size_1 |
1473 				((uint32_t)parm->lba_size_2 << 16);
1474 
1475 	u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1476 				((u_int64_t)parm->lba_size48_2 << 16) |
1477 				((u_int64_t)parm->lba_size48_3 << 32) |
1478 				((u_int64_t)parm->lba_size48_4 << 48);
1479 
1480 	if (header) {
1481 		printf("\nFeature                      "
1482 		       "Support  Enabled   Value\n");
1483 	}
1484 
1485 	printf("Host Protected Area (HPA)      ");
1486 	if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1487 		u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1488 		printf("yes      %s     %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1489 			lba, hpasize);
1490 
1491 		printf("HPA - Security                 ");
1492 		if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY)
1493 			printf("yes      %s\n", (parm->enabled.command2 &
1494 			    ATA_SUPPORT_MAXSECURITY) ? "yes" : "no ");
1495 		else
1496 			printf("no\n");
1497 	} else {
1498 		printf("no\n");
1499 	}
1500 }
1501 
1502 static void
1503 ataama_print(struct ata_params *parm, u_int64_t nativesize, int header)
1504 {
1505 	uint32_t lbasize = (uint32_t)parm->lba_size_1 |
1506 				((uint32_t)parm->lba_size_2 << 16);
1507 
1508 	u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1509 				((u_int64_t)parm->lba_size48_2 << 16) |
1510 				((u_int64_t)parm->lba_size48_3 << 32) |
1511 				((u_int64_t)parm->lba_size48_4 << 48);
1512 
1513 	if (header) {
1514 		printf("\nFeature                      "
1515 		       "Support  Enabled   Value\n");
1516 	}
1517 
1518 	printf("Accessible Max Address Config  ");
1519 	if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) {
1520 		u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1521 		printf("yes      %s     %ju/%ju\n",
1522 		    (nativesize > lba) ? "yes" : "no ", lba, nativesize);
1523 	} else {
1524 		printf("no\n");
1525 	}
1526 }
1527 
1528 static int
1529 atasata(struct ata_params *parm)
1530 {
1531 
1532 
1533 	if (parm->satacapabilities != 0xffff &&
1534 	    parm->satacapabilities != 0x0000)
1535 		return 1;
1536 
1537 	return 0;
1538 }
1539 
1540 static void
1541 atacapprint(struct ata_params *parm)
1542 {
1543 	const char *proto;
1544 	uint32_t lbasize = (uint32_t)parm->lba_size_1 |
1545 				((uint32_t)parm->lba_size_2 << 16);
1546 
1547 	u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1548 				((u_int64_t)parm->lba_size48_2 << 16) |
1549 				((u_int64_t)parm->lba_size48_3 << 32) |
1550 				((u_int64_t)parm->lba_size48_4 << 48);
1551 
1552 	printf("\n");
1553 	printf("protocol              ");
1554 	proto = (parm->config == ATA_PROTO_CFA) ? "CFA" :
1555 		(parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
1556 	if (ata_version(parm->version_major) == 0) {
1557 		printf("%s", proto);
1558 	} else if (ata_version(parm->version_major) <= 7) {
1559 		printf("%s-%d", proto,
1560 		    ata_version(parm->version_major));
1561 	} else if (ata_version(parm->version_major) == 8) {
1562 		printf("%s8-ACS", proto);
1563 	} else {
1564 		printf("ACS-%d %s",
1565 		    ata_version(parm->version_major) - 7, proto);
1566 	}
1567 	if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1568 		if (parm->satacapabilities & ATA_SATA_GEN3)
1569 			printf(" SATA 3.x\n");
1570 		else if (parm->satacapabilities & ATA_SATA_GEN2)
1571 			printf(" SATA 2.x\n");
1572 		else if (parm->satacapabilities & ATA_SATA_GEN1)
1573 			printf(" SATA 1.x\n");
1574 		else
1575 			printf(" SATA\n");
1576 	}
1577 	else
1578 		printf("\n");
1579 	printf("device model          %.40s\n", parm->model);
1580 	printf("firmware revision     %.8s\n", parm->revision);
1581 	printf("serial number         %.20s\n", parm->serial);
1582 	if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1583 		printf("WWN                   %04x%04x%04x%04x\n",
1584 		    parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1585 	}
1586 	printf("additional product id %.8s\n", parm->product_id);
1587 	if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1588 		printf("media serial number   %.30s\n",
1589 		    parm->media_serial);
1590 	}
1591 
1592 	printf("cylinders             %d\n", parm->cylinders);
1593 	printf("heads                 %d\n", parm->heads);
1594 	printf("sectors/track         %d\n", parm->sectors);
1595 	printf("sector size           logical %u, physical %lu, offset %lu\n",
1596 	    ata_logical_sector_size(parm),
1597 	    (unsigned long)ata_physical_sector_size(parm),
1598 	    (unsigned long)ata_logical_sector_offset(parm));
1599 
1600 	if (parm->config == ATA_PROTO_CFA ||
1601 	    (parm->support.command2 & ATA_SUPPORT_CFA))
1602 		printf("CFA supported\n");
1603 
1604 	printf("LBA%ssupported         ",
1605 		parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1606 	if (lbasize)
1607 		printf("%d sectors\n", lbasize);
1608 	else
1609 		printf("\n");
1610 
1611 	printf("LBA48%ssupported       ",
1612 		parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1613 	if (lbasize48)
1614 		printf("%ju sectors\n", (uintmax_t)lbasize48);
1615 	else
1616 		printf("\n");
1617 
1618 	printf("PIO supported         PIO");
1619 	switch (ata_max_pmode(parm)) {
1620 	case ATA_PIO4:
1621 		printf("4");
1622 		break;
1623 	case ATA_PIO3:
1624 		printf("3");
1625 		break;
1626 	case ATA_PIO2:
1627 		printf("2");
1628 		break;
1629 	case ATA_PIO1:
1630 		printf("1");
1631 		break;
1632 	default:
1633 		printf("0");
1634 	}
1635 	if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1636 		printf(" w/o IORDY");
1637 	printf("\n");
1638 
1639 	printf("DMA%ssupported         ",
1640 		parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1641 	if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1642 		if (parm->mwdmamodes & 0xff) {
1643 			printf("WDMA");
1644 			if (parm->mwdmamodes & 0x04)
1645 				printf("2");
1646 			else if (parm->mwdmamodes & 0x02)
1647 				printf("1");
1648 			else if (parm->mwdmamodes & 0x01)
1649 				printf("0");
1650 			printf(" ");
1651 		}
1652 		if ((parm->atavalid & ATA_FLAG_88) &&
1653 		    (parm->udmamodes & 0xff)) {
1654 			printf("UDMA");
1655 			if (parm->udmamodes & 0x40)
1656 				printf("6");
1657 			else if (parm->udmamodes & 0x20)
1658 				printf("5");
1659 			else if (parm->udmamodes & 0x10)
1660 				printf("4");
1661 			else if (parm->udmamodes & 0x08)
1662 				printf("3");
1663 			else if (parm->udmamodes & 0x04)
1664 				printf("2");
1665 			else if (parm->udmamodes & 0x02)
1666 				printf("1");
1667 			else if (parm->udmamodes & 0x01)
1668 				printf("0");
1669 			printf(" ");
1670 		}
1671 	}
1672 	printf("\n");
1673 
1674 	if (parm->media_rotation_rate == 1) {
1675 		printf("media RPM             non-rotating\n");
1676 	} else if (parm->media_rotation_rate >= 0x0401 &&
1677 	    parm->media_rotation_rate <= 0xFFFE) {
1678 		printf("media RPM             %d\n",
1679 			parm->media_rotation_rate);
1680 	}
1681 
1682 	printf("Zoned-Device Commands ");
1683 	switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1684 		case ATA_SUPPORT_ZONE_DEV_MANAGED:
1685 			printf("device managed\n");
1686 			break;
1687 		case ATA_SUPPORT_ZONE_HOST_AWARE:
1688 			printf("host aware\n");
1689 			break;
1690 		default:
1691 			printf("no\n");
1692 	}
1693 
1694 	printf("\nFeature                      "
1695 		"Support  Enabled   Value           Vendor\n");
1696 	printf("read ahead                     %s	%s\n",
1697 		parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1698 		parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1699 	printf("write cache                    %s	%s\n",
1700 		parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1701 		parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1702 	printf("flush cache                    %s	%s\n",
1703 		parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1704 		parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1705 	printf("Native Command Queuing (NCQ)   ");
1706 	if (atasata(parm) && (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1707 		printf("yes		%d tags\n",
1708 		    ATA_QUEUE_LEN(parm->queue) + 1);
1709 		printf("NCQ Priority Information       %s\n",
1710 		    parm->satacapabilities & ATA_SUPPORT_NCQ_PRIO ?
1711 		    "yes" : "no");
1712 		printf("NCQ Non-Data Command           %s\n",
1713 		    parm->satacapabilities2 & ATA_SUPPORT_NCQ_NON_DATA ?
1714 		    "yes" : "no");
1715 		printf("NCQ Streaming                  %s\n",
1716 		    parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1717 		    "yes" : "no");
1718 		printf("Receive & Send FPDMA Queued    %s\n",
1719 		    parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1720 		    "yes" : "no");
1721 		printf("NCQ Autosense                  %s\n",
1722 		    parm->satasupport & ATA_SUPPORT_NCQ_AUTOSENSE ?
1723 		    "yes" : "no");
1724 	} else
1725 		printf("no\n");
1726 
1727 	printf("SMART                          %s	%s\n",
1728 		parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1729 		parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1730 	printf("security                       %s	%s\n",
1731 		parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1732 		parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1733 	printf("power management               %s	%s\n",
1734 		parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1735 		parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1736 	printf("microcode download             %s	%s\n",
1737 		parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1738 		parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1739 	printf("advanced power management      %s	%s",
1740 		parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1741 		parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1742 		if (parm->support.command2 & ATA_SUPPORT_APM) {
1743 			printf("	%d/0x%02X\n",
1744 			    parm->apm_value & 0xff, parm->apm_value & 0xff);
1745 		} else
1746 			printf("\n");
1747 	printf("automatic acoustic management  %s	%s",
1748 		parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1749 		parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1750 		if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1751 			printf("	%d/0x%02X	%d/0x%02X\n",
1752 			    ATA_ACOUSTIC_CURRENT(parm->acoustic),
1753 			    ATA_ACOUSTIC_CURRENT(parm->acoustic),
1754 			    ATA_ACOUSTIC_VENDOR(parm->acoustic),
1755 			    ATA_ACOUSTIC_VENDOR(parm->acoustic));
1756 		} else
1757 			printf("\n");
1758 	printf("media status notification      %s	%s\n",
1759 		parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1760 		parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1761 	printf("power-up in Standby            %s	%s\n",
1762 		parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1763 		parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1764 	printf("write-read-verify              %s	%s",
1765 		parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1766 		parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1767 		if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1768 			printf("	%d/0x%x\n",
1769 			    parm->wrv_mode, parm->wrv_mode);
1770 		} else
1771 			printf("\n");
1772 	printf("unload                         %s	%s\n",
1773 		parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1774 		parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1775 	printf("general purpose logging        %s	%s\n",
1776 		parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1777 		parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1778 	printf("free-fall                      %s	%s\n",
1779 		parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1780 		parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1781 	printf("sense data reporting           %s	%s\n",
1782 		parm->support2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no",
1783 		parm->enabled2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no");
1784 	printf("extended power conditions      %s	%s\n",
1785 		parm->support2 & ATA_SUPPORT_EPC ? "yes" : "no",
1786 		parm->enabled2 & ATA_SUPPORT_EPC ? "yes" : "no");
1787 	printf("device statistics notification %s	%s\n",
1788 		parm->support2 & ATA_SUPPORT_DSN ? "yes" : "no",
1789 		parm->enabled2 & ATA_SUPPORT_DSN ? "yes" : "no");
1790 	printf("Data Set Management (DSM/TRIM) ");
1791 	if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1792 		printf("yes\n");
1793 		printf("DSM - max 512byte blocks       ");
1794 		if (parm->max_dsm_blocks == 0x00)
1795 			printf("yes              not specified\n");
1796 		else
1797 			printf("yes              %d\n",
1798 				parm->max_dsm_blocks);
1799 
1800 		printf("DSM - deterministic read       ");
1801 		if (parm->support3 & ATA_SUPPORT_DRAT) {
1802 			if (parm->support3 & ATA_SUPPORT_RZAT)
1803 				printf("yes              zeroed\n");
1804 			else
1805 				printf("yes              any value\n");
1806 		} else {
1807 			printf("no\n");
1808 		}
1809 	} else {
1810 		printf("no\n");
1811 	}
1812 	printf("Trusted Computing              %s\n",
1813 	    ((parm->tcg & 0xc000) == 0x4000) && (parm->tcg & ATA_SUPPORT_TCG) ?
1814 	    "yes" : "no");
1815 	printf("encrypts all user data         %s\n",
1816 		parm->support3 & ATA_ENCRYPTS_ALL_USER_DATA ? "yes" : "no");
1817 	printf("Sanitize                       ");
1818 	if (parm->multi & ATA_SUPPORT_SANITIZE) {
1819 		printf("yes\t\t%s%s%s\n",
1820 		    parm->multi & ATA_SUPPORT_BLOCK_ERASE_EXT ? "block, " : "",
1821 		    parm->multi & ATA_SUPPORT_OVERWRITE_EXT ? "overwrite, " : "",
1822 		    parm->multi & ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT ? "crypto" : "");
1823 		printf("Sanitize - commands allowed    %s\n",
1824 		    parm->multi & ATA_SUPPORT_SANITIZE_ALLOWED ? "yes" : "no");
1825 		printf("Sanitize - antifreeze lock     %s\n",
1826 		    parm->multi & ATA_SUPPORT_ANTIFREEZE_LOCK_EXT ? "yes" : "no");
1827 	} else {
1828 		printf("no\n");
1829 	}
1830 }
1831 
1832 static int
1833 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb)
1834 {
1835 	struct ata_pass_16 *ata_pass_16;
1836 	struct ata_cmd ata_cmd;
1837 
1838 	ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1839 	ata_cmd.command = ata_pass_16->command;
1840 	ata_cmd.control = ata_pass_16->control;
1841 	ata_cmd.features = ata_pass_16->features;
1842 
1843 	if (arglist & CAM_ARG_VERBOSE) {
1844 		warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1845 		      ata_op_string(&ata_cmd),
1846 		      ccb->csio.ccb_h.timeout);
1847 	}
1848 
1849 	/* Disable freezing the device queue */
1850 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1851 
1852 	if (arglist & CAM_ARG_ERR_RECOVER)
1853 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1854 
1855 	if (cam_send_ccb(device, ccb) < 0) {
1856 		warn("error sending ATA %s via pass_16", ata_op_string(&ata_cmd));
1857 		return (1);
1858 	}
1859 
1860 	/*
1861 	 * Consider any non-CAM_REQ_CMP status as error and report it here,
1862 	 * unless caller set AP_FLAG_CHK_COND, in which case it is responsible.
1863 	 */
1864 	if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1865 	    (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1866 		warnx("ATA %s via pass_16 failed", ata_op_string(&ata_cmd));
1867 		if (arglist & CAM_ARG_VERBOSE) {
1868 			cam_error_print(device, ccb, CAM_ESF_ALL,
1869 					CAM_EPF_ALL, stderr);
1870 		}
1871 		return (1);
1872 	}
1873 
1874 	return (0);
1875 }
1876 
1877 
1878 static int
1879 ata_cam_send(struct cam_device *device, union ccb *ccb)
1880 {
1881 	if (arglist & CAM_ARG_VERBOSE) {
1882 		warnx("sending ATA %s with timeout of %u msecs",
1883 		      ata_op_string(&(ccb->ataio.cmd)),
1884 		      ccb->ataio.ccb_h.timeout);
1885 	}
1886 
1887 	/* Disable freezing the device queue */
1888 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1889 
1890 	if (arglist & CAM_ARG_ERR_RECOVER)
1891 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1892 
1893 	if (cam_send_ccb(device, ccb) < 0) {
1894 		warn("error sending ATA %s", ata_op_string(&(ccb->ataio.cmd)));
1895 		return (1);
1896 	}
1897 
1898 	/*
1899 	 * Consider any non-CAM_REQ_CMP status as error and report it here,
1900 	 * unless caller set AP_FLAG_CHK_COND, in which case it is responsible.
1901 	 */
1902 	if (!(ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT) &&
1903 	    (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1904 		warnx("ATA %s failed", ata_op_string(&(ccb->ataio.cmd)));
1905 		if (arglist & CAM_ARG_VERBOSE) {
1906 			cam_error_print(device, ccb, CAM_ESF_ALL,
1907 					CAM_EPF_ALL, stderr);
1908 		}
1909 		return (1);
1910 	}
1911 
1912 	return (0);
1913 }
1914 
1915 static int
1916 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1917 	       uint32_t flags, uint8_t protocol, uint8_t ata_flags,
1918 	       uint8_t tag_action, uint8_t command, uint16_t features,
1919 	       u_int64_t lba, uint16_t sector_count, uint8_t *data_ptr,
1920 	       uint16_t dxfer_len, int timeout)
1921 {
1922 	if (data_ptr != NULL) {
1923 		if (flags & CAM_DIR_OUT)
1924 			ata_flags |= AP_FLAG_TDIR_TO_DEV;
1925 		else
1926 			ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1927 	} else {
1928 		ata_flags |= AP_FLAG_TLEN_NO_DATA;
1929 	}
1930 
1931 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1932 
1933 	scsi_ata_pass_16(&ccb->csio,
1934 			 retries,
1935 			 NULL,
1936 			 flags,
1937 			 tag_action,
1938 			 protocol,
1939 			 ata_flags,
1940 			 features,
1941 			 sector_count,
1942 			 lba,
1943 			 command,
1944 			 /*control*/0,
1945 			 data_ptr,
1946 			 dxfer_len,
1947 			 /*sense_len*/SSD_FULL_SIZE,
1948 			 timeout);
1949 
1950 	return scsi_cam_pass_16_send(device, ccb);
1951 }
1952 
1953 static int
1954 ata_try_pass_16(struct cam_device *device)
1955 {
1956 	struct ccb_pathinq cpi;
1957 
1958 	if (get_cpi(device, &cpi) != 0) {
1959 		warnx("couldn't get CPI");
1960 		return (-1);
1961 	}
1962 
1963 	if (cpi.protocol == PROTO_SCSI) {
1964 		/* possibly compatible with pass_16 */
1965 		return (1);
1966 	}
1967 
1968 	/* likely not compatible with pass_16 */
1969 	return (0);
1970 }
1971 
1972 static int
1973 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1974 	   uint32_t flags, uint8_t protocol, uint8_t ata_flags,
1975 	   uint8_t tag_action, uint8_t command, uint16_t features,
1976 	   u_int64_t lba, uint16_t sector_count, uint8_t *data_ptr,
1977 	   uint16_t dxfer_len, int timeout, int force48bit)
1978 {
1979 	int retval;
1980 
1981 	retval = ata_try_pass_16(device);
1982 	if (retval == -1)
1983 		return (1);
1984 
1985 	if (retval == 1) {
1986 		return (ata_do_pass_16(device, ccb, retries, flags, protocol,
1987 				      ata_flags, tag_action, command, features,
1988 				      lba, sector_count, data_ptr, dxfer_len,
1989 				      timeout));
1990 	}
1991 
1992 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1993 	cam_fill_ataio(&ccb->ataio,
1994 		       retries,
1995 		       NULL,
1996 		       flags,
1997 		       tag_action,
1998 		       data_ptr,
1999 		       dxfer_len,
2000 		       timeout);
2001 
2002 	if (force48bit || lba > ATA_MAX_28BIT_LBA)
2003 		ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
2004 	else
2005 		ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
2006 
2007 	if (ata_flags & AP_FLAG_CHK_COND)
2008 		ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
2009 
2010 	return ata_cam_send(device, ccb);
2011 }
2012 
2013 static void
2014 dump_data(uint16_t *ptr, uint32_t len)
2015 {
2016 	u_int i;
2017 
2018 	for (i = 0; i < len / 2; i++) {
2019 		if ((i % 8) == 0)
2020 			printf(" %3d: ", i);
2021 		printf("%04hx ", ptr[i]);
2022 		if ((i % 8) == 7)
2023 			printf("\n");
2024 	}
2025 	if ((i % 8) != 7)
2026 		printf("\n");
2027 }
2028 
2029 static int
2030 atahpa_proc_resp(struct cam_device *device, union ccb *ccb, u_int64_t *hpasize)
2031 {
2032 	uint8_t error = 0, ata_device = 0, status = 0;
2033 	uint16_t count = 0;
2034 	uint64_t lba = 0;
2035 	int retval;
2036 
2037 	retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
2038 	    &status);
2039 	if (retval == 1) {
2040 		if (arglist & CAM_ARG_VERBOSE) {
2041 			cam_error_print(device, ccb, CAM_ESF_ALL,
2042 					CAM_EPF_ALL, stderr);
2043 		}
2044 		warnx("Can't get ATA command status");
2045 		return (retval);
2046 	}
2047 
2048 	if (status & ATA_STATUS_ERROR) {
2049 		if (arglist & CAM_ARG_VERBOSE) {
2050 			cam_error_print(device, ccb, CAM_ESF_ALL,
2051 					CAM_EPF_ALL, stderr);
2052 		}
2053 
2054 		if (error & ATA_ERROR_ID_NOT_FOUND) {
2055 			warnx("Max address has already been set since "
2056 			      "last power-on or hardware reset");
2057 		} else if (hpasize == NULL)
2058 			warnx("Command failed with ATA error");
2059 
2060 		return (1);
2061 	}
2062 
2063 	if (hpasize != NULL) {
2064 		if (retval == 2 || retval == 6)
2065 			return (1);
2066 		*hpasize = lba + 1;
2067 	}
2068 
2069 	return (0);
2070 }
2071 
2072 static int
2073 ata_read_native_max(struct cam_device *device, int retry_count,
2074 		      uint32_t timeout, union ccb *ccb,
2075 		      struct ata_params *parm, u_int64_t *hpasize)
2076 {
2077 	int error;
2078 	u_int cmd, is48bit;
2079 	uint8_t protocol;
2080 
2081 	is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2082 	protocol = AP_PROTO_NON_DATA;
2083 
2084 	if (is48bit) {
2085 		cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2086 		protocol |= AP_EXTEND;
2087 	} else {
2088 		cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2089 	}
2090 
2091 	error = ata_do_cmd(device,
2092 			   ccb,
2093 			   retry_count,
2094 			   /*flags*/CAM_DIR_NONE,
2095 			   /*protocol*/protocol,
2096 			   /*ata_flags*/AP_FLAG_CHK_COND,
2097 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2098 			   /*command*/cmd,
2099 			   /*features*/0,
2100 			   /*lba*/0,
2101 			   /*sector_count*/0,
2102 			   /*data_ptr*/NULL,
2103 			   /*dxfer_len*/0,
2104 			   timeout ? timeout : 5000,
2105 			   is48bit);
2106 
2107 	if (error)
2108 		return (error);
2109 
2110 	return atahpa_proc_resp(device, ccb, hpasize);
2111 }
2112 
2113 static int
2114 atahpa_set_max(struct cam_device *device, int retry_count,
2115 	      uint32_t timeout, union ccb *ccb,
2116 	      int is48bit, u_int64_t maxsize, int persist)
2117 {
2118 	int error;
2119 	u_int cmd;
2120 	uint8_t protocol;
2121 
2122 	protocol = AP_PROTO_NON_DATA;
2123 
2124 	if (is48bit) {
2125 		cmd = ATA_SET_MAX_ADDRESS48;
2126 		protocol |= AP_EXTEND;
2127 	} else {
2128 		cmd = ATA_SET_MAX_ADDRESS;
2129 	}
2130 
2131 	/* lba's are zero indexed so the max lba is requested max - 1 */
2132 	if (maxsize)
2133 		maxsize--;
2134 
2135 	error = ata_do_cmd(device,
2136 			   ccb,
2137 			   retry_count,
2138 			   /*flags*/CAM_DIR_NONE,
2139 			   /*protocol*/protocol,
2140 			   /*ata_flags*/AP_FLAG_CHK_COND,
2141 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2142 			   /*command*/cmd,
2143 			   /*features*/ATA_HPA_FEAT_MAX_ADDR,
2144 			   /*lba*/maxsize,
2145 			   /*sector_count*/persist,
2146 			   /*data_ptr*/NULL,
2147 			   /*dxfer_len*/0,
2148 			   timeout ? timeout : 1000,
2149 			   is48bit);
2150 
2151 	if (error)
2152 		return (error);
2153 
2154 	return atahpa_proc_resp(device, ccb, NULL);
2155 }
2156 
2157 static int
2158 atahpa_password(struct cam_device *device, int retry_count,
2159 		uint32_t timeout, union ccb *ccb,
2160 		int is48bit, struct ata_set_max_pwd *pwd)
2161 {
2162 	u_int cmd;
2163 	uint8_t protocol;
2164 
2165 	protocol = AP_PROTO_PIO_OUT;
2166 	cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2167 
2168 	return (ata_do_cmd(device,
2169 			   ccb,
2170 			   retry_count,
2171 			   /*flags*/CAM_DIR_OUT,
2172 			   /*protocol*/protocol,
2173 			   /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2174 			    AP_FLAG_TLEN_SECT_CNT,
2175 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2176 			   /*command*/cmd,
2177 			   /*features*/ATA_HPA_FEAT_SET_PWD,
2178 			   /*lba*/0,
2179 			   /*sector_count*/sizeof(*pwd) / 512,
2180 			   /*data_ptr*/(uint8_t*)pwd,
2181 			   /*dxfer_len*/sizeof(*pwd),
2182 			   timeout ? timeout : 1000,
2183 			   is48bit));
2184 }
2185 
2186 static int
2187 atahpa_lock(struct cam_device *device, int retry_count,
2188 	    uint32_t timeout, union ccb *ccb, int is48bit)
2189 {
2190 	u_int cmd;
2191 	uint8_t protocol;
2192 
2193 	protocol = AP_PROTO_NON_DATA;
2194 	cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2195 
2196 	return (ata_do_cmd(device,
2197 			   ccb,
2198 			   retry_count,
2199 			   /*flags*/CAM_DIR_NONE,
2200 			   /*protocol*/protocol,
2201 			   /*ata_flags*/0,
2202 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2203 			   /*command*/cmd,
2204 			   /*features*/ATA_HPA_FEAT_LOCK,
2205 			   /*lba*/0,
2206 			   /*sector_count*/0,
2207 			   /*data_ptr*/NULL,
2208 			   /*dxfer_len*/0,
2209 			   timeout ? timeout : 1000,
2210 			   is48bit));
2211 }
2212 
2213 static int
2214 atahpa_unlock(struct cam_device *device, int retry_count,
2215 	      uint32_t timeout, union ccb *ccb,
2216 	      int is48bit, struct ata_set_max_pwd *pwd)
2217 {
2218 	u_int cmd;
2219 	uint8_t protocol;
2220 
2221 	protocol = AP_PROTO_PIO_OUT;
2222 	cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2223 
2224 	return (ata_do_cmd(device,
2225 			   ccb,
2226 			   retry_count,
2227 			   /*flags*/CAM_DIR_OUT,
2228 			   /*protocol*/protocol,
2229 			   /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2230 			    AP_FLAG_TLEN_SECT_CNT,
2231 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2232 			   /*command*/cmd,
2233 			   /*features*/ATA_HPA_FEAT_UNLOCK,
2234 			   /*lba*/0,
2235 			   /*sector_count*/sizeof(*pwd) / 512,
2236 			   /*data_ptr*/(uint8_t*)pwd,
2237 			   /*dxfer_len*/sizeof(*pwd),
2238 			   timeout ? timeout : 1000,
2239 			   is48bit));
2240 }
2241 
2242 static int
2243 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2244 		   uint32_t timeout, union ccb *ccb, int is48bit)
2245 {
2246 	u_int cmd;
2247 	uint8_t protocol;
2248 
2249 	protocol = AP_PROTO_NON_DATA;
2250 	cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2251 
2252 	return (ata_do_cmd(device,
2253 			   ccb,
2254 			   retry_count,
2255 			   /*flags*/CAM_DIR_NONE,
2256 			   /*protocol*/protocol,
2257 			   /*ata_flags*/0,
2258 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2259 			   /*command*/cmd,
2260 			   /*features*/ATA_HPA_FEAT_FREEZE,
2261 			   /*lba*/0,
2262 			   /*sector_count*/0,
2263 			   /*data_ptr*/NULL,
2264 			   /*dxfer_len*/0,
2265 			   timeout ? timeout : 1000,
2266 			   is48bit));
2267 }
2268 
2269 static int
2270 ata_get_native_max(struct cam_device *device, int retry_count,
2271 		      uint32_t timeout, union ccb *ccb,
2272 		      u_int64_t *nativesize)
2273 {
2274 	int error;
2275 
2276 	error = ata_do_cmd(device,
2277 			   ccb,
2278 			   retry_count,
2279 			   /*flags*/CAM_DIR_NONE,
2280 			   /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2281 			   /*ata_flags*/AP_FLAG_CHK_COND,
2282 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2283 			   /*command*/ATA_AMAX_ADDR,
2284 			   /*features*/ATA_AMAX_ADDR_GET,
2285 			   /*lba*/0,
2286 			   /*sector_count*/0,
2287 			   /*data_ptr*/NULL,
2288 			   /*dxfer_len*/0,
2289 			   timeout ? timeout : 30 * 1000,
2290 			   /*force48bit*/1);
2291 
2292 	if (error)
2293 		return (error);
2294 
2295 	return atahpa_proc_resp(device, ccb, nativesize);
2296 }
2297 
2298 static int
2299 ataama_set(struct cam_device *device, int retry_count,
2300 	      uint32_t timeout, union ccb *ccb, u_int64_t maxsize)
2301 {
2302 	int error;
2303 
2304 	/* lba's are zero indexed so the max lba is requested max - 1 */
2305 	if (maxsize)
2306 		maxsize--;
2307 
2308 	error = ata_do_cmd(device,
2309 			   ccb,
2310 			   retry_count,
2311 			   /*flags*/CAM_DIR_NONE,
2312 			   /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2313 			   /*ata_flags*/AP_FLAG_CHK_COND,
2314 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2315 			   /*command*/ATA_AMAX_ADDR,
2316 			   /*features*/ATA_AMAX_ADDR_SET,
2317 			   /*lba*/maxsize,
2318 			   /*sector_count*/0,
2319 			   /*data_ptr*/NULL,
2320 			   /*dxfer_len*/0,
2321 			   timeout ? timeout : 30 * 1000,
2322 			   /*force48bit*/1);
2323 
2324 	if (error)
2325 		return (error);
2326 
2327 	return atahpa_proc_resp(device, ccb, NULL);
2328 }
2329 
2330 static int
2331 ataama_freeze(struct cam_device *device, int retry_count,
2332 		   uint32_t timeout, union ccb *ccb)
2333 {
2334 
2335 	return (ata_do_cmd(device,
2336 			   ccb,
2337 			   retry_count,
2338 			   /*flags*/CAM_DIR_NONE,
2339 			   /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2340 			   /*ata_flags*/0,
2341 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2342 			   /*command*/ATA_AMAX_ADDR,
2343 			   /*features*/ATA_AMAX_ADDR_FREEZE,
2344 			   /*lba*/0,
2345 			   /*sector_count*/0,
2346 			   /*data_ptr*/NULL,
2347 			   /*dxfer_len*/0,
2348 			   timeout ? timeout : 30 * 1000,
2349 			   /*force48bit*/1));
2350 }
2351 
2352 int
2353 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2354 		union ccb *ccb, struct ata_params** ident_bufp)
2355 {
2356 	struct ata_params *ident_buf;
2357 	struct ccb_pathinq cpi;
2358 	struct ccb_getdev cgd;
2359 	u_int i, error;
2360 	int16_t *ptr;
2361 	uint8_t command, retry_command;
2362 
2363 	if (get_cpi(device, &cpi) != 0) {
2364 		warnx("couldn't get CPI");
2365 		return (-1);
2366 	}
2367 
2368 	/* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2369 	if (cpi.protocol == PROTO_ATA) {
2370 		if (get_cgd(device, &cgd) != 0) {
2371 			warnx("couldn't get CGD");
2372 			return (-1);
2373 		}
2374 
2375 		command = (cgd.protocol == PROTO_ATA) ?
2376 		    ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2377 		retry_command = 0;
2378 	} else {
2379 		/* We don't know which for sure so try both */
2380 		command = ATA_ATA_IDENTIFY;
2381 		retry_command = ATA_ATAPI_IDENTIFY;
2382 	}
2383 
2384 	ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2385 	if (ptr == NULL) {
2386 		warnx("can't calloc memory for identify\n");
2387 		return (1);
2388 	}
2389 
2390 retry:
2391 	error = ata_do_cmd(device,
2392 			   ccb,
2393 			   /*retries*/retry_count,
2394 			   /*flags*/CAM_DIR_IN,
2395 			   /*protocol*/AP_PROTO_PIO_IN,
2396 			   /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2397 			    AP_FLAG_TLEN_SECT_CNT,
2398 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2399 			   /*command*/command,
2400 			   /*features*/0,
2401 			   /*lba*/0,
2402 			   /*sector_count*/sizeof(struct ata_params) / 512,
2403 			   /*data_ptr*/(uint8_t *)ptr,
2404 			   /*dxfer_len*/sizeof(struct ata_params),
2405 			   /*timeout*/timeout ? timeout : 30 * 1000,
2406 			   /*force48bit*/0);
2407 
2408 	if (error != 0) {
2409 		if (retry_command != 0) {
2410 			command = retry_command;
2411 			retry_command = 0;
2412 			goto retry;
2413 		}
2414 		free(ptr);
2415 		return (1);
2416 	}
2417 
2418 	ident_buf = (struct ata_params *)ptr;
2419 	ata_param_fixup(ident_buf);
2420 
2421 	error = 1;
2422 	for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2423 		if (ptr[i] != 0)
2424 			error = 0;
2425 	}
2426 
2427 	/* check for invalid (all zero) response */
2428 	if (error != 0) {
2429 		warnx("Invalid identify response detected");
2430 		free(ptr);
2431 		return (error);
2432 	}
2433 
2434 	*ident_bufp = ident_buf;
2435 
2436 	return (0);
2437 }
2438 
2439 
2440 static int
2441 ataidentify(struct cam_device *device, int retry_count, int timeout)
2442 {
2443 	union ccb *ccb;
2444 	struct ata_params *ident_buf;
2445 	u_int64_t hpasize = 0, nativesize = 0;
2446 
2447 	if ((ccb = cam_getccb(device)) == NULL) {
2448 		warnx("couldn't allocate CCB");
2449 		return (1);
2450 	}
2451 
2452 	if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2453 		cam_freeccb(ccb);
2454 		return (1);
2455 	}
2456 
2457 	if (arglist & CAM_ARG_VERBOSE) {
2458 		printf("%s%d: Raw identify data:\n",
2459 		    device->device_name, device->dev_unit_num);
2460 		dump_data((uint16_t *)ident_buf, sizeof(struct ata_params));
2461 	}
2462 
2463 	if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2464 		ata_read_native_max(device, retry_count, timeout, ccb,
2465 				    ident_buf, &hpasize);
2466 	}
2467 	if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2468 		ata_get_native_max(device, retry_count, timeout, ccb,
2469 				   &nativesize);
2470 	}
2471 
2472 	printf("%s%d: ", device->device_name, device->dev_unit_num);
2473 	ata_print_ident(ident_buf);
2474 	camxferrate(device);
2475 	atacapprint(ident_buf);
2476 	atahpa_print(ident_buf, hpasize, 0);
2477 	ataama_print(ident_buf, nativesize, 0);
2478 
2479 	free(ident_buf);
2480 	cam_freeccb(ccb);
2481 
2482 	return (0);
2483 }
2484 
2485 static int
2486 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2487 {
2488 	struct nvme_controller_data cdata;
2489 
2490 	if (nvme_get_cdata(device, &cdata))
2491 		return (1);
2492 	nvme_print_controller(&cdata);
2493 
2494 	return (0);
2495 }
2496 
2497 static int
2498 identify(struct cam_device *device, int retry_count, int timeout)
2499 {
2500 	struct ccb_pathinq cpi;
2501 
2502 	if (get_cpi(device, &cpi) != 0) {
2503 		warnx("couldn't get CPI");
2504 		return (-1);
2505 	}
2506 
2507 	if (cpi.protocol == PROTO_NVME) {
2508 		return (nvmeidentify(device, retry_count, timeout));
2509 	}
2510 	return (ataidentify(device, retry_count, timeout));
2511 }
2512 
2513 
2514 enum {
2515 	ATA_SECURITY_ACTION_PRINT,
2516 	ATA_SECURITY_ACTION_FREEZE,
2517 	ATA_SECURITY_ACTION_UNLOCK,
2518 	ATA_SECURITY_ACTION_DISABLE,
2519 	ATA_SECURITY_ACTION_ERASE,
2520 	ATA_SECURITY_ACTION_ERASE_ENHANCED,
2521 	ATA_SECURITY_ACTION_SET_PASSWORD
2522 };
2523 
2524 static void
2525 atasecurity_print_time(uint16_t tw)
2526 {
2527 
2528 	if (tw == 0)
2529 		printf("unspecified");
2530 	else if (tw >= 255)
2531 		printf("> 508 min");
2532 	else
2533 		printf("%i min", 2 * tw);
2534 }
2535 
2536 static uint32_t
2537 atasecurity_erase_timeout_msecs(uint16_t timeout)
2538 {
2539 
2540 	if (timeout == 0)
2541 		return 2 * 3600 * 1000; /* default: two hours */
2542 	else if (timeout > 255)
2543 		return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2544 
2545 	return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2546 }
2547 
2548 
2549 static void
2550 atasecurity_notify(uint8_t command, struct ata_security_password *pwd)
2551 {
2552 	struct ata_cmd cmd;
2553 
2554 	bzero(&cmd, sizeof(cmd));
2555 	cmd.command = command;
2556 	printf("Issuing %s", ata_op_string(&cmd));
2557 
2558 	if (pwd != NULL) {
2559 		/* pwd->password may not be null terminated */
2560 		char pass[sizeof(pwd->password)+1];
2561 
2562 		strlcpy(pass, pwd->password, sizeof(pass));
2563 		printf(" password='%s', user='%s'",
2564 			pass,
2565 			(pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2566 			"master" : "user");
2567 
2568 		if (command == ATA_SECURITY_SET_PASSWORD) {
2569 			printf(", mode='%s'",
2570 			       (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2571 			       "maximum" : "high");
2572 		}
2573 	}
2574 
2575 	printf("\n");
2576 }
2577 
2578 static int
2579 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2580 		   int retry_count, uint32_t timeout, int quiet)
2581 {
2582 
2583 	if (quiet == 0)
2584 		atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2585 
2586 	return ata_do_cmd(device,
2587 			  ccb,
2588 			  retry_count,
2589 			  /*flags*/CAM_DIR_NONE,
2590 			  /*protocol*/AP_PROTO_NON_DATA,
2591 			  /*ata_flags*/0,
2592 			  /*tag_action*/MSG_SIMPLE_Q_TAG,
2593 			  /*command*/ATA_SECURITY_FREEZE_LOCK,
2594 			  /*features*/0,
2595 			  /*lba*/0,
2596 			  /*sector_count*/0,
2597 			  /*data_ptr*/NULL,
2598 			  /*dxfer_len*/0,
2599 			  /*timeout*/timeout,
2600 			  /*force48bit*/0);
2601 }
2602 
2603 static int
2604 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2605 		   int retry_count, uint32_t timeout,
2606 		   struct ata_security_password *pwd, int quiet)
2607 {
2608 
2609 	if (quiet == 0)
2610 		atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2611 
2612 	return ata_do_cmd(device,
2613 			  ccb,
2614 			  retry_count,
2615 			  /*flags*/CAM_DIR_OUT,
2616 			  /*protocol*/AP_PROTO_PIO_OUT,
2617 			  /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2618 			    AP_FLAG_TLEN_SECT_CNT,
2619 			  /*tag_action*/MSG_SIMPLE_Q_TAG,
2620 			  /*command*/ATA_SECURITY_UNLOCK,
2621 			  /*features*/0,
2622 			  /*lba*/0,
2623 			  /*sector_count*/sizeof(*pwd) / 512,
2624 			  /*data_ptr*/(uint8_t *)pwd,
2625 			  /*dxfer_len*/sizeof(*pwd),
2626 			  /*timeout*/timeout,
2627 			  /*force48bit*/0);
2628 }
2629 
2630 static int
2631 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2632 		    int retry_count, uint32_t timeout,
2633 		    struct ata_security_password *pwd, int quiet)
2634 {
2635 
2636 	if (quiet == 0)
2637 		atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2638 	return ata_do_cmd(device,
2639 			  ccb,
2640 			  retry_count,
2641 			  /*flags*/CAM_DIR_OUT,
2642 			  /*protocol*/AP_PROTO_PIO_OUT,
2643 			  /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2644 			    AP_FLAG_TLEN_SECT_CNT,
2645 			  /*tag_action*/MSG_SIMPLE_Q_TAG,
2646 			  /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2647 			  /*features*/0,
2648 			  /*lba*/0,
2649 			  /*sector_count*/sizeof(*pwd) / 512,
2650 			  /*data_ptr*/(uint8_t *)pwd,
2651 			  /*dxfer_len*/sizeof(*pwd),
2652 			  /*timeout*/timeout,
2653 			  /*force48bit*/0);
2654 }
2655 
2656 
2657 static int
2658 atasecurity_erase_confirm(struct cam_device *device,
2659 			  struct ata_params* ident_buf)
2660 {
2661 
2662 	printf("\nYou are about to ERASE ALL DATA from the following"
2663 	       " device:\n%s%d,%s%d: ", device->device_name,
2664 	       device->dev_unit_num, device->given_dev_name,
2665 	       device->given_unit_number);
2666 	ata_print_ident(ident_buf);
2667 
2668 	for(;;) {
2669 		char str[50];
2670 		printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2671 
2672 		if (fgets(str, sizeof(str), stdin) != NULL) {
2673 			if (strncasecmp(str, "yes", 3) == 0) {
2674 				return (1);
2675 			} else if (strncasecmp(str, "no", 2) == 0) {
2676 				return (0);
2677 			} else {
2678 				printf("Please answer \"yes\" or "
2679 				       "\"no\"\n");
2680 			}
2681 		}
2682 	}
2683 
2684 	/* NOTREACHED */
2685 	return (0);
2686 }
2687 
2688 static int
2689 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2690 		  int retry_count, uint32_t timeout,
2691 		  uint32_t erase_timeout,
2692 		  struct ata_security_password *pwd, int quiet)
2693 {
2694 	int error;
2695 
2696 	if (quiet == 0)
2697 		atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2698 
2699 	error = ata_do_cmd(device,
2700 			   ccb,
2701 			   retry_count,
2702 			   /*flags*/CAM_DIR_NONE,
2703 			   /*protocol*/AP_PROTO_NON_DATA,
2704 			   /*ata_flags*/0,
2705 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2706 			   /*command*/ATA_SECURITY_ERASE_PREPARE,
2707 			   /*features*/0,
2708 			   /*lba*/0,
2709 			   /*sector_count*/0,
2710 			   /*data_ptr*/NULL,
2711 			   /*dxfer_len*/0,
2712 			   /*timeout*/timeout,
2713 			   /*force48bit*/0);
2714 
2715 	if (error != 0)
2716 		return error;
2717 
2718 	if (quiet == 0)
2719 		atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2720 
2721 	error = ata_do_cmd(device,
2722 			   ccb,
2723 			   retry_count,
2724 			   /*flags*/CAM_DIR_OUT,
2725 			   /*protocol*/AP_PROTO_PIO_OUT,
2726 			   /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2727 			    AP_FLAG_TLEN_SECT_CNT,
2728 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2729 			   /*command*/ATA_SECURITY_ERASE_UNIT,
2730 			   /*features*/0,
2731 			   /*lba*/0,
2732 			   /*sector_count*/sizeof(*pwd) / 512,
2733 			   /*data_ptr*/(uint8_t *)pwd,
2734 			   /*dxfer_len*/sizeof(*pwd),
2735 			   /*timeout*/erase_timeout,
2736 			   /*force48bit*/0);
2737 
2738 	if (error == 0 && quiet == 0)
2739 		printf("\nErase Complete\n");
2740 
2741 	return error;
2742 }
2743 
2744 static int
2745 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2746 			 int retry_count, uint32_t timeout,
2747 			 struct ata_security_password *pwd, int quiet)
2748 {
2749 
2750 	if (quiet == 0)
2751 		atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2752 
2753 	return ata_do_cmd(device,
2754 			  ccb,
2755 			  retry_count,
2756 			  /*flags*/CAM_DIR_OUT,
2757 			  /*protocol*/AP_PROTO_PIO_OUT,
2758 			  /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2759 			   AP_FLAG_TLEN_SECT_CNT,
2760 			  /*tag_action*/MSG_SIMPLE_Q_TAG,
2761 			  /*command*/ATA_SECURITY_SET_PASSWORD,
2762 			  /*features*/0,
2763 			  /*lba*/0,
2764 			  /*sector_count*/sizeof(*pwd) / 512,
2765 			  /*data_ptr*/(uint8_t *)pwd,
2766 			  /*dxfer_len*/sizeof(*pwd),
2767 			  /*timeout*/timeout,
2768 			  /*force48bit*/0);
2769 }
2770 
2771 static void
2772 atasecurity_print(struct ata_params *parm)
2773 {
2774 
2775 	printf("\nSecurity Option           Value\n");
2776 	if (arglist & CAM_ARG_VERBOSE) {
2777 		printf("status                    %04x\n",
2778 		       parm->security_status);
2779 	}
2780 	printf("supported                 %s\n",
2781 		parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2782 	if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2783 		return;
2784 	printf("enabled                   %s\n",
2785 		parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2786 	printf("drive locked              %s\n",
2787 		parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2788 	printf("security config frozen    %s\n",
2789 		parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2790 	printf("count expired             %s\n",
2791 		parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2792 	printf("security level            %s\n",
2793 		parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2794 	printf("enhanced erase supported  %s\n",
2795 		parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2796 	printf("erase time                ");
2797 	atasecurity_print_time(parm->erase_time);
2798 	printf("\n");
2799 	printf("enhanced erase time       ");
2800 	atasecurity_print_time(parm->enhanced_erase_time);
2801 	printf("\n");
2802 	printf("master password rev       %04x%s\n",
2803 		parm->master_passwd_revision,
2804 		parm->master_passwd_revision == 0x0000 ||
2805 		parm->master_passwd_revision == 0xFFFF ?  " (unsupported)" : "");
2806 }
2807 
2808 /*
2809  * Validates and copies the password in optarg to the passed buffer.
2810  * If the password in optarg is the same length as the buffer then
2811  * the data will still be copied but no null termination will occur.
2812  */
2813 static int
2814 ata_getpwd(uint8_t *passwd, int max, char opt)
2815 {
2816 	int len;
2817 
2818 	len = strlen(optarg);
2819 	if (len > max) {
2820 		warnx("-%c password is too long", opt);
2821 		return (1);
2822 	} else if (len == 0) {
2823 		warnx("-%c password is missing", opt);
2824 		return (1);
2825 	} else if (optarg[0] == '-'){
2826 		warnx("-%c password starts with '-' (generic arg?)", opt);
2827 		return (1);
2828 	} else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2829 		warnx("-%c password conflicts with existing password from -%c",
2830 		      opt, pwd_opt);
2831 		return (1);
2832 	}
2833 
2834 	/* Callers pass in a buffer which does NOT need to be terminated */
2835 	strncpy(passwd, optarg, max);
2836 	pwd_opt = opt;
2837 
2838 	return (0);
2839 }
2840 
2841 enum {
2842 	ATA_HPA_ACTION_PRINT,
2843 	ATA_HPA_ACTION_SET_MAX,
2844 	ATA_HPA_ACTION_SET_PWD,
2845 	ATA_HPA_ACTION_LOCK,
2846 	ATA_HPA_ACTION_UNLOCK,
2847 	ATA_HPA_ACTION_FREEZE_LOCK
2848 };
2849 
2850 static int
2851 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2852 		   u_int64_t maxsize, int persist)
2853 {
2854 	printf("\nYou are about to configure HPA to limit the user accessible\n"
2855 	       "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2856 	       persist ? "persistently" : "temporarily",
2857 	       device->device_name, device->dev_unit_num,
2858 	       device->given_dev_name, device->given_unit_number);
2859 	ata_print_ident(ident_buf);
2860 
2861 	for(;;) {
2862 		char str[50];
2863 		printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2864 
2865 		if (NULL != fgets(str, sizeof(str), stdin)) {
2866 			if (0 == strncasecmp(str, "yes", 3)) {
2867 				return (1);
2868 			} else if (0 == strncasecmp(str, "no", 2)) {
2869 				return (0);
2870 			} else {
2871 				printf("Please answer \"yes\" or "
2872 				       "\"no\"\n");
2873 			}
2874 		}
2875 	}
2876 
2877 	/* NOTREACHED */
2878 	return (0);
2879 }
2880 
2881 static int
2882 atahpa(struct cam_device *device, int retry_count, int timeout,
2883        int argc, char **argv, char *combinedopt)
2884 {
2885 	union ccb *ccb;
2886 	struct ata_params *ident_buf;
2887 	struct ccb_getdev cgd;
2888 	struct ata_set_max_pwd pwd;
2889 	int error, confirm, quiet, c, action, actions, persist;
2890 	int security, is48bit, pwdsize;
2891 	u_int64_t hpasize, maxsize;
2892 
2893 	actions = 0;
2894 	confirm = 0;
2895 	quiet = 0;
2896 	maxsize = 0;
2897 	persist = 0;
2898 	security = 0;
2899 
2900 	memset(&pwd, 0, sizeof(pwd));
2901 
2902 	/* default action is to print hpa information */
2903 	action = ATA_HPA_ACTION_PRINT;
2904 	pwdsize = sizeof(pwd.password);
2905 
2906 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
2907 		switch(c){
2908 		case 's':
2909 			action = ATA_HPA_ACTION_SET_MAX;
2910 			maxsize = strtoumax(optarg, NULL, 0);
2911 			actions++;
2912 			break;
2913 
2914 		case 'p':
2915 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2916 				return (1);
2917 			action = ATA_HPA_ACTION_SET_PWD;
2918 			security = 1;
2919 			actions++;
2920 			break;
2921 
2922 		case 'l':
2923 			action = ATA_HPA_ACTION_LOCK;
2924 			security = 1;
2925 			actions++;
2926 			break;
2927 
2928 		case 'U':
2929 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2930 				return (1);
2931 			action = ATA_HPA_ACTION_UNLOCK;
2932 			security = 1;
2933 			actions++;
2934 			break;
2935 
2936 		case 'f':
2937 			action = ATA_HPA_ACTION_FREEZE_LOCK;
2938 			security = 1;
2939 			actions++;
2940 			break;
2941 
2942 		case 'P':
2943 			persist = 1;
2944 			break;
2945 
2946 		case 'y':
2947 			confirm++;
2948 			break;
2949 
2950 		case 'q':
2951 			quiet++;
2952 			break;
2953 		}
2954 	}
2955 
2956 	if (actions > 1) {
2957 		warnx("too many hpa actions specified");
2958 		return (1);
2959 	}
2960 
2961 	if (get_cgd(device, &cgd) != 0) {
2962 		warnx("couldn't get CGD");
2963 		return (1);
2964 	}
2965 
2966 	ccb = cam_getccb(device);
2967 	if (ccb == NULL) {
2968 		warnx("couldn't allocate CCB");
2969 		return (1);
2970 	}
2971 
2972 	error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2973 	if (error != 0) {
2974 		cam_freeccb(ccb);
2975 		return (1);
2976 	}
2977 
2978 	if (quiet == 0) {
2979 		printf("%s%d: ", device->device_name, device->dev_unit_num);
2980 		ata_print_ident(ident_buf);
2981 		camxferrate(device);
2982 	}
2983 
2984 	if (action == ATA_HPA_ACTION_PRINT) {
2985 		hpasize = 0;
2986 		if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2987 			ata_read_native_max(device, retry_count, timeout, ccb,
2988 				    ident_buf, &hpasize);
2989 		atahpa_print(ident_buf, hpasize, 1);
2990 
2991 		cam_freeccb(ccb);
2992 		free(ident_buf);
2993 		return (error);
2994 	}
2995 
2996 	if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2997 		warnx("HPA is not supported by this device");
2998 		cam_freeccb(ccb);
2999 		free(ident_buf);
3000 		return (1);
3001 	}
3002 
3003 	if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
3004 		warnx("HPA Security is not supported by this device");
3005 		cam_freeccb(ccb);
3006 		free(ident_buf);
3007 		return (1);
3008 	}
3009 
3010 	is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
3011 
3012 	/*
3013 	 * The ATA spec requires:
3014 	 * 1. Read native max addr is called directly before set max addr
3015 	 * 2. Read native max addr is NOT called before any other set max call
3016 	 */
3017 	switch(action) {
3018 	case ATA_HPA_ACTION_SET_MAX:
3019 		if (confirm == 0 &&
3020 		    atahpa_set_confirm(device, ident_buf, maxsize,
3021 		    persist) == 0) {
3022 			cam_freeccb(ccb);
3023 			free(ident_buf);
3024 			return (1);
3025 		}
3026 
3027 		error = ata_read_native_max(device, retry_count, timeout,
3028 					    ccb, ident_buf, &hpasize);
3029 		if (error == 0) {
3030 			error = atahpa_set_max(device, retry_count, timeout,
3031 					       ccb, is48bit, maxsize, persist);
3032 			if (error == 0) {
3033 				if (quiet == 0) {
3034 					/* redo identify to get new values */
3035 					error = ata_do_identify(device,
3036 					    retry_count, timeout, ccb,
3037 					    &ident_buf);
3038 					atahpa_print(ident_buf, hpasize, 1);
3039 				}
3040 				/* Hint CAM to reprobe the device. */
3041 				reprobe(device);
3042 			}
3043 		}
3044 		break;
3045 
3046 	case ATA_HPA_ACTION_SET_PWD:
3047 		error = atahpa_password(device, retry_count, timeout,
3048 					ccb, is48bit, &pwd);
3049 		if (error == 0 && quiet == 0)
3050 			printf("HPA password has been set\n");
3051 		break;
3052 
3053 	case ATA_HPA_ACTION_LOCK:
3054 		error = atahpa_lock(device, retry_count, timeout,
3055 				    ccb, is48bit);
3056 		if (error == 0 && quiet == 0)
3057 			printf("HPA has been locked\n");
3058 		break;
3059 
3060 	case ATA_HPA_ACTION_UNLOCK:
3061 		error = atahpa_unlock(device, retry_count, timeout,
3062 				      ccb, is48bit, &pwd);
3063 		if (error == 0 && quiet == 0)
3064 			printf("HPA has been unlocked\n");
3065 		break;
3066 
3067 	case ATA_HPA_ACTION_FREEZE_LOCK:
3068 		error = atahpa_freeze_lock(device, retry_count, timeout,
3069 					   ccb, is48bit);
3070 		if (error == 0 && quiet == 0)
3071 			printf("HPA has been frozen\n");
3072 		break;
3073 
3074 	default:
3075 		errx(1, "Option currently not supported");
3076 	}
3077 
3078 	cam_freeccb(ccb);
3079 	free(ident_buf);
3080 
3081 	return (error);
3082 }
3083 
3084 enum {
3085 	ATA_AMA_ACTION_PRINT,
3086 	ATA_AMA_ACTION_SET_MAX,
3087 	ATA_AMA_ACTION_FREEZE_LOCK
3088 };
3089 
3090 static int
3091 ataama(struct cam_device *device, int retry_count, int timeout,
3092        int argc, char **argv, char *combinedopt)
3093 {
3094 	union ccb *ccb;
3095 	struct ata_params *ident_buf;
3096 	struct ccb_getdev cgd;
3097 	int error, quiet, c, action, actions;
3098 	u_int64_t nativesize, maxsize;
3099 
3100 	actions = 0;
3101 	quiet = 0;
3102 	maxsize = 0;
3103 
3104 	/* default action is to print AMA information */
3105 	action = ATA_AMA_ACTION_PRINT;
3106 
3107 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3108 		switch(c){
3109 		case 's':
3110 			action = ATA_AMA_ACTION_SET_MAX;
3111 			maxsize = strtoumax(optarg, NULL, 0);
3112 			actions++;
3113 			break;
3114 
3115 		case 'f':
3116 			action = ATA_AMA_ACTION_FREEZE_LOCK;
3117 			actions++;
3118 			break;
3119 
3120 		case 'q':
3121 			quiet++;
3122 			break;
3123 		}
3124 	}
3125 
3126 	if (actions > 1) {
3127 		warnx("too many AMA actions specified");
3128 		return (1);
3129 	}
3130 
3131 	if (get_cgd(device, &cgd) != 0) {
3132 		warnx("couldn't get CGD");
3133 		return (1);
3134 	}
3135 
3136 	ccb = cam_getccb(device);
3137 	if (ccb == NULL) {
3138 		warnx("couldn't allocate CCB");
3139 		return (1);
3140 	}
3141 
3142 	error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3143 	if (error != 0) {
3144 		cam_freeccb(ccb);
3145 		return (1);
3146 	}
3147 
3148 	if (quiet == 0) {
3149 		printf("%s%d: ", device->device_name, device->dev_unit_num);
3150 		ata_print_ident(ident_buf);
3151 		camxferrate(device);
3152 	}
3153 
3154 	if (action == ATA_AMA_ACTION_PRINT) {
3155 		nativesize = 0;
3156 		if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3157 			ata_get_native_max(device, retry_count, timeout, ccb,
3158 					   &nativesize);
3159 		ataama_print(ident_buf, nativesize, 1);
3160 
3161 		cam_freeccb(ccb);
3162 		free(ident_buf);
3163 		return (error);
3164 	}
3165 
3166 	if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3167 		warnx("Accessible Max Address is not supported by this device");
3168 		cam_freeccb(ccb);
3169 		free(ident_buf);
3170 		return (1);
3171 	}
3172 
3173 	switch(action) {
3174 	case ATA_AMA_ACTION_SET_MAX:
3175 		error = ata_get_native_max(device, retry_count, timeout, ccb,
3176 					   &nativesize);
3177 		if (error == 0) {
3178 			error = ataama_set(device, retry_count, timeout,
3179 				       ccb, maxsize);
3180 			if (error == 0) {
3181 				if (quiet == 0) {
3182 					/* redo identify to get new values */
3183 					error = ata_do_identify(device,
3184 					    retry_count, timeout, ccb,
3185 					    &ident_buf);
3186 					ataama_print(ident_buf, nativesize, 1);
3187 				}
3188 				/* Hint CAM to reprobe the device. */
3189 				reprobe(device);
3190 			}
3191 		}
3192 		break;
3193 
3194 	case ATA_AMA_ACTION_FREEZE_LOCK:
3195 		error = ataama_freeze(device, retry_count, timeout,
3196 					   ccb);
3197 		if (error == 0 && quiet == 0)
3198 			printf("Accessible Max Address has been frozen\n");
3199 		break;
3200 
3201 	default:
3202 		errx(1, "Option currently not supported");
3203 	}
3204 
3205 	cam_freeccb(ccb);
3206 	free(ident_buf);
3207 
3208 	return (error);
3209 }
3210 
3211 static int
3212 atasecurity(struct cam_device *device, int retry_count, int timeout,
3213 	    int argc, char **argv, char *combinedopt)
3214 {
3215 	union ccb *ccb;
3216 	struct ata_params *ident_buf;
3217 	int error, confirm, quiet, c, action, actions, setpwd;
3218 	int security_enabled, erase_timeout, pwdsize;
3219 	struct ata_security_password pwd;
3220 
3221 	actions = 0;
3222 	setpwd = 0;
3223 	erase_timeout = 0;
3224 	confirm = 0;
3225 	quiet = 0;
3226 
3227 	memset(&pwd, 0, sizeof(pwd));
3228 
3229 	/* default action is to print security information */
3230 	action = ATA_SECURITY_ACTION_PRINT;
3231 
3232 	/* user is master by default as its safer that way */
3233 	pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3234 	pwdsize = sizeof(pwd.password);
3235 
3236 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3237 		switch(c){
3238 		case 'f':
3239 			action = ATA_SECURITY_ACTION_FREEZE;
3240 			actions++;
3241 			break;
3242 
3243 		case 'U':
3244 			if (strcasecmp(optarg, "user") == 0) {
3245 				pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3246 				pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3247 			} else if (strcasecmp(optarg, "master") == 0) {
3248 				pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3249 				pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3250 			} else {
3251 				warnx("-U argument '%s' is invalid (must be "
3252 				      "'user' or 'master')", optarg);
3253 				return (1);
3254 			}
3255 			break;
3256 
3257 		case 'l':
3258 			if (strcasecmp(optarg, "high") == 0) {
3259 				pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3260 				pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3261 			} else if (strcasecmp(optarg, "maximum") == 0) {
3262 				pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3263 				pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3264 			} else {
3265 				warnx("-l argument '%s' is unknown (must be "
3266 				      "'high' or 'maximum')", optarg);
3267 				return (1);
3268 			}
3269 			break;
3270 
3271 		case 'k':
3272 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3273 				return (1);
3274 			action = ATA_SECURITY_ACTION_UNLOCK;
3275 			actions++;
3276 			break;
3277 
3278 		case 'd':
3279 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3280 				return (1);
3281 			action = ATA_SECURITY_ACTION_DISABLE;
3282 			actions++;
3283 			break;
3284 
3285 		case 'e':
3286 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3287 				return (1);
3288 			action = ATA_SECURITY_ACTION_ERASE;
3289 			actions++;
3290 			break;
3291 
3292 		case 'h':
3293 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3294 				return (1);
3295 			pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3296 			action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3297 			actions++;
3298 			break;
3299 
3300 		case 's':
3301 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3302 				return (1);
3303 			setpwd = 1;
3304 			if (action == ATA_SECURITY_ACTION_PRINT)
3305 				action = ATA_SECURITY_ACTION_SET_PASSWORD;
3306 			/*
3307 			 * Don't increment action as this can be combined
3308 			 * with other actions.
3309 			 */
3310 			break;
3311 
3312 		case 'y':
3313 			confirm++;
3314 			break;
3315 
3316 		case 'q':
3317 			quiet++;
3318 			break;
3319 
3320 		case 'T':
3321 			erase_timeout = atoi(optarg) * 1000;
3322 			break;
3323 		}
3324 	}
3325 
3326 	if (actions > 1) {
3327 		warnx("too many security actions specified");
3328 		return (1);
3329 	}
3330 
3331 	if ((ccb = cam_getccb(device)) == NULL) {
3332 		warnx("couldn't allocate CCB");
3333 		return (1);
3334 	}
3335 
3336 	error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3337 	if (error != 0) {
3338 		cam_freeccb(ccb);
3339 		return (1);
3340 	}
3341 
3342 	if (quiet == 0) {
3343 		printf("%s%d: ", device->device_name, device->dev_unit_num);
3344 		ata_print_ident(ident_buf);
3345 		camxferrate(device);
3346 	}
3347 
3348 	if (action == ATA_SECURITY_ACTION_PRINT) {
3349 		atasecurity_print(ident_buf);
3350 		free(ident_buf);
3351 		cam_freeccb(ccb);
3352 		return (0);
3353 	}
3354 
3355 	if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3356 		warnx("Security not supported");
3357 		free(ident_buf);
3358 		cam_freeccb(ccb);
3359 		return (1);
3360 	}
3361 
3362 	/* default timeout 15 seconds the same as linux hdparm */
3363 	timeout = timeout ? timeout : 15 * 1000;
3364 
3365 	security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3366 
3367 	/* first set the password if requested */
3368 	if (setpwd == 1) {
3369 		/* confirm we can erase before setting the password if erasing */
3370 		if (confirm == 0 &&
3371 		    (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3372 		    action == ATA_SECURITY_ACTION_ERASE) &&
3373 		    atasecurity_erase_confirm(device, ident_buf) == 0) {
3374 			cam_freeccb(ccb);
3375 			free(ident_buf);
3376 			return (error);
3377 		}
3378 
3379 		if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3380 			pwd.revision = ident_buf->master_passwd_revision;
3381 			if (pwd.revision != 0 && pwd.revision != 0xfff &&
3382 			    --pwd.revision == 0) {
3383 				pwd.revision = 0xfffe;
3384 			}
3385 		}
3386 		error = atasecurity_set_password(device, ccb, retry_count,
3387 						 timeout, &pwd, quiet);
3388 		if (error != 0) {
3389 			cam_freeccb(ccb);
3390 			free(ident_buf);
3391 			return (error);
3392 		}
3393 		security_enabled = 1;
3394 	}
3395 
3396 	switch(action) {
3397 	case ATA_SECURITY_ACTION_FREEZE:
3398 		error = atasecurity_freeze(device, ccb, retry_count,
3399 					   timeout, quiet);
3400 		break;
3401 
3402 	case ATA_SECURITY_ACTION_UNLOCK:
3403 		if (security_enabled) {
3404 			if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3405 				error = atasecurity_unlock(device, ccb,
3406 					retry_count, timeout, &pwd, quiet);
3407 			} else {
3408 				warnx("Can't unlock, drive is not locked");
3409 				error = 1;
3410 			}
3411 		} else {
3412 			warnx("Can't unlock, security is disabled");
3413 			error = 1;
3414 		}
3415 		break;
3416 
3417 	case ATA_SECURITY_ACTION_DISABLE:
3418 		if (security_enabled) {
3419 			/* First unlock the drive if its locked */
3420 			if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3421 				error = atasecurity_unlock(device, ccb,
3422 							   retry_count,
3423 							   timeout,
3424 							   &pwd,
3425 							   quiet);
3426 			}
3427 
3428 			if (error == 0) {
3429 				error = atasecurity_disable(device,
3430 							    ccb,
3431 							    retry_count,
3432 							    timeout,
3433 							    &pwd,
3434 							    quiet);
3435 			}
3436 		} else {
3437 			warnx("Can't disable security (already disabled)");
3438 			error = 1;
3439 		}
3440 		break;
3441 
3442 	case ATA_SECURITY_ACTION_ERASE:
3443 		if (security_enabled) {
3444 			if (erase_timeout == 0) {
3445 				erase_timeout = atasecurity_erase_timeout_msecs(
3446 				    ident_buf->erase_time);
3447 			}
3448 
3449 			error = atasecurity_erase(device, ccb, retry_count,
3450 			    timeout, erase_timeout, &pwd, quiet);
3451 		} else {
3452 			warnx("Can't secure erase (security is disabled)");
3453 			error = 1;
3454 		}
3455 		break;
3456 
3457 	case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3458 		if (security_enabled) {
3459 			if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3460 				if (erase_timeout == 0) {
3461 					erase_timeout =
3462 					    atasecurity_erase_timeout_msecs(
3463 						ident_buf->enhanced_erase_time);
3464 				}
3465 
3466 				error = atasecurity_erase(device, ccb,
3467 							  retry_count, timeout,
3468 							  erase_timeout, &pwd,
3469 							  quiet);
3470 			} else {
3471 				warnx("Enhanced erase is not supported");
3472 				error = 1;
3473 			}
3474 		} else {
3475 			warnx("Can't secure erase (enhanced), "
3476 			      "(security is disabled)");
3477 			error = 1;
3478 		}
3479 		break;
3480 	}
3481 
3482 	cam_freeccb(ccb);
3483 	free(ident_buf);
3484 
3485 	return (error);
3486 }
3487 
3488 /*
3489  * Convert periph name into a bus, target and lun.
3490  *
3491  * Returns the number of parsed components, or 0.
3492  */
3493 static int
3494 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3495     cam_argmask *arglst)
3496 {
3497 	int fd;
3498 	union ccb ccb;
3499 
3500 	bzero(&ccb, sizeof(ccb));
3501 	ccb.ccb_h.func_code = XPT_GDEVLIST;
3502 	if (cam_get_device(tstr, ccb.cgdl.periph_name,
3503 	    sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3504 		warnx("%s", cam_errbuf);
3505 		return (0);
3506 	}
3507 
3508 	/*
3509 	 * Attempt to get the passthrough device.  This ioctl will
3510 	 * fail if the device name is null, if the device doesn't
3511 	 * exist, or if the passthrough driver isn't in the kernel.
3512 	 */
3513 	if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3514 		warn("Unable to open %s", XPT_DEVICE);
3515 		return (0);
3516 	}
3517 	if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3518 		warn("Unable to find bus:target:lun for device %s%d",
3519 		    ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3520 		close(fd);
3521 		return (0);
3522 	}
3523 	close(fd);
3524 	if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3525 		const struct cam_status_entry *entry;
3526 
3527 		entry = cam_fetch_status_entry(ccb.ccb_h.status);
3528 		warnx("Unable to find bus:target_lun for device %s%d, "
3529 		    "CAM status: %s (%#x)",
3530 		    ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3531 		    entry ? entry->status_text : "Unknown",
3532 		    ccb.ccb_h.status);
3533 		return (0);
3534 	}
3535 
3536 	/*
3537 	 * The kernel fills in the bus/target/lun.  We don't
3538 	 * need the passthrough device name and unit number since
3539 	 * we aren't going to open it.
3540 	 */
3541 	*bus = ccb.ccb_h.path_id;
3542 	*target = ccb.ccb_h.target_id;
3543 	*lun = ccb.ccb_h.target_lun;
3544 	*arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3545 	return (3);
3546 }
3547 
3548 /*
3549  * Parse out a bus, or a bus, target and lun in the following
3550  * format:
3551  * bus
3552  * bus:target
3553  * bus:target:lun
3554  *
3555  * Returns the number of parsed components, or 0.
3556  */
3557 static int
3558 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3559     cam_argmask *arglst)
3560 {
3561 	char *tmpstr, *end;
3562 	int convs = 0;
3563 
3564 	*bus = CAM_BUS_WILDCARD;
3565 	*target = CAM_TARGET_WILDCARD;
3566 	*lun = CAM_LUN_WILDCARD;
3567 
3568 	while (isspace(*tstr) && (*tstr != '\0'))
3569 		tstr++;
3570 
3571 	if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3572 		arglist |= CAM_ARG_BUS;
3573 		return (1);
3574 	}
3575 
3576 	if (!isdigit(*tstr))
3577 		return (parse_btl_name(tstr, bus, target, lun, arglst));
3578 
3579 	tmpstr = strsep(&tstr, ":");
3580 	if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3581 		*bus = strtol(tmpstr, &end, 0);
3582 		if (*end != '\0')
3583 			return (0);
3584 		*arglst |= CAM_ARG_BUS;
3585 		convs++;
3586 		tmpstr = strsep(&tstr, ":");
3587 		if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3588 			*target = strtol(tmpstr, &end, 0);
3589 			if (*end != '\0')
3590 				return (0);
3591 			*arglst |= CAM_ARG_TARGET;
3592 			convs++;
3593 			tmpstr = strsep(&tstr, ":");
3594 			if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3595 				*lun = strtoll(tmpstr, &end, 0);
3596 				if (*end != '\0')
3597 					return (0);
3598 				*arglst |= CAM_ARG_LUN;
3599 				convs++;
3600 			}
3601 		}
3602 	}
3603 
3604 	return convs;
3605 }
3606 
3607 static int
3608 dorescan_or_reset(int argc, char **argv, int rescan)
3609 {
3610 	static const char must[] =
3611 	    "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3612 	int rv, error = 0;
3613 	path_id_t bus = CAM_BUS_WILDCARD;
3614 	target_id_t target = CAM_TARGET_WILDCARD;
3615 	lun_id_t lun = CAM_LUN_WILDCARD;
3616 	char *tstr;
3617 
3618 	if (argc < 3) {
3619 		warnx(must, rescan? "rescan" : "reset");
3620 		return (1);
3621 	}
3622 
3623 	tstr = argv[optind];
3624 	while (isspace(*tstr) && (*tstr != '\0'))
3625 		tstr++;
3626 	if (strncasecmp(tstr, "all", strlen("all")) == 0)
3627 		arglist |= CAM_ARG_BUS;
3628 	else {
3629 		rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3630 		if (rv != 1 && rv != 3) {
3631 			warnx(must, rescan ? "rescan" : "reset");
3632 			return (1);
3633 		}
3634 	}
3635 
3636 	if (arglist & CAM_ARG_LUN)
3637 		error = scanlun_or_reset_dev(bus, target, lun, rescan);
3638 	else
3639 		error = rescan_or_reset_bus(bus, rescan);
3640 
3641 	return (error);
3642 }
3643 
3644 static int
3645 rescan_or_reset_bus(path_id_t bus, int rescan)
3646 {
3647 	union ccb *ccb = NULL, *matchccb = NULL;
3648 	int fd = -1, retval;
3649 	int bufsize;
3650 
3651 	retval = 0;
3652 
3653 	if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3654 		warnx("error opening transport layer device %s", XPT_DEVICE);
3655 		warn("%s", XPT_DEVICE);
3656 		return (1);
3657 	}
3658 
3659 	ccb = malloc(sizeof(*ccb));
3660 	if (ccb == NULL) {
3661 		warn("failed to allocate CCB");
3662 		retval = 1;
3663 		goto bailout;
3664 	}
3665 	bzero(ccb, sizeof(*ccb));
3666 
3667 	if (bus != CAM_BUS_WILDCARD) {
3668 		ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3669 		ccb->ccb_h.path_id = bus;
3670 		ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3671 		ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3672 		ccb->crcn.flags = CAM_FLAG_NONE;
3673 
3674 		/* run this at a low priority */
3675 		ccb->ccb_h.pinfo.priority = 5;
3676 
3677 		if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3678 			warn("CAMIOCOMMAND ioctl failed");
3679 			retval = 1;
3680 			goto bailout;
3681 		}
3682 
3683 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3684 			fprintf(stdout, "%s of bus %d was successful\n",
3685 			    rescan ? "Re-scan" : "Reset", bus);
3686 		} else {
3687 			fprintf(stdout, "%s of bus %d returned error %#x\n",
3688 				rescan ? "Re-scan" : "Reset", bus,
3689 				ccb->ccb_h.status & CAM_STATUS_MASK);
3690 			retval = 1;
3691 		}
3692 
3693 		goto bailout;
3694 	}
3695 
3696 
3697 	/*
3698 	 * The right way to handle this is to modify the xpt so that it can
3699 	 * handle a wildcarded bus in a rescan or reset CCB.  At the moment
3700 	 * that isn't implemented, so instead we enumerate the buses and
3701 	 * send the rescan or reset to those buses in the case where the
3702 	 * given bus is -1 (wildcard).  We don't send a rescan or reset
3703 	 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3704 	 * no-op, sending a rescan to the xpt bus would result in a status of
3705 	 * CAM_REQ_INVALID.
3706 	 */
3707 	matchccb = malloc(sizeof(*matchccb));
3708 	if (matchccb == NULL) {
3709 		warn("failed to allocate CCB");
3710 		retval = 1;
3711 		goto bailout;
3712 	}
3713 	bzero(matchccb, sizeof(*matchccb));
3714 	matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3715 	matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3716 	bufsize = sizeof(struct dev_match_result) * 20;
3717 	matchccb->cdm.match_buf_len = bufsize;
3718 	matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3719 	if (matchccb->cdm.matches == NULL) {
3720 		warnx("can't malloc memory for matches");
3721 		retval = 1;
3722 		goto bailout;
3723 	}
3724 	matchccb->cdm.num_matches = 0;
3725 
3726 	matchccb->cdm.num_patterns = 1;
3727 	matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3728 
3729 	matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3730 		matchccb->cdm.pattern_buf_len);
3731 	if (matchccb->cdm.patterns == NULL) {
3732 		warnx("can't malloc memory for patterns");
3733 		retval = 1;
3734 		goto bailout;
3735 	}
3736 	matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3737 	matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3738 
3739 	do {
3740 		unsigned int i;
3741 
3742 		if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3743 			warn("CAMIOCOMMAND ioctl failed");
3744 			retval = 1;
3745 			goto bailout;
3746 		}
3747 
3748 		if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3749 		 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3750 		   && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3751 			warnx("got CAM error %#x, CDM error %d\n",
3752 			      matchccb->ccb_h.status, matchccb->cdm.status);
3753 			retval = 1;
3754 			goto bailout;
3755 		}
3756 
3757 		for (i = 0; i < matchccb->cdm.num_matches; i++) {
3758 			struct bus_match_result *bus_result;
3759 
3760 			/* This shouldn't happen. */
3761 			if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3762 				continue;
3763 
3764 			bus_result =&matchccb->cdm.matches[i].result.bus_result;
3765 
3766 			/*
3767 			 * We don't want to rescan or reset the xpt bus.
3768 			 * See above.
3769 			 */
3770 			if (bus_result->path_id == CAM_XPT_PATH_ID)
3771 				continue;
3772 
3773 			ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3774 						       XPT_RESET_BUS;
3775 			ccb->ccb_h.path_id = bus_result->path_id;
3776 			ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3777 			ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3778 			ccb->crcn.flags = CAM_FLAG_NONE;
3779 
3780 			/* run this at a low priority */
3781 			ccb->ccb_h.pinfo.priority = 5;
3782 
3783 			if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3784 				warn("CAMIOCOMMAND ioctl failed");
3785 				retval = 1;
3786 				goto bailout;
3787 			}
3788 
3789 			if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3790 				fprintf(stdout, "%s of bus %d was successful\n",
3791 					rescan? "Re-scan" : "Reset",
3792 					bus_result->path_id);
3793 			} else {
3794 				/*
3795 				 * Don't bail out just yet, maybe the other
3796 				 * rescan or reset commands will complete
3797 				 * successfully.
3798 				 */
3799 				fprintf(stderr, "%s of bus %d returned error "
3800 					"%#x\n", rescan? "Re-scan" : "Reset",
3801 					bus_result->path_id,
3802 					ccb->ccb_h.status & CAM_STATUS_MASK);
3803 				retval = 1;
3804 			}
3805 		}
3806 	} while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3807 		 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3808 
3809 bailout:
3810 
3811 	if (fd != -1)
3812 		close(fd);
3813 
3814 	if (matchccb != NULL) {
3815 		free(matchccb->cdm.patterns);
3816 		free(matchccb->cdm.matches);
3817 		free(matchccb);
3818 	}
3819 	free(ccb);
3820 
3821 	return (retval);
3822 }
3823 
3824 static int
3825 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3826 {
3827 	union ccb ccb;
3828 	struct cam_device *device;
3829 	int fd;
3830 
3831 	device = NULL;
3832 
3833 	if (bus == CAM_BUS_WILDCARD) {
3834 		warnx("invalid bus number %d", bus);
3835 		return (1);
3836 	}
3837 
3838 	if (target == CAM_TARGET_WILDCARD) {
3839 		warnx("invalid target number %d", target);
3840 		return (1);
3841 	}
3842 
3843 	if (lun == CAM_LUN_WILDCARD) {
3844 		warnx("invalid lun number %jx", (uintmax_t)lun);
3845 		return (1);
3846 	}
3847 
3848 	fd = -1;
3849 
3850 	bzero(&ccb, sizeof(union ccb));
3851 
3852 	if (scan) {
3853 		if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3854 			warnx("error opening transport layer device %s\n",
3855 			    XPT_DEVICE);
3856 			warn("%s", XPT_DEVICE);
3857 			return (1);
3858 		}
3859 	} else {
3860 		device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3861 		if (device == NULL) {
3862 			warnx("%s", cam_errbuf);
3863 			return (1);
3864 		}
3865 	}
3866 
3867 	ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3868 	ccb.ccb_h.path_id = bus;
3869 	ccb.ccb_h.target_id = target;
3870 	ccb.ccb_h.target_lun = lun;
3871 	ccb.ccb_h.timeout = 5000;
3872 	ccb.crcn.flags = CAM_FLAG_NONE;
3873 
3874 	/* run this at a low priority */
3875 	ccb.ccb_h.pinfo.priority = 5;
3876 
3877 	if (scan) {
3878 		if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3879 			warn("CAMIOCOMMAND ioctl failed");
3880 			close(fd);
3881 			return (1);
3882 		}
3883 	} else {
3884 		if (cam_send_ccb(device, &ccb) < 0) {
3885 			warn("error sending XPT_RESET_DEV CCB");
3886 			cam_close_device(device);
3887 			return (1);
3888 		}
3889 	}
3890 
3891 	if (scan)
3892 		close(fd);
3893 	else
3894 		cam_close_device(device);
3895 
3896 	/*
3897 	 * An error code of CAM_BDR_SENT is normal for a BDR request.
3898 	 */
3899 	if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3900 	 || ((!scan)
3901 	  && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3902 		fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3903 		    scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3904 		return (0);
3905 	} else {
3906 		fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3907 		    scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3908 		    ccb.ccb_h.status & CAM_STATUS_MASK);
3909 		return (1);
3910 	}
3911 }
3912 
3913 
3914 static struct scsi_nv defect_list_type_map[] = {
3915 	{ "block", SRDD10_BLOCK_FORMAT },
3916 	{ "extbfi", SRDD10_EXT_BFI_FORMAT },
3917 	{ "extphys", SRDD10_EXT_PHYS_FORMAT },
3918 	{ "longblock", SRDD10_LONG_BLOCK_FORMAT },
3919 	{ "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3920 	{ "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3921 };
3922 
3923 static int
3924 readdefects(struct cam_device *device, int argc, char **argv,
3925 	    char *combinedopt, int task_attr, int retry_count, int timeout)
3926 {
3927 	union ccb *ccb = NULL;
3928 	struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3929 	struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3930 	size_t hdr_size = 0, entry_size = 0;
3931 	uint8_t *defect_list = NULL;
3932 	uint8_t list_format = 0;
3933 	uint32_t dlist_length = 0;
3934 	uint32_t returned_length = 0, valid_len = 0;
3935 	uint32_t num_returned = 0, num_valid = 0;
3936 	uint32_t max_possible_size = 0, hdr_max = 0;
3937 	uint32_t starting_offset = 0;
3938 	uint8_t returned_format, returned_type;
3939 	unsigned int i;
3940 	int c, error = 0;
3941 	int mads = 0;
3942 	bool summary = false, quiet = false, list_type_set = false;
3943 	bool get_length = true, use_12byte = false, first_pass = true;
3944 	bool hex_format = false;
3945 
3946 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3947 		switch(c){
3948 		case 'f':
3949 		{
3950 			scsi_nv_status status;
3951 			int entry_num = 0;
3952 
3953 			if (list_type_set) {
3954 				warnx("%s: -f specified twice", __func__);
3955 				error = 1;
3956 				goto defect_bailout;
3957 			}
3958 
3959 			status = scsi_get_nv(defect_list_type_map,
3960 			    sizeof(defect_list_type_map) /
3961 			    sizeof(defect_list_type_map[0]), optarg,
3962 			    &entry_num, SCSI_NV_FLAG_IG_CASE);
3963 
3964 			if (status == SCSI_NV_FOUND) {
3965 				list_format |= defect_list_type_map[
3966 				    entry_num].value;
3967 				list_type_set = true;
3968 			} else {
3969 				warnx("%s: %s %s option %s", __func__,
3970 				    (status == SCSI_NV_AMBIGUOUS) ?
3971 				    "ambiguous" : "invalid", "defect list type",
3972 				    optarg);
3973 				error = 1;
3974 				goto defect_bailout;
3975 			}
3976 			break;
3977 		}
3978 		case 'G':
3979 			list_format |= SRDD10_GLIST;
3980 			break;
3981 		case 'P':
3982 			list_format |= SRDD10_PLIST;
3983 			break;
3984 		case 'q':
3985 			quiet = true;
3986 			break;
3987 		case 's':
3988 			summary = true;
3989 			break;
3990 		case 'S': {
3991 			char *endptr;
3992 
3993 			starting_offset = strtoul(optarg, &endptr, 0);
3994 			if (*endptr != '\0') {
3995 				error = 1;
3996 				warnx("invalid starting offset %s", optarg);
3997 				goto defect_bailout;
3998 			}
3999 			use_12byte = true;
4000 			break;
4001 		}
4002 		case 'X':
4003 			hex_format = true;
4004 			break;
4005 		default:
4006 			break;
4007 		}
4008 	}
4009 
4010 	if (!list_type_set) {
4011 		error = 1;
4012 		warnx("no defect list format specified");
4013 		goto defect_bailout;
4014 	}
4015 
4016 	/*
4017 	 * This implies a summary, and was the previous behavior.
4018 	 */
4019 	if ((list_format & ~SRDD10_DLIST_FORMAT_MASK) == 0)
4020 		summary = true;
4021 
4022 	ccb = cam_getccb(device);
4023 
4024 	/*
4025 	 * We start off asking for just the header to determine how much defect
4026 	 * data is available.  Some Hitachi drives return an error if you ask
4027 	 * for more data than the drive has.  Once we know the length, we retry
4028 	 * the command with the returned length.  When we're retrying the with
4029 	 * 12-byte command, we're always changing to the 12-byte command and
4030 	 * need to get the length. Simplify the logic below by always setting
4031 	 * use_12byte in this case with this slightly more complex logic here.
4032 	 */
4033 	if (!use_12byte) {
4034 		dlist_length = sizeof(*hdr10);
4035 	} else  {
4036 retry_12byte:
4037 		get_length = true;
4038 		use_12byte = true;
4039 		dlist_length = sizeof(*hdr12);
4040 	}
4041 
4042 retry:
4043 	if (defect_list != NULL) {
4044 		free(defect_list);
4045 		defect_list = NULL;
4046 	}
4047 	defect_list = malloc(dlist_length);
4048 	if (defect_list == NULL) {
4049 		warnx("can't malloc memory for defect list");
4050 		error = 1;
4051 		goto defect_bailout;
4052 	}
4053 
4054 next_batch:
4055 	bzero(defect_list, dlist_length);
4056 
4057 	/*
4058 	 * cam_getccb() zeros the CCB header only.  So we need to zero the
4059 	 * payload portion of the ccb.
4060 	 */
4061 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4062 
4063 	scsi_read_defects(&ccb->csio,
4064 			  /*retries*/ retry_count,
4065 			  /*cbfcnp*/ NULL,
4066 			  /*tag_action*/ task_attr,
4067 			  /*list_format*/ list_format,
4068 			  /*addr_desc_index*/ starting_offset,
4069 			  /*data_ptr*/ defect_list,
4070 			  /*dxfer_len*/ dlist_length,
4071 			  /*minimum_cmd_size*/ use_12byte ? 12 : 0,
4072 			  /*sense_len*/ SSD_FULL_SIZE,
4073 			  /*timeout*/ timeout ? timeout : 5000);
4074 
4075 	/* Disable freezing the device queue */
4076 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4077 
4078 	if (cam_send_ccb(device, ccb) < 0) {
4079 		warn("error sending READ DEFECT DATA command");
4080 		error = 1;
4081 		goto defect_bailout;
4082 	}
4083 
4084 	valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
4085 
4086 	if (!use_12byte) {
4087 		hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
4088 		hdr_size = sizeof(*hdr10);
4089 		hdr_max = SRDDH10_MAX_LENGTH;
4090 
4091 		if (valid_len >= hdr_size) {
4092 			returned_length = scsi_2btoul(hdr10->length);
4093 			returned_format = hdr10->format;
4094 		} else {
4095 			returned_length = 0;
4096 			returned_format = 0;
4097 		}
4098 	} else {
4099 		hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4100 		hdr_size = sizeof(*hdr12);
4101 		hdr_max = SRDDH12_MAX_LENGTH;
4102 
4103 		if (valid_len >= hdr_size) {
4104 			returned_length = scsi_4btoul(hdr12->length);
4105 			returned_format = hdr12->format;
4106 		} else {
4107 			returned_length = 0;
4108 			returned_format = 0;
4109 		}
4110 	}
4111 
4112 	returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4113 	switch (returned_type) {
4114 	case SRDD10_BLOCK_FORMAT:
4115 		entry_size = sizeof(struct scsi_defect_desc_block);
4116 		break;
4117 	case SRDD10_LONG_BLOCK_FORMAT:
4118 		entry_size = sizeof(struct scsi_defect_desc_long_block);
4119 		break;
4120 	case SRDD10_EXT_PHYS_FORMAT:
4121 	case SRDD10_PHYSICAL_SECTOR_FORMAT:
4122 		entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4123 		break;
4124 	case SRDD10_EXT_BFI_FORMAT:
4125 	case SRDD10_BYTES_FROM_INDEX_FORMAT:
4126 		entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4127 		break;
4128 	default:
4129 		warnx("Unknown defect format 0x%x\n", returned_type);
4130 		error = 1;
4131 		goto defect_bailout;
4132 		break;
4133 	}
4134 
4135 	max_possible_size = (hdr_max / entry_size) * entry_size;
4136 	num_returned = returned_length / entry_size;
4137 	num_valid = min(returned_length, valid_len - hdr_size);
4138 	num_valid /= entry_size;
4139 
4140 	if (get_length) {
4141 		get_length = false;
4142 
4143 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4144 		     CAM_SCSI_STATUS_ERROR) {
4145 			struct scsi_sense_data *sense;
4146 			int error_code, sense_key, asc, ascq;
4147 
4148 			sense = &ccb->csio.sense_data;
4149 			scsi_extract_sense_len(sense, ccb->csio.sense_len -
4150 			    ccb->csio.sense_resid, &error_code, &sense_key,
4151 			    &asc, &ascq, /*show_errors*/ 1);
4152 
4153 			/*
4154 			 * If the drive is reporting that it just doesn't
4155 			 * support the defect list format, go ahead and use
4156 			 * the length it reported.  Otherwise, the length
4157 			 * may not be valid, so use the maximum.
4158 			 */
4159 			if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4160 			 && (asc == 0x1c) && (ascq == 0x00)
4161 			 && (returned_length > 0)) {
4162 				if (!use_12byte
4163 				 && (returned_length >= max_possible_size)) {
4164 					goto retry_12byte;
4165 				}
4166 				dlist_length = returned_length + hdr_size;
4167 			} else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4168 				&& (asc == 0x1f) && (ascq == 0x00)
4169 				&& (returned_length > 0)) {
4170 				/* Partial defect list transfer */
4171 				/*
4172 				 * Hitachi drives return this error
4173 				 * along with a partial defect list if they
4174 				 * have more defects than the 10 byte
4175 				 * command can support.  Retry with the 12
4176 				 * byte command.
4177 				 */
4178 				if (!use_12byte) {
4179 					goto retry_12byte;
4180 				}
4181 				dlist_length = returned_length + hdr_size;
4182 			} else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4183 				&& (asc == 0x24) && (ascq == 0x00)) {
4184 				/* Invalid field in CDB */
4185 				/*
4186 				 * SBC-3 says that if the drive has more
4187 				 * defects than can be reported with the
4188 				 * 10 byte command, it should return this
4189 	 			 * error and no data.  Retry with the 12
4190 				 * byte command.
4191 				 */
4192 				if (!use_12byte) {
4193 					goto retry_12byte;
4194 				}
4195 				dlist_length = returned_length + hdr_size;
4196 			} else {
4197 				/*
4198 				 * If we got a SCSI error and no valid length,
4199 				 * just use the 10 byte maximum.  The 12
4200 				 * byte maximum is too large.
4201 				 */
4202 				if (returned_length == 0)
4203 					dlist_length = SRDD10_MAX_LENGTH;
4204 				else {
4205 					if (!use_12byte
4206 					 && (returned_length >=
4207 					     max_possible_size)) {
4208 						goto retry_12byte;
4209 					}
4210 					dlist_length = returned_length +
4211 					    hdr_size;
4212 				}
4213 			}
4214 		} else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4215 			    CAM_REQ_CMP){
4216 			error = 1;
4217 			warnx("Error reading defect header");
4218 			if (arglist & CAM_ARG_VERBOSE)
4219 				cam_error_print(device, ccb, CAM_ESF_ALL,
4220 						CAM_EPF_ALL, stderr);
4221 			goto defect_bailout;
4222 		} else {
4223 			if (!use_12byte
4224 			 && (returned_length >= max_possible_size)) {
4225 				goto retry_12byte;
4226 			}
4227 			dlist_length = returned_length + hdr_size;
4228 		}
4229 		if (summary) {
4230 			fprintf(stdout, "%u", num_returned);
4231 			if (!quiet) {
4232 				fprintf(stdout, " defect%s",
4233 					(num_returned != 1) ? "s" : "");
4234 			}
4235 			fprintf(stdout, "\n");
4236 
4237 			goto defect_bailout;
4238 		}
4239 
4240 		/*
4241 		 * We always limit the list length to the 10-byte maximum
4242 		 * length (0xffff).  The reason is that some controllers
4243 		 * can't handle larger I/Os, and we can transfer the entire
4244 		 * 10 byte list in one shot.  For drives that support the 12
4245 		 * byte read defects command, we'll step through the list
4246 		 * by specifying a starting offset.  For drives that don't
4247 		 * support the 12 byte command's starting offset, we'll
4248 		 * just display the first 64K.
4249 		 */
4250 		dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4251 
4252 		goto retry;
4253 	}
4254 
4255 
4256 	if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4257 	 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4258 	 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4259 		struct scsi_sense_data *sense;
4260 		int error_code, sense_key, asc, ascq;
4261 
4262 		sense = &ccb->csio.sense_data;
4263 		scsi_extract_sense_len(sense, ccb->csio.sense_len -
4264 		    ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4265 		    &ascq, /*show_errors*/ 1);
4266 
4267 		/*
4268 		 * According to the SCSI spec, if the disk doesn't support
4269 		 * the requested format, it will generally return a sense
4270 		 * key of RECOVERED ERROR, and an additional sense code
4271 		 * of "DEFECT LIST NOT FOUND".  HGST drives also return
4272 		 * Primary/Grown defect list not found errors.  So just
4273 		 * check for an ASC of 0x1c.
4274 		 */
4275 		if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4276 		 && (asc == 0x1c)) {
4277 			const char *format_str;
4278 
4279 			format_str = scsi_nv_to_str(defect_list_type_map,
4280 			    sizeof(defect_list_type_map) /
4281 			    sizeof(defect_list_type_map[0]),
4282 			    list_format & SRDD10_DLIST_FORMAT_MASK);
4283 			warnx("requested defect format %s not available",
4284 			    format_str ? format_str : "unknown");
4285 
4286 			format_str = scsi_nv_to_str(defect_list_type_map,
4287 			    sizeof(defect_list_type_map) /
4288 			    sizeof(defect_list_type_map[0]), returned_type);
4289 			if (format_str != NULL) {
4290 				warnx("Device returned %s format",
4291 				    format_str);
4292 			} else {
4293 				error = 1;
4294 				warnx("Device returned unknown defect"
4295 				     " data format %#x", returned_type);
4296 				goto defect_bailout;
4297 			}
4298 		} else {
4299 			error = 1;
4300 			warnx("Error returned from read defect data command");
4301 			if (arglist & CAM_ARG_VERBOSE)
4302 				cam_error_print(device, ccb, CAM_ESF_ALL,
4303 						CAM_EPF_ALL, stderr);
4304 			goto defect_bailout;
4305 		}
4306 	} else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4307 		error = 1;
4308 		warnx("Error returned from read defect data command");
4309 		if (arglist & CAM_ARG_VERBOSE)
4310 			cam_error_print(device, ccb, CAM_ESF_ALL,
4311 					CAM_EPF_ALL, stderr);
4312 		goto defect_bailout;
4313 	}
4314 
4315 	if (first_pass) {
4316 		fprintf(stderr, "Got %d defect", num_returned);
4317 
4318 		if (!summary || (num_returned == 0)) {
4319 			fprintf(stderr, "s.\n");
4320 			goto defect_bailout;
4321 		} else if (num_returned == 1)
4322 			fprintf(stderr, ":\n");
4323 		else
4324 			fprintf(stderr, "s:\n");
4325 
4326 		first_pass = false;
4327 	}
4328 
4329 	/*
4330 	 * XXX KDM  I should probably clean up the printout format for the
4331 	 * disk defects.
4332 	 */
4333 	switch (returned_type) {
4334 	case SRDD10_PHYSICAL_SECTOR_FORMAT:
4335 	case SRDD10_EXT_PHYS_FORMAT:
4336 	{
4337 		struct scsi_defect_desc_phys_sector *dlist;
4338 
4339 		dlist = (struct scsi_defect_desc_phys_sector *)
4340 			(defect_list + hdr_size);
4341 
4342 		for (i = 0; i < num_valid; i++) {
4343 			uint32_t sector;
4344 
4345 			sector = scsi_4btoul(dlist[i].sector);
4346 			if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4347 				mads = (sector & SDD_EXT_PHYS_MADS) ?
4348 				       0 : 1;
4349 				sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4350 			}
4351 			if (!hex_format)
4352 				fprintf(stdout, "%d:%d:%d%s",
4353 					scsi_3btoul(dlist[i].cylinder),
4354 					dlist[i].head,
4355 					scsi_4btoul(dlist[i].sector),
4356 					mads ? " - " : "\n");
4357 			else
4358 				fprintf(stdout, "0x%x:0x%x:0x%x%s",
4359 					scsi_3btoul(dlist[i].cylinder),
4360 					dlist[i].head,
4361 					scsi_4btoul(dlist[i].sector),
4362 					mads ? " - " : "\n");
4363 			mads = 0;
4364 		}
4365 		if (num_valid < num_returned) {
4366 			starting_offset += num_valid;
4367 			goto next_batch;
4368 		}
4369 		break;
4370 	}
4371 	case SRDD10_BYTES_FROM_INDEX_FORMAT:
4372 	case SRDD10_EXT_BFI_FORMAT:
4373 	{
4374 		struct scsi_defect_desc_bytes_from_index *dlist;
4375 
4376 		dlist = (struct scsi_defect_desc_bytes_from_index *)
4377 			(defect_list + hdr_size);
4378 
4379 		for (i = 0; i < num_valid; i++) {
4380 			uint32_t bfi;
4381 
4382 			bfi = scsi_4btoul(dlist[i].bytes_from_index);
4383 			if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4384 				mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4385 				bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4386 			}
4387 			if (!hex_format)
4388 				fprintf(stdout, "%d:%d:%d%s",
4389 					scsi_3btoul(dlist[i].cylinder),
4390 					dlist[i].head,
4391 					scsi_4btoul(dlist[i].bytes_from_index),
4392 					mads ? " - " : "\n");
4393 			else
4394 				fprintf(stdout, "0x%x:0x%x:0x%x%s",
4395 					scsi_3btoul(dlist[i].cylinder),
4396 					dlist[i].head,
4397 					scsi_4btoul(dlist[i].bytes_from_index),
4398 					mads ? " - " : "\n");
4399 
4400 			mads = 0;
4401 		}
4402 		if (num_valid < num_returned) {
4403 			starting_offset += num_valid;
4404 			goto next_batch;
4405 		}
4406 		break;
4407 	}
4408 	case SRDDH10_BLOCK_FORMAT:
4409 	{
4410 		struct scsi_defect_desc_block *dlist;
4411 
4412 		dlist = (struct scsi_defect_desc_block *)
4413 			(defect_list + hdr_size);
4414 
4415 		for (i = 0; i < num_valid; i++) {
4416 			if (!hex_format)
4417 				fprintf(stdout, "%u\n",
4418 					scsi_4btoul(dlist[i].address));
4419 			else
4420 				fprintf(stdout, "0x%x\n",
4421 					scsi_4btoul(dlist[i].address));
4422 		}
4423 
4424 		if (num_valid < num_returned) {
4425 			starting_offset += num_valid;
4426 			goto next_batch;
4427 		}
4428 
4429 		break;
4430 	}
4431 	case SRDD10_LONG_BLOCK_FORMAT:
4432 	{
4433 		struct scsi_defect_desc_long_block *dlist;
4434 
4435 		dlist = (struct scsi_defect_desc_long_block *)
4436 			(defect_list + hdr_size);
4437 
4438 		for (i = 0; i < num_valid; i++) {
4439 			if (!hex_format)
4440 				fprintf(stdout, "%ju\n",
4441 					(uintmax_t)scsi_8btou64(
4442 					dlist[i].address));
4443 			else
4444 				fprintf(stdout, "0x%jx\n",
4445 					(uintmax_t)scsi_8btou64(
4446 					dlist[i].address));
4447 		}
4448 
4449 		if (num_valid < num_returned) {
4450 			starting_offset += num_valid;
4451 			goto next_batch;
4452 		}
4453 		break;
4454 	}
4455 	default:
4456 		fprintf(stderr, "Unknown defect format 0x%x\n",
4457 			returned_type);
4458 		error = 1;
4459 		break;
4460 	}
4461 defect_bailout:
4462 
4463 	if (defect_list != NULL)
4464 		free(defect_list);
4465 
4466 	if (ccb != NULL)
4467 		cam_freeccb(ccb);
4468 
4469 	return (error);
4470 }
4471 
4472 #if 0
4473 void
4474 reassignblocks(struct cam_device *device, uint32_t *blocks, int num_blocks)
4475 {
4476 	union ccb *ccb;
4477 
4478 	ccb = cam_getccb(device);
4479 
4480 	cam_freeccb(ccb);
4481 }
4482 #endif
4483 
4484 void
4485 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4486     int page, int subpage, int task_attr, int retry_count, int timeout,
4487     uint8_t *data, int datalen)
4488 {
4489 	union ccb *ccb;
4490 	int error_code, sense_key, asc, ascq;
4491 
4492 	ccb = cam_getccb(device);
4493 	if (ccb == NULL)
4494 		errx(1, "mode_sense: couldn't allocate CCB");
4495 
4496 retry:
4497 	/*
4498 	 * MODE SENSE(6) can't handle more then 255 bytes.  If there are more,
4499 	 * device must return error, so we should not get truncated data.
4500 	 */
4501 	if (*cdb_len == 6 && datalen > 255)
4502 		datalen = 255;
4503 
4504 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4505 
4506 	scsi_mode_sense_subpage(&ccb->csio,
4507 			/* retries */ retry_count,
4508 			/* cbfcnp */ NULL,
4509 			/* tag_action */ task_attr,
4510 			/* dbd */ dbd,
4511 			/* pc */ pc << 6,
4512 			/* page */ page,
4513 			/* subpage */ subpage,
4514 			/* param_buf */ data,
4515 			/* param_len */ datalen,
4516 			/* minimum_cmd_size */ *cdb_len,
4517 			/* sense_len */ SSD_FULL_SIZE,
4518 			/* timeout */ timeout ? timeout : 5000);
4519 	if (llbaa && ccb->csio.cdb_len == 10) {
4520 		struct scsi_mode_sense_10 *cdb =
4521 		    (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4522 		cdb->byte2 |= SMS10_LLBAA;
4523 	}
4524 
4525 	/* Record what CDB size the above function really set. */
4526 	*cdb_len = ccb->csio.cdb_len;
4527 
4528 	if (arglist & CAM_ARG_ERR_RECOVER)
4529 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4530 
4531 	/* Disable freezing the device queue */
4532 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4533 
4534 	if (cam_send_ccb(device, ccb) < 0)
4535 		err(1, "error sending mode sense command");
4536 
4537 	/* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4538 	if (*cdb_len != 6 &&
4539 	    ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4540 	     (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4541 	      && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4542 		*cdb_len = 6;
4543 		goto retry;
4544 	}
4545 
4546 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4547 		if (arglist & CAM_ARG_VERBOSE) {
4548 			cam_error_print(device, ccb, CAM_ESF_ALL,
4549 					CAM_EPF_ALL, stderr);
4550 		}
4551 		cam_freeccb(ccb);
4552 		cam_close_device(device);
4553 		errx(1, "mode sense command returned error");
4554 	}
4555 
4556 	cam_freeccb(ccb);
4557 }
4558 
4559 void
4560 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4561     int task_attr, int retry_count, int timeout, uint8_t *data, int datalen)
4562 {
4563 	union ccb *ccb;
4564 	int retval;
4565 
4566 	ccb = cam_getccb(device);
4567 
4568 	if (ccb == NULL)
4569 		errx(1, "mode_select: couldn't allocate CCB");
4570 
4571 	scsi_mode_select_len(&ccb->csio,
4572 			 /* retries */ retry_count,
4573 			 /* cbfcnp */ NULL,
4574 			 /* tag_action */ task_attr,
4575 			 /* scsi_page_fmt */ 1,
4576 			 /* save_pages */ save_pages,
4577 			 /* param_buf */ data,
4578 			 /* param_len */ datalen,
4579 			 /* minimum_cmd_size */ cdb_len,
4580 			 /* sense_len */ SSD_FULL_SIZE,
4581 			 /* timeout */ timeout ? timeout : 5000);
4582 
4583 	if (arglist & CAM_ARG_ERR_RECOVER)
4584 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4585 
4586 	/* Disable freezing the device queue */
4587 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4588 
4589 	if (((retval = cam_send_ccb(device, ccb)) < 0)
4590 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4591 		if (arglist & CAM_ARG_VERBOSE) {
4592 			cam_error_print(device, ccb, CAM_ESF_ALL,
4593 					CAM_EPF_ALL, stderr);
4594 		}
4595 		cam_freeccb(ccb);
4596 		cam_close_device(device);
4597 
4598 		if (retval < 0)
4599 			err(1, "error sending mode select command");
4600 		else
4601 			errx(1, "error sending mode select command");
4602 
4603 	}
4604 
4605 	cam_freeccb(ccb);
4606 }
4607 
4608 void
4609 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4610 	 int task_attr, int retry_count, int timeout)
4611 {
4612 	char *str_subpage;
4613 	int c, page = -1, subpage = 0, pc = 0, llbaa = 0;
4614 	int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4615 
4616 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
4617 		switch(c) {
4618 		case '6':
4619 			cdb_len = 6;
4620 			break;
4621 		case 'b':
4622 			binary = 1;
4623 			break;
4624 		case 'd':
4625 			dbd = 1;
4626 			break;
4627 		case 'e':
4628 			edit = 1;
4629 			break;
4630 		case 'l':
4631 			list++;
4632 			break;
4633 		case 'm':
4634 			str_subpage = optarg;
4635 			strsep(&str_subpage, ",");
4636 			page = strtol(optarg, NULL, 0);
4637 			if (str_subpage)
4638 			    subpage = strtol(str_subpage, NULL, 0);
4639 			if (page < 0 || page > 0x3f)
4640 				errx(1, "invalid mode page %d", page);
4641 			if (subpage < 0 || subpage > 0xff)
4642 				errx(1, "invalid mode subpage %d", subpage);
4643 			break;
4644 		case 'D':
4645 			desc = 1;
4646 			break;
4647 		case 'L':
4648 			llbaa = 1;
4649 			break;
4650 		case 'P':
4651 			pc = strtol(optarg, NULL, 0);
4652 			if ((pc < 0) || (pc > 3))
4653 				errx(1, "invalid page control field %d", pc);
4654 			break;
4655 		default:
4656 			break;
4657 		}
4658 	}
4659 
4660 	if (desc && page == -1)
4661 		page = SMS_ALL_PAGES_PAGE;
4662 
4663 	if (page == -1 && list == 0)
4664 		errx(1, "you must specify a mode page!");
4665 
4666 	if (dbd && desc)
4667 		errx(1, "-d and -D are incompatible!");
4668 
4669 	if (llbaa && cdb_len != 10)
4670 		errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4671 
4672 	if (list != 0) {
4673 		mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4674 		    retry_count, timeout);
4675 	} else {
4676 		mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4677 		    edit, binary, task_attr, retry_count, timeout);
4678 	}
4679 }
4680 
4681 static int
4682 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4683 	int task_attr, int retry_count, int timeout)
4684 {
4685 	union ccb *ccb;
4686 	uint32_t flags = CAM_DIR_NONE;
4687 	uint8_t *data_ptr = NULL;
4688 	uint8_t cdb[20];
4689 	uint8_t atacmd[12];
4690 	struct get_hook hook;
4691 	int c, data_bytes = 0, valid_bytes;
4692 	int cdb_len = 0;
4693 	int atacmd_len = 0;
4694 	int dmacmd = 0;
4695 	int fpdmacmd = 0;
4696 	int need_res = 0;
4697 	char *datastr = NULL, *tstr, *resstr = NULL;
4698 	int error = 0;
4699 	int fd_data = 0, fd_res = 0;
4700 	int retval;
4701 
4702 	ccb = cam_getccb(device);
4703 
4704 	if (ccb == NULL) {
4705 		warnx("scsicmd: error allocating ccb");
4706 		return (1);
4707 	}
4708 
4709 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
4710 		switch(c) {
4711 		case 'a':
4712 			tstr = optarg;
4713 			while (isspace(*tstr) && (*tstr != '\0'))
4714 				tstr++;
4715 			hook.argc = argc - optind;
4716 			hook.argv = argv + optind;
4717 			hook.got = 0;
4718 			atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4719 						    iget, &hook);
4720 			/*
4721 			 * Increment optind by the number of arguments the
4722 			 * encoding routine processed.  After each call to
4723 			 * getopt(3), optind points to the argument that
4724 			 * getopt should process _next_.  In this case,
4725 			 * that means it points to the first command string
4726 			 * argument, if there is one.  Once we increment
4727 			 * this, it should point to either the next command
4728 			 * line argument, or it should be past the end of
4729 			 * the list.
4730 			 */
4731 			optind += hook.got;
4732 			break;
4733 		case 'c':
4734 			tstr = optarg;
4735 			while (isspace(*tstr) && (*tstr != '\0'))
4736 				tstr++;
4737 			hook.argc = argc - optind;
4738 			hook.argv = argv + optind;
4739 			hook.got = 0;
4740 			cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4741 						    iget, &hook);
4742 			/*
4743 			 * Increment optind by the number of arguments the
4744 			 * encoding routine processed.  After each call to
4745 			 * getopt(3), optind points to the argument that
4746 			 * getopt should process _next_.  In this case,
4747 			 * that means it points to the first command string
4748 			 * argument, if there is one.  Once we increment
4749 			 * this, it should point to either the next command
4750 			 * line argument, or it should be past the end of
4751 			 * the list.
4752 			 */
4753 			optind += hook.got;
4754 			break;
4755 		case 'd':
4756 			dmacmd = 1;
4757 			break;
4758 		case 'f':
4759 			fpdmacmd = 1;
4760 			break;
4761 		case 'i':
4762 			if (arglist & CAM_ARG_CMD_OUT) {
4763 				warnx("command must either be "
4764 				      "read or write, not both");
4765 				error = 1;
4766 				goto scsicmd_bailout;
4767 			}
4768 			arglist |= CAM_ARG_CMD_IN;
4769 			flags = CAM_DIR_IN;
4770 			data_bytes = strtol(optarg, NULL, 0);
4771 			if (data_bytes <= 0) {
4772 				warnx("invalid number of input bytes %d",
4773 				      data_bytes);
4774 				error = 1;
4775 				goto scsicmd_bailout;
4776 			}
4777 			hook.argc = argc - optind;
4778 			hook.argv = argv + optind;
4779 			hook.got = 0;
4780 			optind++;
4781 			datastr = cget(&hook, NULL);
4782 			/*
4783 			 * If the user supplied "-" instead of a format, he
4784 			 * wants the data to be written to stdout.
4785 			 */
4786 			if ((datastr != NULL)
4787 			 && (datastr[0] == '-'))
4788 				fd_data = 1;
4789 
4790 			data_ptr = (uint8_t *)malloc(data_bytes);
4791 			if (data_ptr == NULL) {
4792 				warnx("can't malloc memory for data_ptr");
4793 				error = 1;
4794 				goto scsicmd_bailout;
4795 			}
4796 			break;
4797 		case 'o':
4798 			if (arglist & CAM_ARG_CMD_IN) {
4799 				warnx("command must either be "
4800 				      "read or write, not both");
4801 				error = 1;
4802 				goto scsicmd_bailout;
4803 			}
4804 			arglist |= CAM_ARG_CMD_OUT;
4805 			flags = CAM_DIR_OUT;
4806 			data_bytes = strtol(optarg, NULL, 0);
4807 			if (data_bytes <= 0) {
4808 				warnx("invalid number of output bytes %d",
4809 				      data_bytes);
4810 				error = 1;
4811 				goto scsicmd_bailout;
4812 			}
4813 			hook.argc = argc - optind;
4814 			hook.argv = argv + optind;
4815 			hook.got = 0;
4816 			datastr = cget(&hook, NULL);
4817 			data_ptr = (uint8_t *)malloc(data_bytes);
4818 			if (data_ptr == NULL) {
4819 				warnx("can't malloc memory for data_ptr");
4820 				error = 1;
4821 				goto scsicmd_bailout;
4822 			}
4823 			bzero(data_ptr, data_bytes);
4824 			/*
4825 			 * If the user supplied "-" instead of a format, he
4826 			 * wants the data to be read from stdin.
4827 			 */
4828 			if ((datastr != NULL)
4829 			 && (datastr[0] == '-'))
4830 				fd_data = 1;
4831 			else
4832 				buff_encode_visit(data_ptr, data_bytes, datastr,
4833 						  iget, &hook);
4834 			optind += hook.got;
4835 			break;
4836 		case 'r':
4837 			need_res = 1;
4838 			hook.argc = argc - optind;
4839 			hook.argv = argv + optind;
4840 			hook.got = 0;
4841 			resstr = cget(&hook, NULL);
4842 			if ((resstr != NULL) && (resstr[0] == '-'))
4843 				fd_res = 1;
4844 			optind += hook.got;
4845 			break;
4846 		default:
4847 			break;
4848 		}
4849 	}
4850 
4851 	/*
4852 	 * If fd_data is set, and we're writing to the device, we need to
4853 	 * read the data the user wants written from stdin.
4854 	 */
4855 	if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4856 		ssize_t amt_read;
4857 		int amt_to_read = data_bytes;
4858 		uint8_t *buf_ptr = data_ptr;
4859 
4860 		for (amt_read = 0; amt_to_read > 0;
4861 		     amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4862 			if (amt_read == -1) {
4863 				warn("error reading data from stdin");
4864 				error = 1;
4865 				goto scsicmd_bailout;
4866 			}
4867 			amt_to_read -= amt_read;
4868 			buf_ptr += amt_read;
4869 		}
4870 	}
4871 
4872 	if (arglist & CAM_ARG_ERR_RECOVER)
4873 		flags |= CAM_PASS_ERR_RECOVER;
4874 
4875 	/* Disable freezing the device queue */
4876 	flags |= CAM_DEV_QFRZDIS;
4877 
4878 	if (cdb_len) {
4879 		/*
4880 		 * This is taken from the SCSI-3 draft spec.
4881 		 * (T10/1157D revision 0.3)
4882 		 * The top 3 bits of an opcode are the group code.
4883 		 * The next 5 bits are the command code.
4884 		 * Group 0:  six byte commands
4885 		 * Group 1:  ten byte commands
4886 		 * Group 2:  ten byte commands
4887 		 * Group 3:  reserved
4888 		 * Group 4:  sixteen byte commands
4889 		 * Group 5:  twelve byte commands
4890 		 * Group 6:  vendor specific
4891 		 * Group 7:  vendor specific
4892 		 */
4893 		switch((cdb[0] >> 5) & 0x7) {
4894 			case 0:
4895 				cdb_len = 6;
4896 				break;
4897 			case 1:
4898 			case 2:
4899 				cdb_len = 10;
4900 				break;
4901 			case 3:
4902 			case 6:
4903 			case 7:
4904 				/* computed by buff_encode_visit */
4905 				break;
4906 			case 4:
4907 				cdb_len = 16;
4908 				break;
4909 			case 5:
4910 				cdb_len = 12;
4911 				break;
4912 		}
4913 
4914 		/*
4915 		 * We should probably use csio_build_visit or something like that
4916 		 * here, but it's easier to encode arguments as you go.  The
4917 		 * alternative would be skipping the CDB argument and then encoding
4918 		 * it here, since we've got the data buffer argument by now.
4919 		 */
4920 		bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4921 
4922 		cam_fill_csio(&ccb->csio,
4923 		      /*retries*/ retry_count,
4924 		      /*cbfcnp*/ NULL,
4925 		      /*flags*/ flags,
4926 		      /*tag_action*/ task_attr,
4927 		      /*data_ptr*/ data_ptr,
4928 		      /*dxfer_len*/ data_bytes,
4929 		      /*sense_len*/ SSD_FULL_SIZE,
4930 		      /*cdb_len*/ cdb_len,
4931 		      /*timeout*/ timeout ? timeout : 5000);
4932 	} else {
4933 		atacmd_len = 12;
4934 		bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4935 		if (need_res)
4936 			ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4937 		if (dmacmd)
4938 			ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4939 		if (fpdmacmd)
4940 			ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4941 
4942 		cam_fill_ataio(&ccb->ataio,
4943 		      /*retries*/ retry_count,
4944 		      /*cbfcnp*/ NULL,
4945 		      /*flags*/ flags,
4946 		      /*tag_action*/ 0,
4947 		      /*data_ptr*/ data_ptr,
4948 		      /*dxfer_len*/ data_bytes,
4949 		      /*timeout*/ timeout ? timeout : 5000);
4950 	}
4951 
4952 	if (((retval = cam_send_ccb(device, ccb)) < 0)
4953 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4954 		const char warnstr[] = "error sending command";
4955 
4956 		if (retval < 0)
4957 			warn(warnstr);
4958 		else
4959 			warnx(warnstr);
4960 
4961 		if (arglist & CAM_ARG_VERBOSE) {
4962 			cam_error_print(device, ccb, CAM_ESF_ALL,
4963 					CAM_EPF_ALL, stderr);
4964 		}
4965 
4966 		error = 1;
4967 		goto scsicmd_bailout;
4968 	}
4969 
4970 	if (atacmd_len && need_res) {
4971 		if (fd_res == 0) {
4972 			buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4973 					  arg_put, NULL);
4974 			fprintf(stdout, "\n");
4975 		} else {
4976 			fprintf(stdout,
4977 			    "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4978 			    ccb->ataio.res.status,
4979 			    ccb->ataio.res.error,
4980 			    ccb->ataio.res.lba_low,
4981 			    ccb->ataio.res.lba_mid,
4982 			    ccb->ataio.res.lba_high,
4983 			    ccb->ataio.res.device,
4984 			    ccb->ataio.res.lba_low_exp,
4985 			    ccb->ataio.res.lba_mid_exp,
4986 			    ccb->ataio.res.lba_high_exp,
4987 			    ccb->ataio.res.sector_count,
4988 			    ccb->ataio.res.sector_count_exp);
4989 			fflush(stdout);
4990 		}
4991 	}
4992 
4993 	if (cdb_len)
4994 		valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4995 	else
4996 		valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4997 	if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4998 	 && (arglist & CAM_ARG_CMD_IN)
4999 	 && (valid_bytes > 0)) {
5000 		if (fd_data == 0) {
5001 			buff_decode_visit(data_ptr, valid_bytes, datastr,
5002 					  arg_put, NULL);
5003 			fprintf(stdout, "\n");
5004 		} else {
5005 			ssize_t amt_written;
5006 			int amt_to_write = valid_bytes;
5007 			uint8_t *buf_ptr = data_ptr;
5008 
5009 			for (amt_written = 0; (amt_to_write > 0) &&
5010 			     (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
5011 				amt_to_write -= amt_written;
5012 				buf_ptr += amt_written;
5013 			}
5014 			if (amt_written == -1) {
5015 				warn("error writing data to stdout");
5016 				error = 1;
5017 				goto scsicmd_bailout;
5018 			} else if ((amt_written == 0)
5019 				&& (amt_to_write > 0)) {
5020 				warnx("only wrote %u bytes out of %u",
5021 				      valid_bytes - amt_to_write, valid_bytes);
5022 			}
5023 		}
5024 	}
5025 
5026 scsicmd_bailout:
5027 
5028 	if ((data_bytes > 0) && (data_ptr != NULL))
5029 		free(data_ptr);
5030 
5031 	cam_freeccb(ccb);
5032 
5033 	return (error);
5034 }
5035 
5036 static int
5037 camdebug(int argc, char **argv, char *combinedopt)
5038 {
5039 	int c, fd;
5040 	path_id_t bus = CAM_BUS_WILDCARD;
5041 	target_id_t target = CAM_TARGET_WILDCARD;
5042 	lun_id_t lun = CAM_LUN_WILDCARD;
5043 	char *tstr;
5044 	union ccb ccb;
5045 	int error = 0, rv;
5046 
5047 	bzero(&ccb, sizeof(union ccb));
5048 
5049 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
5050 		switch(c) {
5051 		case 'I':
5052 			arglist |= CAM_ARG_DEBUG_INFO;
5053 			ccb.cdbg.flags |= CAM_DEBUG_INFO;
5054 			break;
5055 		case 'P':
5056 			arglist |= CAM_ARG_DEBUG_PERIPH;
5057 			ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
5058 			break;
5059 		case 'S':
5060 			arglist |= CAM_ARG_DEBUG_SUBTRACE;
5061 			ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5062 			break;
5063 		case 'T':
5064 			arglist |= CAM_ARG_DEBUG_TRACE;
5065 			ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5066 			break;
5067 		case 'X':
5068 			arglist |= CAM_ARG_DEBUG_XPT;
5069 			ccb.cdbg.flags |= CAM_DEBUG_XPT;
5070 			break;
5071 		case 'c':
5072 			arglist |= CAM_ARG_DEBUG_CDB;
5073 			ccb.cdbg.flags |= CAM_DEBUG_CDB;
5074 			break;
5075 		case 'p':
5076 			arglist |= CAM_ARG_DEBUG_PROBE;
5077 			ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5078 			break;
5079 		default:
5080 			break;
5081 		}
5082 	}
5083 
5084 	argc -= optind;
5085 	argv += optind;
5086 
5087 	if (argc <= 0) {
5088 		warnx("you must specify \"off\", \"all\" or a bus,");
5089 		warnx("bus:target, bus:target:lun or periph");
5090 		return (1);
5091 	}
5092 
5093 	tstr = *argv;
5094 	while (isspace(*tstr) && (*tstr != '\0'))
5095 		tstr++;
5096 
5097 	if (strncmp(tstr, "off", 3) == 0) {
5098 		ccb.cdbg.flags = CAM_DEBUG_NONE;
5099 		arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5100 			     CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5101 			     CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5102 	} else {
5103 		rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5104 		if (rv < 1) {
5105 			warnx("you must specify \"all\", \"off\", or a bus,");
5106 			warnx("bus:target, bus:target:lun or periph to debug");
5107 			return (1);
5108 		}
5109 	}
5110 
5111 	if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5112 		warnx("error opening transport layer device %s", XPT_DEVICE);
5113 		warn("%s", XPT_DEVICE);
5114 		return (1);
5115 	}
5116 
5117 	ccb.ccb_h.func_code = XPT_DEBUG;
5118 	ccb.ccb_h.path_id = bus;
5119 	ccb.ccb_h.target_id = target;
5120 	ccb.ccb_h.target_lun = lun;
5121 
5122 	if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5123 		warn("CAMIOCOMMAND ioctl failed");
5124 		error = 1;
5125 	} else {
5126 		if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5127 		     CAM_FUNC_NOTAVAIL) {
5128 			warnx("CAM debugging not available");
5129 			warnx("you need to put options CAMDEBUG in"
5130 			      " your kernel config file!");
5131 			error = 1;
5132 		} else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5133 			    CAM_REQ_CMP) {
5134 			warnx("XPT_DEBUG CCB failed with status %#x",
5135 			      ccb.ccb_h.status);
5136 			error = 1;
5137 		} else {
5138 			if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5139 				fprintf(stderr,
5140 					"Debugging turned off\n");
5141 			} else {
5142 				fprintf(stderr,
5143 					"Debugging enabled for "
5144 					"%d:%d:%jx\n",
5145 					bus, target, (uintmax_t)lun);
5146 			}
5147 		}
5148 	}
5149 	close(fd);
5150 
5151 	return (error);
5152 }
5153 
5154 static int
5155 tagcontrol(struct cam_device *device, int argc, char **argv,
5156 	   char *combinedopt)
5157 {
5158 	int c;
5159 	union ccb *ccb;
5160 	int numtags = -1;
5161 	int retval = 0;
5162 	int quiet = 0;
5163 	char pathstr[1024];
5164 
5165 	ccb = cam_getccb(device);
5166 
5167 	if (ccb == NULL) {
5168 		warnx("tagcontrol: error allocating ccb");
5169 		return (1);
5170 	}
5171 
5172 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
5173 		switch(c) {
5174 		case 'N':
5175 			numtags = strtol(optarg, NULL, 0);
5176 			if (numtags < 0) {
5177 				warnx("tag count %d is < 0", numtags);
5178 				retval = 1;
5179 				goto tagcontrol_bailout;
5180 			}
5181 			break;
5182 		case 'q':
5183 			quiet++;
5184 			break;
5185 		default:
5186 			break;
5187 		}
5188 	}
5189 
5190 	cam_path_string(device, pathstr, sizeof(pathstr));
5191 
5192 	if (numtags >= 0) {
5193 		ccb->ccb_h.func_code = XPT_REL_SIMQ;
5194 		ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5195 		ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5196 		ccb->crs.openings = numtags;
5197 
5198 
5199 		if (cam_send_ccb(device, ccb) < 0) {
5200 			warn("error sending XPT_REL_SIMQ CCB");
5201 			retval = 1;
5202 			goto tagcontrol_bailout;
5203 		}
5204 
5205 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5206 			warnx("XPT_REL_SIMQ CCB failed");
5207 			cam_error_print(device, ccb, CAM_ESF_ALL,
5208 					CAM_EPF_ALL, stderr);
5209 			retval = 1;
5210 			goto tagcontrol_bailout;
5211 		}
5212 
5213 
5214 		if (quiet == 0)
5215 			fprintf(stdout, "%stagged openings now %d\n",
5216 				pathstr, ccb->crs.openings);
5217 	}
5218 
5219 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5220 
5221 	ccb->ccb_h.func_code = XPT_GDEV_STATS;
5222 
5223 	if (cam_send_ccb(device, ccb) < 0) {
5224 		warn("error sending XPT_GDEV_STATS CCB");
5225 		retval = 1;
5226 		goto tagcontrol_bailout;
5227 	}
5228 
5229 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5230 		warnx("XPT_GDEV_STATS CCB failed");
5231 		cam_error_print(device, ccb, CAM_ESF_ALL,
5232 				CAM_EPF_ALL, stderr);
5233 		retval = 1;
5234 		goto tagcontrol_bailout;
5235 	}
5236 
5237 	if (arglist & CAM_ARG_VERBOSE) {
5238 		fprintf(stdout, "%s", pathstr);
5239 		fprintf(stdout, "dev_openings  %d\n", ccb->cgds.dev_openings);
5240 		fprintf(stdout, "%s", pathstr);
5241 		fprintf(stdout, "dev_active    %d\n", ccb->cgds.dev_active);
5242 		fprintf(stdout, "%s", pathstr);
5243 		fprintf(stdout, "allocated     %d\n", ccb->cgds.allocated);
5244 		fprintf(stdout, "%s", pathstr);
5245 		fprintf(stdout, "queued        %d\n", ccb->cgds.queued);
5246 		fprintf(stdout, "%s", pathstr);
5247 		fprintf(stdout, "held          %d\n", ccb->cgds.held);
5248 		fprintf(stdout, "%s", pathstr);
5249 		fprintf(stdout, "mintags       %d\n", ccb->cgds.mintags);
5250 		fprintf(stdout, "%s", pathstr);
5251 		fprintf(stdout, "maxtags       %d\n", ccb->cgds.maxtags);
5252 	} else {
5253 		if (quiet == 0) {
5254 			fprintf(stdout, "%s", pathstr);
5255 			fprintf(stdout, "device openings: ");
5256 		}
5257 		fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5258 			ccb->cgds.dev_active);
5259 	}
5260 
5261 tagcontrol_bailout:
5262 
5263 	cam_freeccb(ccb);
5264 	return (retval);
5265 }
5266 
5267 static void
5268 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5269 {
5270 	char pathstr[1024];
5271 
5272 	cam_path_string(device, pathstr, sizeof(pathstr));
5273 
5274 	if (cts->transport == XPORT_SPI) {
5275 		struct ccb_trans_settings_spi *spi =
5276 		    &cts->xport_specific.spi;
5277 
5278 		if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5279 
5280 			fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5281 				spi->sync_period);
5282 
5283 			if (spi->sync_offset != 0) {
5284 				u_int freq;
5285 
5286 				freq = scsi_calc_syncsrate(spi->sync_period);
5287 				fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5288 					pathstr, freq / 1000, freq % 1000);
5289 			}
5290 		}
5291 
5292 		if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5293 			fprintf(stdout, "%soffset: %d\n", pathstr,
5294 			    spi->sync_offset);
5295 		}
5296 
5297 		if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5298 			fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5299 				(0x01 << spi->bus_width) * 8);
5300 		}
5301 
5302 		if (spi->valid & CTS_SPI_VALID_DISC) {
5303 			fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5304 				(spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5305 				"enabled" : "disabled");
5306 		}
5307 	}
5308 	if (cts->transport == XPORT_FC) {
5309 		struct ccb_trans_settings_fc *fc =
5310 		    &cts->xport_specific.fc;
5311 
5312 		if (fc->valid & CTS_FC_VALID_WWNN)
5313 			fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5314 			    (long long) fc->wwnn);
5315 		if (fc->valid & CTS_FC_VALID_WWPN)
5316 			fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5317 			    (long long) fc->wwpn);
5318 		if (fc->valid & CTS_FC_VALID_PORT)
5319 			fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5320 		if (fc->valid & CTS_FC_VALID_SPEED)
5321 			fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5322 			    pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5323 	}
5324 	if (cts->transport == XPORT_SAS) {
5325 		struct ccb_trans_settings_sas *sas =
5326 		    &cts->xport_specific.sas;
5327 
5328 		if (sas->valid & CTS_SAS_VALID_SPEED)
5329 			fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5330 			    pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5331 	}
5332 	if (cts->transport == XPORT_ATA) {
5333 		struct ccb_trans_settings_pata *pata =
5334 		    &cts->xport_specific.ata;
5335 
5336 		if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5337 			fprintf(stdout, "%sATA mode: %s\n", pathstr,
5338 				ata_mode2string(pata->mode));
5339 		}
5340 		if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5341 			fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5342 				pata->atapi);
5343 		}
5344 		if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5345 			fprintf(stdout, "%sPIO transaction length: %d\n",
5346 				pathstr, pata->bytecount);
5347 		}
5348 	}
5349 	if (cts->transport == XPORT_SATA) {
5350 		struct ccb_trans_settings_sata *sata =
5351 		    &cts->xport_specific.sata;
5352 
5353 		if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5354 			fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5355 				sata->revision);
5356 		}
5357 		if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5358 			fprintf(stdout, "%sATA mode: %s\n", pathstr,
5359 				ata_mode2string(sata->mode));
5360 		}
5361 		if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5362 			fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5363 				sata->atapi);
5364 		}
5365 		if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5366 			fprintf(stdout, "%sPIO transaction length: %d\n",
5367 				pathstr, sata->bytecount);
5368 		}
5369 		if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5370 			fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5371 				sata->pm_present);
5372 		}
5373 		if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5374 			fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5375 				sata->tags);
5376 		}
5377 		if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5378 			fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5379 				sata->caps);
5380 		}
5381 	}
5382 	if (cts->transport == XPORT_NVME) {
5383 		struct ccb_trans_settings_nvme *nvme =
5384 		    &cts->xport_specific.nvme;
5385 
5386 		if (nvme->valid & CTS_NVME_VALID_LINK) {
5387 			fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5388 			    nvme->lanes, nvme->max_lanes);
5389 			fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5390 			    nvme->speed, nvme->max_speed);
5391 		}
5392 	}
5393 	if (cts->transport == XPORT_NVMF) {
5394 		struct ccb_trans_settings_nvmf *nvmf =
5395 		    &cts->xport_specific.nvmf;
5396 
5397 		if (nvmf->valid & CTS_NVMF_VALID_TRTYPE) {
5398 			fprintf(stdout, "%sTransport: %s\n", pathstr,
5399 			    nvmf_transport_type(nvmf->trtype));
5400 		}
5401 	}
5402 	if (cts->protocol == PROTO_ATA) {
5403 		struct ccb_trans_settings_ata *ata=
5404 		    &cts->proto_specific.ata;
5405 
5406 		if (ata->valid & CTS_ATA_VALID_TQ) {
5407 			fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5408 				(ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5409 				"enabled" : "disabled");
5410 		}
5411 	}
5412 	if (cts->protocol == PROTO_SCSI) {
5413 		struct ccb_trans_settings_scsi *scsi=
5414 		    &cts->proto_specific.scsi;
5415 
5416 		if (scsi->valid & CTS_SCSI_VALID_TQ) {
5417 			fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5418 				(scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5419 				"enabled" : "disabled");
5420 		}
5421 	}
5422 	if (cts->protocol == PROTO_NVME) {
5423 		struct ccb_trans_settings_nvme *nvme =
5424 		    &cts->proto_specific.nvme;
5425 
5426 		if (nvme->valid & CTS_NVME_VALID_SPEC) {
5427 			fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5428 			    NVME_MAJOR(nvme->spec),
5429 			    NVME_MINOR(nvme->spec));
5430 		}
5431 	}
5432 }
5433 
5434 /*
5435  * Get a path inquiry CCB for the specified device.
5436  */
5437 static int
5438 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5439 {
5440 	union ccb *ccb;
5441 	int retval = 0;
5442 
5443 	ccb = cam_getccb(device);
5444 	if (ccb == NULL) {
5445 		warnx("get_cpi: couldn't allocate CCB");
5446 		return (1);
5447 	}
5448 	ccb->ccb_h.func_code = XPT_PATH_INQ;
5449 	if (cam_send_ccb(device, ccb) < 0) {
5450 		warn("get_cpi: error sending Path Inquiry CCB");
5451 		retval = 1;
5452 		goto get_cpi_bailout;
5453 	}
5454 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5455 		if (arglist & CAM_ARG_VERBOSE)
5456 			cam_error_print(device, ccb, CAM_ESF_ALL,
5457 					CAM_EPF_ALL, stderr);
5458 		retval = 1;
5459 		goto get_cpi_bailout;
5460 	}
5461 	bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5462 
5463 get_cpi_bailout:
5464 	cam_freeccb(ccb);
5465 	return (retval);
5466 }
5467 
5468 /*
5469  * Get a get device CCB for the specified device.
5470  */
5471 static int
5472 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5473 {
5474 	union ccb *ccb;
5475 	int retval = 0;
5476 
5477 	ccb = cam_getccb(device);
5478 	if (ccb == NULL) {
5479 		warnx("get_cgd: couldn't allocate CCB");
5480 		return (1);
5481 	}
5482 	ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5483 	if (cam_send_ccb(device, ccb) < 0) {
5484 		warn("get_cgd: error sending Get type information CCB");
5485 		retval = 1;
5486 		goto get_cgd_bailout;
5487 	}
5488 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5489 		if (arglist & CAM_ARG_VERBOSE)
5490 			cam_error_print(device, ccb, CAM_ESF_ALL,
5491 					CAM_EPF_ALL, stderr);
5492 		retval = 1;
5493 		goto get_cgd_bailout;
5494 	}
5495 	bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5496 
5497 get_cgd_bailout:
5498 	cam_freeccb(ccb);
5499 	return (retval);
5500 }
5501 
5502 /*
5503  * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5504  * error.
5505  */
5506 int
5507 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5508 		 int timeout, int verbosemode)
5509 {
5510 	union ccb *ccb = NULL;
5511 	struct scsi_vpd_supported_page_list sup_pages;
5512 	int i;
5513 	int retval = 0;
5514 
5515 	ccb = cam_getccb(dev);
5516 	if (ccb == NULL) {
5517 		warn("Unable to allocate CCB");
5518 		retval = -1;
5519 		goto bailout;
5520 	}
5521 
5522 	bzero(&sup_pages, sizeof(sup_pages));
5523 
5524 	scsi_inquiry(&ccb->csio,
5525 		     /*retries*/ retry_count,
5526 		     /*cbfcnp*/ NULL,
5527 		     /* tag_action */ MSG_SIMPLE_Q_TAG,
5528 		     /* inq_buf */ (uint8_t *)&sup_pages,
5529 		     /* inq_len */ sizeof(sup_pages),
5530 		     /* evpd */ 1,
5531 		     /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5532 		     /* sense_len */ SSD_FULL_SIZE,
5533 		     /* timeout */ timeout ? timeout : 5000);
5534 
5535 	/* Disable freezing the device queue */
5536 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5537 
5538 	if (retry_count != 0)
5539 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5540 
5541 	if (cam_send_ccb(dev, ccb) < 0) {
5542 		cam_freeccb(ccb);
5543 		ccb = NULL;
5544 		retval = -1;
5545 		goto bailout;
5546 	}
5547 
5548 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5549 		if (verbosemode != 0)
5550 			cam_error_print(dev, ccb, CAM_ESF_ALL,
5551 					CAM_EPF_ALL, stderr);
5552 		retval = -1;
5553 		goto bailout;
5554 	}
5555 
5556 	for (i = 0; i < sup_pages.length; i++) {
5557 		if (sup_pages.list[i] == page_id) {
5558 			retval = 1;
5559 			goto bailout;
5560 		}
5561 	}
5562 bailout:
5563 	if (ccb != NULL)
5564 		cam_freeccb(ccb);
5565 
5566 	return (retval);
5567 }
5568 
5569 /*
5570  * devtype is filled in with the type of device.
5571  * Returns 0 for success, non-zero for failure.
5572  */
5573 int
5574 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5575 		    int verbosemode, camcontrol_devtype *devtype)
5576 {
5577 	struct ccb_getdev cgd;
5578 	int retval;
5579 
5580 	retval = get_cgd(dev, &cgd);
5581 	if (retval != 0)
5582 		goto bailout;
5583 
5584 	switch (cgd.protocol) {
5585 	case PROTO_SCSI:
5586 		break;
5587 	case PROTO_ATA:
5588 	case PROTO_ATAPI:
5589 	case PROTO_SATAPM:
5590 		*devtype = CC_DT_ATA;
5591 		goto bailout;
5592 		break; /*NOTREACHED*/
5593 	case PROTO_NVME:
5594 		*devtype = CC_DT_NVME;
5595 		goto bailout;
5596 		break; /*NOTREACHED*/
5597 	case PROTO_MMCSD:
5598 		*devtype = CC_DT_MMCSD;
5599 		goto bailout;
5600 		break; /*NOTREACHED*/
5601 	default:
5602 		*devtype = CC_DT_UNKNOWN;
5603 		goto bailout;
5604 		break; /*NOTREACHED*/
5605 	}
5606 
5607 	if (retry_count == -1) {
5608 		/*
5609 		 * For a retry count of -1, used only the cached data to avoid
5610 		 * I/O to the drive. Sending the identify command to the drive
5611 		 * can cause issues for SATL attachaed drives since identify is
5612 		 * not an NCQ command. We check for the strings that windows
5613 		 * displays since those will not be NULs (they are supposed
5614 		 * to be space padded). We could check other bits, but anything
5615 		 * non-zero implies SATL.
5616 		 */
5617 		if (cgd.ident_data.serial[0] != 0 ||
5618 		    cgd.ident_data.revision[0] != 0 ||
5619 		    cgd.ident_data.model[0] != 0)
5620 			*devtype = CC_DT_SATL;
5621 		else
5622 			*devtype = CC_DT_SCSI;
5623 	} else {
5624 		/*
5625 		 * Check for the ATA Information VPD page (0x89).  If this is an
5626 		 * ATA device behind a SCSI to ATA translation layer (SATL),
5627 		 * this VPD page should be present.
5628 		 *
5629 		 * If that VPD page isn't present, or we get an error back from
5630 		 * the INQUIRY command, we'll just treat it as a normal SCSI
5631 		 * device.
5632 		 */
5633 		retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5634 		    timeout, verbosemode);
5635 		if (retval == 1)
5636 			*devtype = CC_DT_SATL;
5637 		else
5638 			*devtype = CC_DT_SCSI;
5639 	}
5640 	retval = 0;
5641 
5642 bailout:
5643 	return (retval);
5644 }
5645 
5646 int
5647 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5648     uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5649     uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5650     uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5651     size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5652     int is48bit, camcontrol_devtype devtype)
5653 {
5654 	int retval = 0;
5655 
5656 	if (devtype == CC_DT_ATA) {
5657 		cam_fill_ataio(&ccb->ataio,
5658 		    /*retries*/ retry_count,
5659 		    /*cbfcnp*/ NULL,
5660 		    /*flags*/ flags,
5661 		    /*tag_action*/ tag_action,
5662 		    /*data_ptr*/ data_ptr,
5663 		    /*dxfer_len*/ dxfer_len,
5664 		    /*timeout*/ timeout);
5665 		if (is48bit || lba > ATA_MAX_28BIT_LBA)
5666 			ata_48bit_cmd(&ccb->ataio, command, features, lba,
5667 			    sector_count);
5668 		else
5669 			ata_28bit_cmd(&ccb->ataio, command, features, lba,
5670 			    sector_count);
5671 
5672 		if (auxiliary != 0) {
5673 			ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5674 			ccb->ataio.aux = auxiliary;
5675 		}
5676 
5677 		if (ata_flags & AP_FLAG_CHK_COND)
5678 			ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5679 
5680 		if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5681 			ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5682 		else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5683 			ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5684 	} else {
5685 		if (is48bit || lba > ATA_MAX_28BIT_LBA)
5686 			protocol |= AP_EXTEND;
5687 
5688 		retval = scsi_ata_pass(&ccb->csio,
5689 		    /*retries*/ retry_count,
5690 		    /*cbfcnp*/ NULL,
5691 		    /*flags*/ flags,
5692 		    /*tag_action*/ tag_action,
5693 		    /*protocol*/ protocol,
5694 		    /*ata_flags*/ ata_flags,
5695 		    /*features*/ features,
5696 		    /*sector_count*/ sector_count,
5697 		    /*lba*/ lba,
5698 		    /*command*/ command,
5699 		    /*device*/ 0,
5700 		    /*icc*/ 0,
5701 		    /*auxiliary*/ auxiliary,
5702 		    /*control*/ 0,
5703 		    /*data_ptr*/ data_ptr,
5704 		    /*dxfer_len*/ dxfer_len,
5705 		    /*cdb_storage*/ cdb_storage,
5706 		    /*cdb_storage_len*/ cdb_storage_len,
5707 		    /*minimum_cmd_size*/ 0,
5708 		    /*sense_len*/ sense_len,
5709 		    /*timeout*/ timeout);
5710 	}
5711 
5712 	return (retval);
5713 }
5714 
5715 /*
5716  * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5717  *	    4 -- count truncated, 6 -- lba and count truncated.
5718  */
5719 int
5720 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5721 	       uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5722 {
5723 	int retval;
5724 
5725 	switch (ccb->ccb_h.func_code) {
5726 	case XPT_SCSI_IO: {
5727 		uint8_t opcode;
5728 		int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5729 		u_int sense_len;
5730 
5731 		/*
5732 		 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5733 		 * or 16 byte, and need to see what
5734 		 */
5735 		if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5736 			opcode = ccb->csio.cdb_io.cdb_ptr[0];
5737 		else
5738 			opcode = ccb->csio.cdb_io.cdb_bytes[0];
5739 		if ((opcode != ATA_PASS_12)
5740 		 && (opcode != ATA_PASS_16)) {
5741 			warnx("%s: unsupported opcode %02x", __func__, opcode);
5742 			return (1);
5743 		}
5744 
5745 		retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5746 						&asc, &ascq);
5747 		/* Note: the _ccb() variant returns 0 for an error */
5748 		if (retval == 0)
5749 			return (1);
5750 
5751 		sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5752 		switch (error_code) {
5753 		case SSD_DESC_CURRENT_ERROR:
5754 		case SSD_DESC_DEFERRED_ERROR: {
5755 			struct scsi_sense_data_desc *sense;
5756 			struct scsi_sense_ata_ret_desc *desc;
5757 			uint8_t *desc_ptr;
5758 
5759 			sense = (struct scsi_sense_data_desc *)
5760 			    &ccb->csio.sense_data;
5761 
5762 			desc_ptr = scsi_find_desc(sense, sense_len,
5763 			    SSD_DESC_ATA);
5764 			if (desc_ptr == NULL) {
5765 				cam_error_print(dev, ccb, CAM_ESF_ALL,
5766 				    CAM_EPF_ALL, stderr);
5767 				return (1);
5768 			}
5769 			desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5770 
5771 			*error = desc->error;
5772 			*count = (desc->count_15_8 << 8) |
5773 				  desc->count_7_0;
5774 			*lba = ((uint64_t)desc->lba_47_40 << 40) |
5775 			       ((uint64_t)desc->lba_39_32 << 32) |
5776 			       ((uint64_t)desc->lba_31_24 << 24) |
5777 			       (desc->lba_23_16 << 16) |
5778 			       (desc->lba_15_8  <<  8) |
5779 				desc->lba_7_0;
5780 			*device = desc->device;
5781 			*status = desc->status;
5782 
5783 			/*
5784 			 * If the extend bit isn't set, the result is for a
5785 			 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5786 			 * command without the extend bit set.  This means
5787 			 * that the device is supposed to return 28-bit
5788 			 * status.  The count field is only 8 bits, and the
5789 			 * LBA field is only 8 bits.
5790 			 */
5791 			if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5792 				*count &= 0xff;
5793 				*lba &= 0x0fffffff;
5794 			}
5795 			break;
5796 		}
5797 		case SSD_CURRENT_ERROR:
5798 		case SSD_DEFERRED_ERROR: {
5799 			uint64_t val;
5800 
5801 			/*
5802 			 * In my understanding of SAT-5 specification, saying:
5803 			 * "without interpreting the contents of the STATUS",
5804 			 * this should not happen if CK_COND was set, but it
5805 			 * does at least for some devices, so try to revert.
5806 			 */
5807 			if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5808 			    (asc == 0) && (ascq == 0)) {
5809 				*status = ATA_STATUS_ERROR;
5810 				*error = ATA_ERROR_ABORT;
5811 				*device = 0;
5812 				*count = 0;
5813 				*lba = 0;
5814 				return (0);
5815 			}
5816 
5817 			if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5818 			    (asc != 0x00) || (ascq != 0x1d))
5819 				return (1);
5820 
5821 			val = 0;
5822 			scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5823 			    SSD_DESC_INFO, &val, NULL);
5824 			*error = (val >> 24) & 0xff;
5825 			*status = (val >> 16) & 0xff;
5826 			*device = (val >> 8) & 0xff;
5827 			*count = val & 0xff;
5828 
5829 			val = 0;
5830 			scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5831 			    SSD_DESC_COMMAND, &val, NULL);
5832 			*lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5833 				((val & 0xff) << 16);
5834 
5835 			/* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5836 			return ((val >> 28) & 0x06);
5837 		}
5838 		default:
5839 			return (1);
5840 		}
5841 
5842 		break;
5843 	}
5844 	case XPT_ATA_IO: {
5845 		struct ata_res *res;
5846 
5847 		/* Only some statuses return ATA result register set. */
5848 		if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5849 		    cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5850 			return (1);
5851 
5852 		res = &ccb->ataio.res;
5853 		*error = res->error;
5854 		*status = res->status;
5855 		*device = res->device;
5856 		*count = res->sector_count;
5857 		*lba = (res->lba_high << 16) |
5858 		       (res->lba_mid << 8) |
5859 		       (res->lba_low);
5860 		if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5861 			*count |= (res->sector_count_exp << 8);
5862 			*lba |= ((uint64_t)res->lba_low_exp << 24) |
5863 				((uint64_t)res->lba_mid_exp << 32) |
5864 				((uint64_t)res->lba_high_exp << 40);
5865 		} else {
5866 			*lba |= (res->device & 0xf) << 24;
5867 		}
5868 		break;
5869 	}
5870 	default:
5871 		return (1);
5872 	}
5873 	return (0);
5874 }
5875 
5876 static void
5877 cpi_print(struct ccb_pathinq *cpi)
5878 {
5879 	char adapter_str[1024];
5880 	uint64_t i;
5881 
5882 	snprintf(adapter_str, sizeof(adapter_str),
5883 		 "%s%d:", cpi->dev_name, cpi->unit_number);
5884 
5885 	fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5886 		cpi->version_num);
5887 
5888 	for (i = 1; i < UINT8_MAX; i = i << 1) {
5889 		const char *str;
5890 
5891 		if ((i & cpi->hba_inquiry) == 0)
5892 			continue;
5893 
5894 		fprintf(stdout, "%s supports ", adapter_str);
5895 
5896 		switch(i) {
5897 		case PI_MDP_ABLE:
5898 			str = "MDP message";
5899 			break;
5900 		case PI_WIDE_32:
5901 			str = "32 bit wide SCSI";
5902 			break;
5903 		case PI_WIDE_16:
5904 			str = "16 bit wide SCSI";
5905 			break;
5906 		case PI_SDTR_ABLE:
5907 			str = "SDTR message";
5908 			break;
5909 		case PI_LINKED_CDB:
5910 			str = "linked CDBs";
5911 			break;
5912 		case PI_TAG_ABLE:
5913 			str = "tag queue messages";
5914 			break;
5915 		case PI_SOFT_RST:
5916 			str = "soft reset alternative";
5917 			break;
5918 		case PI_SATAPM:
5919 			str = "SATA Port Multiplier";
5920 			break;
5921 		default:
5922 			str = "unknown PI bit set";
5923 			break;
5924 		}
5925 		fprintf(stdout, "%s\n", str);
5926 	}
5927 
5928 	for (i = 1; i < UINT32_MAX; i = i << 1) {
5929 		const char *str;
5930 
5931 		if ((i & cpi->hba_misc) == 0)
5932 			continue;
5933 
5934 		fprintf(stdout, "%s ", adapter_str);
5935 
5936 		switch(i) {
5937 		case PIM_ATA_EXT:
5938 			str = "can understand ata_ext requests";
5939 			break;
5940 		case PIM_EXTLUNS:
5941 			str = "64bit extended LUNs supported";
5942 			break;
5943 		case PIM_SCANHILO:
5944 			str = "bus scans from high ID to low ID";
5945 			break;
5946 		case PIM_NOREMOVE:
5947 			str = "removable devices not included in scan";
5948 			break;
5949 		case PIM_NOINITIATOR:
5950 			str = "initiator role not supported";
5951 			break;
5952 		case PIM_NOBUSRESET:
5953 			str = "user has disabled initial BUS RESET or"
5954 			      " controller is in target/mixed mode";
5955 			break;
5956 		case PIM_NO_6_BYTE:
5957 			str = "do not send 6-byte commands";
5958 			break;
5959 		case PIM_SEQSCAN:
5960 			str = "scan bus sequentially";
5961 			break;
5962 		case PIM_UNMAPPED:
5963 			str = "unmapped I/O supported";
5964 			break;
5965 		case PIM_NOSCAN:
5966 			str = "does its own scanning";
5967 			break;
5968 		default:
5969 			str = "unknown PIM bit set";
5970 			break;
5971 		}
5972 		fprintf(stdout, "%s\n", str);
5973 	}
5974 
5975 	for (i = 1; i < UINT16_MAX; i = i << 1) {
5976 		const char *str;
5977 
5978 		if ((i & cpi->target_sprt) == 0)
5979 			continue;
5980 
5981 		fprintf(stdout, "%s supports ", adapter_str);
5982 		switch(i) {
5983 		case PIT_PROCESSOR:
5984 			str = "target mode processor mode";
5985 			break;
5986 		case PIT_PHASE:
5987 			str = "target mode phase cog. mode";
5988 			break;
5989 		case PIT_DISCONNECT:
5990 			str = "disconnects in target mode";
5991 			break;
5992 		case PIT_TERM_IO:
5993 			str = "terminate I/O message in target mode";
5994 			break;
5995 		case PIT_GRP_6:
5996 			str = "group 6 commands in target mode";
5997 			break;
5998 		case PIT_GRP_7:
5999 			str = "group 7 commands in target mode";
6000 			break;
6001 		default:
6002 			str = "unknown PIT bit set";
6003 			break;
6004 		}
6005 
6006 		fprintf(stdout, "%s\n", str);
6007 	}
6008 	fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
6009 		cpi->hba_eng_cnt);
6010 	fprintf(stdout, "%s maximum target: %d\n", adapter_str,
6011 		cpi->max_target);
6012 	fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
6013 		cpi->max_lun);
6014 	fprintf(stdout, "%s highest path ID in subsystem: %d\n",
6015 		adapter_str, cpi->hpath_id);
6016 	fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
6017 		cpi->initiator_id);
6018 	fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
6019 	fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
6020 	fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
6021 	    adapter_str, cpi->hba_vendor);
6022 	fprintf(stdout, "%s HBA device ID: 0x%04x\n",
6023 	    adapter_str, cpi->hba_device);
6024 	fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
6025 	    adapter_str, cpi->hba_subvendor);
6026 	fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
6027 	    adapter_str, cpi->hba_subdevice);
6028 	fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
6029 	fprintf(stdout, "%s base transfer speed: ", adapter_str);
6030 	if (cpi->base_transfer_speed > 1000)
6031 		fprintf(stdout, "%d.%03dMB/sec\n",
6032 			cpi->base_transfer_speed / 1000,
6033 			cpi->base_transfer_speed % 1000);
6034 	else
6035 		fprintf(stdout, "%dKB/sec\n",
6036 			(cpi->base_transfer_speed % 1000) * 1000);
6037 	fprintf(stdout, "%s maximum transfer size: %u bytes\n",
6038 	    adapter_str, cpi->maxio);
6039 }
6040 
6041 static int
6042 get_print_cts(struct cam_device *device, int user_settings, int quiet,
6043 	      struct ccb_trans_settings *cts)
6044 {
6045 	int retval;
6046 	union ccb *ccb;
6047 
6048 	retval = 0;
6049 	ccb = cam_getccb(device);
6050 
6051 	if (ccb == NULL) {
6052 		warnx("get_print_cts: error allocating ccb");
6053 		return (1);
6054 	}
6055 
6056 	ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
6057 
6058 	if (user_settings == 0)
6059 		ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
6060 	else
6061 		ccb->cts.type = CTS_TYPE_USER_SETTINGS;
6062 
6063 	if (cam_send_ccb(device, ccb) < 0) {
6064 		warn("error sending XPT_GET_TRAN_SETTINGS CCB");
6065 		retval = 1;
6066 		goto get_print_cts_bailout;
6067 	}
6068 
6069 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6070 		warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6071 		if (arglist & CAM_ARG_VERBOSE)
6072 			cam_error_print(device, ccb, CAM_ESF_ALL,
6073 					CAM_EPF_ALL, stderr);
6074 		retval = 1;
6075 		goto get_print_cts_bailout;
6076 	}
6077 
6078 	if (quiet == 0)
6079 		cts_print(device, &ccb->cts);
6080 
6081 	if (cts != NULL)
6082 		bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6083 
6084 get_print_cts_bailout:
6085 
6086 	cam_freeccb(ccb);
6087 
6088 	return (retval);
6089 }
6090 
6091 static int
6092 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6093 	    int timeout, int argc, char **argv, char *combinedopt)
6094 {
6095 	int c;
6096 	union ccb *ccb;
6097 	int user_settings = 0;
6098 	int retval = 0;
6099 	int disc_enable = -1, tag_enable = -1;
6100 	int mode = -1;
6101 	int offset = -1;
6102 	double syncrate = -1;
6103 	int bus_width = -1;
6104 	int quiet = 0;
6105 	int change_settings = 0, send_tur = 0;
6106 	struct ccb_pathinq cpi;
6107 
6108 	ccb = cam_getccb(device);
6109 	if (ccb == NULL) {
6110 		warnx("ratecontrol: error allocating ccb");
6111 		return (1);
6112 	}
6113 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
6114 		switch(c){
6115 		case 'a':
6116 			send_tur = 1;
6117 			break;
6118 		case 'c':
6119 			user_settings = 0;
6120 			break;
6121 		case 'D':
6122 			if (strncasecmp(optarg, "enable", 6) == 0)
6123 				disc_enable = 1;
6124 			else if (strncasecmp(optarg, "disable", 7) == 0)
6125 				disc_enable = 0;
6126 			else {
6127 				warnx("-D argument \"%s\" is unknown", optarg);
6128 				retval = 1;
6129 				goto ratecontrol_bailout;
6130 			}
6131 			change_settings = 1;
6132 			break;
6133 		case 'M':
6134 			mode = ata_string2mode(optarg);
6135 			if (mode < 0) {
6136 				warnx("unknown mode '%s'", optarg);
6137 				retval = 1;
6138 				goto ratecontrol_bailout;
6139 			}
6140 			change_settings = 1;
6141 			break;
6142 		case 'O':
6143 			offset = strtol(optarg, NULL, 0);
6144 			if (offset < 0) {
6145 				warnx("offset value %d is < 0", offset);
6146 				retval = 1;
6147 				goto ratecontrol_bailout;
6148 			}
6149 			change_settings = 1;
6150 			break;
6151 		case 'q':
6152 			quiet++;
6153 			break;
6154 		case 'R':
6155 			syncrate = atof(optarg);
6156 			if (syncrate < 0) {
6157 				warnx("sync rate %f is < 0", syncrate);
6158 				retval = 1;
6159 				goto ratecontrol_bailout;
6160 			}
6161 			change_settings = 1;
6162 			break;
6163 		case 'T':
6164 			if (strncasecmp(optarg, "enable", 6) == 0)
6165 				tag_enable = 1;
6166 			else if (strncasecmp(optarg, "disable", 7) == 0)
6167 				tag_enable = 0;
6168 			else {
6169 				warnx("-T argument \"%s\" is unknown", optarg);
6170 				retval = 1;
6171 				goto ratecontrol_bailout;
6172 			}
6173 			change_settings = 1;
6174 			break;
6175 		case 'U':
6176 			user_settings = 1;
6177 			break;
6178 		case 'W':
6179 			bus_width = strtol(optarg, NULL, 0);
6180 			if (bus_width < 0) {
6181 				warnx("bus width %d is < 0", bus_width);
6182 				retval = 1;
6183 				goto ratecontrol_bailout;
6184 			}
6185 			change_settings = 1;
6186 			break;
6187 		default:
6188 			break;
6189 		}
6190 	}
6191 	/*
6192 	 * Grab path inquiry information, so we can determine whether
6193 	 * or not the initiator is capable of the things that the user
6194 	 * requests.
6195 	 */
6196 	if ((retval = get_cpi(device, &cpi)) != 0)
6197 		goto ratecontrol_bailout;
6198 	if (quiet == 0) {
6199 		fprintf(stdout, "%s parameters:\n",
6200 		    user_settings ? "User" : "Current");
6201 	}
6202 	retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6203 	if (retval != 0)
6204 		goto ratecontrol_bailout;
6205 
6206 	if (arglist & CAM_ARG_VERBOSE)
6207 		cpi_print(&cpi);
6208 
6209 	if (change_settings) {
6210 		int didsettings = 0;
6211 		struct ccb_trans_settings_spi *spi = NULL;
6212 		struct ccb_trans_settings_pata *pata = NULL;
6213 		struct ccb_trans_settings_sata *sata = NULL;
6214 		struct ccb_trans_settings_ata *ata = NULL;
6215 		struct ccb_trans_settings_scsi *scsi = NULL;
6216 
6217 		if (ccb->cts.transport == XPORT_SPI)
6218 			spi = &ccb->cts.xport_specific.spi;
6219 		if (ccb->cts.transport == XPORT_ATA)
6220 			pata = &ccb->cts.xport_specific.ata;
6221 		if (ccb->cts.transport == XPORT_SATA)
6222 			sata = &ccb->cts.xport_specific.sata;
6223 		if (ccb->cts.protocol == PROTO_ATA)
6224 			ata = &ccb->cts.proto_specific.ata;
6225 		if (ccb->cts.protocol == PROTO_SCSI)
6226 			scsi = &ccb->cts.proto_specific.scsi;
6227 		ccb->cts.xport_specific.valid = 0;
6228 		ccb->cts.proto_specific.valid = 0;
6229 		if (spi && disc_enable != -1) {
6230 			spi->valid |= CTS_SPI_VALID_DISC;
6231 			if (disc_enable == 0)
6232 				spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6233 			else
6234 				spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6235 			didsettings++;
6236 		}
6237 		if (tag_enable != -1) {
6238 			if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6239 				warnx("HBA does not support tagged queueing, "
6240 				      "so you cannot modify tag settings");
6241 				retval = 1;
6242 				goto ratecontrol_bailout;
6243 			}
6244 			if (ata) {
6245 				ata->valid |= CTS_SCSI_VALID_TQ;
6246 				if (tag_enable == 0)
6247 					ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6248 				else
6249 					ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6250 				didsettings++;
6251 			} else if (scsi) {
6252 				scsi->valid |= CTS_SCSI_VALID_TQ;
6253 				if (tag_enable == 0)
6254 					scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6255 				else
6256 					scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6257 				didsettings++;
6258 			}
6259 		}
6260 		if (spi && offset != -1) {
6261 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6262 				warnx("HBA is not capable of changing offset");
6263 				retval = 1;
6264 				goto ratecontrol_bailout;
6265 			}
6266 			spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6267 			spi->sync_offset = offset;
6268 			didsettings++;
6269 		}
6270 		if (spi && syncrate != -1) {
6271 			int prelim_sync_period;
6272 
6273 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6274 				warnx("HBA is not capable of changing "
6275 				      "transfer rates");
6276 				retval = 1;
6277 				goto ratecontrol_bailout;
6278 			}
6279 			spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6280 			/*
6281 			 * The sync rate the user gives us is in MHz.
6282 			 * We need to translate it into KHz for this
6283 			 * calculation.
6284 			 */
6285 			syncrate *= 1000;
6286 			/*
6287 			 * Next, we calculate a "preliminary" sync period
6288 			 * in tenths of a nanosecond.
6289 			 */
6290 			if (syncrate == 0)
6291 				prelim_sync_period = 0;
6292 			else
6293 				prelim_sync_period = 10000000 / syncrate;
6294 			spi->sync_period =
6295 				scsi_calc_syncparam(prelim_sync_period);
6296 			didsettings++;
6297 		}
6298 		if (sata && syncrate != -1) {
6299 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6300 				warnx("HBA is not capable of changing "
6301 				      "transfer rates");
6302 				retval = 1;
6303 				goto ratecontrol_bailout;
6304 			}
6305 			if  (!user_settings) {
6306 				warnx("You can modify only user rate "
6307 				    "settings for SATA");
6308 				retval = 1;
6309 				goto ratecontrol_bailout;
6310 			}
6311 			sata->revision = ata_speed2revision(syncrate * 100);
6312 			if (sata->revision < 0) {
6313 				warnx("Invalid rate %f", syncrate);
6314 				retval = 1;
6315 				goto ratecontrol_bailout;
6316 			}
6317 			sata->valid |= CTS_SATA_VALID_REVISION;
6318 			didsettings++;
6319 		}
6320 		if ((pata || sata) && mode != -1) {
6321 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6322 				warnx("HBA is not capable of changing "
6323 				      "transfer rates");
6324 				retval = 1;
6325 				goto ratecontrol_bailout;
6326 			}
6327 			if  (!user_settings) {
6328 				warnx("You can modify only user mode "
6329 				    "settings for ATA/SATA");
6330 				retval = 1;
6331 				goto ratecontrol_bailout;
6332 			}
6333 			if (pata) {
6334 				pata->mode = mode;
6335 				pata->valid |= CTS_ATA_VALID_MODE;
6336 			} else {
6337 				sata->mode = mode;
6338 				sata->valid |= CTS_SATA_VALID_MODE;
6339 			}
6340 			didsettings++;
6341 		}
6342 		/*
6343 		 * The bus_width argument goes like this:
6344 		 * 0 == 8 bit
6345 		 * 1 == 16 bit
6346 		 * 2 == 32 bit
6347 		 * Therefore, if you shift the number of bits given on the
6348 		 * command line right by 4, you should get the correct
6349 		 * number.
6350 		 */
6351 		if (spi && bus_width != -1) {
6352 			/*
6353 			 * We might as well validate things here with a
6354 			 * decipherable error message, rather than what
6355 			 * will probably be an indecipherable error message
6356 			 * by the time it gets back to us.
6357 			 */
6358 			if ((bus_width == 16)
6359 			 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6360 				warnx("HBA does not support 16 bit bus width");
6361 				retval = 1;
6362 				goto ratecontrol_bailout;
6363 			} else if ((bus_width == 32)
6364 				&& ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6365 				warnx("HBA does not support 32 bit bus width");
6366 				retval = 1;
6367 				goto ratecontrol_bailout;
6368 			} else if ((bus_width != 8)
6369 				&& (bus_width != 16)
6370 				&& (bus_width != 32)) {
6371 				warnx("Invalid bus width %d", bus_width);
6372 				retval = 1;
6373 				goto ratecontrol_bailout;
6374 			}
6375 			spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6376 			spi->bus_width = bus_width >> 4;
6377 			didsettings++;
6378 		}
6379 		if  (didsettings == 0) {
6380 			goto ratecontrol_bailout;
6381 		}
6382 		ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6383 		if (cam_send_ccb(device, ccb) < 0) {
6384 			warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6385 			retval = 1;
6386 			goto ratecontrol_bailout;
6387 		}
6388 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6389 			warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6390 			if (arglist & CAM_ARG_VERBOSE) {
6391 				cam_error_print(device, ccb, CAM_ESF_ALL,
6392 						CAM_EPF_ALL, stderr);
6393 			}
6394 			retval = 1;
6395 			goto ratecontrol_bailout;
6396 		}
6397 	}
6398 	if (send_tur) {
6399 		retval = testunitready(device, task_attr, retry_count, timeout,
6400 				       (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6401 		/*
6402 		 * If the TUR didn't succeed, just bail.
6403 		 */
6404 		if (retval != 0) {
6405 			if (quiet == 0)
6406 				fprintf(stderr, "Test Unit Ready failed\n");
6407 			goto ratecontrol_bailout;
6408 		}
6409 	}
6410 	if ((change_settings || send_tur) && !quiet &&
6411 	    (ccb->cts.transport == XPORT_ATA ||
6412 	     ccb->cts.transport == XPORT_SATA || send_tur)) {
6413 		fprintf(stdout, "New parameters:\n");
6414 		retval = get_print_cts(device, user_settings, 0, NULL);
6415 	}
6416 
6417 ratecontrol_bailout:
6418 	cam_freeccb(ccb);
6419 	return (retval);
6420 }
6421 
6422 static int
6423 scsiformat(struct cam_device *device, int argc, char **argv,
6424 	   char *combinedopt, int task_attr, int retry_count, int timeout)
6425 {
6426 	union ccb *ccb;
6427 	int c;
6428 	int ycount = 0, quiet = 0;
6429 	int error = 0, retval = 0;
6430 	int use_timeout = 10800 * 1000;
6431 	int immediate = 1;
6432 	struct format_defect_list_header fh;
6433 	uint8_t *data_ptr = NULL;
6434 	uint32_t dxfer_len = 0;
6435 	uint8_t byte2 = 0;
6436 	int num_warnings = 0;
6437 	int reportonly = 0;
6438 
6439 	ccb = cam_getccb(device);
6440 
6441 	if (ccb == NULL) {
6442 		warnx("scsiformat: error allocating ccb");
6443 		return (1);
6444 	}
6445 
6446 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
6447 		switch(c) {
6448 		case 'q':
6449 			quiet++;
6450 			break;
6451 		case 'r':
6452 			reportonly = 1;
6453 			break;
6454 		case 'w':
6455 			immediate = 0;
6456 			break;
6457 		case 'y':
6458 			ycount++;
6459 			break;
6460 		}
6461 	}
6462 
6463 	if (reportonly)
6464 		goto doreport;
6465 
6466 	if (quiet == 0 && ycount == 0) {
6467 		fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6468 			"following device:\n");
6469 
6470 		error = scsidoinquiry(device, argc, argv, combinedopt,
6471 				      task_attr, retry_count, timeout);
6472 
6473 		if (error != 0) {
6474 			warnx("scsiformat: error sending inquiry");
6475 			goto scsiformat_bailout;
6476 		}
6477 	}
6478 
6479 	if (ycount == 0) {
6480 		if (!get_confirmation()) {
6481 			error = 1;
6482 			goto scsiformat_bailout;
6483 		}
6484 	}
6485 
6486 	if (timeout != 0)
6487 		use_timeout = timeout;
6488 
6489 	if (quiet == 0) {
6490 		fprintf(stdout, "Current format timeout is %d seconds\n",
6491 			use_timeout / 1000);
6492 	}
6493 
6494 	/*
6495 	 * If the user hasn't disabled questions and didn't specify a
6496 	 * timeout on the command line, ask them if they want the current
6497 	 * timeout.
6498 	 */
6499 	if ((ycount == 0)
6500 	 && (timeout == 0)) {
6501 		char str[1024];
6502 		int new_timeout = 0;
6503 
6504 		fprintf(stdout, "Enter new timeout in seconds or press\n"
6505 			"return to keep the current timeout [%d] ",
6506 			use_timeout / 1000);
6507 
6508 		if (fgets(str, sizeof(str), stdin) != NULL) {
6509 			if (str[0] != '\0')
6510 				new_timeout = atoi(str);
6511 		}
6512 
6513 		if (new_timeout != 0) {
6514 			use_timeout = new_timeout * 1000;
6515 			fprintf(stdout, "Using new timeout value %d\n",
6516 				use_timeout / 1000);
6517 		}
6518 	}
6519 
6520 	/*
6521 	 * Keep this outside the if block below to silence any unused
6522 	 * variable warnings.
6523 	 */
6524 	bzero(&fh, sizeof(fh));
6525 
6526 	/*
6527 	 * If we're in immediate mode, we've got to include the format
6528 	 * header
6529 	 */
6530 	if (immediate != 0) {
6531 		fh.byte2 = FU_DLH_IMMED;
6532 		data_ptr = (uint8_t *)&fh;
6533 		dxfer_len = sizeof(fh);
6534 		byte2 = FU_FMT_DATA;
6535 	} else if (quiet == 0) {
6536 		fprintf(stdout, "Formatting...");
6537 		fflush(stdout);
6538 	}
6539 
6540 	scsi_format_unit(&ccb->csio,
6541 			 /* retries */ retry_count,
6542 			 /* cbfcnp */ NULL,
6543 			 /* tag_action */ task_attr,
6544 			 /* byte2 */ byte2,
6545 			 /* ileave */ 0,
6546 			 /* data_ptr */ data_ptr,
6547 			 /* dxfer_len */ dxfer_len,
6548 			 /* sense_len */ SSD_FULL_SIZE,
6549 			 /* timeout */ use_timeout);
6550 
6551 	/* Disable freezing the device queue */
6552 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6553 
6554 	if (arglist & CAM_ARG_ERR_RECOVER)
6555 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6556 
6557 	if (((retval = cam_send_ccb(device, ccb)) < 0)
6558 	 || ((immediate == 0)
6559 	   && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6560 		const char errstr[] = "error sending format command";
6561 
6562 		if (retval < 0)
6563 			warn(errstr);
6564 		else
6565 			warnx(errstr);
6566 
6567 		if (arglist & CAM_ARG_VERBOSE) {
6568 			cam_error_print(device, ccb, CAM_ESF_ALL,
6569 					CAM_EPF_ALL, stderr);
6570 		}
6571 		error = 1;
6572 		goto scsiformat_bailout;
6573 	}
6574 
6575 	/*
6576 	 * If we ran in non-immediate mode, we already checked for errors
6577 	 * above and printed out any necessary information.  If we're in
6578 	 * immediate mode, we need to loop through and get status
6579 	 * information periodically.
6580 	 */
6581 	if (immediate == 0) {
6582 		if (quiet == 0) {
6583 			fprintf(stdout, "Format Complete\n");
6584 		}
6585 		goto scsiformat_bailout;
6586 	}
6587 
6588 doreport:
6589 	do {
6590 		cam_status status;
6591 
6592 		CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6593 
6594 		/*
6595 		 * There's really no need to do error recovery or
6596 		 * retries here, since we're just going to sit in a
6597 		 * loop and wait for the device to finish formatting.
6598 		 */
6599 		scsi_test_unit_ready(&ccb->csio,
6600 				     /* retries */ 0,
6601 				     /* cbfcnp */ NULL,
6602 				     /* tag_action */ task_attr,
6603 				     /* sense_len */ SSD_FULL_SIZE,
6604 				     /* timeout */ 5000);
6605 
6606 		/* Disable freezing the device queue */
6607 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6608 
6609 		retval = cam_send_ccb(device, ccb);
6610 
6611 		/*
6612 		 * If we get an error from the ioctl, bail out.  SCSI
6613 		 * errors are expected.
6614 		 */
6615 		if (retval < 0) {
6616 			warn("error sending TEST UNIT READY command");
6617 			error = 1;
6618 			goto scsiformat_bailout;
6619 		}
6620 
6621 		status = ccb->ccb_h.status & CAM_STATUS_MASK;
6622 
6623 		if ((status != CAM_REQ_CMP)
6624 		 && (status == CAM_SCSI_STATUS_ERROR)
6625 		 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6626 			struct scsi_sense_data *sense;
6627 			int error_code, sense_key, asc, ascq;
6628 
6629 			sense = &ccb->csio.sense_data;
6630 			scsi_extract_sense_len(sense, ccb->csio.sense_len -
6631 			    ccb->csio.sense_resid, &error_code, &sense_key,
6632 			    &asc, &ascq, /*show_errors*/ 1);
6633 
6634 			/*
6635 			 * According to the SCSI-2 and SCSI-3 specs, a
6636 			 * drive that is in the middle of a format should
6637 			 * return NOT READY with an ASC of "logical unit
6638 			 * not ready, format in progress".  The sense key
6639 			 * specific bytes will then be a progress indicator.
6640 			 */
6641 			if ((sense_key == SSD_KEY_NOT_READY)
6642 			 && (asc == 0x04) && (ascq == 0x04)) {
6643 				uint8_t sks[3];
6644 
6645 				if ((scsi_get_sks(sense, ccb->csio.sense_len -
6646 				     ccb->csio.sense_resid, sks) == 0)
6647 				 && (quiet == 0)) {
6648 					uint32_t val;
6649 					u_int64_t percentage;
6650 
6651 					val = scsi_2btoul(&sks[1]);
6652 					percentage = 10000ull * val;
6653 
6654 					fprintf(stdout,
6655 						"\rFormatting:  %ju.%02u %% "
6656 						"(%u/%d) done",
6657 						(uintmax_t)(percentage /
6658 						(0x10000 * 100)),
6659 						(unsigned)((percentage /
6660 						0x10000) % 100),
6661 						val, 0x10000);
6662 					fflush(stdout);
6663 				} else if ((quiet == 0)
6664 					&& (++num_warnings <= 1)) {
6665 					warnx("Unexpected SCSI Sense Key "
6666 					      "Specific value returned "
6667 					      "during format:");
6668 					scsi_sense_print(device, &ccb->csio,
6669 							 stderr);
6670 					warnx("Unable to print status "
6671 					      "information, but format will "
6672 					      "proceed.");
6673 					warnx("will exit when format is "
6674 					      "complete");
6675 				}
6676 				sleep(1);
6677 			} else {
6678 				warnx("Unexpected SCSI error during format");
6679 				cam_error_print(device, ccb, CAM_ESF_ALL,
6680 						CAM_EPF_ALL, stderr);
6681 				error = 1;
6682 				goto scsiformat_bailout;
6683 			}
6684 
6685 		} else if (status != CAM_REQ_CMP) {
6686 			warnx("Unexpected CAM status %#x", status);
6687 			if (arglist & CAM_ARG_VERBOSE)
6688 				cam_error_print(device, ccb, CAM_ESF_ALL,
6689 						CAM_EPF_ALL, stderr);
6690 			error = 1;
6691 			goto scsiformat_bailout;
6692 		}
6693 
6694 	} while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6695 
6696 	if (quiet == 0)
6697 		fprintf(stdout, "\nFormat Complete\n");
6698 
6699 scsiformat_bailout:
6700 
6701 	cam_freeccb(ccb);
6702 
6703 	return (error);
6704 }
6705 
6706 static int
6707 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6708     camcontrol_devtype devtype)
6709 {
6710 	int retval;
6711 	uint8_t error = 0, ata_device = 0, status = 0;
6712 	uint16_t count = 0;
6713 	uint64_t lba = 0;
6714 	u_int val, perc;
6715 
6716 	do {
6717 		retval = build_ata_cmd(ccb,
6718 			     /*retries*/ 0,
6719 			     /*flags*/ CAM_DIR_NONE,
6720 			     /*tag_action*/ MSG_SIMPLE_Q_TAG,
6721 			     /*protocol*/ AP_PROTO_NON_DATA,
6722 			     /*ata_flags*/ AP_FLAG_CHK_COND,
6723 			     /*features*/ 0x00, /* SANITIZE STATUS EXT */
6724 			     /*sector_count*/ 0,
6725 			     /*lba*/ 0,
6726 			     /*command*/ ATA_SANITIZE,
6727 			     /*auxiliary*/ 0,
6728 			     /*data_ptr*/ NULL,
6729 			     /*dxfer_len*/ 0,
6730 			     /*cdb_storage*/ NULL,
6731 			     /*cdb_storage_len*/ 0,
6732 			     /*sense_len*/ SSD_FULL_SIZE,
6733 			     /*timeout*/ 10000,
6734 			     /*is48bit*/ 1,
6735 			     /*devtype*/ devtype);
6736 		if (retval != 0) {
6737 			warnx("%s: build_ata_cmd() failed, likely "
6738 			    "programmer error", __func__);
6739 			return (1);
6740 		}
6741 
6742 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6743 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6744 		retval = cam_send_ccb(device, ccb);
6745 		if (retval != 0) {
6746 			warn("error sending SANITIZE STATUS EXT command");
6747 			return (1);
6748 		}
6749 
6750 		retval = get_ata_status(device, ccb, &error, &count, &lba,
6751 		    &ata_device, &status);
6752 		if (retval != 0) {
6753 			warnx("Can't get SANITIZE STATUS EXT status, "
6754 			    "sanitize may still run.");
6755 			return (retval);
6756 		}
6757 		if (status & ATA_STATUS_ERROR) {
6758 			if (error & ATA_ERROR_ABORT) {
6759 				switch (lba & 0xff) {
6760 				case 0x00:
6761 					warnx("Reason not reported or sanitize failed.");
6762 					return (1);
6763 				case 0x01:
6764 					warnx("Sanitize command unsuccessful.       ");
6765 					return (1);
6766 				case 0x02:
6767 					warnx("Unsupported sanitize device command. ");
6768 					return (1);
6769 				case 0x03:
6770 					warnx("Device is in sanitize frozen state.  ");
6771 					return (1);
6772 				case 0x04:
6773 					warnx("Sanitize antifreeze lock is enabled. ");
6774 					return (1);
6775 				}
6776 			}
6777 			warnx("SANITIZE STATUS EXT failed, "
6778 			    "sanitize may still run.");
6779 			return (1);
6780 		}
6781 		if (count & 0x4000) {
6782 			if (quiet == 0) {
6783 				val = lba & 0xffff;
6784 				perc = 10000 * val;
6785 				fprintf(stdout,
6786 				    "Sanitizing: %u.%02u%% (%d/%d)\r",
6787 				    (perc / (0x10000 * 100)),
6788 				    ((perc / 0x10000) % 100),
6789 				    val, 0x10000);
6790 				fflush(stdout);
6791 			}
6792 			sleep(1);
6793 		} else
6794 			break;
6795 	} while (1);
6796 	return (0);
6797 }
6798 
6799 static int
6800 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6801 {
6802 	int warnings = 0, retval;
6803 	cam_status status;
6804 	u_int val, perc;
6805 
6806 	do {
6807 		CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6808 
6809 		/*
6810 		 * There's really no need to do error recovery or
6811 		 * retries here, since we're just going to sit in a
6812 		 * loop and wait for the device to finish sanitizing.
6813 		 */
6814 		scsi_test_unit_ready(&ccb->csio,
6815 				     /* retries */ 0,
6816 				     /* cbfcnp */ NULL,
6817 				     /* tag_action */ task_attr,
6818 				     /* sense_len */ SSD_FULL_SIZE,
6819 				     /* timeout */ 5000);
6820 
6821 		/* Disable freezing the device queue */
6822 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6823 
6824 		retval = cam_send_ccb(device, ccb);
6825 
6826 		/*
6827 		 * If we get an error from the ioctl, bail out.  SCSI
6828 		 * errors are expected.
6829 		 */
6830 		if (retval < 0) {
6831 			warn("error sending TEST UNIT READY command");
6832 			return (1);
6833 		}
6834 
6835 		status = ccb->ccb_h.status & CAM_STATUS_MASK;
6836 		if ((status == CAM_SCSI_STATUS_ERROR) &&
6837 		    ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6838 			struct scsi_sense_data *sense;
6839 			int error_code, sense_key, asc, ascq;
6840 
6841 			sense = &ccb->csio.sense_data;
6842 			scsi_extract_sense_len(sense, ccb->csio.sense_len -
6843 			    ccb->csio.sense_resid, &error_code, &sense_key,
6844 			    &asc, &ascq, /*show_errors*/ 1);
6845 
6846 			/*
6847 			 * According to the SCSI-3 spec, a drive that is in the
6848 			 * middle of a sanitize should return NOT READY with an
6849 			 * ASC of "logical unit not ready, sanitize in
6850 			 * progress". The sense key specific bytes will then
6851 			 * be a progress indicator.
6852 			 */
6853 			if ((sense_key == SSD_KEY_NOT_READY)
6854 			 && (asc == 0x04) && (ascq == 0x1b)) {
6855 				uint8_t sks[3];
6856 
6857 				if ((scsi_get_sks(sense, ccb->csio.sense_len -
6858 				     ccb->csio.sense_resid, sks) == 0)
6859 				 && (quiet == 0)) {
6860 					val = scsi_2btoul(&sks[1]);
6861 					perc = 10000 * val;
6862 					fprintf(stdout,
6863 					    "Sanitizing: %u.%02u%% (%d/%d)\r",
6864 					    (perc / (0x10000 * 100)),
6865 					    ((perc / 0x10000) % 100),
6866 					    val, 0x10000);
6867 					fflush(stdout);
6868 				} else if ((quiet == 0) && (++warnings <= 1)) {
6869 					warnx("Unexpected SCSI Sense Key "
6870 					      "Specific value returned "
6871 					      "during sanitize:");
6872 					scsi_sense_print(device, &ccb->csio,
6873 							 stderr);
6874 					warnx("Unable to print status "
6875 					      "information, but sanitze will "
6876 					      "proceed.");
6877 					warnx("will exit when sanitize is "
6878 					      "complete");
6879 				}
6880 				sleep(1);
6881 			} else {
6882 				warnx("Unexpected SCSI error during sanitize");
6883 				cam_error_print(device, ccb, CAM_ESF_ALL,
6884 						CAM_EPF_ALL, stderr);
6885 				return (1);
6886 			}
6887 
6888 		} else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6889 			warnx("Unexpected CAM status %#x", status);
6890 			if (arglist & CAM_ARG_VERBOSE)
6891 				cam_error_print(device, ccb, CAM_ESF_ALL,
6892 						CAM_EPF_ALL, stderr);
6893 			return (1);
6894 		}
6895 	} while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6896 	return (0);
6897 }
6898 
6899 static int
6900 sanitize(struct cam_device *device, int argc, char **argv,
6901 	     char *combinedopt, int task_attr, int retry_count, int timeout)
6902 {
6903 	union ccb *ccb;
6904 	uint8_t action = 0;
6905 	int c;
6906 	int ycount = 0, quiet = 0;
6907 	int error = 0;
6908 	int use_timeout;
6909 	int immediate = 1;
6910 	int invert = 0;
6911 	int passes = 0;
6912 	int ause = 0;
6913 	int fd = -1;
6914 	const char *pattern = NULL;
6915 	uint8_t *data_ptr = NULL;
6916 	uint32_t dxfer_len = 0;
6917 	uint8_t byte2;
6918 	uint16_t feature, count;
6919 	uint64_t lba;
6920 	int reportonly = 0;
6921 	camcontrol_devtype dt;
6922 
6923 	/*
6924 	 * Get the device type, request no I/O be done to do this.
6925 	 */
6926 	error = get_device_type(device, -1, 0, 0, &dt);
6927 	if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6928 		warnx("sanitize: can't get device type");
6929 		return (1);
6930 	}
6931 
6932 	ccb = cam_getccb(device);
6933 
6934 	if (ccb == NULL) {
6935 		warnx("sanitize: error allocating ccb");
6936 		return (1);
6937 	}
6938 
6939 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
6940 		switch(c) {
6941 		case 'a':
6942 			if (strcasecmp(optarg, "overwrite") == 0)
6943 				action = SSZ_SERVICE_ACTION_OVERWRITE;
6944 			else if (strcasecmp(optarg, "block") == 0)
6945 				action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6946 			else if (strcasecmp(optarg, "crypto") == 0)
6947 				action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6948 			else if (strcasecmp(optarg, "exitfailure") == 0)
6949 				action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6950 			else {
6951 				warnx("invalid service operation \"%s\"",
6952 				      optarg);
6953 				error = 1;
6954 				goto sanitize_bailout;
6955 			}
6956 			break;
6957 		case 'c':
6958 			passes = strtol(optarg, NULL, 0);
6959 			if (passes < 1 || passes > 31) {
6960 				warnx("invalid passes value %d", passes);
6961 				error = 1;
6962 				goto sanitize_bailout;
6963 			}
6964 			break;
6965 		case 'I':
6966 			invert = 1;
6967 			break;
6968 		case 'P':
6969 			pattern = optarg;
6970 			break;
6971 		case 'q':
6972 			quiet++;
6973 			break;
6974 		case 'U':
6975 			ause = 1;
6976 			break;
6977 		case 'r':
6978 			reportonly = 1;
6979 			break;
6980 		case 'w':
6981 			/* ATA supports only immediate commands. */
6982 			if (dt == CC_DT_SCSI)
6983 				immediate = 0;
6984 			break;
6985 		case 'y':
6986 			ycount++;
6987 			break;
6988 		}
6989 	}
6990 
6991 	if (reportonly)
6992 		goto doreport;
6993 
6994 	if (action == 0) {
6995 		warnx("an action is required");
6996 		error = 1;
6997 		goto sanitize_bailout;
6998 	} else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6999 		struct scsi_sanitize_parameter_list *pl;
7000 		struct stat sb;
7001 		ssize_t sz, amt;
7002 
7003 		if (pattern == NULL) {
7004 			warnx("overwrite action requires -P argument");
7005 			error = 1;
7006 			goto sanitize_bailout;
7007 		}
7008 		fd = open(pattern, O_RDONLY);
7009 		if (fd < 0) {
7010 			warn("cannot open pattern file %s", pattern);
7011 			error = 1;
7012 			goto sanitize_bailout;
7013 		}
7014 		if (fstat(fd, &sb) < 0) {
7015 			warn("cannot stat pattern file %s", pattern);
7016 			error = 1;
7017 			goto sanitize_bailout;
7018 		}
7019 		sz = sb.st_size;
7020 		if (sz > SSZPL_MAX_PATTERN_LENGTH) {
7021 			warnx("pattern file size exceeds maximum value %d",
7022 			      SSZPL_MAX_PATTERN_LENGTH);
7023 			error = 1;
7024 			goto sanitize_bailout;
7025 		}
7026 		dxfer_len = sizeof(*pl) + sz;
7027 		data_ptr = calloc(1, dxfer_len);
7028 		if (data_ptr == NULL) {
7029 			warnx("cannot allocate parameter list buffer");
7030 			error = 1;
7031 			goto sanitize_bailout;
7032 		}
7033 
7034 		amt = read(fd, data_ptr + sizeof(*pl), sz);
7035 		if (amt < 0) {
7036 			warn("cannot read pattern file");
7037 			error = 1;
7038 			goto sanitize_bailout;
7039 		} else if (amt != sz) {
7040 			warnx("short pattern file read");
7041 			error = 1;
7042 			goto sanitize_bailout;
7043 		}
7044 
7045 		pl = (struct scsi_sanitize_parameter_list *)data_ptr;
7046 		if (passes == 0)
7047 			pl->byte1 = 1;
7048 		else
7049 			pl->byte1 = passes;
7050 		if (invert != 0)
7051 			pl->byte1 |= SSZPL_INVERT;
7052 		scsi_ulto2b(sz, pl->length);
7053 	} else {
7054 		const char *arg;
7055 
7056 		if (passes != 0)
7057 			arg = "-c";
7058 		else if (invert != 0)
7059 			arg = "-I";
7060 		else if (pattern != NULL)
7061 			arg = "-P";
7062 		else
7063 			arg = NULL;
7064 		if (arg != NULL) {
7065 			warnx("%s argument only valid with overwrite "
7066 			      "operation", arg);
7067 			error = 1;
7068 			goto sanitize_bailout;
7069 		}
7070 	}
7071 
7072 	if (quiet == 0 && ycount == 0) {
7073 		fprintf(stdout, "You are about to REMOVE ALL DATA from the "
7074 			"following device:\n");
7075 
7076 		if (dt == CC_DT_SCSI) {
7077 			error = scsidoinquiry(device, argc, argv, combinedopt,
7078 					      task_attr, retry_count, timeout);
7079 		} else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7080 			struct ata_params *ident_buf;
7081 			error = ata_do_identify(device, retry_count, timeout,
7082 						ccb, &ident_buf);
7083 			if (error == 0) {
7084 				printf("%s%d: ", device->device_name,
7085 				    device->dev_unit_num);
7086 				ata_print_ident(ident_buf);
7087 				free(ident_buf);
7088 			}
7089 		} else
7090 			error = 1;
7091 
7092 		if (error != 0) {
7093 			warnx("sanitize: error sending inquiry");
7094 			goto sanitize_bailout;
7095 		}
7096 	}
7097 
7098 	if (ycount == 0) {
7099 		if (!get_confirmation()) {
7100 			error = 1;
7101 			goto sanitize_bailout;
7102 		}
7103 	}
7104 
7105 	if (timeout != 0)
7106 		use_timeout = timeout;
7107 	else
7108 		use_timeout = (immediate ? 10 : 10800) * 1000;
7109 
7110 	if (immediate == 0 && quiet == 0) {
7111 		fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7112 			use_timeout / 1000);
7113 	}
7114 
7115 	/*
7116 	 * If the user hasn't disabled questions and didn't specify a
7117 	 * timeout on the command line, ask them if they want the current
7118 	 * timeout.
7119 	 */
7120 	if (immediate == 0 && ycount == 0 && timeout == 0) {
7121 		char str[1024];
7122 		int new_timeout = 0;
7123 
7124 		fprintf(stdout, "Enter new timeout in seconds or press\n"
7125 			"return to keep the current timeout [%d] ",
7126 			use_timeout / 1000);
7127 
7128 		if (fgets(str, sizeof(str), stdin) != NULL) {
7129 			if (str[0] != '\0')
7130 				new_timeout = atoi(str);
7131 		}
7132 
7133 		if (new_timeout != 0) {
7134 			use_timeout = new_timeout * 1000;
7135 			fprintf(stdout, "Using new timeout value %d\n",
7136 				use_timeout / 1000);
7137 		}
7138 	}
7139 
7140 	if (dt == CC_DT_SCSI) {
7141 		byte2 = action;
7142 		if (ause != 0)
7143 			byte2 |= SSZ_UNRESTRICTED_EXIT;
7144 		if (immediate != 0)
7145 			byte2 |= SSZ_IMMED;
7146 		scsi_sanitize(&ccb->csio,
7147 			      /* retries */ retry_count,
7148 			      /* cbfcnp */ NULL,
7149 			      /* tag_action */ task_attr,
7150 			      /* byte2 */ byte2,
7151 			      /* control */ 0,
7152 			      /* data_ptr */ data_ptr,
7153 			      /* dxfer_len */ dxfer_len,
7154 			      /* sense_len */ SSD_FULL_SIZE,
7155 			      /* timeout */ use_timeout);
7156 
7157 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7158 		if (arglist & CAM_ARG_ERR_RECOVER)
7159 			ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7160 		if (cam_send_ccb(device, ccb) < 0) {
7161 			warn("error sending sanitize command");
7162 			error = 1;
7163 			goto sanitize_bailout;
7164 		}
7165 	} else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7166 		if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7167 			feature = 0x14; /* OVERWRITE EXT */
7168 			lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7169 			count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7170 			if (invert)
7171 				count |= 0x80; /* INVERT PATTERN */
7172 			if (ause)
7173 				count |= 0x10; /* FAILURE MODE */
7174 		} else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7175 			feature = 0x12; /* BLOCK ERASE EXT */
7176 			lba = 0x0000426B4572;
7177 			count = 0;
7178 			if (ause)
7179 				count |= 0x10; /* FAILURE MODE */
7180 		} else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7181 			feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7182 			lba = 0x000043727970;
7183 			count = 0;
7184 			if (ause)
7185 				count |= 0x10; /* FAILURE MODE */
7186 		} else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7187 			feature = 0x00; /* SANITIZE STATUS EXT */
7188 			lba = 0;
7189 			count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7190 		} else {
7191 			error = 1;
7192 			goto sanitize_bailout;
7193 		}
7194 
7195 		error = ata_do_cmd(device,
7196 				   ccb,
7197 				   retry_count,
7198 				   /*flags*/CAM_DIR_NONE,
7199 				   /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7200 				   /*ata_flags*/0,
7201 				   /*tag_action*/MSG_SIMPLE_Q_TAG,
7202 				   /*command*/ATA_SANITIZE,
7203 				   /*features*/feature,
7204 				   /*lba*/lba,
7205 				   /*sector_count*/count,
7206 				   /*data_ptr*/NULL,
7207 				   /*dxfer_len*/0,
7208 				   /*timeout*/ use_timeout,
7209 				   /*is48bit*/1);
7210 	}
7211 
7212 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7213 		struct scsi_sense_data *sense;
7214 		int error_code, sense_key, asc, ascq;
7215 
7216 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7217 		    CAM_SCSI_STATUS_ERROR) {
7218 			sense = &ccb->csio.sense_data;
7219 			scsi_extract_sense_len(sense, ccb->csio.sense_len -
7220 			    ccb->csio.sense_resid, &error_code, &sense_key,
7221 			    &asc, &ascq, /*show_errors*/ 1);
7222 
7223 			if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7224 			    asc == 0x20 && ascq == 0x00)
7225 				warnx("sanitize is not supported by "
7226 				      "this device");
7227 			else
7228 				warnx("error sanitizing this device");
7229 		} else
7230 			warnx("error sanitizing this device");
7231 
7232 		if (arglist & CAM_ARG_VERBOSE) {
7233 			cam_error_print(device, ccb, CAM_ESF_ALL,
7234 					CAM_EPF_ALL, stderr);
7235 		}
7236 		error = 1;
7237 		goto sanitize_bailout;
7238 	}
7239 
7240 	/*
7241 	 * If we ran in non-immediate mode, we already checked for errors
7242 	 * above and printed out any necessary information.  If we're in
7243 	 * immediate mode, we need to loop through and get status
7244 	 * information periodically.
7245 	 */
7246 	if (immediate == 0) {
7247 		if (quiet == 0) {
7248 			fprintf(stdout, "Sanitize Complete\n");
7249 		}
7250 		goto sanitize_bailout;
7251 	}
7252 
7253 doreport:
7254 	if (dt == CC_DT_SCSI) {
7255 		error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7256 	} else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7257 		error = sanitize_wait_ata(device, ccb, quiet, dt);
7258 	} else
7259 		error = 1;
7260 	if (error == 0 && quiet == 0)
7261 		fprintf(stdout, "Sanitize Complete                      \n");
7262 
7263 sanitize_bailout:
7264 	if (fd >= 0)
7265 		close(fd);
7266 	if (data_ptr != NULL)
7267 		free(data_ptr);
7268 	cam_freeccb(ccb);
7269 
7270 	return (error);
7271 }
7272 
7273 static int
7274 scsireportluns(struct cam_device *device, int argc, char **argv,
7275 	       char *combinedopt, int task_attr, int retry_count, int timeout)
7276 {
7277 	union ccb *ccb;
7278 	int c, countonly, lunsonly;
7279 	struct scsi_report_luns_data *lundata;
7280 	int alloc_len;
7281 	uint8_t report_type;
7282 	uint32_t list_len, i, j;
7283 	int retval;
7284 
7285 	retval = 0;
7286 	lundata = NULL;
7287 	report_type = RPL_REPORT_DEFAULT;
7288 	ccb = cam_getccb(device);
7289 
7290 	if (ccb == NULL) {
7291 		warnx("%s: error allocating ccb", __func__);
7292 		return (1);
7293 	}
7294 
7295 	countonly = 0;
7296 	lunsonly = 0;
7297 
7298 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
7299 		switch (c) {
7300 		case 'c':
7301 			countonly++;
7302 			break;
7303 		case 'l':
7304 			lunsonly++;
7305 			break;
7306 		case 'r':
7307 			if (strcasecmp(optarg, "default") == 0)
7308 				report_type = RPL_REPORT_DEFAULT;
7309 			else if (strcasecmp(optarg, "wellknown") == 0)
7310 				report_type = RPL_REPORT_WELLKNOWN;
7311 			else if (strcasecmp(optarg, "all") == 0)
7312 				report_type = RPL_REPORT_ALL;
7313 			else {
7314 				warnx("%s: invalid report type \"%s\"",
7315 				      __func__, optarg);
7316 				retval = 1;
7317 				goto bailout;
7318 			}
7319 			break;
7320 		default:
7321 			break;
7322 		}
7323 	}
7324 
7325 	if ((countonly != 0)
7326 	 && (lunsonly != 0)) {
7327 		warnx("%s: you can only specify one of -c or -l", __func__);
7328 		retval = 1;
7329 		goto bailout;
7330 	}
7331 	/*
7332 	 * According to SPC-4, the allocation length must be at least 16
7333 	 * bytes -- enough for the header and one LUN.
7334 	 */
7335 	alloc_len = sizeof(*lundata) + 8;
7336 
7337 retry:
7338 
7339 	lundata = malloc(alloc_len);
7340 
7341 	if (lundata == NULL) {
7342 		warn("%s: error mallocing %d bytes", __func__, alloc_len);
7343 		retval = 1;
7344 		goto bailout;
7345 	}
7346 
7347 	scsi_report_luns(&ccb->csio,
7348 			 /*retries*/ retry_count,
7349 			 /*cbfcnp*/ NULL,
7350 			 /*tag_action*/ task_attr,
7351 			 /*select_report*/ report_type,
7352 			 /*rpl_buf*/ lundata,
7353 			 /*alloc_len*/ alloc_len,
7354 			 /*sense_len*/ SSD_FULL_SIZE,
7355 			 /*timeout*/ timeout ? timeout : 5000);
7356 
7357 	/* Disable freezing the device queue */
7358 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7359 
7360 	if (arglist & CAM_ARG_ERR_RECOVER)
7361 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7362 
7363 	if (cam_send_ccb(device, ccb) < 0) {
7364 		warn("error sending REPORT LUNS command");
7365 		retval = 1;
7366 		goto bailout;
7367 	}
7368 
7369 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7370 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7371 		retval = 1;
7372 		goto bailout;
7373 	}
7374 
7375 
7376 	list_len = scsi_4btoul(lundata->length);
7377 
7378 	/*
7379 	 * If we need to list the LUNs, and our allocation
7380 	 * length was too short, reallocate and retry.
7381 	 */
7382 	if ((countonly == 0)
7383 	 && (list_len > (alloc_len - sizeof(*lundata)))) {
7384 		alloc_len = list_len + sizeof(*lundata);
7385 		free(lundata);
7386 		goto retry;
7387 	}
7388 
7389 	if (lunsonly == 0)
7390 		fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7391 			((list_len / 8) > 1) ? "s" : "");
7392 
7393 	if (countonly != 0)
7394 		goto bailout;
7395 
7396 	for (i = 0; i < (list_len / 8); i++) {
7397 		int no_more;
7398 
7399 		no_more = 0;
7400 		for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7401 			if (j != 0)
7402 				fprintf(stdout, ",");
7403 			switch (lundata->luns[i].lundata[j] &
7404 				RPL_LUNDATA_ATYP_MASK) {
7405 			case RPL_LUNDATA_ATYP_PERIPH:
7406 				if ((lundata->luns[i].lundata[j] &
7407 				    RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7408 					fprintf(stdout, "%d:",
7409 						lundata->luns[i].lundata[j] &
7410 						RPL_LUNDATA_PERIPH_BUS_MASK);
7411 				else if ((j == 0)
7412 				      && ((lundata->luns[i].lundata[j+2] &
7413 					  RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7414 					no_more = 1;
7415 
7416 				fprintf(stdout, "%d",
7417 					lundata->luns[i].lundata[j+1]);
7418 				break;
7419 			case RPL_LUNDATA_ATYP_FLAT: {
7420 				uint8_t tmplun[2];
7421 				tmplun[0] = lundata->luns[i].lundata[j] &
7422 					RPL_LUNDATA_FLAT_LUN_MASK;
7423 				tmplun[1] = lundata->luns[i].lundata[j+1];
7424 
7425 				fprintf(stdout, "%d", scsi_2btoul(tmplun));
7426 				no_more = 1;
7427 				break;
7428 			}
7429 			case RPL_LUNDATA_ATYP_LUN:
7430 				fprintf(stdout, "%d:%d:%d",
7431 					(lundata->luns[i].lundata[j+1] &
7432 					RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7433 					lundata->luns[i].lundata[j] &
7434 					RPL_LUNDATA_LUN_TARG_MASK,
7435 					lundata->luns[i].lundata[j+1] &
7436 					RPL_LUNDATA_LUN_LUN_MASK);
7437 				break;
7438 			case RPL_LUNDATA_ATYP_EXTLUN: {
7439 				int field_len_code, eam_code;
7440 
7441 				eam_code = lundata->luns[i].lundata[j] &
7442 					RPL_LUNDATA_EXT_EAM_MASK;
7443 				field_len_code = (lundata->luns[i].lundata[j] &
7444 					RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7445 
7446 				if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7447 				 && (field_len_code == 0x00)) {
7448 					fprintf(stdout, "%d",
7449 						lundata->luns[i].lundata[j+1]);
7450 				} else if ((eam_code ==
7451 					    RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7452 					&& (field_len_code == 0x03)) {
7453 					uint8_t tmp_lun[8];
7454 
7455 					/*
7456 					 * This format takes up all 8 bytes.
7457 					 * If we aren't starting at offset 0,
7458 					 * that's a bug.
7459 					 */
7460 					if (j != 0) {
7461 						fprintf(stdout, "Invalid "
7462 							"offset %d for "
7463 							"Extended LUN not "
7464 							"specified format", j);
7465 						no_more = 1;
7466 						break;
7467 					}
7468 					bzero(tmp_lun, sizeof(tmp_lun));
7469 					bcopy(&lundata->luns[i].lundata[j+1],
7470 					      &tmp_lun[1], sizeof(tmp_lun) - 1);
7471 					fprintf(stdout, "%#jx",
7472 					       (intmax_t)scsi_8btou64(tmp_lun));
7473 					no_more = 1;
7474 				} else {
7475 					fprintf(stderr, "Unknown Extended LUN"
7476 						"Address method %#x, length "
7477 						"code %#x", eam_code,
7478 						field_len_code);
7479 					no_more = 1;
7480 				}
7481 				break;
7482 			}
7483 			default:
7484 				fprintf(stderr, "Unknown LUN address method "
7485 					"%#x\n", lundata->luns[i].lundata[0] &
7486 					RPL_LUNDATA_ATYP_MASK);
7487 				break;
7488 			}
7489 			/*
7490 			 * For the flat addressing method, there are no
7491 			 * other levels after it.
7492 			 */
7493 			if (no_more != 0)
7494 				break;
7495 		}
7496 		fprintf(stdout, "\n");
7497 	}
7498 
7499 bailout:
7500 
7501 	cam_freeccb(ccb);
7502 
7503 	free(lundata);
7504 
7505 	return (retval);
7506 }
7507 
7508 static int
7509 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7510 		 char *combinedopt, int task_attr, int retry_count, int timeout)
7511 {
7512 	union ccb *ccb;
7513 	int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7514 	struct scsi_read_capacity_data rcap;
7515 	struct scsi_read_capacity_data_long rcaplong;
7516 	uint64_t maxsector;
7517 	uint32_t block_len;
7518 	int retval;
7519 	int c;
7520 
7521 	blocksizeonly = 0;
7522 	humanize = 0;
7523 	longonly = 0;
7524 	numblocks = 0;
7525 	quiet = 0;
7526 	sizeonly = 0;
7527 	baseten = 0;
7528 	retval = 0;
7529 
7530 	ccb = cam_getccb(device);
7531 
7532 	if (ccb == NULL) {
7533 		warnx("%s: error allocating ccb", __func__);
7534 		return (1);
7535 	}
7536 
7537 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
7538 		switch (c) {
7539 		case 'b':
7540 			blocksizeonly++;
7541 			break;
7542 		case 'h':
7543 			humanize++;
7544 			baseten = 0;
7545 			break;
7546 		case 'H':
7547 			humanize++;
7548 			baseten++;
7549 			break;
7550 		case 'l':
7551 			longonly++;
7552 			break;
7553 		case 'N':
7554 			numblocks++;
7555 			break;
7556 		case 'q':
7557 			quiet++;
7558 			break;
7559 		case 's':
7560 			sizeonly++;
7561 			break;
7562 		default:
7563 			break;
7564 		}
7565 	}
7566 
7567 	if ((blocksizeonly != 0)
7568 	 && (numblocks != 0)) {
7569 		warnx("%s: you can only specify one of -b or -N", __func__);
7570 		retval = 1;
7571 		goto bailout;
7572 	}
7573 
7574 	if ((blocksizeonly != 0)
7575 	 && (sizeonly != 0)) {
7576 		warnx("%s: you can only specify one of -b or -s", __func__);
7577 		retval = 1;
7578 		goto bailout;
7579 	}
7580 
7581 	if ((humanize != 0)
7582 	 && (quiet != 0)) {
7583 		warnx("%s: you can only specify one of -h/-H or -q", __func__);
7584 		retval = 1;
7585 		goto bailout;
7586 	}
7587 
7588 	if ((humanize != 0)
7589 	 && (blocksizeonly != 0)) {
7590 		warnx("%s: you can only specify one of -h/-H or -b", __func__);
7591 		retval = 1;
7592 		goto bailout;
7593 	}
7594 
7595 	if (longonly != 0)
7596 		goto long_only;
7597 
7598 	scsi_read_capacity(&ccb->csio,
7599 			   /*retries*/ retry_count,
7600 			   /*cbfcnp*/ NULL,
7601 			   /*tag_action*/ task_attr,
7602 			   &rcap,
7603 			   SSD_FULL_SIZE,
7604 			   /*timeout*/ timeout ? timeout : 5000);
7605 
7606 	/* Disable freezing the device queue */
7607 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7608 
7609 	if (arglist & CAM_ARG_ERR_RECOVER)
7610 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7611 
7612 	if (cam_send_ccb(device, ccb) < 0) {
7613 		warn("error sending READ CAPACITY command");
7614 		retval = 1;
7615 		goto bailout;
7616 	}
7617 
7618 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7619 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7620 		retval = 1;
7621 		goto bailout;
7622 	}
7623 
7624 	maxsector = scsi_4btoul(rcap.addr);
7625 	block_len = scsi_4btoul(rcap.length);
7626 
7627 	/*
7628 	 * A last block of 2^32-1 means that the true capacity is over 2TB,
7629 	 * and we need to issue the long READ CAPACITY to get the real
7630 	 * capacity.  Otherwise, we're all set.
7631 	 */
7632 	if (maxsector != 0xffffffff)
7633 		goto do_print;
7634 
7635 long_only:
7636 	scsi_read_capacity_16(&ccb->csio,
7637 			      /*retries*/ retry_count,
7638 			      /*cbfcnp*/ NULL,
7639 			      /*tag_action*/ task_attr,
7640 			      /*lba*/ 0,
7641 			      /*reladdr*/ 0,
7642 			      /*pmi*/ 0,
7643 			      /*rcap_buf*/ (uint8_t *)&rcaplong,
7644 			      /*rcap_buf_len*/ sizeof(rcaplong),
7645 			      /*sense_len*/ SSD_FULL_SIZE,
7646 			      /*timeout*/ timeout ? timeout : 5000);
7647 
7648 	/* Disable freezing the device queue */
7649 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7650 
7651 	if (arglist & CAM_ARG_ERR_RECOVER)
7652 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7653 
7654 	if (cam_send_ccb(device, ccb) < 0) {
7655 		warn("error sending READ CAPACITY (16) command");
7656 		retval = 1;
7657 		goto bailout;
7658 	}
7659 
7660 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7661 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7662 		retval = 1;
7663 		goto bailout;
7664 	}
7665 
7666 	maxsector = scsi_8btou64(rcaplong.addr);
7667 	block_len = scsi_4btoul(rcaplong.length);
7668 
7669 do_print:
7670 	if (blocksizeonly == 0) {
7671 		/*
7672 		 * Humanize implies !quiet, and also implies numblocks.
7673 		 */
7674 		if (humanize != 0) {
7675 			char tmpstr[6];
7676 			int64_t tmpbytes;
7677 			int ret;
7678 
7679 			tmpbytes = (maxsector + 1) * block_len;
7680 			ret = humanize_number(tmpstr, sizeof(tmpstr),
7681 					      tmpbytes, "", HN_AUTOSCALE,
7682 					      HN_B | HN_DECIMAL |
7683 					      ((baseten != 0) ?
7684 					      HN_DIVISOR_1000 : 0));
7685 			if (ret == -1) {
7686 				warnx("%s: humanize_number failed!", __func__);
7687 				retval = 1;
7688 				goto bailout;
7689 			}
7690 			fprintf(stdout, "Device Size: %s%s", tmpstr,
7691 				(sizeonly == 0) ?  ", " : "\n");
7692 		} else if (numblocks != 0) {
7693 			fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7694 				"Blocks: " : "", (uintmax_t)maxsector + 1,
7695 				(sizeonly == 0) ? ", " : "\n");
7696 		} else {
7697 			fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7698 				"Last Block: " : "", (uintmax_t)maxsector,
7699 				(sizeonly == 0) ? ", " : "\n");
7700 		}
7701 	}
7702 	if (sizeonly == 0)
7703 		fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7704 			"Block Length: " : "", block_len, (quiet == 0) ?
7705 			" bytes" : "");
7706 bailout:
7707 	cam_freeccb(ccb);
7708 
7709 	return (retval);
7710 }
7711 
7712 static int
7713 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7714        int retry_count, int timeout)
7715 {
7716 	int c, error = 0;
7717 	union ccb *ccb;
7718 	uint8_t *smp_request = NULL, *smp_response = NULL;
7719 	int request_size = 0, response_size = 0;
7720 	int fd_request = 0, fd_response = 0;
7721 	char *datastr = NULL;
7722 	struct get_hook hook;
7723 	int retval;
7724 	int flags = 0;
7725 
7726 	/*
7727 	 * Note that at the moment we don't support sending SMP CCBs to
7728 	 * devices that aren't probed by CAM.
7729 	 */
7730 	ccb = cam_getccb(device);
7731 	if (ccb == NULL) {
7732 		warnx("%s: error allocating CCB", __func__);
7733 		return (1);
7734 	}
7735 
7736 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
7737 		switch (c) {
7738 		case 'R':
7739 			arglist |= CAM_ARG_CMD_IN;
7740 			response_size = strtol(optarg, NULL, 0);
7741 			if (response_size <= 0) {
7742 				warnx("invalid number of response bytes %d",
7743 				      response_size);
7744 				error = 1;
7745 				goto smpcmd_bailout;
7746 			}
7747 			hook.argc = argc - optind;
7748 			hook.argv = argv + optind;
7749 			hook.got = 0;
7750 			optind++;
7751 			datastr = cget(&hook, NULL);
7752 			/*
7753 			 * If the user supplied "-" instead of a format, he
7754 			 * wants the data to be written to stdout.
7755 			 */
7756 			if ((datastr != NULL)
7757 			 && (datastr[0] == '-'))
7758 				fd_response = 1;
7759 
7760 			smp_response = (uint8_t *)malloc(response_size);
7761 			if (smp_response == NULL) {
7762 				warn("can't malloc memory for SMP response");
7763 				error = 1;
7764 				goto smpcmd_bailout;
7765 			}
7766 			break;
7767 		case 'r':
7768 			arglist |= CAM_ARG_CMD_OUT;
7769 			request_size = strtol(optarg, NULL, 0);
7770 			if (request_size <= 0) {
7771 				warnx("invalid number of request bytes %d",
7772 				      request_size);
7773 				error = 1;
7774 				goto smpcmd_bailout;
7775 			}
7776 			hook.argc = argc - optind;
7777 			hook.argv = argv + optind;
7778 			hook.got = 0;
7779 			datastr = cget(&hook, NULL);
7780 			smp_request = (uint8_t *)malloc(request_size);
7781 			if (smp_request == NULL) {
7782 				warn("can't malloc memory for SMP request");
7783 				error = 1;
7784 				goto smpcmd_bailout;
7785 			}
7786 			bzero(smp_request, request_size);
7787 			/*
7788 			 * If the user supplied "-" instead of a format, he
7789 			 * wants the data to be read from stdin.
7790 			 */
7791 			if ((datastr != NULL)
7792 			 && (datastr[0] == '-'))
7793 				fd_request = 1;
7794 			else
7795 				buff_encode_visit(smp_request, request_size,
7796 						  datastr,
7797 						  iget, &hook);
7798 			optind += hook.got;
7799 			break;
7800 		default:
7801 			break;
7802 		}
7803 	}
7804 
7805 	/*
7806 	 * If fd_data is set, and we're writing to the device, we need to
7807 	 * read the data the user wants written from stdin.
7808 	 */
7809 	if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7810 		ssize_t amt_read;
7811 		int amt_to_read = request_size;
7812 		uint8_t *buf_ptr = smp_request;
7813 
7814 		for (amt_read = 0; amt_to_read > 0;
7815 		     amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7816 			if (amt_read == -1) {
7817 				warn("error reading data from stdin");
7818 				error = 1;
7819 				goto smpcmd_bailout;
7820 			}
7821 			amt_to_read -= amt_read;
7822 			buf_ptr += amt_read;
7823 		}
7824 	}
7825 
7826 	if (((arglist & CAM_ARG_CMD_IN) == 0)
7827 	 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7828 		warnx("%s: need both the request (-r) and response (-R) "
7829 		      "arguments", __func__);
7830 		error = 1;
7831 		goto smpcmd_bailout;
7832 	}
7833 
7834 	flags |= CAM_DEV_QFRZDIS;
7835 
7836 	cam_fill_smpio(&ccb->smpio,
7837 		       /*retries*/ retry_count,
7838 		       /*cbfcnp*/ NULL,
7839 		       /*flags*/ flags,
7840 		       /*smp_request*/ smp_request,
7841 		       /*smp_request_len*/ request_size,
7842 		       /*smp_response*/ smp_response,
7843 		       /*smp_response_len*/ response_size,
7844 		       /*timeout*/ timeout ? timeout : 5000);
7845 
7846 	ccb->smpio.flags = SMP_FLAG_NONE;
7847 
7848 	if (((retval = cam_send_ccb(device, ccb)) < 0)
7849 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7850 		const char warnstr[] = "error sending command";
7851 
7852 		if (retval < 0)
7853 			warn(warnstr);
7854 		else
7855 			warnx(warnstr);
7856 
7857 		if (arglist & CAM_ARG_VERBOSE) {
7858 			cam_error_print(device, ccb, CAM_ESF_ALL,
7859 					CAM_EPF_ALL, stderr);
7860 		}
7861 	}
7862 
7863 	if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7864 	 && (response_size > 0)) {
7865 		if (fd_response == 0) {
7866 			buff_decode_visit(smp_response, response_size,
7867 					  datastr, arg_put, NULL);
7868 			fprintf(stdout, "\n");
7869 		} else {
7870 			ssize_t amt_written;
7871 			int amt_to_write = response_size;
7872 			uint8_t *buf_ptr = smp_response;
7873 
7874 			for (amt_written = 0; (amt_to_write > 0) &&
7875 			     (amt_written = write(STDOUT_FILENO, buf_ptr,
7876 						  amt_to_write)) > 0;){
7877 				amt_to_write -= amt_written;
7878 				buf_ptr += amt_written;
7879 			}
7880 			if (amt_written == -1) {
7881 				warn("error writing data to stdout");
7882 				error = 1;
7883 				goto smpcmd_bailout;
7884 			} else if ((amt_written == 0)
7885 				&& (amt_to_write > 0)) {
7886 				warnx("only wrote %u bytes out of %u",
7887 				      response_size - amt_to_write,
7888 				      response_size);
7889 			}
7890 		}
7891 	}
7892 smpcmd_bailout:
7893 	if (ccb != NULL)
7894 		cam_freeccb(ccb);
7895 
7896 	if (smp_request != NULL)
7897 		free(smp_request);
7898 
7899 	if (smp_response != NULL)
7900 		free(smp_response);
7901 
7902 	return (error);
7903 }
7904 
7905 static int
7906 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7907        int retry_count, int timeout)
7908 {
7909 	int c, error = 0;
7910 	union ccb *ccb;
7911 	int32_t mmc_opcode = 0, mmc_arg = 0;
7912 	int32_t mmc_flags = -1;
7913 	int retval;
7914 	int is_write = 0;
7915 	int is_bw_4 = 0, is_bw_1 = 0;
7916 	int is_frequency = 0;
7917 	int is_highspeed = 0, is_stdspeed = 0;
7918 	int is_info_request = 0;
7919 	int flags = 0;
7920 	uint8_t mmc_data_byte = 0;
7921 	uint32_t mmc_frequency = 0;
7922 
7923 	/* For IO_RW_EXTENDED command */
7924 	uint8_t *mmc_data = NULL;
7925 	struct mmc_data mmc_d;
7926 	int mmc_data_len = 0;
7927 
7928 	/*
7929 	 * Note that at the moment we don't support sending SMP CCBs to
7930 	 * devices that aren't probed by CAM.
7931 	 */
7932 	ccb = cam_getccb(device);
7933 	if (ccb == NULL) {
7934 		warnx("%s: error allocating CCB", __func__);
7935 		return (1);
7936 	}
7937 
7938 	bzero(&(&ccb->ccb_h)[1],
7939 	      sizeof(union ccb) - sizeof(struct ccb_hdr));
7940 
7941 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
7942 		switch (c) {
7943 		case '4':
7944 			is_bw_4 = 1;
7945 			break;
7946 		case '1':
7947 			is_bw_1 = 1;
7948 			break;
7949 		case 'S':
7950 			if (!strcmp(optarg, "high"))
7951 				is_highspeed = 1;
7952 			else
7953 				is_stdspeed = 1;
7954 			break;
7955 		case 'I':
7956 			is_info_request = 1;
7957 			break;
7958 		case 'F':
7959 			is_frequency = 1;
7960 			mmc_frequency = strtol(optarg, NULL, 0);
7961 			break;
7962 		case 'c':
7963 			mmc_opcode = strtol(optarg, NULL, 0);
7964 			if (mmc_opcode < 0) {
7965 				warnx("invalid MMC opcode %d",
7966 				      mmc_opcode);
7967 				error = 1;
7968 				goto mmccmd_bailout;
7969 			}
7970 			break;
7971 		case 'a':
7972 			mmc_arg = strtol(optarg, NULL, 0);
7973 			if (mmc_arg < 0) {
7974 				warnx("invalid MMC arg %d",
7975 				      mmc_arg);
7976 				error = 1;
7977 				goto mmccmd_bailout;
7978 			}
7979 			break;
7980 		case 'f':
7981 			mmc_flags = strtol(optarg, NULL, 0);
7982 			if (mmc_flags < 0) {
7983 				warnx("invalid MMC flags %d",
7984 				      mmc_flags);
7985 				error = 1;
7986 				goto mmccmd_bailout;
7987 			}
7988 			break;
7989 		case 'l':
7990 			mmc_data_len = strtol(optarg, NULL, 0);
7991 			if (mmc_data_len <= 0) {
7992 				warnx("invalid MMC data len %d",
7993 				      mmc_data_len);
7994 				error = 1;
7995 				goto mmccmd_bailout;
7996 			}
7997 			break;
7998 		case 'W':
7999 			is_write = 1;
8000 			break;
8001 		case 'b':
8002 			mmc_data_byte = strtol(optarg, NULL, 0);
8003 			break;
8004 		default:
8005 			break;
8006 		}
8007 	}
8008 	flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
8009 
8010 	/* If flags are left default, supply the right flags */
8011 	if (mmc_flags < 0)
8012 		switch (mmc_opcode) {
8013 		case MMC_GO_IDLE_STATE:
8014 			mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
8015 			break;
8016 		case IO_SEND_OP_COND:
8017 			mmc_flags = MMC_RSP_R4;
8018 			break;
8019 		case SD_SEND_RELATIVE_ADDR:
8020 			mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
8021 			break;
8022 		case MMC_SELECT_CARD:
8023 			mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
8024 			mmc_arg = mmc_arg << 16;
8025 			break;
8026 		case SD_IO_RW_DIRECT:
8027 			mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
8028 			mmc_arg = SD_IO_RW_ADR(mmc_arg);
8029 			if (is_write)
8030 				mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
8031 			break;
8032 		case SD_IO_RW_EXTENDED:
8033 			mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
8034 			mmc_arg = SD_IO_RW_ADR(mmc_arg);
8035 			int len_arg = mmc_data_len;
8036 			if (mmc_data_len == 512)
8037 				len_arg = 0;
8038 
8039 			// Byte mode
8040 			mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
8041 			// Block mode
8042 //                        mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
8043 			break;
8044 		default:
8045 			mmc_flags = MMC_RSP_R1;
8046 			break;
8047 		}
8048 
8049 	// Switch bus width instead of sending IO command
8050 	if (is_bw_4 || is_bw_1) {
8051 		struct ccb_trans_settings_mmc *cts;
8052 		ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8053 		ccb->ccb_h.flags = 0;
8054 		cts = &ccb->cts.proto_specific.mmc;
8055 		cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
8056 		cts->ios_valid = MMC_BW;
8057 		if (((retval = cam_send_ccb(device, ccb)) < 0)
8058 		    || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8059 			warn("Error sending command");
8060 		} else {
8061 			printf("Parameters set OK\n");
8062 		}
8063 		cam_freeccb(ccb);
8064 		return (retval);
8065 	}
8066 
8067 	if (is_frequency) {
8068 		struct ccb_trans_settings_mmc *cts;
8069 		ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8070 		ccb->ccb_h.flags = 0;
8071 		cts = &ccb->cts.proto_specific.mmc;
8072 		cts->ios.clock = mmc_frequency;
8073 		cts->ios_valid = MMC_CLK;
8074 		if (((retval = cam_send_ccb(device, ccb)) < 0)
8075 		    || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8076 			warn("Error sending command");
8077 		} else {
8078 			printf("Parameters set OK\n");
8079 		}
8080 		cam_freeccb(ccb);
8081 		return (retval);
8082 	}
8083 
8084 	// Switch bus speed instead of sending IO command
8085 	if (is_stdspeed || is_highspeed) {
8086 		struct ccb_trans_settings_mmc *cts;
8087 		ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8088 		ccb->ccb_h.flags = 0;
8089 		cts = &ccb->cts.proto_specific.mmc;
8090 		cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
8091 		cts->ios_valid = MMC_BT;
8092 		if (((retval = cam_send_ccb(device, ccb)) < 0)
8093 		    || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8094 			warn("Error sending command");
8095 		} else {
8096 			printf("Speed set OK (HS: %d)\n", is_highspeed);
8097 		}
8098 		cam_freeccb(ccb);
8099 		return (retval);
8100 	}
8101 
8102 	// Get information about controller and its settings
8103 	if (is_info_request) {
8104 		ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8105 		ccb->ccb_h.flags = 0;
8106 		struct ccb_trans_settings_mmc *cts;
8107 		cts = &ccb->cts.proto_specific.mmc;
8108 		if (((retval = cam_send_ccb(device, ccb)) < 0)
8109 		    || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8110 			warn("Error sending command");
8111 			return (retval);
8112 		}
8113 		printf("Host controller information\n");
8114 		printf("Host OCR: 0x%x\n", cts->host_ocr);
8115 		printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8116 		printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8117 		printf("Supported bus width:\n");
8118 		if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8119 			printf(" 4 bit\n");
8120 		if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8121 			printf(" 8 bit\n");
8122 
8123 		printf("Supported operating modes:\n");
8124 		if (cts->host_caps & MMC_CAP_HSPEED)
8125 			printf(" Can do High Speed transfers\n");
8126 		if (cts->host_caps & MMC_CAP_UHS_SDR12)
8127 			printf(" Can do UHS SDR12\n");
8128 		if (cts->host_caps & MMC_CAP_UHS_SDR25)
8129 			printf(" Can do UHS SDR25\n");
8130 		if (cts->host_caps & MMC_CAP_UHS_SDR50)
8131 			printf(" Can do UHS SDR50\n");
8132 		if (cts->host_caps & MMC_CAP_UHS_SDR104)
8133 			printf(" Can do UHS SDR104\n");
8134 		if (cts->host_caps & MMC_CAP_UHS_DDR50)
8135 			printf(" Can do UHS DDR50\n");
8136 		if (cts->host_caps & MMC_CAP_MMC_DDR52_120)
8137 			printf(" Can do eMMC DDR52 at 1.2V\n");
8138 		if (cts->host_caps & MMC_CAP_MMC_DDR52_180)
8139 			printf(" Can do eMMC DDR52 at 1.8V\n");
8140 		if (cts->host_caps & MMC_CAP_MMC_HS200_120)
8141 			printf(" Can do eMMC HS200 at 1.2V\n");
8142 		if (cts->host_caps & MMC_CAP_MMC_HS200_180)
8143 			printf(" Can do eMMC HS200 at 1.8V\n");
8144 		if (cts->host_caps & MMC_CAP_MMC_HS400_120)
8145 			printf(" Can do eMMC HS400 at 1.2V\n");
8146 		if (cts->host_caps & MMC_CAP_MMC_HS400_180)
8147 			printf(" Can do eMMC HS400 at 1.8V\n");
8148 
8149 		printf("Supported VCCQ voltages:\n");
8150 		if (cts->host_caps & MMC_CAP_SIGNALING_120)
8151 			printf(" 1.2V\n");
8152 		if (cts->host_caps & MMC_CAP_SIGNALING_180)
8153 			printf(" 1.8V\n");
8154 		if (cts->host_caps & MMC_CAP_SIGNALING_330)
8155 			printf(" 3.3V\n");
8156 
8157 		printf("Current settings:\n");
8158 		printf(" Bus width: ");
8159 		switch (cts->ios.bus_width) {
8160 		case bus_width_1:
8161 			printf("1 bit\n");
8162 			break;
8163 		case bus_width_4:
8164 			printf("4 bit\n");
8165 			break;
8166 		case bus_width_8:
8167 			printf("8 bit\n");
8168 			break;
8169 		}
8170 		printf(" Freq: %d.%03d MHz%s\n",
8171 		       cts->ios.clock / 1000000,
8172 		       (cts->ios.clock / 1000) % 1000,
8173 		       cts->ios.timing == bus_timing_hs ? " (high-speed timing)" : "");
8174 
8175 		printf(" VCCQ: ");
8176 		switch (cts->ios.vccq) {
8177 		case vccq_330:
8178 			printf("3.3V\n");
8179 			break;
8180 		case vccq_180:
8181 			printf("1.8V\n");
8182 			break;
8183 		case vccq_120:
8184 			printf("1.2V\n");
8185 			break;
8186 		}
8187 		return (0);
8188 	}
8189 
8190 	printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8191 
8192 	if (mmc_data_len > 0) {
8193 		flags |= CAM_DIR_IN;
8194 		mmc_data = malloc(mmc_data_len);
8195 		memset(mmc_data, 0, mmc_data_len);
8196 		memset(&mmc_d, 0, sizeof(mmc_d));
8197 		mmc_d.len = mmc_data_len;
8198 		mmc_d.data = mmc_data;
8199 		mmc_d.flags = MMC_DATA_READ;
8200 	} else flags |= CAM_DIR_NONE;
8201 
8202 	cam_fill_mmcio(&ccb->mmcio,
8203 		       /*retries*/ retry_count,
8204 		       /*cbfcnp*/ NULL,
8205 		       /*flags*/ flags,
8206 		       /*mmc_opcode*/ mmc_opcode,
8207 		       /*mmc_arg*/ mmc_arg,
8208 		       /*mmc_flags*/ mmc_flags,
8209 		       /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8210 		       /*timeout*/ timeout ? timeout : 5000);
8211 
8212 	if (((retval = cam_send_ccb(device, ccb)) < 0)
8213 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8214 		const char warnstr[] = "error sending command";
8215 
8216 		if (retval < 0)
8217 			warn(warnstr);
8218 		else
8219 			warnx(warnstr);
8220 
8221 		if (arglist & CAM_ARG_VERBOSE) {
8222 			cam_error_print(device, ccb, CAM_ESF_ALL,
8223 					CAM_EPF_ALL, stderr);
8224 		}
8225 	}
8226 
8227 	if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8228 		printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8229 		       ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8230 		       ccb->mmcio.cmd.resp[1],
8231 		       ccb->mmcio.cmd.resp[2],
8232 		       ccb->mmcio.cmd.resp[3]);
8233 
8234 		switch (mmc_opcode) {
8235 		case SD_IO_RW_DIRECT:
8236 			printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8237 			       SD_R5_DATA(ccb->mmcio.cmd.resp),
8238 			       (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8239 			break;
8240 		case SD_IO_RW_EXTENDED:
8241 			printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8242 			hexdump(mmc_data, mmc_data_len, NULL, 0);
8243 			break;
8244 		case SD_SEND_RELATIVE_ADDR:
8245 			printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8246 			break;
8247 		default:
8248 			printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8249 			if (mmc_data_len > 0)
8250 				hexdump(mmc_data, mmc_data_len, NULL, 0);
8251 		}
8252 	}
8253 mmccmd_bailout:
8254 	if (ccb != NULL)
8255 		cam_freeccb(ccb);
8256 
8257 	if (mmc_data_len > 0 && mmc_data != NULL)
8258 		free(mmc_data);
8259 
8260 	return (error);
8261 }
8262 
8263 static int
8264 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8265 		 char *combinedopt, int retry_count, int timeout)
8266 {
8267 	union ccb *ccb;
8268 	struct smp_report_general_request *request = NULL;
8269 	struct smp_report_general_response *response = NULL;
8270 	struct sbuf *sb = NULL;
8271 	int error = 0;
8272 	int c, long_response = 0;
8273 	int retval;
8274 
8275 	/*
8276 	 * Note that at the moment we don't support sending SMP CCBs to
8277 	 * devices that aren't probed by CAM.
8278 	 */
8279 	ccb = cam_getccb(device);
8280 	if (ccb == NULL) {
8281 		warnx("%s: error allocating CCB", __func__);
8282 		return (1);
8283 	}
8284 
8285 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
8286 		switch (c) {
8287 		case 'l':
8288 			long_response = 1;
8289 			break;
8290 		default:
8291 			break;
8292 		}
8293 	}
8294 	request = malloc(sizeof(*request));
8295 	if (request == NULL) {
8296 		warn("%s: unable to allocate %zd bytes", __func__,
8297 		     sizeof(*request));
8298 		error = 1;
8299 		goto bailout;
8300 	}
8301 
8302 	response = malloc(sizeof(*response));
8303 	if (response == NULL) {
8304 		warn("%s: unable to allocate %zd bytes", __func__,
8305 		     sizeof(*response));
8306 		error = 1;
8307 		goto bailout;
8308 	}
8309 
8310 try_long:
8311 	smp_report_general(&ccb->smpio,
8312 			   retry_count,
8313 			   /*cbfcnp*/ NULL,
8314 			   request,
8315 			   /*request_len*/ sizeof(*request),
8316 			   (uint8_t *)response,
8317 			   /*response_len*/ sizeof(*response),
8318 			   /*long_response*/ long_response,
8319 			   timeout);
8320 
8321 	if (((retval = cam_send_ccb(device, ccb)) < 0)
8322 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8323 		const char warnstr[] = "error sending command";
8324 
8325 		if (retval < 0)
8326 			warn(warnstr);
8327 		else
8328 			warnx(warnstr);
8329 
8330 		if (arglist & CAM_ARG_VERBOSE) {
8331 			cam_error_print(device, ccb, CAM_ESF_ALL,
8332 					CAM_EPF_ALL, stderr);
8333 		}
8334 		error = 1;
8335 		goto bailout;
8336 	}
8337 
8338 	/*
8339 	 * If the device supports the long response bit, try again and see
8340 	 * if we can get all of the data.
8341 	 */
8342 	if ((response->long_response & SMP_RG_LONG_RESPONSE)
8343 	 && (long_response == 0)) {
8344 		ccb->ccb_h.status = CAM_REQ_INPROG;
8345 		CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8346 		long_response = 1;
8347 		goto try_long;
8348 	}
8349 
8350 	/*
8351 	 * XXX KDM detect and decode SMP errors here.
8352 	 */
8353 	sb = sbuf_new_auto();
8354 	if (sb == NULL) {
8355 		warnx("%s: error allocating sbuf", __func__);
8356 		goto bailout;
8357 	}
8358 
8359 	smp_report_general_sbuf(response, sizeof(*response), sb);
8360 
8361 	if (sbuf_finish(sb) != 0) {
8362 		warnx("%s: sbuf_finish", __func__);
8363 		goto bailout;
8364 	}
8365 
8366 	printf("%s", sbuf_data(sb));
8367 
8368 bailout:
8369 	if (ccb != NULL)
8370 		cam_freeccb(ccb);
8371 
8372 	if (request != NULL)
8373 		free(request);
8374 
8375 	if (response != NULL)
8376 		free(response);
8377 
8378 	if (sb != NULL)
8379 		sbuf_delete(sb);
8380 
8381 	return (error);
8382 }
8383 
8384 static struct camcontrol_opts phy_ops[] = {
8385 	{"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8386 	{"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8387 	{"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8388 	{"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8389 	{"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8390 	{"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8391 	{"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8392 	{"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8393 	{"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8394 	{NULL, 0, 0, NULL}
8395 };
8396 
8397 static int
8398 smpphycontrol(struct cam_device *device, int argc, char **argv,
8399 	      char *combinedopt, int retry_count, int timeout)
8400 {
8401 	union ccb *ccb;
8402 	struct smp_phy_control_request *request = NULL;
8403 	struct smp_phy_control_response *response = NULL;
8404 	int long_response = 0;
8405 	int retval = 0;
8406 	int phy = -1;
8407 	uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8408 	int phy_op_set = 0;
8409 	uint64_t attached_dev_name = 0;
8410 	int dev_name_set = 0;
8411 	uint32_t min_plr = 0, max_plr = 0;
8412 	uint32_t pp_timeout_val = 0;
8413 	int slumber_partial = 0;
8414 	int set_pp_timeout_val = 0;
8415 	int c;
8416 
8417 	/*
8418 	 * Note that at the moment we don't support sending SMP CCBs to
8419 	 * devices that aren't probed by CAM.
8420 	 */
8421 	ccb = cam_getccb(device);
8422 	if (ccb == NULL) {
8423 		warnx("%s: error allocating CCB", __func__);
8424 		return (1);
8425 	}
8426 
8427 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
8428 		switch (c) {
8429 		case 'a':
8430 		case 'A':
8431 		case 's':
8432 		case 'S': {
8433 			int enable = -1;
8434 
8435 			if (strcasecmp(optarg, "enable") == 0)
8436 				enable = 1;
8437 			else if (strcasecmp(optarg, "disable") == 0)
8438 				enable = 2;
8439 			else {
8440 				warnx("%s: Invalid argument %s", __func__,
8441 				      optarg);
8442 				retval = 1;
8443 				goto bailout;
8444 			}
8445 			switch (c) {
8446 			case 's':
8447 				slumber_partial |= enable <<
8448 						   SMP_PC_SAS_SLUMBER_SHIFT;
8449 				break;
8450 			case 'S':
8451 				slumber_partial |= enable <<
8452 						   SMP_PC_SAS_PARTIAL_SHIFT;
8453 				break;
8454 			case 'a':
8455 				slumber_partial |= enable <<
8456 						   SMP_PC_SATA_SLUMBER_SHIFT;
8457 				break;
8458 			case 'A':
8459 				slumber_partial |= enable <<
8460 						   SMP_PC_SATA_PARTIAL_SHIFT;
8461 				break;
8462 			default:
8463 				warnx("%s: programmer error", __func__);
8464 				retval = 1;
8465 				goto bailout;
8466 				break; /*NOTREACHED*/
8467 			}
8468 			break;
8469 		}
8470 		case 'd':
8471 			attached_dev_name = (uintmax_t)strtoumax(optarg,
8472 								 NULL,0);
8473 			dev_name_set = 1;
8474 			break;
8475 		case 'l':
8476 			long_response = 1;
8477 			break;
8478 		case 'm':
8479 			/*
8480 			 * We don't do extensive checking here, so this
8481 			 * will continue to work when new speeds come out.
8482 			 */
8483 			min_plr = strtoul(optarg, NULL, 0);
8484 			if ((min_plr == 0)
8485 			 || (min_plr > 0xf)) {
8486 				warnx("%s: invalid link rate %x",
8487 				      __func__, min_plr);
8488 				retval = 1;
8489 				goto bailout;
8490 			}
8491 			break;
8492 		case 'M':
8493 			/*
8494 			 * We don't do extensive checking here, so this
8495 			 * will continue to work when new speeds come out.
8496 			 */
8497 			max_plr = strtoul(optarg, NULL, 0);
8498 			if ((max_plr == 0)
8499 			 || (max_plr > 0xf)) {
8500 				warnx("%s: invalid link rate %x",
8501 				      __func__, max_plr);
8502 				retval = 1;
8503 				goto bailout;
8504 			}
8505 			break;
8506 		case 'o': {
8507 			camcontrol_optret optreturn;
8508 			cam_argmask argnums;
8509 			const char *subopt;
8510 
8511 			if (phy_op_set != 0) {
8512 				warnx("%s: only one phy operation argument "
8513 				      "(-o) allowed", __func__);
8514 				retval = 1;
8515 				goto bailout;
8516 			}
8517 
8518 			phy_op_set = 1;
8519 
8520 			/*
8521 			 * Allow the user to specify the phy operation
8522 			 * numerically, as well as with a name.  This will
8523 			 * future-proof it a bit, so options that are added
8524 			 * in future specs can be used.
8525 			 */
8526 			if (isdigit(optarg[0])) {
8527 				phy_operation = strtoul(optarg, NULL, 0);
8528 				if ((phy_operation == 0)
8529 				 || (phy_operation > 0xff)) {
8530 					warnx("%s: invalid phy operation %#x",
8531 					      __func__, phy_operation);
8532 					retval = 1;
8533 					goto bailout;
8534 				}
8535 				break;
8536 			}
8537 			optreturn = getoption(phy_ops, optarg, &phy_operation,
8538 					      &argnums, &subopt);
8539 
8540 			if (optreturn == CC_OR_AMBIGUOUS) {
8541 				warnx("%s: ambiguous option %s", __func__,
8542 				      optarg);
8543 				usage(0);
8544 				retval = 1;
8545 				goto bailout;
8546 			} else if (optreturn == CC_OR_NOT_FOUND) {
8547 				warnx("%s: option %s not found", __func__,
8548 				      optarg);
8549 				usage(0);
8550 				retval = 1;
8551 				goto bailout;
8552 			}
8553 			break;
8554 		}
8555 		case 'p':
8556 			phy = atoi(optarg);
8557 			break;
8558 		case 'T':
8559 			pp_timeout_val = strtoul(optarg, NULL, 0);
8560 			if (pp_timeout_val > 15) {
8561 				warnx("%s: invalid partial pathway timeout "
8562 				      "value %u, need a value less than 16",
8563 				      __func__, pp_timeout_val);
8564 				retval = 1;
8565 				goto bailout;
8566 			}
8567 			set_pp_timeout_val = 1;
8568 			break;
8569 		default:
8570 			break;
8571 		}
8572 	}
8573 
8574 	if (phy == -1) {
8575 		warnx("%s: a PHY (-p phy) argument is required",__func__);
8576 		retval = 1;
8577 		goto bailout;
8578 	}
8579 
8580 	if (((dev_name_set != 0)
8581 	  && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8582 	 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8583 	  && (dev_name_set == 0))) {
8584 		warnx("%s: -d name and -o setdevname arguments both "
8585 		      "required to set device name", __func__);
8586 		retval = 1;
8587 		goto bailout;
8588 	}
8589 
8590 	request = malloc(sizeof(*request));
8591 	if (request == NULL) {
8592 		warn("%s: unable to allocate %zd bytes", __func__,
8593 		     sizeof(*request));
8594 		retval = 1;
8595 		goto bailout;
8596 	}
8597 
8598 	response = malloc(sizeof(*response));
8599 	if (response == NULL) {
8600 		warn("%s: unable to allocate %zd bytes", __func__,
8601 		     sizeof(*response));
8602 		retval = 1;
8603 		goto bailout;
8604 	}
8605 
8606 	smp_phy_control(&ccb->smpio,
8607 			retry_count,
8608 			/*cbfcnp*/ NULL,
8609 			request,
8610 			sizeof(*request),
8611 			(uint8_t *)response,
8612 			sizeof(*response),
8613 			long_response,
8614 			/*expected_exp_change_count*/ 0,
8615 			phy,
8616 			phy_operation,
8617 			(set_pp_timeout_val != 0) ? 1 : 0,
8618 			attached_dev_name,
8619 			min_plr,
8620 			max_plr,
8621 			slumber_partial,
8622 			pp_timeout_val,
8623 			timeout);
8624 
8625 	if (((retval = cam_send_ccb(device, ccb)) < 0)
8626 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8627 		const char warnstr[] = "error sending command";
8628 
8629 		if (retval < 0)
8630 			warn(warnstr);
8631 		else
8632 			warnx(warnstr);
8633 
8634 		if (arglist & CAM_ARG_VERBOSE) {
8635 			/*
8636 			 * Use CAM_EPF_NORMAL so we only get one line of
8637 			 * SMP command decoding.
8638 			 */
8639 			cam_error_print(device, ccb, CAM_ESF_ALL,
8640 					CAM_EPF_NORMAL, stderr);
8641 		}
8642 		retval = 1;
8643 		goto bailout;
8644 	}
8645 
8646 	/* XXX KDM print out something here for success? */
8647 bailout:
8648 	if (ccb != NULL)
8649 		cam_freeccb(ccb);
8650 
8651 	if (request != NULL)
8652 		free(request);
8653 
8654 	if (response != NULL)
8655 		free(response);
8656 
8657 	return (retval);
8658 }
8659 
8660 static int
8661 smpmaninfo(struct cam_device *device, int argc, char **argv,
8662 	   char *combinedopt, int retry_count, int timeout)
8663 {
8664 	union ccb *ccb;
8665 	struct smp_report_manuf_info_request request;
8666 	struct smp_report_manuf_info_response response;
8667 	struct sbuf *sb = NULL;
8668 	int long_response = 0;
8669 	int retval = 0;
8670 	int c;
8671 
8672 	/*
8673 	 * Note that at the moment we don't support sending SMP CCBs to
8674 	 * devices that aren't probed by CAM.
8675 	 */
8676 	ccb = cam_getccb(device);
8677 	if (ccb == NULL) {
8678 		warnx("%s: error allocating CCB", __func__);
8679 		return (1);
8680 	}
8681 
8682 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
8683 		switch (c) {
8684 		case 'l':
8685 			long_response = 1;
8686 			break;
8687 		default:
8688 			break;
8689 		}
8690 	}
8691 	bzero(&request, sizeof(request));
8692 	bzero(&response, sizeof(response));
8693 
8694 	smp_report_manuf_info(&ccb->smpio,
8695 			      retry_count,
8696 			      /*cbfcnp*/ NULL,
8697 			      &request,
8698 			      sizeof(request),
8699 			      (uint8_t *)&response,
8700 			      sizeof(response),
8701 			      long_response,
8702 			      timeout);
8703 
8704 	if (((retval = cam_send_ccb(device, ccb)) < 0)
8705 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8706 		const char warnstr[] = "error sending command";
8707 
8708 		if (retval < 0)
8709 			warn(warnstr);
8710 		else
8711 			warnx(warnstr);
8712 
8713 		if (arglist & CAM_ARG_VERBOSE) {
8714 			cam_error_print(device, ccb, CAM_ESF_ALL,
8715 					CAM_EPF_ALL, stderr);
8716 		}
8717 		retval = 1;
8718 		goto bailout;
8719 	}
8720 
8721 	sb = sbuf_new_auto();
8722 	if (sb == NULL) {
8723 		warnx("%s: error allocating sbuf", __func__);
8724 		goto bailout;
8725 	}
8726 
8727 	smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8728 
8729 	if (sbuf_finish(sb) != 0) {
8730 		warnx("%s: sbuf_finish", __func__);
8731 		goto bailout;
8732 	}
8733 
8734 	printf("%s", sbuf_data(sb));
8735 
8736 bailout:
8737 
8738 	if (ccb != NULL)
8739 		cam_freeccb(ccb);
8740 
8741 	if (sb != NULL)
8742 		sbuf_delete(sb);
8743 
8744 	return (retval);
8745 }
8746 
8747 static int
8748 getdevid(struct cam_devitem *item)
8749 {
8750 	int retval = 0;
8751 	union ccb *ccb = NULL;
8752 
8753 	struct cam_device *dev;
8754 
8755 	dev = cam_open_btl(item->dev_match.path_id,
8756 			   item->dev_match.target_id,
8757 			   item->dev_match.target_lun, O_RDWR, NULL);
8758 
8759 	if (dev == NULL) {
8760 		warnx("%s", cam_errbuf);
8761 		retval = 1;
8762 		goto bailout;
8763 	}
8764 
8765 	item->device_id_len = 0;
8766 
8767 	ccb = cam_getccb(dev);
8768 	if (ccb == NULL) {
8769 		warnx("%s: error allocating CCB", __func__);
8770 		retval = 1;
8771 		goto bailout;
8772 	}
8773 
8774 	/*
8775 	 * On the first try, we just probe for the size of the data, and
8776 	 * then allocate that much memory and try again.
8777 	 */
8778 retry:
8779 	ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8780 	ccb->ccb_h.flags = CAM_DIR_IN;
8781 	ccb->cdai.flags = CDAI_FLAG_NONE;
8782 	ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8783 	ccb->cdai.bufsiz = item->device_id_len;
8784 	if (item->device_id_len != 0)
8785 		ccb->cdai.buf = (uint8_t *)item->device_id;
8786 
8787 	if (cam_send_ccb(dev, ccb) < 0) {
8788 		warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8789 		retval = 1;
8790 		goto bailout;
8791 	}
8792 
8793 	if (ccb->ccb_h.status != CAM_REQ_CMP) {
8794 		warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8795 		retval = 1;
8796 		goto bailout;
8797 	}
8798 
8799 	if (item->device_id_len == 0) {
8800 		/*
8801 		 * This is our first time through.  Allocate the buffer,
8802 		 * and then go back to get the data.
8803 		 */
8804 		if (ccb->cdai.provsiz == 0) {
8805 			warnx("%s: invalid .provsiz field returned with "
8806 			     "XPT_GDEV_ADVINFO CCB", __func__);
8807 			retval = 1;
8808 			goto bailout;
8809 		}
8810 		item->device_id_len = ccb->cdai.provsiz;
8811 		item->device_id = malloc(item->device_id_len);
8812 		if (item->device_id == NULL) {
8813 			warn("%s: unable to allocate %d bytes", __func__,
8814 			     item->device_id_len);
8815 			retval = 1;
8816 			goto bailout;
8817 		}
8818 		ccb->ccb_h.status = CAM_REQ_INPROG;
8819 		goto retry;
8820 	}
8821 
8822 bailout:
8823 	if (dev != NULL)
8824 		cam_close_device(dev);
8825 
8826 	if (ccb != NULL)
8827 		cam_freeccb(ccb);
8828 
8829 	return (retval);
8830 }
8831 
8832 /*
8833  * XXX KDM merge this code with getdevtree()?
8834  */
8835 static int
8836 buildbusdevlist(struct cam_devlist *devlist)
8837 {
8838 	union ccb ccb;
8839 	int bufsize, fd = -1;
8840 	struct dev_match_pattern *patterns;
8841 	struct cam_devitem *item = NULL;
8842 	int skip_device = 0;
8843 	int retval = 0;
8844 
8845 	if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8846 		warn("couldn't open %s", XPT_DEVICE);
8847 		return (1);
8848 	}
8849 
8850 	bzero(&ccb, sizeof(union ccb));
8851 
8852 	ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8853 	ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8854 	ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8855 
8856 	ccb.ccb_h.func_code = XPT_DEV_MATCH;
8857 	bufsize = sizeof(struct dev_match_result) * 100;
8858 	ccb.cdm.match_buf_len = bufsize;
8859 	ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8860 	if (ccb.cdm.matches == NULL) {
8861 		warnx("can't malloc memory for matches");
8862 		close(fd);
8863 		return (1);
8864 	}
8865 	ccb.cdm.num_matches = 0;
8866 	ccb.cdm.num_patterns = 2;
8867 	ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8868 		ccb.cdm.num_patterns;
8869 
8870 	patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8871 	if (patterns == NULL) {
8872 		warnx("can't malloc memory for patterns");
8873 		retval = 1;
8874 		goto bailout;
8875 	}
8876 
8877 	ccb.cdm.patterns = patterns;
8878 	bzero(patterns, ccb.cdm.pattern_buf_len);
8879 
8880 	patterns[0].type = DEV_MATCH_DEVICE;
8881 	patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8882 	patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8883 	patterns[1].type = DEV_MATCH_PERIPH;
8884 	patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8885 	patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8886 
8887 	/*
8888 	 * We do the ioctl multiple times if necessary, in case there are
8889 	 * more than 100 nodes in the EDT.
8890 	 */
8891 	do {
8892 		unsigned int i;
8893 
8894 		if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8895 			warn("error sending CAMIOCOMMAND ioctl");
8896 			retval = 1;
8897 			goto bailout;
8898 		}
8899 
8900 		if ((ccb.ccb_h.status != CAM_REQ_CMP)
8901 		 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8902 		    && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8903 			warnx("got CAM error %#x, CDM error %d\n",
8904 			      ccb.ccb_h.status, ccb.cdm.status);
8905 			retval = 1;
8906 			goto bailout;
8907 		}
8908 
8909 		for (i = 0; i < ccb.cdm.num_matches; i++) {
8910 			switch (ccb.cdm.matches[i].type) {
8911 			case DEV_MATCH_DEVICE: {
8912 				struct device_match_result *dev_result;
8913 
8914 				dev_result =
8915 				     &ccb.cdm.matches[i].result.device_result;
8916 
8917 				if (dev_result->flags &
8918 				    DEV_RESULT_UNCONFIGURED) {
8919 					skip_device = 1;
8920 					break;
8921 				} else
8922 					skip_device = 0;
8923 
8924 				item = malloc(sizeof(*item));
8925 				if (item == NULL) {
8926 					warn("%s: unable to allocate %zd bytes",
8927 					     __func__, sizeof(*item));
8928 					retval = 1;
8929 					goto bailout;
8930 				}
8931 				bzero(item, sizeof(*item));
8932 				bcopy(dev_result, &item->dev_match,
8933 				      sizeof(*dev_result));
8934 				STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8935 						   links);
8936 
8937 				if (getdevid(item) != 0) {
8938 					retval = 1;
8939 					goto bailout;
8940 				}
8941 				break;
8942 			}
8943 			case DEV_MATCH_PERIPH: {
8944 				struct periph_match_result *periph_result;
8945 
8946 				periph_result =
8947 				      &ccb.cdm.matches[i].result.periph_result;
8948 
8949 				if (skip_device != 0)
8950 					break;
8951 				item->num_periphs++;
8952 				item->periph_matches = realloc(
8953 					item->periph_matches,
8954 					item->num_periphs *
8955 					sizeof(struct periph_match_result));
8956 				if (item->periph_matches == NULL) {
8957 					warn("%s: error allocating periph "
8958 					     "list", __func__);
8959 					retval = 1;
8960 					goto bailout;
8961 				}
8962 				bcopy(periph_result, &item->periph_matches[
8963 				      item->num_periphs - 1],
8964 				      sizeof(*periph_result));
8965 				break;
8966 			}
8967 			default:
8968 				fprintf(stderr, "%s: unexpected match "
8969 					"type %d\n", __func__,
8970 					ccb.cdm.matches[i].type);
8971 				retval = 1;
8972 				goto bailout;
8973 				break; /*NOTREACHED*/
8974 			}
8975 		}
8976 	} while ((ccb.ccb_h.status == CAM_REQ_CMP)
8977 		&& (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8978 bailout:
8979 
8980 	if (fd != -1)
8981 		close(fd);
8982 
8983 	free(patterns);
8984 
8985 	free(ccb.cdm.matches);
8986 
8987 	if (retval != 0)
8988 		freebusdevlist(devlist);
8989 
8990 	return (retval);
8991 }
8992 
8993 static void
8994 freebusdevlist(struct cam_devlist *devlist)
8995 {
8996 	struct cam_devitem *item, *item2;
8997 
8998 	STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8999 		STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
9000 			      links);
9001 		free(item->device_id);
9002 		free(item->periph_matches);
9003 		free(item);
9004 	}
9005 }
9006 
9007 static struct cam_devitem *
9008 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
9009 {
9010 	struct cam_devitem *item;
9011 
9012 	STAILQ_FOREACH(item, &devlist->dev_queue, links) {
9013 		struct scsi_vpd_id_descriptor *idd;
9014 
9015 		/*
9016 		 * XXX KDM look for LUN IDs as well?
9017 		 */
9018 		idd = scsi_get_devid(item->device_id,
9019 					   item->device_id_len,
9020 					   scsi_devid_is_sas_target);
9021 		if (idd == NULL)
9022 			continue;
9023 
9024 		if (scsi_8btou64(idd->identifier) == sasaddr)
9025 			return (item);
9026 	}
9027 
9028 	return (NULL);
9029 }
9030 
9031 static int
9032 smpphylist(struct cam_device *device, int argc, char **argv,
9033 	   char *combinedopt, int retry_count, int timeout)
9034 {
9035 	struct smp_report_general_request *rgrequest = NULL;
9036 	struct smp_report_general_response *rgresponse = NULL;
9037 	struct smp_discover_request *disrequest = NULL;
9038 	struct smp_discover_response *disresponse = NULL;
9039 	struct cam_devlist devlist;
9040 	union ccb *ccb;
9041 	int long_response = 0;
9042 	int num_phys = 0;
9043 	int quiet = 0;
9044 	int retval;
9045 	int i, c;
9046 
9047 	/*
9048 	 * Note that at the moment we don't support sending SMP CCBs to
9049 	 * devices that aren't probed by CAM.
9050 	 */
9051 	ccb = cam_getccb(device);
9052 	if (ccb == NULL) {
9053 		warnx("%s: error allocating CCB", __func__);
9054 		return (1);
9055 	}
9056 
9057 	STAILQ_INIT(&devlist.dev_queue);
9058 
9059 	rgrequest = malloc(sizeof(*rgrequest));
9060 	if (rgrequest == NULL) {
9061 		warn("%s: unable to allocate %zd bytes", __func__,
9062 		     sizeof(*rgrequest));
9063 		retval = 1;
9064 		goto bailout;
9065 	}
9066 
9067 	rgresponse = malloc(sizeof(*rgresponse));
9068 	if (rgresponse == NULL) {
9069 		warn("%s: unable to allocate %zd bytes", __func__,
9070 		     sizeof(*rgresponse));
9071 		retval = 1;
9072 		goto bailout;
9073 	}
9074 
9075 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
9076 		switch (c) {
9077 		case 'l':
9078 			long_response = 1;
9079 			break;
9080 		case 'q':
9081 			quiet = 1;
9082 			break;
9083 		default:
9084 			break;
9085 		}
9086 	}
9087 
9088 	smp_report_general(&ccb->smpio,
9089 			   retry_count,
9090 			   /*cbfcnp*/ NULL,
9091 			   rgrequest,
9092 			   /*request_len*/ sizeof(*rgrequest),
9093 			   (uint8_t *)rgresponse,
9094 			   /*response_len*/ sizeof(*rgresponse),
9095 			   /*long_response*/ long_response,
9096 			   timeout);
9097 
9098 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9099 
9100 	if (((retval = cam_send_ccb(device, ccb)) < 0)
9101 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
9102 		const char warnstr[] = "error sending command";
9103 
9104 		if (retval < 0)
9105 			warn(warnstr);
9106 		else
9107 			warnx(warnstr);
9108 
9109 		if (arglist & CAM_ARG_VERBOSE) {
9110 			cam_error_print(device, ccb, CAM_ESF_ALL,
9111 					CAM_EPF_ALL, stderr);
9112 		}
9113 		retval = 1;
9114 		goto bailout;
9115 	}
9116 
9117 	num_phys = rgresponse->num_phys;
9118 
9119 	if (num_phys == 0) {
9120 		if (quiet == 0)
9121 			fprintf(stdout, "%s: No Phys reported\n", __func__);
9122 		retval = 1;
9123 		goto bailout;
9124 	}
9125 
9126 	devlist.path_id = device->path_id;
9127 
9128 	retval = buildbusdevlist(&devlist);
9129 	if (retval != 0)
9130 		goto bailout;
9131 
9132 	if (quiet == 0) {
9133 		fprintf(stdout, "%d PHYs:\n", num_phys);
9134 		fprintf(stdout, "PHY  Attached SAS Address\n");
9135 	}
9136 
9137 	disrequest = malloc(sizeof(*disrequest));
9138 	if (disrequest == NULL) {
9139 		warn("%s: unable to allocate %zd bytes", __func__,
9140 		     sizeof(*disrequest));
9141 		retval = 1;
9142 		goto bailout;
9143 	}
9144 
9145 	disresponse = malloc(sizeof(*disresponse));
9146 	if (disresponse == NULL) {
9147 		warn("%s: unable to allocate %zd bytes", __func__,
9148 		     sizeof(*disresponse));
9149 		retval = 1;
9150 		goto bailout;
9151 	}
9152 
9153 	for (i = 0; i < num_phys; i++) {
9154 		struct cam_devitem *item;
9155 		struct device_match_result *dev_match;
9156 		char vendor[16], product[48], revision[16];
9157 		char tmpstr[256];
9158 		int j;
9159 
9160 		CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9161 
9162 		ccb->ccb_h.status = CAM_REQ_INPROG;
9163 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9164 
9165 		smp_discover(&ccb->smpio,
9166 			     retry_count,
9167 			     /*cbfcnp*/ NULL,
9168 			     disrequest,
9169 			     sizeof(*disrequest),
9170 			     (uint8_t *)disresponse,
9171 			     sizeof(*disresponse),
9172 			     long_response,
9173 			     /*ignore_zone_group*/ 0,
9174 			     /*phy*/ i,
9175 			     timeout);
9176 
9177 		if (((retval = cam_send_ccb(device, ccb)) < 0)
9178 		 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9179 		  && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9180 			const char warnstr[] = "error sending command";
9181 
9182 			if (retval < 0)
9183 				warn(warnstr);
9184 			else
9185 				warnx(warnstr);
9186 
9187 			if (arglist & CAM_ARG_VERBOSE) {
9188 				cam_error_print(device, ccb, CAM_ESF_ALL,
9189 						CAM_EPF_ALL, stderr);
9190 			}
9191 			retval = 1;
9192 			goto bailout;
9193 		}
9194 
9195 		if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9196 			if (quiet == 0)
9197 				fprintf(stdout, "%3d  <vacant>\n", i);
9198 			continue;
9199 		}
9200 
9201 		if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9202 			item = NULL;
9203 		} else {
9204 			item = findsasdevice(&devlist,
9205 			    scsi_8btou64(disresponse->attached_sas_address));
9206 		}
9207 
9208 		if ((quiet == 0)
9209 		 || (item != NULL)) {
9210 			fprintf(stdout, "%3d  0x%016jx", i,
9211 				(uintmax_t)scsi_8btou64(
9212 				disresponse->attached_sas_address));
9213 			if (item == NULL) {
9214 				fprintf(stdout, "\n");
9215 				continue;
9216 			}
9217 		} else if (quiet != 0)
9218 			continue;
9219 
9220 		dev_match = &item->dev_match;
9221 
9222 		if (dev_match->protocol == PROTO_SCSI) {
9223 			cam_strvis(vendor, dev_match->inq_data.vendor,
9224 				   sizeof(dev_match->inq_data.vendor),
9225 				   sizeof(vendor));
9226 			cam_strvis(product, dev_match->inq_data.product,
9227 				   sizeof(dev_match->inq_data.product),
9228 				   sizeof(product));
9229 			cam_strvis(revision, dev_match->inq_data.revision,
9230 				   sizeof(dev_match->inq_data.revision),
9231 				   sizeof(revision));
9232 			sprintf(tmpstr, "<%s %s %s>", vendor, product,
9233 				revision);
9234 		} else if ((dev_match->protocol == PROTO_ATA)
9235 			|| (dev_match->protocol == PROTO_SATAPM)) {
9236 			cam_strvis(product, dev_match->ident_data.model,
9237 				   sizeof(dev_match->ident_data.model),
9238 				   sizeof(product));
9239 			cam_strvis(revision, dev_match->ident_data.revision,
9240 				   sizeof(dev_match->ident_data.revision),
9241 				   sizeof(revision));
9242 			sprintf(tmpstr, "<%s %s>", product, revision);
9243 		} else {
9244 			sprintf(tmpstr, "<>");
9245 		}
9246 		fprintf(stdout, "   %-33s ", tmpstr);
9247 
9248 		/*
9249 		 * If we have 0 periphs, that's a bug...
9250 		 */
9251 		if (item->num_periphs == 0) {
9252 			fprintf(stdout, "\n");
9253 			continue;
9254 		}
9255 
9256 		fprintf(stdout, "(");
9257 		for (j = 0; j < item->num_periphs; j++) {
9258 			if (j > 0)
9259 				fprintf(stdout, ",");
9260 
9261 			fprintf(stdout, "%s%d",
9262 				item->periph_matches[j].periph_name,
9263 				item->periph_matches[j].unit_number);
9264 
9265 		}
9266 		fprintf(stdout, ")\n");
9267 	}
9268 bailout:
9269 	if (ccb != NULL)
9270 		cam_freeccb(ccb);
9271 
9272 	free(rgrequest);
9273 
9274 	free(rgresponse);
9275 
9276 	free(disrequest);
9277 
9278 	free(disresponse);
9279 
9280 	freebusdevlist(&devlist);
9281 
9282 	return (retval);
9283 }
9284 
9285 static int
9286 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9287 {
9288 	uint8_t error = 0, ata_device = 0, status = 0;
9289 	uint16_t count = 0;
9290 	uint64_t lba = 0;
9291 	int retval;
9292 
9293 	retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9294 	    &status);
9295 	if (retval == 1) {
9296 		if (arglist & CAM_ARG_VERBOSE) {
9297 			cam_error_print(device, ccb, CAM_ESF_ALL,
9298 					CAM_EPF_ALL, stderr);
9299 		}
9300 		warnx("Can't get ATA command status");
9301 		return (retval);
9302 	}
9303 
9304 	if (status & ATA_STATUS_ERROR) {
9305 		cam_error_print(device, ccb, CAM_ESF_ALL,
9306 		    CAM_EPF_ALL, stderr);
9307 	        return (1);
9308 	}
9309 
9310 	printf("%s%d: ", device->device_name, device->dev_unit_num);
9311 	switch (count) {
9312 	case ATA_PM_STANDBY:
9313 		printf("Standby mode\n");
9314 		break;
9315 	case ATA_PM_STANDBY_Y:
9316 		printf("Standby_y mode\n");
9317 		break;
9318 	case 0x40:	/* obsolete since ACS-3 */
9319 		printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9320 		break;
9321 	case 0x41:	/* obsolete since ACS-3 */
9322 		printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9323 		break;
9324 	case ATA_PM_IDLE:
9325 		printf("Idle mode\n");
9326 		break;
9327 	case ATA_PM_IDLE_A:
9328 		printf("Idle_a mode\n");
9329 		break;
9330 	case ATA_PM_IDLE_B:
9331 		printf("Idle_b mode\n");
9332 		break;
9333 	case ATA_PM_IDLE_C:
9334 		printf("Idle_c mode\n");
9335 		break;
9336 	case ATA_PM_ACTIVE_IDLE:
9337 		printf("Active or Idle mode\n");
9338 		break;
9339 	default:
9340 		printf("Unknown mode 0x%02x\n", count);
9341 		break;
9342 	}
9343 
9344 	return (0);
9345 }
9346 
9347 static int
9348 atapm(struct cam_device *device, int argc, char **argv,
9349 		 char *combinedopt, int retry_count, int timeout)
9350 {
9351 	union ccb *ccb;
9352 	int retval = 0;
9353 	int t = -1;
9354 	int c;
9355 	uint8_t ata_flags = 0;
9356 	u_char cmd, sc;
9357 
9358 	ccb = cam_getccb(device);
9359 
9360 	if (ccb == NULL) {
9361 		warnx("%s: error allocating ccb", __func__);
9362 		return (1);
9363 	}
9364 
9365 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
9366 		switch (c) {
9367 		case 't':
9368 			t = atoi(optarg);
9369 			break;
9370 		default:
9371 			break;
9372 		}
9373 	}
9374 	if (strcmp(argv[1], "idle") == 0) {
9375 		if (t == -1)
9376 			cmd = ATA_IDLE_IMMEDIATE;
9377 		else
9378 			cmd = ATA_IDLE_CMD;
9379 	} else if (strcmp(argv[1], "standby") == 0) {
9380 		if (t == -1)
9381 			cmd = ATA_STANDBY_IMMEDIATE;
9382 		else
9383 			cmd = ATA_STANDBY_CMD;
9384 	} else if (strcmp(argv[1], "powermode") == 0) {
9385 		cmd = ATA_CHECK_POWER_MODE;
9386 		ata_flags = AP_FLAG_CHK_COND;
9387 		t = -1;
9388 	} else {
9389 		cmd = ATA_SLEEP;
9390 		t = -1;
9391 	}
9392 
9393 	if (t < 0)
9394 		sc = 0;
9395 	else if (t <= (240 * 5))
9396 		sc = (t + 4) / 5;
9397 	else if (t <= (252 * 5))
9398 		/* special encoding for 21 minutes */
9399 		sc = 252;
9400 	else if (t <= (11 * 30 * 60))
9401 		sc = (t - 1) / (30 * 60) + 241;
9402 	else
9403 		sc = 253;
9404 
9405 	retval = ata_do_cmd(device,
9406 	    ccb,
9407 	    /*retries*/retry_count,
9408 	    /*flags*/CAM_DIR_NONE,
9409 	    /*protocol*/AP_PROTO_NON_DATA,
9410 	    /*ata_flags*/ata_flags,
9411 	    /*tag_action*/MSG_SIMPLE_Q_TAG,
9412 	    /*command*/cmd,
9413 	    /*features*/0,
9414 	    /*lba*/0,
9415 	    /*sector_count*/sc,
9416 	    /*data_ptr*/NULL,
9417 	    /*dxfer_len*/0,
9418 	    /*timeout*/timeout ? timeout : 30 * 1000,
9419 	    /*force48bit*/0);
9420 
9421 	if (retval == 0 && cmd == ATA_CHECK_POWER_MODE)
9422 		retval = atapm_proc_resp(device, ccb);
9423 
9424 	cam_freeccb(ccb);
9425 	return (retval);
9426 }
9427 
9428 static int
9429 ataaxm(struct cam_device *device, int argc, char **argv,
9430 		 char *combinedopt, int retry_count, int timeout)
9431 {
9432 	union ccb *ccb;
9433 	int retval = 0;
9434 	int l = -1;
9435 	int c;
9436 	u_char cmd, sc;
9437 
9438 	ccb = cam_getccb(device);
9439 
9440 	if (ccb == NULL) {
9441 		warnx("%s: error allocating ccb", __func__);
9442 		return (1);
9443 	}
9444 
9445 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
9446 		switch (c) {
9447 		case 'l':
9448 			l = atoi(optarg);
9449 			break;
9450 		default:
9451 			break;
9452 		}
9453 	}
9454 	sc = 0;
9455 	if (strcmp(argv[1], "apm") == 0) {
9456 		if (l == -1)
9457 			cmd = 0x85;
9458 		else {
9459 			cmd = 0x05;
9460 			sc = l;
9461 		}
9462 	} else /* aam */ {
9463 		if (l == -1)
9464 			cmd = 0xC2;
9465 		else {
9466 			cmd = 0x42;
9467 			sc = l;
9468 		}
9469 	}
9470 
9471 	retval = ata_do_cmd(device,
9472 	    ccb,
9473 	    /*retries*/retry_count,
9474 	    /*flags*/CAM_DIR_NONE,
9475 	    /*protocol*/AP_PROTO_NON_DATA,
9476 	    /*ata_flags*/0,
9477 	    /*tag_action*/MSG_SIMPLE_Q_TAG,
9478 	    /*command*/ATA_SETFEATURES,
9479 	    /*features*/cmd,
9480 	    /*lba*/0,
9481 	    /*sector_count*/sc,
9482 	    /*data_ptr*/NULL,
9483 	    /*dxfer_len*/0,
9484 	    /*timeout*/timeout ? timeout : 30 * 1000,
9485 	    /*force48bit*/0);
9486 
9487 	cam_freeccb(ccb);
9488 	return (retval);
9489 }
9490 
9491 int
9492 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9493 	       int show_sa_errors, int sa_set, int service_action,
9494 	       int timeout_desc, int task_attr, int retry_count, int timeout,
9495 	       int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9496 {
9497 	union ccb *ccb = NULL;
9498 	uint8_t *buf = NULL;
9499 	uint32_t alloc_len = 0, num_opcodes;
9500 	uint32_t valid_len = 0;
9501 	uint32_t avail_len = 0;
9502 	struct scsi_report_supported_opcodes_all *all_hdr;
9503 	struct scsi_report_supported_opcodes_one *one;
9504 	int options = 0;
9505 	int retval = 0;
9506 
9507 	/*
9508 	 * Make it clear that we haven't yet allocated or filled anything.
9509 	 */
9510 	*fill_len = 0;
9511 	*data_ptr = NULL;
9512 
9513 	ccb = cam_getccb(device);
9514 	if (ccb == NULL) {
9515 		warnx("couldn't allocate CCB");
9516 		retval = 1;
9517 		goto bailout;
9518 	}
9519 
9520 	if (opcode_set != 0) {
9521 		options |= RSO_OPTIONS_OC;
9522 		num_opcodes = 1;
9523 		alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9524 	} else {
9525 		num_opcodes = 256;
9526 		alloc_len = sizeof(*all_hdr) + (num_opcodes *
9527 		    sizeof(struct scsi_report_supported_opcodes_descr));
9528 	}
9529 
9530 	if (timeout_desc != 0) {
9531 		options |= RSO_RCTD;
9532 		alloc_len += num_opcodes *
9533 		    sizeof(struct scsi_report_supported_opcodes_timeout);
9534 	}
9535 
9536 	if (sa_set != 0) {
9537 		options |= RSO_OPTIONS_OC_SA;
9538 		if (show_sa_errors != 0)
9539 			options &= ~RSO_OPTIONS_OC;
9540 	}
9541 
9542 retry_alloc:
9543 	if (buf != NULL) {
9544 		free(buf);
9545 		buf = NULL;
9546 	}
9547 
9548 	buf = malloc(alloc_len);
9549 	if (buf == NULL) {
9550 		warn("Unable to allocate %u bytes", alloc_len);
9551 		retval = 1;
9552 		goto bailout;
9553 	}
9554 	bzero(buf, alloc_len);
9555 
9556 	scsi_report_supported_opcodes(&ccb->csio,
9557 				      /*retries*/ retry_count,
9558 				      /*cbfcnp*/ NULL,
9559 				      /*tag_action*/ task_attr,
9560 				      /*options*/ options,
9561 				      /*req_opcode*/ opcode,
9562 				      /*req_service_action*/ service_action,
9563 				      /*data_ptr*/ buf,
9564 				      /*dxfer_len*/ alloc_len,
9565 				      /*sense_len*/ SSD_FULL_SIZE,
9566 				      /*timeout*/ timeout ? timeout : 10000);
9567 
9568 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9569 
9570 	if (retry_count != 0)
9571 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9572 
9573 	if (cam_send_ccb(device, ccb) < 0) {
9574 		warn("error sending REPORT SUPPORTED OPERATION CODES command");
9575 		retval = 1;
9576 		goto bailout;
9577 	}
9578 
9579 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9580 		if (verbosemode != 0)
9581 			cam_error_print(device, ccb, CAM_ESF_ALL,
9582 					CAM_EPF_ALL, stderr);
9583 		retval = 1;
9584 		goto bailout;
9585 	}
9586 
9587 	valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9588 
9589 	if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9590 	 && (valid_len >= sizeof(*all_hdr))) {
9591 		all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9592 		avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9593 	} else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9594 		&& (valid_len >= sizeof(*one))) {
9595 		uint32_t cdb_length;
9596 
9597 		one = (struct scsi_report_supported_opcodes_one *)buf;
9598 		cdb_length = scsi_2btoul(one->cdb_length);
9599 		avail_len = sizeof(*one) + cdb_length;
9600 		if (one->support & RSO_ONE_CTDP) {
9601 			struct scsi_report_supported_opcodes_timeout *td;
9602 
9603 			td = (struct scsi_report_supported_opcodes_timeout *)
9604 			    &buf[avail_len];
9605 			if (valid_len >= (avail_len + sizeof(td->length))) {
9606 				avail_len += scsi_2btoul(td->length) +
9607 				    sizeof(td->length);
9608 			} else {
9609 				avail_len += sizeof(*td);
9610 			}
9611 		}
9612 	}
9613 
9614 	/*
9615 	 * avail_len could be zero if we didn't get enough data back from
9616 	 * thet target to determine
9617 	 */
9618 	if ((avail_len != 0)
9619 	 && (avail_len > valid_len)) {
9620 		alloc_len = avail_len;
9621 		goto retry_alloc;
9622 	}
9623 
9624 	*fill_len = valid_len;
9625 	*data_ptr = buf;
9626 bailout:
9627 	if (retval != 0)
9628 		free(buf);
9629 
9630 	cam_freeccb(ccb);
9631 
9632 	return (retval);
9633 }
9634 
9635 static int
9636 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9637 		   int req_sa, uint8_t *buf, uint32_t valid_len)
9638 {
9639 	struct scsi_report_supported_opcodes_one *one;
9640 	struct scsi_report_supported_opcodes_timeout *td;
9641 	uint32_t cdb_len = 0, td_len = 0;
9642 	const char *op_desc = NULL;
9643 	unsigned int i;
9644 	int retval = 0;
9645 
9646 	one = (struct scsi_report_supported_opcodes_one *)buf;
9647 
9648 	/*
9649 	 * If we don't have the full single opcode descriptor, no point in
9650 	 * continuing.
9651 	 */
9652 	if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9653 	    cdb_length)) {
9654 		warnx("Only %u bytes returned, not enough to verify support",
9655 		      valid_len);
9656 		retval = 1;
9657 		goto bailout;
9658 	}
9659 
9660 	op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9661 
9662 	printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9663 	       req_opcode);
9664 	if (sa_set != 0)
9665 		printf(", SA 0x%x", req_sa);
9666 	printf(": ");
9667 
9668 	switch (one->support & RSO_ONE_SUP_MASK) {
9669 	case RSO_ONE_SUP_UNAVAIL:
9670 		printf("No command support information currently available\n");
9671 		break;
9672 	case RSO_ONE_SUP_NOT_SUP:
9673 		printf("Command not supported\n");
9674 		retval = 1;
9675 		goto bailout;
9676 		break; /*NOTREACHED*/
9677 	case RSO_ONE_SUP_AVAIL:
9678 		printf("Command is supported, complies with a SCSI standard\n");
9679 		break;
9680 	case RSO_ONE_SUP_VENDOR:
9681 		printf("Command is supported, vendor-specific "
9682 		       "implementation\n");
9683 		break;
9684 	default:
9685 		printf("Unknown command support flags 0x%#x\n",
9686 		       one->support & RSO_ONE_SUP_MASK);
9687 		break;
9688 	}
9689 
9690 	/*
9691 	 * If we don't have the CDB length, it isn't exactly an error, the
9692 	 * command probably isn't supported.
9693 	 */
9694 	if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9695 	    cdb_usage))
9696 		goto bailout;
9697 
9698 	cdb_len = scsi_2btoul(one->cdb_length);
9699 
9700 	/*
9701 	 * If our valid data doesn't include the full reported length,
9702 	 * return.  The caller should have detected this and adjusted his
9703 	 * allocation length to get all of the available data.
9704 	 */
9705 	if (valid_len < sizeof(*one) + cdb_len) {
9706 		retval = 1;
9707 		goto bailout;
9708 	}
9709 
9710 	/*
9711 	 * If all we have is the opcode, there is no point in printing out
9712 	 * the usage bitmap.
9713 	 */
9714 	if (cdb_len <= 1) {
9715 		retval = 1;
9716 		goto bailout;
9717 	}
9718 
9719 	printf("CDB usage bitmap:");
9720 	for (i = 0; i < cdb_len; i++) {
9721 		printf(" %02x", one->cdb_usage[i]);
9722 	}
9723 	printf("\n");
9724 
9725 	/*
9726 	 * If we don't have a timeout descriptor, we're done.
9727 	 */
9728 	if ((one->support & RSO_ONE_CTDP) == 0)
9729 		goto bailout;
9730 
9731 	/*
9732 	 * If we don't have enough valid length to include the timeout
9733 	 * descriptor length, we're done.
9734 	 */
9735 	if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9736 		goto bailout;
9737 
9738 	td = (struct scsi_report_supported_opcodes_timeout *)
9739 	    &buf[sizeof(*one) + cdb_len];
9740 	td_len = scsi_2btoul(td->length);
9741 	td_len += sizeof(td->length);
9742 
9743 	/*
9744 	 * If we don't have the full timeout descriptor, we're done.
9745 	 */
9746 	if (td_len < sizeof(*td))
9747 		goto bailout;
9748 
9749 	/*
9750 	 * If we don't have enough valid length to contain the full timeout
9751 	 * descriptor, we're done.
9752 	 */
9753 	if (valid_len < (sizeof(*one) + cdb_len + td_len))
9754 		goto bailout;
9755 
9756 	printf("Timeout information:\n");
9757 	printf("Command-specific:    0x%02x\n", td->cmd_specific);
9758 	printf("Nominal timeout:     %u seconds\n",
9759 	       scsi_4btoul(td->nominal_time));
9760 	printf("Recommended timeout: %u seconds\n",
9761 	       scsi_4btoul(td->recommended_time));
9762 
9763 bailout:
9764 	return (retval);
9765 }
9766 
9767 static int
9768 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9769 		 uint32_t valid_len)
9770 {
9771 	struct scsi_report_supported_opcodes_all *hdr;
9772 	struct scsi_report_supported_opcodes_descr *desc;
9773 	uint32_t avail_len = 0, used_len = 0;
9774 	uint8_t *cur_ptr;
9775 	int retval = 0;
9776 
9777 	if (valid_len < sizeof(*hdr)) {
9778 		warnx("%s: not enough returned data (%u bytes) opcode list",
9779 		      __func__, valid_len);
9780 		retval = 1;
9781 		goto bailout;
9782 	}
9783 	hdr = (struct scsi_report_supported_opcodes_all *)buf;
9784 	avail_len = scsi_4btoul(hdr->length);
9785 	avail_len += sizeof(hdr->length);
9786 	/*
9787 	 * Take the lesser of the amount of data the drive claims is
9788 	 * available, and the amount of data the HBA says was returned.
9789 	 */
9790 	avail_len = MIN(avail_len, valid_len);
9791 
9792 	used_len = sizeof(hdr->length);
9793 
9794 	printf("%-6s %4s %8s ",
9795 	       "Opcode", "SA", "CDB len" );
9796 
9797 	if (td_req != 0)
9798 		printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9799 	printf(" Description\n");
9800 
9801 	while ((avail_len - used_len) > sizeof(*desc)) {
9802 		struct scsi_report_supported_opcodes_timeout *td;
9803 		uint32_t td_len;
9804 		const char *op_desc = NULL;
9805 
9806 		cur_ptr = &buf[used_len];
9807 		desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9808 
9809 		op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9810 		if (op_desc == NULL)
9811 			op_desc = "UNKNOWN";
9812 
9813 		printf("0x%02x   %#4x %8u ", desc->opcode,
9814 		       scsi_2btoul(desc->service_action),
9815 		       scsi_2btoul(desc->cdb_length));
9816 
9817 		used_len += sizeof(*desc);
9818 
9819 		if ((desc->flags & RSO_CTDP) == 0) {
9820 			printf(" %s\n", op_desc);
9821 			continue;
9822 		}
9823 
9824 		/*
9825 		 * If we don't have enough space to fit a timeout
9826 		 * descriptor, then we're done.
9827 		 */
9828 		if (avail_len - used_len < sizeof(*td)) {
9829 			used_len = avail_len;
9830 			printf(" %s\n", op_desc);
9831 			continue;
9832 		}
9833 		cur_ptr = &buf[used_len];
9834 		td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9835 		td_len = scsi_2btoul(td->length);
9836 		td_len += sizeof(td->length);
9837 
9838 		used_len += td_len;
9839 		/*
9840 		 * If the given timeout descriptor length is less than what
9841 		 * we understand, skip it.
9842 		 */
9843 		if (td_len < sizeof(*td)) {
9844 			printf(" %s\n", op_desc);
9845 			continue;
9846 		}
9847 
9848 		printf(" 0x%02x %6u %6u  %s\n", td->cmd_specific,
9849 		       scsi_4btoul(td->nominal_time),
9850 		       scsi_4btoul(td->recommended_time), op_desc);
9851 	}
9852 bailout:
9853 	return (retval);
9854 }
9855 
9856 static int
9857 scsiopcodes(struct cam_device *device, int argc, char **argv,
9858 	    char *combinedopt, int task_attr, int retry_count, int timeout,
9859 	    int verbosemode)
9860 {
9861 	int c;
9862 	uint32_t opcode = 0, service_action = 0;
9863 	int td_set = 0, opcode_set = 0, sa_set = 0;
9864 	int show_sa_errors = 1;
9865 	uint32_t valid_len = 0;
9866 	uint8_t *buf = NULL;
9867 	char *endptr;
9868 	int retval = 0;
9869 
9870 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
9871 		switch (c) {
9872 		case 'N':
9873 			show_sa_errors = 0;
9874 			break;
9875 		case 'o':
9876 			opcode = strtoul(optarg, &endptr, 0);
9877 			if (*endptr != '\0') {
9878 				warnx("Invalid opcode \"%s\", must be a number",
9879 				      optarg);
9880 				retval = 1;
9881 				goto bailout;
9882 			}
9883 			if (opcode > 0xff) {
9884 				warnx("Invalid opcode 0x%#x, must be between"
9885 				      "0 and 0xff inclusive", opcode);
9886 				retval = 1;
9887 				goto bailout;
9888 			}
9889 			opcode_set = 1;
9890 			break;
9891 		case 's':
9892 			service_action = strtoul(optarg, &endptr, 0);
9893 			if (*endptr != '\0') {
9894 				warnx("Invalid service action \"%s\", must "
9895 				      "be a number", optarg);
9896 				retval = 1;
9897 				goto bailout;
9898 			}
9899 			if (service_action > 0xffff) {
9900 				warnx("Invalid service action 0x%#x, must "
9901 				      "be between 0 and 0xffff inclusive",
9902 				      service_action);
9903 				retval = 1;
9904 			}
9905 			sa_set = 1;
9906 			break;
9907 		case 'T':
9908 			td_set = 1;
9909 			break;
9910 		default:
9911 			break;
9912 		}
9913 	}
9914 
9915 	if ((sa_set != 0)
9916 	 && (opcode_set == 0)) {
9917 		warnx("You must specify an opcode with -o if a service "
9918 		      "action is given");
9919 		retval = 1;
9920 		goto bailout;
9921 	}
9922 	retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9923 				sa_set, service_action, td_set, task_attr,
9924 				retry_count, timeout, verbosemode, &valid_len,
9925 				&buf);
9926 	if (retval != 0)
9927 		goto bailout;
9928 
9929 	if ((opcode_set != 0)
9930 	 || (sa_set != 0)) {
9931 		retval = scsiprintoneopcode(device, opcode, sa_set,
9932 					    service_action, buf, valid_len);
9933 	} else {
9934 		retval = scsiprintopcodes(device, td_set, buf, valid_len);
9935 	}
9936 
9937 bailout:
9938 	free(buf);
9939 
9940 	return (retval);
9941 }
9942 
9943 
9944 static int
9945 reprobe(struct cam_device *device)
9946 {
9947 	union ccb *ccb;
9948 	int retval = 0;
9949 
9950 	ccb = cam_getccb(device);
9951 
9952 	if (ccb == NULL) {
9953 		warnx("%s: error allocating ccb", __func__);
9954 		return (1);
9955 	}
9956 
9957 	ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9958 
9959 	if (cam_send_ccb(device, ccb) < 0) {
9960 		warn("error sending XPT_REPROBE_LUN CCB");
9961 		retval = 1;
9962 		goto bailout;
9963 	}
9964 
9965 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9966 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9967 		retval = 1;
9968 		goto bailout;
9969 	}
9970 
9971 bailout:
9972 	cam_freeccb(ccb);
9973 
9974 	return (retval);
9975 }
9976 
9977 void
9978 usage(int printlong)
9979 {
9980 
9981 	fprintf(printlong ? stdout : stderr,
9982 "usage:  camcontrol <command>  [device id][generic args][command args]\n"
9983 "        camcontrol devlist    [-b] [-v]\n"
9984 "        camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9985 "        camcontrol tur        [dev_id][generic args]\n"
9986 "        camcontrol sense      [dev_id][generic args][-D][-x]\n"
9987 "        camcontrol inquiry    [dev_id][generic args] [-D] [-S] [-R]\n"
9988 "        camcontrol identify   [dev_id][generic args] [-v]\n"
9989 "        camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9990 "        camcontrol readcap    [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9991 "                              [-q] [-s] [-l]\n"
9992 "        camcontrol start      [dev_id][generic args]\n"
9993 "        camcontrol stop       [dev_id][generic args]\n"
9994 "        camcontrol load       [dev_id][generic args]\n"
9995 "        camcontrol eject      [dev_id][generic args]\n"
9996 "        camcontrol reprobe    [dev_id][generic args]\n"
9997 "        camcontrol rescan     <all | bus[:target:lun] | dev_id>\n"
9998 "        camcontrol reset      <all | bus[:target:lun] | dev_id>\n"
9999 "        camcontrol defects    [dev_id][generic args] <-f format> [-P][-G]\n"
10000 "                              [-q][-s][-S offset][-X]\n"
10001 "        camcontrol modepage   [dev_id][generic args] <-m page | -l>\n"
10002 "                              [-P pagectl][-e | -b][-d]\n"
10003 "        camcontrol cmd        [dev_id][generic args]\n"
10004 "                              <-a cmd [args] | -c cmd [args]>\n"
10005 "                              [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
10006 "        camcontrol smpcmd     [dev_id][generic args]\n"
10007 "                              <-r len fmt [args]> <-R len fmt [args]>\n"
10008 "        camcontrol smprg      [dev_id][generic args][-l]\n"
10009 "        camcontrol smppc      [dev_id][generic args] <-p phy> [-l]\n"
10010 "                              [-o operation][-d name][-m rate][-M rate]\n"
10011 "                              [-T pp_timeout][-a enable|disable]\n"
10012 "                              [-A enable|disable][-s enable|disable]\n"
10013 "                              [-S enable|disable]\n"
10014 "        camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
10015 "        camcontrol smpmaninfo [dev_id][generic args][-l]\n"
10016 "        camcontrol debug      [-I][-P][-T][-S][-X][-c]\n"
10017 "                              <all|dev_id|bus[:target[:lun]]|off>\n"
10018 "        camcontrol tags       [dev_id][generic args] [-N tags] [-q] [-v]\n"
10019 "        camcontrol negotiate  [dev_id][generic args] [-a][-c]\n"
10020 "                              [-D <enable|disable>][-M mode][-O offset]\n"
10021 "                              [-q][-R syncrate][-v][-T <enable|disable>]\n"
10022 "                              [-U][-W bus_width]\n"
10023 "        camcontrol format     [dev_id][generic args][-q][-r][-w][-y]\n"
10024 "        camcontrol sanitize   [dev_id][generic args]\n"
10025 "                              [-a overwrite|block|crypto|exitfailure]\n"
10026 "                              [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
10027 "                              [-y]\n"
10028 "        camcontrol idle       [dev_id][generic args][-t time]\n"
10029 "        camcontrol standby    [dev_id][generic args][-t time]\n"
10030 "        camcontrol sleep      [dev_id][generic args]\n"
10031 "        camcontrol powermode  [dev_id][generic args]\n"
10032 "        camcontrol apm        [dev_id][generic args][-l level]\n"
10033 "        camcontrol aam        [dev_id][generic args][-l level]\n"
10034 "        camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
10035 "                              [-s][-y]\n"
10036 "        camcontrol security   [dev_id][generic args]\n"
10037 "                              <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
10038 "                              [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
10039 "                              [-U <user|master>] [-y]\n"
10040 "        camcontrol hpa        [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
10041 "                              [-q] [-s max_sectors] [-U pwd] [-y]\n"
10042 "        camcontrol ama        [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
10043 "        camcontrol persist    [dev_id][generic args] <-i action|-o action>\n"
10044 "                              [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
10045 "                              [-s scope][-S][-T type][-U]\n"
10046 "        camcontrol attrib     [dev_id][generic args] <-r action|-w attr>\n"
10047 "                              [-a attr_num][-c][-e elem][-F form1,form1]\n"
10048 "                              [-p part][-s start][-T type][-V vol]\n"
10049 "        camcontrol opcodes    [dev_id][generic args][-o opcode][-s SA]\n"
10050 "                              [-N][-T]\n"
10051 "        camcontrol zone       [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
10052 "                              [-o rep_opts] [-P print_opts]\n"
10053 "        camcontrol epc        [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
10054 "                              [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
10055 "                              [-S power_src] [-T timer]\n"
10056 "        camcontrol timestamp  [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
10057 "                              <-s <-f format -T time | -U >>\n"
10058 "        camcontrol devtype    [dev_id]\n"
10059 "        camcontrol depop      [dev_id] [-d | -l | -r] [-e element] [-c capacity]\n"
10060 "        camcontrol mmcsdcmd   [dev_id] [[-c mmc_opcode] [-a mmc_arg]\n"
10061 "                                  [-f mmc_flags] [-l data_len]\n"
10062 "                                  [-W [-b data_byte]]] |\n"
10063 "                              [-F frequency] |\n"
10064 "                              [-I]\n"
10065 "                              [-1 | -4]\n"
10066 "                              [-S high|normal]\n"
10067 "                              \n"
10068 "        camcontrol help\n");
10069 	if (!printlong)
10070 		return;
10071 	fprintf(stdout,
10072 "Specify one of the following options:\n"
10073 "devlist     list all CAM devices\n"
10074 "periphlist  list all CAM peripheral drivers attached to a device\n"
10075 "sense       send a request sense command to the named device\n"
10076 "tur         send a test unit ready to the named device\n"
10077 "inquiry     send a SCSI inquiry command to the named device\n"
10078 "identify    send a ATA identify command to the named device\n"
10079 "reportluns  send a SCSI report luns command to the device\n"
10080 "readcap     send a SCSI read capacity command to the device\n"
10081 "start       send a Start Unit command to the device\n"
10082 "stop        send a Stop Unit command to the device\n"
10083 "load        send a Start Unit command to the device with the load bit set\n"
10084 "eject       send a Stop Unit command to the device with the eject bit set\n"
10085 "reprobe     update capacity information of the given device\n"
10086 "rescan      rescan all buses, the given bus, bus:target:lun or device\n"
10087 "reset       reset all buses, the given bus, bus:target:lun or device\n"
10088 "defects     read the defect list of the specified device\n"
10089 "modepage    display or edit (-e) the given mode page\n"
10090 "cmd         send the given SCSI command, may need -i or -o as well\n"
10091 "smpcmd      send the given SMP command, requires -o and -i\n"
10092 "smprg       send the SMP Report General command\n"
10093 "smppc       send the SMP PHY Control command, requires -p\n"
10094 "smpphylist  display phys attached to a SAS expander\n"
10095 "smpmaninfo  send the SMP Report Manufacturer Info command\n"
10096 "debug       turn debugging on/off for a bus, target, or lun, or all devices\n"
10097 "tags        report or set the number of transaction slots for a device\n"
10098 "negotiate   report or set device negotiation parameters\n"
10099 "format      send the SCSI FORMAT UNIT command to the named device\n"
10100 "sanitize    send the SCSI SANITIZE command to the named device\n"
10101 "idle        send the ATA IDLE command to the named device\n"
10102 "standby     send the ATA STANDBY command to the named device\n"
10103 "sleep       send the ATA SLEEP command to the named device\n"
10104 "powermode   send the ATA CHECK POWER MODE command to the named device\n"
10105 "fwdownload  program firmware of the named device with the given image\n"
10106 "security    report or send ATA security commands to the named device\n"
10107 "persist     send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
10108 "attrib      send the SCSI READ or WRITE ATTRIBUTE commands\n"
10109 "opcodes     send the SCSI REPORT SUPPORTED OPCODES command\n"
10110 "zone        manage Zoned Block (Shingled) devices\n"
10111 "epc         send ATA Extended Power Conditions commands\n"
10112 "timestamp   report or set the device's timestamp\n"
10113 "devtype     report the type of device\n"
10114 "depop       manage drive storage elements\n"
10115 "mmcsdcmd    send the given MMC command, needs -c and -a as well\n"
10116 "help        this message\n"
10117 "Device Identifiers:\n"
10118 "bus:target        specify the bus and target, lun defaults to 0\n"
10119 "bus:target:lun    specify the bus, target and lun\n"
10120 "deviceUNIT        specify the device name, like \"da4\" or \"cd2\"\n"
10121 "Generic arguments:\n"
10122 "-v                be verbose, print out sense information\n"
10123 "-t timeout        command timeout in seconds, overrides default timeout\n"
10124 "-n dev_name       specify device name, e.g. \"da\", \"cd\"\n"
10125 "-u unit           specify unit number, e.g. \"0\", \"5\"\n"
10126 "-E                have the kernel attempt to perform SCSI error recovery\n"
10127 "-C count          specify the SCSI command retry count (needs -E to work)\n"
10128 "-Q task_attr      specify ordered, simple or head tag type for SCSI cmds\n"
10129 "modepage arguments:\n"
10130 "-l                list all available mode pages\n"
10131 "-m page           specify the mode page to view or edit\n"
10132 "-e                edit the specified mode page\n"
10133 "-b                force view to binary mode\n"
10134 "-d                disable block descriptors for mode sense\n"
10135 "-P pgctl          page control field 0-3\n"
10136 "defects arguments:\n"
10137 "-f format         specify defect list format (block, bfi or phys)\n"
10138 "-G                get the grown defect list\n"
10139 "-P                get the permanent defect list\n"
10140 "sense arguments:\n"
10141 "-D                request descriptor sense data\n"
10142 "-x                do a hexdump of the sense data\n"
10143 "inquiry arguments:\n"
10144 "-D                get the standard inquiry data\n"
10145 "-S                get the serial number\n"
10146 "-R                get the transfer rate, etc.\n"
10147 "reportluns arguments:\n"
10148 "-c                only report a count of available LUNs\n"
10149 "-l                only print out luns, and not a count\n"
10150 "-r <reporttype>   specify \"default\", \"wellknown\" or \"all\"\n"
10151 "readcap arguments\n"
10152 "-b                only report the blocksize\n"
10153 "-h                human readable device size, base 2\n"
10154 "-H                human readable device size, base 10\n"
10155 "-N                print the number of blocks instead of last block\n"
10156 "-q                quiet, print numbers only\n"
10157 "-s                only report the last block/device size\n"
10158 "cmd arguments:\n"
10159 "-c cdb [args]     specify the SCSI CDB\n"
10160 "-i len fmt        specify input data and input data format\n"
10161 "-o len fmt [args] specify output data and output data fmt\n"
10162 "smpcmd arguments:\n"
10163 "-r len fmt [args] specify the SMP command to be sent\n"
10164 "-R len fmt [args] specify SMP response format\n"
10165 "smprg arguments:\n"
10166 "-l                specify the long response format\n"
10167 "smppc arguments:\n"
10168 "-p phy            specify the PHY to operate on\n"
10169 "-l                specify the long request/response format\n"
10170 "-o operation      specify the phy control operation\n"
10171 "-d name           set the attached device name\n"
10172 "-m rate           set the minimum physical link rate\n"
10173 "-M rate           set the maximum physical link rate\n"
10174 "-T pp_timeout     set the partial pathway timeout value\n"
10175 "-a enable|disable enable or disable SATA slumber\n"
10176 "-A enable|disable enable or disable SATA partial phy power\n"
10177 "-s enable|disable enable or disable SAS slumber\n"
10178 "-S enable|disable enable or disable SAS partial phy power\n"
10179 "smpphylist arguments:\n"
10180 "-l                specify the long response format\n"
10181 "-q                only print phys with attached devices\n"
10182 "smpmaninfo arguments:\n"
10183 "-l                specify the long response format\n"
10184 "debug arguments:\n"
10185 "-I                CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10186 "-T                CAM_DEBUG_TRACE -- routine flow tracking\n"
10187 "-S                CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10188 "-c                CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10189 "tags arguments:\n"
10190 "-N tags           specify the number of tags to use for this device\n"
10191 "-q                be quiet, don't report the number of tags\n"
10192 "-v                report a number of tag-related parameters\n"
10193 "negotiate arguments:\n"
10194 "-a                send a test unit ready after negotiation\n"
10195 "-c                report/set current negotiation settings\n"
10196 "-D <arg>          \"enable\" or \"disable\" disconnection\n"
10197 "-M mode           set ATA mode\n"
10198 "-O offset         set command delay offset\n"
10199 "-q                be quiet, don't report anything\n"
10200 "-R syncrate       synchronization rate in MHz\n"
10201 "-T <arg>          \"enable\" or \"disable\" tagged queueing\n"
10202 "-U                report/set user negotiation settings\n"
10203 "-W bus_width      set the bus width in bits (8, 16 or 32)\n"
10204 "-v                also print a Path Inquiry CCB for the controller\n"
10205 "format arguments:\n"
10206 "-q                be quiet, don't print status messages\n"
10207 "-r                run in report only mode\n"
10208 "-w                don't send immediate format command\n"
10209 "-y                don't ask any questions\n"
10210 "sanitize arguments:\n"
10211 "-a operation      operation mode: overwrite, block, crypto or exitfailure\n"
10212 "-c passes         overwrite passes to perform (1 to 31)\n"
10213 "-I                invert overwrite pattern after each pass\n"
10214 "-P pattern        path to overwrite pattern file\n"
10215 "-q                be quiet, don't print status messages\n"
10216 "-r                run in report only mode\n"
10217 "-U                run operation in unrestricted completion exit mode\n"
10218 "-w                don't send immediate sanitize command\n"
10219 "-y                don't ask any questions\n"
10220 "idle/standby arguments:\n"
10221 "-t <arg>          number of seconds before respective state.\n"
10222 "fwdownload arguments:\n"
10223 "-f fw_image       path to firmware image file\n"
10224 "-q                don't print informational messages, only errors\n"
10225 "-s                run in simulation mode\n"
10226 "-v                print info for every firmware segment sent to device\n"
10227 "-y                don't ask any questions\n"
10228 "security arguments:\n"
10229 "-d pwd            disable security using the given password for the selected\n"
10230 "                  user\n"
10231 "-e pwd            erase the device using the given pwd for the selected user\n"
10232 "-f                freeze the security configuration of the specified device\n"
10233 "-h pwd            enhanced erase the device using the given pwd for the\n"
10234 "                  selected user\n"
10235 "-k pwd            unlock the device using the given pwd for the selected\n"
10236 "                  user\n"
10237 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10238 "-q                be quiet, do not print any status messages\n"
10239 "-s pwd            password the device (enable security) using the given\n"
10240 "                  pwd for the selected user\n"
10241 "-T timeout        overrides the timeout (seconds) used for erase operation\n"
10242 "-U <user|master>  specifies which user to set: user or master\n"
10243 "-y                don't ask any questions\n"
10244 "hpa arguments:\n"
10245 "-f                freeze the HPA configuration of the device\n"
10246 "-l                lock the HPA configuration of the device\n"
10247 "-P                make the HPA max sectors persist\n"
10248 "-p pwd            Set the HPA configuration password required for unlock\n"
10249 "                  calls\n"
10250 "-q                be quiet, do not print any status messages\n"
10251 "-s sectors        configures the maximum user accessible sectors of the\n"
10252 "                  device\n"
10253 "-U pwd            unlock the HPA configuration of the device\n"
10254 "-y                don't ask any questions\n"
10255 "ama arguments:\n"
10256 "-f                freeze the AMA configuration of the device\n"
10257 "-q                be quiet, do not print any status messages\n"
10258 "-s sectors        configures the maximum user accessible sectors of the\n"
10259 "                  device\n"
10260 "persist arguments:\n"
10261 "-i action         specify read_keys, read_reservation, report_cap, or\n"
10262 "                  read_full_status\n"
10263 "-o action         specify register, register_ignore, reserve, release,\n"
10264 "                  clear, preempt, preempt_abort, register_move, replace_lost\n"
10265 "-a                set the All Target Ports (ALL_TG_PT) bit\n"
10266 "-I tid            specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10267 "-k key            specify the Reservation Key\n"
10268 "-K sa_key         specify the Service Action Reservation Key\n"
10269 "-p                set the Activate Persist Through Power Loss bit\n"
10270 "-R rtp            specify the Relative Target Port\n"
10271 "-s scope          specify the scope: lun, extent, element or a number\n"
10272 "-S                specify Transport ID for register, requires -I\n"
10273 "-T res_type       specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10274 "                  ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10275 "-U                unregister the current initiator for register_move\n"
10276 "attrib arguments:\n"
10277 "-r action         specify attr_values, attr_list, lv_list, part_list, or\n"
10278 "                  supp_attr\n"
10279 "-w attr           specify an attribute to write, one -w argument per attr\n"
10280 "-a attr_num       only display this attribute number\n"
10281 "-c                get cached attributes\n"
10282 "-e elem_addr      request attributes for the given element in a changer\n"
10283 "-F form1,form2    output format, comma separated list: text_esc, text_raw,\n"
10284 "                  nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10285 "                  field_none, field_desc, field_num, field_size, field_rw\n"
10286 "-p partition      request attributes for the given partition\n"
10287 "-s start_attr     request attributes starting at the given number\n"
10288 "-T elem_type      specify the element type (used with -e)\n"
10289 "-V logical_vol    specify the logical volume ID\n"
10290 "opcodes arguments:\n"
10291 "-o opcode         specify the individual opcode to list\n"
10292 "-s service_action specify the service action for the opcode\n"
10293 "-N                do not return SCSI error for unsupported SA\n"
10294 "-T                request nominal and recommended timeout values\n"
10295 "zone arguments:\n"
10296 "-c cmd            required: rz, open, close, finish, or rwp\n"
10297 "-a                apply the action to all zones\n"
10298 "-l LBA            specify the zone starting LBA\n"
10299 "-o rep_opts       report zones options: all, empty, imp_open, exp_open,\n"
10300 "                  closed, full, ro, offline, reset, nonseq, nonwp\n"
10301 "-P print_opt      report zones printing:  normal, summary, script\n"
10302 "epc arguments:\n"
10303 "-c cmd            required: restore, goto, timer, state, enable, disable,\n"
10304 "                  source, status, list\n"
10305 "-d                disable power mode (timer, state)\n"
10306 "-D                delayed entry (goto)\n"
10307 "-e                enable power mode (timer, state)\n"
10308 "-H                hold power mode (goto)\n"
10309 "-p power_cond     Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10310 "                  state, goto)\n"
10311 "-P                only display power mode (status)\n"
10312 "-r rst_src        restore settings from: default, saved (restore)\n"
10313 "-s                save mode (timer, state, restore)\n"
10314 "-S power_src      set power source: battery, nonbattery (source)\n"
10315 "-T timer          set timer, seconds, .1 sec resolution (timer)\n"
10316 "timestamp arguments:\n"
10317 "-r                report the timestamp of the device\n"
10318 "-f format         report the timestamp of the device with the given\n"
10319 "                  strftime(3) format string\n"
10320 "-m                report the timestamp of the device as milliseconds since\n"
10321 "                  January 1st, 1970\n"
10322 "-U                report the time with UTC instead of the local time zone\n"
10323 "-s                set the timestamp of the device\n"
10324 "-f format         the format of the time string passed into strptime(3)\n"
10325 "-T time           the time value passed into strptime(3)\n"
10326 "-U                set the timestamp of the device to UTC time\n"
10327 "depop arguments:\n"
10328 "-d                remove an element from service\n"
10329 "-l                list status of all elements of drive\n"
10330 "-r                restore all elements to service\n"
10331 "-e elm            element to remove\n"
10332 "-c capacity       requested new capacity\n"
10333 "mmcsdcmd arguments:\n"
10334 "-c mmc_cmd        MMC command to send to the card\n"
10335 "-a mmc_arg        Argument for the MMC command\n"
10336 "-f mmc_flag       Flags to set for the MMC command\n"
10337 "-l data_len       Expect data_len bytes of data in reply and display them\n"
10338 "-W                Fill the data buffer before invoking the MMC command\n"
10339 "-b data_byte      One byte of data to fill the data buffer with\n"
10340 "-F frequency      Operating frequency to set on the controller\n"
10341 "-4                Set bus width to 4 bit\n"
10342 "-1                Set bus width to 8 bit\n"
10343 "-S high | std     Set high-speed or standard timing\n"
10344 "-I                Display various card and host controller information\n"
10345 );
10346 }
10347 
10348 int
10349 main(int argc, char **argv)
10350 {
10351 	int c;
10352 	char *device = NULL;
10353 	int unit = 0;
10354 	struct cam_device *cam_dev = NULL;
10355 	int timeout = 0, retry_count = 1;
10356 	camcontrol_optret optreturn;
10357 	char *tstr;
10358 	const char *mainopt = "C:En:Q:t:u:v";
10359 	const char *subopt = NULL;
10360 	char combinedopt[256];
10361 	int error = 0, optstart = 2;
10362 	int task_attr = MSG_SIMPLE_Q_TAG;
10363 	int devopen = 1;
10364 	cam_cmd cmdlist;
10365 	path_id_t bus;
10366 	target_id_t target;
10367 	lun_id_t lun;
10368 
10369 	cmdlist = CAM_CMD_NONE;
10370 	arglist = CAM_ARG_NONE;
10371 
10372 	if (argc < 2) {
10373 		usage(0);
10374 		exit(1);
10375 	}
10376 
10377 	/*
10378 	 * Get the base option.
10379 	 */
10380 	optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10381 
10382 	if (optreturn == CC_OR_AMBIGUOUS) {
10383 		warnx("ambiguous option %s", argv[1]);
10384 		usage(0);
10385 		exit(1);
10386 	} else if (optreturn == CC_OR_NOT_FOUND) {
10387 		warnx("option %s not found", argv[1]);
10388 		usage(0);
10389 		exit(1);
10390 	}
10391 
10392 	/*
10393 	 * Ahh, getopt(3) is a pain.
10394 	 *
10395 	 * This is a gross hack.  There really aren't many other good
10396 	 * options (excuse the pun) for parsing options in a situation like
10397 	 * this.  getopt is kinda braindead, so you end up having to run
10398 	 * through the options twice, and give each invocation of getopt
10399 	 * the option string for the other invocation.
10400 	 *
10401 	 * You would think that you could just have two groups of options.
10402 	 * The first group would get parsed by the first invocation of
10403 	 * getopt, and the second group would get parsed by the second
10404 	 * invocation of getopt.  It doesn't quite work out that way.  When
10405 	 * the first invocation of getopt finishes, it leaves optind pointing
10406 	 * to the argument _after_ the first argument in the second group.
10407 	 * So when the second invocation of getopt comes around, it doesn't
10408 	 * recognize the first argument it gets and then bails out.
10409 	 *
10410 	 * A nice alternative would be to have a flag for getopt that says
10411 	 * "just keep parsing arguments even when you encounter an unknown
10412 	 * argument", but there isn't one.  So there's no real clean way to
10413 	 * easily parse two sets of arguments without having one invocation
10414 	 * of getopt know about the other.
10415 	 *
10416 	 * Without this hack, the first invocation of getopt would work as
10417 	 * long as the generic arguments are first, but the second invocation
10418 	 * (in the subfunction) would fail in one of two ways.  In the case
10419 	 * where you don't set optreset, it would fail because optind may be
10420 	 * pointing to the argument after the one it should be pointing at.
10421 	 * In the case where you do set optreset, and reset optind, it would
10422 	 * fail because getopt would run into the first set of options, which
10423 	 * it doesn't understand.
10424 	 *
10425 	 * All of this would "sort of" work if you could somehow figure out
10426 	 * whether optind had been incremented one option too far.  The
10427 	 * mechanics of that, however, are more daunting than just giving
10428 	 * both invocations all of the expect options for either invocation.
10429 	 *
10430 	 * Needless to say, I wouldn't mind if someone invented a better
10431 	 * (non-GPL!) command line parsing interface than getopt.  I
10432 	 * wouldn't mind if someone added more knobs to getopt to make it
10433 	 * work better.  Who knows, I may talk myself into doing it someday,
10434 	 * if the standards weenies let me.  As it is, it just leads to
10435 	 * hackery like this and causes people to avoid it in some cases.
10436 	 *
10437 	 * KDM, September 8th, 1998
10438 	 */
10439 	if (subopt != NULL)
10440 		sprintf(combinedopt, "%s%s", mainopt, subopt);
10441 	else
10442 		sprintf(combinedopt, "%s", mainopt);
10443 
10444 	/*
10445 	 * For these options we do not parse optional device arguments and
10446 	 * we do not open a passthrough device.
10447 	 */
10448 	if ((cmdlist == CAM_CMD_RESCAN)
10449 	 || (cmdlist == CAM_CMD_RESET)
10450 	 || (cmdlist == CAM_CMD_DEVTREE)
10451 	 || (cmdlist == CAM_CMD_USAGE)
10452 	 || (cmdlist == CAM_CMD_DEBUG))
10453 		devopen = 0;
10454 
10455 	if ((devopen == 1)
10456 	 && (argc > 2 && argv[2][0] != '-')) {
10457 		char name[30];
10458 		int rv;
10459 
10460 		if (isdigit(argv[2][0])) {
10461 			/* device specified as bus:target[:lun] */
10462 			rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10463 			if (rv < 2)
10464 				errx(1, "numeric device specification must "
10465 				     "be either bus:target, or "
10466 				     "bus:target:lun");
10467 			/* default to 0 if lun was not specified */
10468 			if ((arglist & CAM_ARG_LUN) == 0) {
10469 				lun = 0;
10470 				arglist |= CAM_ARG_LUN;
10471 			}
10472 			optstart++;
10473 		} else {
10474 			if (cam_get_device(argv[2], name, sizeof name, &unit)
10475 			    == -1)
10476 				errx(1, "%s", cam_errbuf);
10477 			device = strdup(name);
10478 			arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10479 			optstart++;
10480 		}
10481 	}
10482 	/*
10483 	 * Start getopt processing at argv[2/3], since we've already
10484 	 * accepted argv[1..2] as the command name, and as a possible
10485 	 * device name.
10486 	 */
10487 	optind = optstart;
10488 
10489 	/*
10490 	 * Now we run through the argument list looking for generic
10491 	 * options, and ignoring options that possibly belong to
10492 	 * subfunctions.
10493 	 */
10494 	while ((c = getopt(argc, argv, combinedopt))!= -1){
10495 		switch(c) {
10496 			case 'C':
10497 				retry_count = strtol(optarg, NULL, 0);
10498 				if (retry_count < 0)
10499 					errx(1, "retry count %d is < 0",
10500 					     retry_count);
10501 				arglist |= CAM_ARG_RETRIES;
10502 				break;
10503 			case 'E':
10504 				arglist |= CAM_ARG_ERR_RECOVER;
10505 				break;
10506 			case 'n':
10507 				arglist |= CAM_ARG_DEVICE;
10508 				tstr = optarg;
10509 				while (isspace(*tstr) && (*tstr != '\0'))
10510 					tstr++;
10511 				device = (char *)strdup(tstr);
10512 				break;
10513 			case 'Q': {
10514 				char *endptr;
10515 				int table_entry = 0;
10516 
10517 				tstr = optarg;
10518 				while (isspace(*tstr) && (*tstr != '\0'))
10519 					tstr++;
10520 				if (isdigit(*tstr)) {
10521 					task_attr = strtol(tstr, &endptr, 0);
10522 					if (*endptr != '\0') {
10523 						errx(1, "Invalid queue option "
10524 						    "%s", tstr);
10525 					}
10526 				} else {
10527 					size_t table_size;
10528 					scsi_nv_status status;
10529 
10530 					table_size = sizeof(task_attrs) /
10531 						     sizeof(task_attrs[0]);
10532 					status = scsi_get_nv(task_attrs,
10533 					    table_size, tstr, &table_entry,
10534 					    SCSI_NV_FLAG_IG_CASE);
10535 					if (status == SCSI_NV_FOUND)
10536 						task_attr = task_attrs[
10537 						    table_entry].value;
10538 					else {
10539 						errx(1, "%s option %s",
10540 						  (status == SCSI_NV_AMBIGUOUS)?
10541 						    "ambiguous" : "invalid",
10542 						    tstr);
10543 					}
10544 				}
10545 				break;
10546 			}
10547 			case 't':
10548 				timeout = strtol(optarg, NULL, 0);
10549 				if (timeout < 0)
10550 					errx(1, "invalid timeout %d", timeout);
10551 				/* Convert the timeout from seconds to ms */
10552 				timeout *= 1000;
10553 				arglist |= CAM_ARG_TIMEOUT;
10554 				break;
10555 			case 'u':
10556 				arglist |= CAM_ARG_UNIT;
10557 				unit = strtol(optarg, NULL, 0);
10558 				break;
10559 			case 'v':
10560 				arglist |= CAM_ARG_VERBOSE;
10561 				break;
10562 			default:
10563 				break;
10564 		}
10565 	}
10566 
10567 	/*
10568 	 * For most commands we'll want to open the passthrough device
10569 	 * associated with the specified device.  In the case of the rescan
10570 	 * commands, we don't use a passthrough device at all, just the
10571 	 * transport layer device.
10572 	 */
10573 	if (devopen == 1) {
10574 		if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10575 		 && (((arglist & CAM_ARG_DEVICE) == 0)
10576 		  || ((arglist & CAM_ARG_UNIT) == 0))) {
10577 			errx(1, "subcommand \"%s\" requires a valid device "
10578 			     "identifier", argv[1]);
10579 		}
10580 
10581 		if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10582 				cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10583 				cam_open_spec_device(device,unit,O_RDWR,NULL)))
10584 		     == NULL)
10585 			errx(1,"%s", cam_errbuf);
10586 	}
10587 
10588 	/*
10589 	 * Reset optind to 2, and reset getopt, so these routines can parse
10590 	 * the arguments again.
10591 	 */
10592 	optind = optstart;
10593 	optreset = 1;
10594 
10595 	switch(cmdlist) {
10596 	case CAM_CMD_DEVLIST:
10597 		error = getdevlist(cam_dev);
10598 		break;
10599 	case CAM_CMD_HPA:
10600 		error = atahpa(cam_dev, retry_count, timeout,
10601 			       argc, argv, combinedopt);
10602 		break;
10603 	case CAM_CMD_AMA:
10604 		error = ataama(cam_dev, retry_count, timeout,
10605 			       argc, argv, combinedopt);
10606 		break;
10607 	case CAM_CMD_DEVTREE:
10608 		error = getdevtree(argc, argv, combinedopt);
10609 		break;
10610 	case CAM_CMD_DEVTYPE:
10611 		error = getdevtype(cam_dev);
10612 		break;
10613 	case CAM_CMD_REQSENSE:
10614 		error = requestsense(cam_dev, argc, argv, combinedopt,
10615 		    task_attr, retry_count, timeout);
10616 		break;
10617 	case CAM_CMD_TUR:
10618 		error = testunitready(cam_dev, task_attr, retry_count,
10619 		    timeout, 0);
10620 		break;
10621 	case CAM_CMD_INQUIRY:
10622 		error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10623 				      task_attr, retry_count, timeout);
10624 		break;
10625 	case CAM_CMD_IDENTIFY:
10626 		error = identify(cam_dev, retry_count, timeout);
10627 		break;
10628 	case CAM_CMD_STARTSTOP:
10629 		error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10630 				  arglist & CAM_ARG_EJECT, task_attr,
10631 				  retry_count, timeout);
10632 		break;
10633 	case CAM_CMD_RESCAN:
10634 		error = dorescan_or_reset(argc, argv, 1);
10635 		break;
10636 	case CAM_CMD_RESET:
10637 		error = dorescan_or_reset(argc, argv, 0);
10638 		break;
10639 	case CAM_CMD_READ_DEFECTS:
10640 		error = readdefects(cam_dev, argc, argv, combinedopt,
10641 				    task_attr, retry_count, timeout);
10642 		break;
10643 	case CAM_CMD_MODE_PAGE:
10644 		modepage(cam_dev, argc, argv, combinedopt,
10645 			 task_attr, retry_count, timeout);
10646 		break;
10647 	case CAM_CMD_SCSI_CMD:
10648 		error = scsicmd(cam_dev, argc, argv, combinedopt,
10649 				task_attr, retry_count, timeout);
10650 		break;
10651 	case CAM_CMD_MMCSD_CMD:
10652 		error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10653 					retry_count, timeout);
10654 		break;
10655 	case CAM_CMD_SMP_CMD:
10656 		error = smpcmd(cam_dev, argc, argv, combinedopt,
10657 			       retry_count, timeout);
10658 		break;
10659 	case CAM_CMD_SMP_RG:
10660 		error = smpreportgeneral(cam_dev, argc, argv,
10661 					 combinedopt, retry_count,
10662 					 timeout);
10663 		break;
10664 	case CAM_CMD_SMP_PC:
10665 		error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10666 				      retry_count, timeout);
10667 		break;
10668 	case CAM_CMD_SMP_PHYLIST:
10669 		error = smpphylist(cam_dev, argc, argv, combinedopt,
10670 				   retry_count, timeout);
10671 		break;
10672 	case CAM_CMD_SMP_MANINFO:
10673 		error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10674 				   retry_count, timeout);
10675 		break;
10676 	case CAM_CMD_DEBUG:
10677 		error = camdebug(argc, argv, combinedopt);
10678 		break;
10679 	case CAM_CMD_TAG:
10680 		error = tagcontrol(cam_dev, argc, argv, combinedopt);
10681 		break;
10682 	case CAM_CMD_RATE:
10683 		error = ratecontrol(cam_dev, task_attr, retry_count,
10684 				    timeout, argc, argv, combinedopt);
10685 		break;
10686 	case CAM_CMD_FORMAT:
10687 		error = scsiformat(cam_dev, argc, argv,
10688 				   combinedopt, task_attr, retry_count,
10689 				   timeout);
10690 		break;
10691 	case CAM_CMD_REPORTLUNS:
10692 		error = scsireportluns(cam_dev, argc, argv,
10693 				       combinedopt, task_attr,
10694 				       retry_count, timeout);
10695 		break;
10696 	case CAM_CMD_READCAP:
10697 		error = scsireadcapacity(cam_dev, argc, argv,
10698 					 combinedopt, task_attr,
10699 					 retry_count, timeout);
10700 		break;
10701 	case CAM_CMD_IDLE:
10702 	case CAM_CMD_STANDBY:
10703 	case CAM_CMD_SLEEP:
10704 	case CAM_CMD_POWER_MODE:
10705 		error = atapm(cam_dev, argc, argv,
10706 			      combinedopt, retry_count, timeout);
10707 		break;
10708 	case CAM_CMD_APM:
10709 	case CAM_CMD_AAM:
10710 		error = ataaxm(cam_dev, argc, argv,
10711 			      combinedopt, retry_count, timeout);
10712 		break;
10713 	case CAM_CMD_SECURITY:
10714 		error = atasecurity(cam_dev, retry_count, timeout,
10715 				    argc, argv, combinedopt);
10716 		break;
10717 	case CAM_CMD_DOWNLOAD_FW:
10718 		error = fwdownload(cam_dev, argc, argv, combinedopt,
10719 		    arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10720 		    timeout);
10721 		break;
10722 	case CAM_CMD_SANITIZE:
10723 		error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10724 				 retry_count, timeout);
10725 		break;
10726 	case CAM_CMD_PERSIST:
10727 		error = scsipersist(cam_dev, argc, argv, combinedopt,
10728 		    task_attr, retry_count, timeout,
10729 		    arglist & CAM_ARG_VERBOSE,
10730 		    arglist & CAM_ARG_ERR_RECOVER);
10731 		break;
10732 	case CAM_CMD_ATTRIB:
10733 		error = scsiattrib(cam_dev, argc, argv, combinedopt,
10734 		    task_attr, retry_count, timeout,
10735 		    arglist & CAM_ARG_VERBOSE,
10736 		    arglist & CAM_ARG_ERR_RECOVER);
10737 		break;
10738 	case CAM_CMD_OPCODES:
10739 		error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10740 		    task_attr, retry_count, timeout,
10741 		    arglist & CAM_ARG_VERBOSE);
10742 		break;
10743 	case CAM_CMD_REPROBE:
10744 		error = reprobe(cam_dev);
10745 		break;
10746 	case CAM_CMD_ZONE:
10747 		error = zone(cam_dev, argc, argv, combinedopt,
10748 		    task_attr, retry_count, timeout,
10749 		    arglist & CAM_ARG_VERBOSE);
10750 		break;
10751 	case CAM_CMD_EPC:
10752 		error = epc(cam_dev, argc, argv, combinedopt,
10753 		    retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10754 		break;
10755 	case CAM_CMD_TIMESTAMP:
10756 		error = timestamp(cam_dev, argc, argv, combinedopt,
10757 		    task_attr, retry_count, timeout,
10758 		    arglist & CAM_ARG_VERBOSE);
10759 		break;
10760 	case CAM_CMD_DEPOP:
10761 		error = depop(cam_dev, argc, argv, combinedopt,
10762 		    task_attr, retry_count, timeout,
10763 		    arglist & CAM_ARG_VERBOSE);
10764 		break;
10765 	case CAM_CMD_USAGE:
10766 		usage(1);
10767 		break;
10768 	default:
10769 		usage(0);
10770 		error = 1;
10771 		break;
10772 	}
10773 
10774 	if (cam_dev != NULL)
10775 		cam_close_device(cam_dev);
10776 
10777 	exit(error);
10778 }
10779