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