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