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