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