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