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