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