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