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