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