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