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