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