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