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