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