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