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