xref: /freebsd/sbin/camcontrol/camcontrol.c (revision e17f5b1d)
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: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 		char pass[sizeof(pwd->password)+1];
2462 
2463 		/* pwd->password may not be null terminated */
2464 		pass[sizeof(pwd->password)] = '\0';
2465 		strncpy(pass, pwd->password, sizeof(pwd->password));
2466 		printf(" password='%s', user='%s'",
2467 			pass,
2468 			(pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2469 			"master" : "user");
2470 
2471 		if (command == ATA_SECURITY_SET_PASSWORD) {
2472 			printf(", mode='%s'",
2473 			       (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2474 			       "maximum" : "high");
2475 		}
2476 	}
2477 
2478 	printf("\n");
2479 }
2480 
2481 static int
2482 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2483 		   int retry_count, u_int32_t timeout, int quiet)
2484 {
2485 
2486 	if (quiet == 0)
2487 		atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2488 
2489 	return ata_do_cmd(device,
2490 			  ccb,
2491 			  retry_count,
2492 			  /*flags*/CAM_DIR_NONE,
2493 			  /*protocol*/AP_PROTO_NON_DATA,
2494 			  /*ata_flags*/0,
2495 			  /*tag_action*/MSG_SIMPLE_Q_TAG,
2496 			  /*command*/ATA_SECURITY_FREEZE_LOCK,
2497 			  /*features*/0,
2498 			  /*lba*/0,
2499 			  /*sector_count*/0,
2500 			  /*data_ptr*/NULL,
2501 			  /*dxfer_len*/0,
2502 			  /*timeout*/timeout,
2503 			  /*force48bit*/0);
2504 }
2505 
2506 static int
2507 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2508 		   int retry_count, u_int32_t timeout,
2509 		   struct ata_security_password *pwd, int quiet)
2510 {
2511 
2512 	if (quiet == 0)
2513 		atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2514 
2515 	return ata_do_cmd(device,
2516 			  ccb,
2517 			  retry_count,
2518 			  /*flags*/CAM_DIR_OUT,
2519 			  /*protocol*/AP_PROTO_PIO_OUT,
2520 			  /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2521 			    AP_FLAG_TLEN_SECT_CNT,
2522 			  /*tag_action*/MSG_SIMPLE_Q_TAG,
2523 			  /*command*/ATA_SECURITY_UNLOCK,
2524 			  /*features*/0,
2525 			  /*lba*/0,
2526 			  /*sector_count*/sizeof(*pwd) / 512,
2527 			  /*data_ptr*/(u_int8_t *)pwd,
2528 			  /*dxfer_len*/sizeof(*pwd),
2529 			  /*timeout*/timeout,
2530 			  /*force48bit*/0);
2531 }
2532 
2533 static int
2534 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2535 		    int retry_count, u_int32_t timeout,
2536 		    struct ata_security_password *pwd, int quiet)
2537 {
2538 
2539 	if (quiet == 0)
2540 		atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2541 	return ata_do_cmd(device,
2542 			  ccb,
2543 			  retry_count,
2544 			  /*flags*/CAM_DIR_OUT,
2545 			  /*protocol*/AP_PROTO_PIO_OUT,
2546 			  /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2547 			    AP_FLAG_TLEN_SECT_CNT,
2548 			  /*tag_action*/MSG_SIMPLE_Q_TAG,
2549 			  /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2550 			  /*features*/0,
2551 			  /*lba*/0,
2552 			  /*sector_count*/sizeof(*pwd) / 512,
2553 			  /*data_ptr*/(u_int8_t *)pwd,
2554 			  /*dxfer_len*/sizeof(*pwd),
2555 			  /*timeout*/timeout,
2556 			  /*force48bit*/0);
2557 }
2558 
2559 
2560 static int
2561 atasecurity_erase_confirm(struct cam_device *device,
2562 			  struct ata_params* ident_buf)
2563 {
2564 
2565 	printf("\nYou are about to ERASE ALL DATA from the following"
2566 	       " device:\n%s%d,%s%d: ", device->device_name,
2567 	       device->dev_unit_num, device->given_dev_name,
2568 	       device->given_unit_number);
2569 	ata_print_ident(ident_buf);
2570 
2571 	for(;;) {
2572 		char str[50];
2573 		printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2574 
2575 		if (fgets(str, sizeof(str), stdin) != NULL) {
2576 			if (strncasecmp(str, "yes", 3) == 0) {
2577 				return (1);
2578 			} else if (strncasecmp(str, "no", 2) == 0) {
2579 				return (0);
2580 			} else {
2581 				printf("Please answer \"yes\" or "
2582 				       "\"no\"\n");
2583 			}
2584 		}
2585 	}
2586 
2587 	/* NOTREACHED */
2588 	return (0);
2589 }
2590 
2591 static int
2592 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2593 		  int retry_count, u_int32_t timeout,
2594 		  u_int32_t erase_timeout,
2595 		  struct ata_security_password *pwd, int quiet)
2596 {
2597 	int error;
2598 
2599 	if (quiet == 0)
2600 		atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2601 
2602 	error = ata_do_cmd(device,
2603 			   ccb,
2604 			   retry_count,
2605 			   /*flags*/CAM_DIR_NONE,
2606 			   /*protocol*/AP_PROTO_NON_DATA,
2607 			   /*ata_flags*/0,
2608 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2609 			   /*command*/ATA_SECURITY_ERASE_PREPARE,
2610 			   /*features*/0,
2611 			   /*lba*/0,
2612 			   /*sector_count*/0,
2613 			   /*data_ptr*/NULL,
2614 			   /*dxfer_len*/0,
2615 			   /*timeout*/timeout,
2616 			   /*force48bit*/0);
2617 
2618 	if (error != 0)
2619 		return error;
2620 
2621 	if (quiet == 0)
2622 		atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2623 
2624 	error = ata_do_cmd(device,
2625 			   ccb,
2626 			   retry_count,
2627 			   /*flags*/CAM_DIR_OUT,
2628 			   /*protocol*/AP_PROTO_PIO_OUT,
2629 			   /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2630 			    AP_FLAG_TLEN_SECT_CNT,
2631 			   /*tag_action*/MSG_SIMPLE_Q_TAG,
2632 			   /*command*/ATA_SECURITY_ERASE_UNIT,
2633 			   /*features*/0,
2634 			   /*lba*/0,
2635 			   /*sector_count*/sizeof(*pwd) / 512,
2636 			   /*data_ptr*/(u_int8_t *)pwd,
2637 			   /*dxfer_len*/sizeof(*pwd),
2638 			   /*timeout*/erase_timeout,
2639 			   /*force48bit*/0);
2640 
2641 	if (error == 0 && quiet == 0)
2642 		printf("\nErase Complete\n");
2643 
2644 	return error;
2645 }
2646 
2647 static int
2648 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2649 			 int retry_count, u_int32_t timeout,
2650 			 struct ata_security_password *pwd, int quiet)
2651 {
2652 
2653 	if (quiet == 0)
2654 		atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2655 
2656 	return ata_do_cmd(device,
2657 			  ccb,
2658 			  retry_count,
2659 			  /*flags*/CAM_DIR_OUT,
2660 			  /*protocol*/AP_PROTO_PIO_OUT,
2661 			  /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2662 			   AP_FLAG_TLEN_SECT_CNT,
2663 			  /*tag_action*/MSG_SIMPLE_Q_TAG,
2664 			  /*command*/ATA_SECURITY_SET_PASSWORD,
2665 			  /*features*/0,
2666 			  /*lba*/0,
2667 			  /*sector_count*/sizeof(*pwd) / 512,
2668 			  /*data_ptr*/(u_int8_t *)pwd,
2669 			  /*dxfer_len*/sizeof(*pwd),
2670 			  /*timeout*/timeout,
2671 			  /*force48bit*/0);
2672 }
2673 
2674 static void
2675 atasecurity_print(struct ata_params *parm)
2676 {
2677 
2678 	printf("\nSecurity Option           Value\n");
2679 	if (arglist & CAM_ARG_VERBOSE) {
2680 		printf("status                    %04x\n",
2681 		       parm->security_status);
2682 	}
2683 	printf("supported                 %s\n",
2684 		parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2685 	if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2686 		return;
2687 	printf("enabled                   %s\n",
2688 		parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2689 	printf("drive locked              %s\n",
2690 		parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2691 	printf("security config frozen    %s\n",
2692 		parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2693 	printf("count expired             %s\n",
2694 		parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2695 	printf("security level            %s\n",
2696 		parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2697 	printf("enhanced erase supported  %s\n",
2698 		parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2699 	printf("erase time                ");
2700 	atasecurity_print_time(parm->erase_time);
2701 	printf("\n");
2702 	printf("enhanced erase time       ");
2703 	atasecurity_print_time(parm->enhanced_erase_time);
2704 	printf("\n");
2705 	printf("master password rev       %04x%s\n",
2706 		parm->master_passwd_revision,
2707 		parm->master_passwd_revision == 0x0000 ||
2708 		parm->master_passwd_revision == 0xFFFF ?  " (unsupported)" : "");
2709 }
2710 
2711 /*
2712  * Validates and copies the password in optarg to the passed buffer.
2713  * If the password in optarg is the same length as the buffer then
2714  * the data will still be copied but no null termination will occur.
2715  */
2716 static int
2717 ata_getpwd(u_int8_t *passwd, int max, char opt)
2718 {
2719 	int len;
2720 
2721 	len = strlen(optarg);
2722 	if (len > max) {
2723 		warnx("-%c password is too long", opt);
2724 		return (1);
2725 	} else if (len == 0) {
2726 		warnx("-%c password is missing", opt);
2727 		return (1);
2728 	} else if (optarg[0] == '-'){
2729 		warnx("-%c password starts with '-' (generic arg?)", opt);
2730 		return (1);
2731 	} else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2732 		warnx("-%c password conflicts with existing password from -%c",
2733 		      opt, pwd_opt);
2734 		return (1);
2735 	}
2736 
2737 	/* Callers pass in a buffer which does NOT need to be terminated */
2738 	strncpy(passwd, optarg, max);
2739 	pwd_opt = opt;
2740 
2741 	return (0);
2742 }
2743 
2744 enum {
2745 	ATA_HPA_ACTION_PRINT,
2746 	ATA_HPA_ACTION_SET_MAX,
2747 	ATA_HPA_ACTION_SET_PWD,
2748 	ATA_HPA_ACTION_LOCK,
2749 	ATA_HPA_ACTION_UNLOCK,
2750 	ATA_HPA_ACTION_FREEZE_LOCK
2751 };
2752 
2753 static int
2754 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2755 		   u_int64_t maxsize, int persist)
2756 {
2757 	printf("\nYou are about to configure HPA to limit the user accessible\n"
2758 	       "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2759 	       persist ? "persistently" : "temporarily",
2760 	       device->device_name, device->dev_unit_num,
2761 	       device->given_dev_name, device->given_unit_number);
2762 	ata_print_ident(ident_buf);
2763 
2764 	for(;;) {
2765 		char str[50];
2766 		printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2767 
2768 		if (NULL != fgets(str, sizeof(str), stdin)) {
2769 			if (0 == strncasecmp(str, "yes", 3)) {
2770 				return (1);
2771 			} else if (0 == strncasecmp(str, "no", 2)) {
2772 				return (0);
2773 			} else {
2774 				printf("Please answer \"yes\" or "
2775 				       "\"no\"\n");
2776 			}
2777 		}
2778 	}
2779 
2780 	/* NOTREACHED */
2781 	return (0);
2782 }
2783 
2784 static int
2785 atahpa(struct cam_device *device, int retry_count, int timeout,
2786        int argc, char **argv, char *combinedopt)
2787 {
2788 	union ccb *ccb;
2789 	struct ata_params *ident_buf;
2790 	struct ccb_getdev cgd;
2791 	struct ata_set_max_pwd pwd;
2792 	int error, confirm, quiet, c, action, actions, persist;
2793 	int security, is48bit, pwdsize;
2794 	u_int64_t hpasize, maxsize;
2795 
2796 	actions = 0;
2797 	confirm = 0;
2798 	quiet = 0;
2799 	maxsize = 0;
2800 	persist = 0;
2801 	security = 0;
2802 
2803 	memset(&pwd, 0, sizeof(pwd));
2804 
2805 	/* default action is to print hpa information */
2806 	action = ATA_HPA_ACTION_PRINT;
2807 	pwdsize = sizeof(pwd.password);
2808 
2809 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
2810 		switch(c){
2811 		case 's':
2812 			action = ATA_HPA_ACTION_SET_MAX;
2813 			maxsize = strtoumax(optarg, NULL, 0);
2814 			actions++;
2815 			break;
2816 
2817 		case 'p':
2818 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2819 				return (1);
2820 			action = ATA_HPA_ACTION_SET_PWD;
2821 			security = 1;
2822 			actions++;
2823 			break;
2824 
2825 		case 'l':
2826 			action = ATA_HPA_ACTION_LOCK;
2827 			security = 1;
2828 			actions++;
2829 			break;
2830 
2831 		case 'U':
2832 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2833 				return (1);
2834 			action = ATA_HPA_ACTION_UNLOCK;
2835 			security = 1;
2836 			actions++;
2837 			break;
2838 
2839 		case 'f':
2840 			action = ATA_HPA_ACTION_FREEZE_LOCK;
2841 			security = 1;
2842 			actions++;
2843 			break;
2844 
2845 		case 'P':
2846 			persist = 1;
2847 			break;
2848 
2849 		case 'y':
2850 			confirm++;
2851 			break;
2852 
2853 		case 'q':
2854 			quiet++;
2855 			break;
2856 		}
2857 	}
2858 
2859 	if (actions > 1) {
2860 		warnx("too many hpa actions specified");
2861 		return (1);
2862 	}
2863 
2864 	if (get_cgd(device, &cgd) != 0) {
2865 		warnx("couldn't get CGD");
2866 		return (1);
2867 	}
2868 
2869 	ccb = cam_getccb(device);
2870 	if (ccb == NULL) {
2871 		warnx("couldn't allocate CCB");
2872 		return (1);
2873 	}
2874 
2875 	error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2876 	if (error != 0) {
2877 		cam_freeccb(ccb);
2878 		return (1);
2879 	}
2880 
2881 	if (quiet == 0) {
2882 		printf("%s%d: ", device->device_name, device->dev_unit_num);
2883 		ata_print_ident(ident_buf);
2884 		camxferrate(device);
2885 	}
2886 
2887 	if (action == ATA_HPA_ACTION_PRINT) {
2888 		hpasize = 0;
2889 		if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2890 			ata_read_native_max(device, retry_count, timeout, ccb,
2891 				    ident_buf, &hpasize);
2892 		atahpa_print(ident_buf, hpasize, 1);
2893 
2894 		cam_freeccb(ccb);
2895 		free(ident_buf);
2896 		return (error);
2897 	}
2898 
2899 	if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2900 		warnx("HPA is not supported by this device");
2901 		cam_freeccb(ccb);
2902 		free(ident_buf);
2903 		return (1);
2904 	}
2905 
2906 	if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
2907 		warnx("HPA Security is not supported by this device");
2908 		cam_freeccb(ccb);
2909 		free(ident_buf);
2910 		return (1);
2911 	}
2912 
2913 	is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2914 
2915 	/*
2916 	 * The ATA spec requires:
2917 	 * 1. Read native max addr is called directly before set max addr
2918 	 * 2. Read native max addr is NOT called before any other set max call
2919 	 */
2920 	switch(action) {
2921 	case ATA_HPA_ACTION_SET_MAX:
2922 		if (confirm == 0 &&
2923 		    atahpa_set_confirm(device, ident_buf, maxsize,
2924 		    persist) == 0) {
2925 			cam_freeccb(ccb);
2926 			free(ident_buf);
2927 			return (1);
2928 		}
2929 
2930 		error = ata_read_native_max(device, retry_count, timeout,
2931 					    ccb, ident_buf, &hpasize);
2932 		if (error == 0) {
2933 			error = atahpa_set_max(device, retry_count, timeout,
2934 					       ccb, is48bit, maxsize, persist);
2935 			if (error == 0) {
2936 				if (quiet == 0) {
2937 					/* redo identify to get new values */
2938 					error = ata_do_identify(device,
2939 					    retry_count, timeout, ccb,
2940 					    &ident_buf);
2941 					atahpa_print(ident_buf, hpasize, 1);
2942 				}
2943 				/* Hint CAM to reprobe the device. */
2944 				reprobe(device);
2945 			}
2946 		}
2947 		break;
2948 
2949 	case ATA_HPA_ACTION_SET_PWD:
2950 		error = atahpa_password(device, retry_count, timeout,
2951 					ccb, is48bit, &pwd);
2952 		if (error == 0 && quiet == 0)
2953 			printf("HPA password has been set\n");
2954 		break;
2955 
2956 	case ATA_HPA_ACTION_LOCK:
2957 		error = atahpa_lock(device, retry_count, timeout,
2958 				    ccb, is48bit);
2959 		if (error == 0 && quiet == 0)
2960 			printf("HPA has been locked\n");
2961 		break;
2962 
2963 	case ATA_HPA_ACTION_UNLOCK:
2964 		error = atahpa_unlock(device, retry_count, timeout,
2965 				      ccb, is48bit, &pwd);
2966 		if (error == 0 && quiet == 0)
2967 			printf("HPA has been unlocked\n");
2968 		break;
2969 
2970 	case ATA_HPA_ACTION_FREEZE_LOCK:
2971 		error = atahpa_freeze_lock(device, retry_count, timeout,
2972 					   ccb, is48bit);
2973 		if (error == 0 && quiet == 0)
2974 			printf("HPA has been frozen\n");
2975 		break;
2976 
2977 	default:
2978 		errx(1, "Option currently not supported");
2979 	}
2980 
2981 	cam_freeccb(ccb);
2982 	free(ident_buf);
2983 
2984 	return (error);
2985 }
2986 
2987 enum {
2988 	ATA_AMA_ACTION_PRINT,
2989 	ATA_AMA_ACTION_SET_MAX,
2990 	ATA_AMA_ACTION_FREEZE_LOCK
2991 };
2992 
2993 static int
2994 ataama(struct cam_device *device, int retry_count, int timeout,
2995        int argc, char **argv, char *combinedopt)
2996 {
2997 	union ccb *ccb;
2998 	struct ata_params *ident_buf;
2999 	struct ccb_getdev cgd;
3000 	int error, quiet, c, action, actions;
3001 	u_int64_t nativesize, maxsize;
3002 
3003 	actions = 0;
3004 	quiet = 0;
3005 	maxsize = 0;
3006 
3007 	/* default action is to print AMA information */
3008 	action = ATA_AMA_ACTION_PRINT;
3009 
3010 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3011 		switch(c){
3012 		case 's':
3013 			action = ATA_AMA_ACTION_SET_MAX;
3014 			maxsize = strtoumax(optarg, NULL, 0);
3015 			actions++;
3016 			break;
3017 
3018 		case 'f':
3019 			action = ATA_AMA_ACTION_FREEZE_LOCK;
3020 			actions++;
3021 			break;
3022 
3023 		case 'q':
3024 			quiet++;
3025 			break;
3026 		}
3027 	}
3028 
3029 	if (actions > 1) {
3030 		warnx("too many AMA actions specified");
3031 		return (1);
3032 	}
3033 
3034 	if (get_cgd(device, &cgd) != 0) {
3035 		warnx("couldn't get CGD");
3036 		return (1);
3037 	}
3038 
3039 	ccb = cam_getccb(device);
3040 	if (ccb == NULL) {
3041 		warnx("couldn't allocate CCB");
3042 		return (1);
3043 	}
3044 
3045 	error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3046 	if (error != 0) {
3047 		cam_freeccb(ccb);
3048 		return (1);
3049 	}
3050 
3051 	if (quiet == 0) {
3052 		printf("%s%d: ", device->device_name, device->dev_unit_num);
3053 		ata_print_ident(ident_buf);
3054 		camxferrate(device);
3055 	}
3056 
3057 	if (action == ATA_AMA_ACTION_PRINT) {
3058 		nativesize = 0;
3059 		if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3060 			ata_get_native_max(device, retry_count, timeout, ccb,
3061 					   &nativesize);
3062 		ataama_print(ident_buf, nativesize, 1);
3063 
3064 		cam_freeccb(ccb);
3065 		free(ident_buf);
3066 		return (error);
3067 	}
3068 
3069 	if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3070 		warnx("Accessible Max Address is not supported by this device");
3071 		cam_freeccb(ccb);
3072 		free(ident_buf);
3073 		return (1);
3074 	}
3075 
3076 	switch(action) {
3077 	case ATA_AMA_ACTION_SET_MAX:
3078 		error = ata_get_native_max(device, retry_count, timeout, ccb,
3079 					   &nativesize);
3080 		if (error == 0) {
3081 			error = ataama_set(device, retry_count, timeout,
3082 				       ccb, maxsize);
3083 			if (error == 0) {
3084 				if (quiet == 0) {
3085 					/* redo identify to get new values */
3086 					error = ata_do_identify(device,
3087 					    retry_count, timeout, ccb,
3088 					    &ident_buf);
3089 					ataama_print(ident_buf, nativesize, 1);
3090 				}
3091 				/* Hint CAM to reprobe the device. */
3092 				reprobe(device);
3093 			}
3094 		}
3095 		break;
3096 
3097 	case ATA_AMA_ACTION_FREEZE_LOCK:
3098 		error = ataama_freeze(device, retry_count, timeout,
3099 					   ccb);
3100 		if (error == 0 && quiet == 0)
3101 			printf("Accessible Max Address has been frozen\n");
3102 		break;
3103 
3104 	default:
3105 		errx(1, "Option currently not supported");
3106 	}
3107 
3108 	cam_freeccb(ccb);
3109 	free(ident_buf);
3110 
3111 	return (error);
3112 }
3113 
3114 static int
3115 atasecurity(struct cam_device *device, int retry_count, int timeout,
3116 	    int argc, char **argv, char *combinedopt)
3117 {
3118 	union ccb *ccb;
3119 	struct ata_params *ident_buf;
3120 	int error, confirm, quiet, c, action, actions, setpwd;
3121 	int security_enabled, erase_timeout, pwdsize;
3122 	struct ata_security_password pwd;
3123 
3124 	actions = 0;
3125 	setpwd = 0;
3126 	erase_timeout = 0;
3127 	confirm = 0;
3128 	quiet = 0;
3129 
3130 	memset(&pwd, 0, sizeof(pwd));
3131 
3132 	/* default action is to print security information */
3133 	action = ATA_SECURITY_ACTION_PRINT;
3134 
3135 	/* user is master by default as its safer that way */
3136 	pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3137 	pwdsize = sizeof(pwd.password);
3138 
3139 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3140 		switch(c){
3141 		case 'f':
3142 			action = ATA_SECURITY_ACTION_FREEZE;
3143 			actions++;
3144 			break;
3145 
3146 		case 'U':
3147 			if (strcasecmp(optarg, "user") == 0) {
3148 				pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3149 				pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3150 			} else if (strcasecmp(optarg, "master") == 0) {
3151 				pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3152 				pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3153 			} else {
3154 				warnx("-U argument '%s' is invalid (must be "
3155 				      "'user' or 'master')", optarg);
3156 				return (1);
3157 			}
3158 			break;
3159 
3160 		case 'l':
3161 			if (strcasecmp(optarg, "high") == 0) {
3162 				pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3163 				pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3164 			} else if (strcasecmp(optarg, "maximum") == 0) {
3165 				pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3166 				pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3167 			} else {
3168 				warnx("-l argument '%s' is unknown (must be "
3169 				      "'high' or 'maximum')", optarg);
3170 				return (1);
3171 			}
3172 			break;
3173 
3174 		case 'k':
3175 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3176 				return (1);
3177 			action = ATA_SECURITY_ACTION_UNLOCK;
3178 			actions++;
3179 			break;
3180 
3181 		case 'd':
3182 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3183 				return (1);
3184 			action = ATA_SECURITY_ACTION_DISABLE;
3185 			actions++;
3186 			break;
3187 
3188 		case 'e':
3189 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3190 				return (1);
3191 			action = ATA_SECURITY_ACTION_ERASE;
3192 			actions++;
3193 			break;
3194 
3195 		case 'h':
3196 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3197 				return (1);
3198 			pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3199 			action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3200 			actions++;
3201 			break;
3202 
3203 		case 's':
3204 			if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3205 				return (1);
3206 			setpwd = 1;
3207 			if (action == ATA_SECURITY_ACTION_PRINT)
3208 				action = ATA_SECURITY_ACTION_SET_PASSWORD;
3209 			/*
3210 			 * Don't increment action as this can be combined
3211 			 * with other actions.
3212 			 */
3213 			break;
3214 
3215 		case 'y':
3216 			confirm++;
3217 			break;
3218 
3219 		case 'q':
3220 			quiet++;
3221 			break;
3222 
3223 		case 'T':
3224 			erase_timeout = atoi(optarg) * 1000;
3225 			break;
3226 		}
3227 	}
3228 
3229 	if (actions > 1) {
3230 		warnx("too many security actions specified");
3231 		return (1);
3232 	}
3233 
3234 	if ((ccb = cam_getccb(device)) == NULL) {
3235 		warnx("couldn't allocate CCB");
3236 		return (1);
3237 	}
3238 
3239 	error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3240 	if (error != 0) {
3241 		cam_freeccb(ccb);
3242 		return (1);
3243 	}
3244 
3245 	if (quiet == 0) {
3246 		printf("%s%d: ", device->device_name, device->dev_unit_num);
3247 		ata_print_ident(ident_buf);
3248 		camxferrate(device);
3249 	}
3250 
3251 	if (action == ATA_SECURITY_ACTION_PRINT) {
3252 		atasecurity_print(ident_buf);
3253 		free(ident_buf);
3254 		cam_freeccb(ccb);
3255 		return (0);
3256 	}
3257 
3258 	if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3259 		warnx("Security not supported");
3260 		free(ident_buf);
3261 		cam_freeccb(ccb);
3262 		return (1);
3263 	}
3264 
3265 	/* default timeout 15 seconds the same as linux hdparm */
3266 	timeout = timeout ? timeout : 15 * 1000;
3267 
3268 	security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3269 
3270 	/* first set the password if requested */
3271 	if (setpwd == 1) {
3272 		/* confirm we can erase before setting the password if erasing */
3273 		if (confirm == 0 &&
3274 		    (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3275 		    action == ATA_SECURITY_ACTION_ERASE) &&
3276 		    atasecurity_erase_confirm(device, ident_buf) == 0) {
3277 			cam_freeccb(ccb);
3278 			free(ident_buf);
3279 			return (error);
3280 		}
3281 
3282 		if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3283 			pwd.revision = ident_buf->master_passwd_revision;
3284 			if (pwd.revision != 0 && pwd.revision != 0xfff &&
3285 			    --pwd.revision == 0) {
3286 				pwd.revision = 0xfffe;
3287 			}
3288 		}
3289 		error = atasecurity_set_password(device, ccb, retry_count,
3290 						 timeout, &pwd, quiet);
3291 		if (error != 0) {
3292 			cam_freeccb(ccb);
3293 			free(ident_buf);
3294 			return (error);
3295 		}
3296 		security_enabled = 1;
3297 	}
3298 
3299 	switch(action) {
3300 	case ATA_SECURITY_ACTION_FREEZE:
3301 		error = atasecurity_freeze(device, ccb, retry_count,
3302 					   timeout, quiet);
3303 		break;
3304 
3305 	case ATA_SECURITY_ACTION_UNLOCK:
3306 		if (security_enabled) {
3307 			if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3308 				error = atasecurity_unlock(device, ccb,
3309 					retry_count, timeout, &pwd, quiet);
3310 			} else {
3311 				warnx("Can't unlock, drive is not locked");
3312 				error = 1;
3313 			}
3314 		} else {
3315 			warnx("Can't unlock, security is disabled");
3316 			error = 1;
3317 		}
3318 		break;
3319 
3320 	case ATA_SECURITY_ACTION_DISABLE:
3321 		if (security_enabled) {
3322 			/* First unlock the drive if its locked */
3323 			if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3324 				error = atasecurity_unlock(device, ccb,
3325 							   retry_count,
3326 							   timeout,
3327 							   &pwd,
3328 							   quiet);
3329 			}
3330 
3331 			if (error == 0) {
3332 				error = atasecurity_disable(device,
3333 							    ccb,
3334 							    retry_count,
3335 							    timeout,
3336 							    &pwd,
3337 							    quiet);
3338 			}
3339 		} else {
3340 			warnx("Can't disable security (already disabled)");
3341 			error = 1;
3342 		}
3343 		break;
3344 
3345 	case ATA_SECURITY_ACTION_ERASE:
3346 		if (security_enabled) {
3347 			if (erase_timeout == 0) {
3348 				erase_timeout = atasecurity_erase_timeout_msecs(
3349 				    ident_buf->erase_time);
3350 			}
3351 
3352 			error = atasecurity_erase(device, ccb, retry_count,
3353 			    timeout, erase_timeout, &pwd, quiet);
3354 		} else {
3355 			warnx("Can't secure erase (security is disabled)");
3356 			error = 1;
3357 		}
3358 		break;
3359 
3360 	case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3361 		if (security_enabled) {
3362 			if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3363 				if (erase_timeout == 0) {
3364 					erase_timeout =
3365 					    atasecurity_erase_timeout_msecs(
3366 						ident_buf->enhanced_erase_time);
3367 				}
3368 
3369 				error = atasecurity_erase(device, ccb,
3370 							  retry_count, timeout,
3371 							  erase_timeout, &pwd,
3372 							  quiet);
3373 			} else {
3374 				warnx("Enhanced erase is not supported");
3375 				error = 1;
3376 			}
3377 		} else {
3378 			warnx("Can't secure erase (enhanced), "
3379 			      "(security is disabled)");
3380 			error = 1;
3381 		}
3382 		break;
3383 	}
3384 
3385 	cam_freeccb(ccb);
3386 	free(ident_buf);
3387 
3388 	return (error);
3389 }
3390 
3391 /*
3392  * Convert periph name into a bus, target and lun.
3393  *
3394  * Returns the number of parsed components, or 0.
3395  */
3396 static int
3397 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3398     cam_argmask *arglst)
3399 {
3400 	int fd;
3401 	union ccb ccb;
3402 
3403 	bzero(&ccb, sizeof(ccb));
3404 	ccb.ccb_h.func_code = XPT_GDEVLIST;
3405 	if (cam_get_device(tstr, ccb.cgdl.periph_name,
3406 	    sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3407 		warnx("%s", cam_errbuf);
3408 		return (0);
3409 	}
3410 
3411 	/*
3412 	 * Attempt to get the passthrough device.  This ioctl will
3413 	 * fail if the device name is null, if the device doesn't
3414 	 * exist, or if the passthrough driver isn't in the kernel.
3415 	 */
3416 	if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3417 		warn("Unable to open %s", XPT_DEVICE);
3418 		return (0);
3419 	}
3420 	if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3421 		warn("Unable to find bus:target:lun for device %s%d",
3422 		    ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3423 		close(fd);
3424 		return (0);
3425 	}
3426 	close(fd);
3427 	if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3428 		const struct cam_status_entry *entry;
3429 
3430 		entry = cam_fetch_status_entry(ccb.ccb_h.status);
3431 		warnx("Unable to find bus:target_lun for device %s%d, "
3432 		    "CAM status: %s (%#x)",
3433 		    ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3434 		    entry ? entry->status_text : "Unknown",
3435 		    ccb.ccb_h.status);
3436 		return (0);
3437 	}
3438 
3439 	/*
3440 	 * The kernel fills in the bus/target/lun.  We don't
3441 	 * need the passthrough device name and unit number since
3442 	 * we aren't going to open it.
3443 	 */
3444 	*bus = ccb.ccb_h.path_id;
3445 	*target = ccb.ccb_h.target_id;
3446 	*lun = ccb.ccb_h.target_lun;
3447 	*arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3448 	return (3);
3449 }
3450 
3451 /*
3452  * Parse out a bus, or a bus, target and lun in the following
3453  * format:
3454  * bus
3455  * bus:target
3456  * bus:target:lun
3457  *
3458  * Returns the number of parsed components, or 0.
3459  */
3460 static int
3461 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3462     cam_argmask *arglst)
3463 {
3464 	char *tmpstr, *end;
3465 	int convs = 0;
3466 
3467 	*bus = CAM_BUS_WILDCARD;
3468 	*target = CAM_TARGET_WILDCARD;
3469 	*lun = CAM_LUN_WILDCARD;
3470 
3471 	while (isspace(*tstr) && (*tstr != '\0'))
3472 		tstr++;
3473 
3474 	if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3475 		arglist |= CAM_ARG_BUS;
3476 		return (1);
3477 	}
3478 
3479 	if (!isdigit(*tstr))
3480 		return (parse_btl_name(tstr, bus, target, lun, arglst));
3481 
3482 	tmpstr = strsep(&tstr, ":");
3483 	if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3484 		*bus = strtol(tmpstr, &end, 0);
3485 		if (*end != '\0')
3486 			return (0);
3487 		*arglst |= CAM_ARG_BUS;
3488 		convs++;
3489 		tmpstr = strsep(&tstr, ":");
3490 		if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3491 			*target = strtol(tmpstr, &end, 0);
3492 			if (*end != '\0')
3493 				return (0);
3494 			*arglst |= CAM_ARG_TARGET;
3495 			convs++;
3496 			tmpstr = strsep(&tstr, ":");
3497 			if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3498 				*lun = strtoll(tmpstr, &end, 0);
3499 				if (*end != '\0')
3500 					return (0);
3501 				*arglst |= CAM_ARG_LUN;
3502 				convs++;
3503 			}
3504 		}
3505 	}
3506 
3507 	return convs;
3508 }
3509 
3510 static int
3511 dorescan_or_reset(int argc, char **argv, int rescan)
3512 {
3513 	static const char must[] =
3514 	    "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3515 	int rv, error = 0;
3516 	path_id_t bus = CAM_BUS_WILDCARD;
3517 	target_id_t target = CAM_TARGET_WILDCARD;
3518 	lun_id_t lun = CAM_LUN_WILDCARD;
3519 	char *tstr;
3520 
3521 	if (argc < 3) {
3522 		warnx(must, rescan? "rescan" : "reset");
3523 		return (1);
3524 	}
3525 
3526 	tstr = argv[optind];
3527 	while (isspace(*tstr) && (*tstr != '\0'))
3528 		tstr++;
3529 	if (strncasecmp(tstr, "all", strlen("all")) == 0)
3530 		arglist |= CAM_ARG_BUS;
3531 	else {
3532 		rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3533 		if (rv != 1 && rv != 3) {
3534 			warnx(must, rescan ? "rescan" : "reset");
3535 			return (1);
3536 		}
3537 	}
3538 
3539 	if (arglist & CAM_ARG_LUN)
3540 		error = scanlun_or_reset_dev(bus, target, lun, rescan);
3541 	else
3542 		error = rescan_or_reset_bus(bus, rescan);
3543 
3544 	return (error);
3545 }
3546 
3547 static int
3548 rescan_or_reset_bus(path_id_t bus, int rescan)
3549 {
3550 	union ccb *ccb = NULL, *matchccb = NULL;
3551 	int fd = -1, retval;
3552 	int bufsize;
3553 
3554 	retval = 0;
3555 
3556 	if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3557 		warnx("error opening transport layer device %s", XPT_DEVICE);
3558 		warn("%s", XPT_DEVICE);
3559 		return (1);
3560 	}
3561 
3562 	ccb = malloc(sizeof(*ccb));
3563 	if (ccb == NULL) {
3564 		warn("failed to allocate CCB");
3565 		retval = 1;
3566 		goto bailout;
3567 	}
3568 	bzero(ccb, sizeof(*ccb));
3569 
3570 	if (bus != CAM_BUS_WILDCARD) {
3571 		ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3572 		ccb->ccb_h.path_id = bus;
3573 		ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3574 		ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3575 		ccb->crcn.flags = CAM_FLAG_NONE;
3576 
3577 		/* run this at a low priority */
3578 		ccb->ccb_h.pinfo.priority = 5;
3579 
3580 		if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3581 			warn("CAMIOCOMMAND ioctl failed");
3582 			retval = 1;
3583 			goto bailout;
3584 		}
3585 
3586 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3587 			fprintf(stdout, "%s of bus %d was successful\n",
3588 			    rescan ? "Re-scan" : "Reset", bus);
3589 		} else {
3590 			fprintf(stdout, "%s of bus %d returned error %#x\n",
3591 				rescan ? "Re-scan" : "Reset", bus,
3592 				ccb->ccb_h.status & CAM_STATUS_MASK);
3593 			retval = 1;
3594 		}
3595 
3596 		goto bailout;
3597 	}
3598 
3599 
3600 	/*
3601 	 * The right way to handle this is to modify the xpt so that it can
3602 	 * handle a wildcarded bus in a rescan or reset CCB.  At the moment
3603 	 * that isn't implemented, so instead we enumerate the buses and
3604 	 * send the rescan or reset to those buses in the case where the
3605 	 * given bus is -1 (wildcard).  We don't send a rescan or reset
3606 	 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3607 	 * no-op, sending a rescan to the xpt bus would result in a status of
3608 	 * CAM_REQ_INVALID.
3609 	 */
3610 	matchccb = malloc(sizeof(*matchccb));
3611 	if (matchccb == NULL) {
3612 		warn("failed to allocate CCB");
3613 		retval = 1;
3614 		goto bailout;
3615 	}
3616 	bzero(matchccb, sizeof(*matchccb));
3617 	matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3618 	matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3619 	bufsize = sizeof(struct dev_match_result) * 20;
3620 	matchccb->cdm.match_buf_len = bufsize;
3621 	matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3622 	if (matchccb->cdm.matches == NULL) {
3623 		warnx("can't malloc memory for matches");
3624 		retval = 1;
3625 		goto bailout;
3626 	}
3627 	matchccb->cdm.num_matches = 0;
3628 
3629 	matchccb->cdm.num_patterns = 1;
3630 	matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3631 
3632 	matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3633 		matchccb->cdm.pattern_buf_len);
3634 	if (matchccb->cdm.patterns == NULL) {
3635 		warnx("can't malloc memory for patterns");
3636 		retval = 1;
3637 		goto bailout;
3638 	}
3639 	matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3640 	matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3641 
3642 	do {
3643 		unsigned int i;
3644 
3645 		if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3646 			warn("CAMIOCOMMAND ioctl failed");
3647 			retval = 1;
3648 			goto bailout;
3649 		}
3650 
3651 		if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3652 		 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3653 		   && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3654 			warnx("got CAM error %#x, CDM error %d\n",
3655 			      matchccb->ccb_h.status, matchccb->cdm.status);
3656 			retval = 1;
3657 			goto bailout;
3658 		}
3659 
3660 		for (i = 0; i < matchccb->cdm.num_matches; i++) {
3661 			struct bus_match_result *bus_result;
3662 
3663 			/* This shouldn't happen. */
3664 			if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3665 				continue;
3666 
3667 			bus_result =&matchccb->cdm.matches[i].result.bus_result;
3668 
3669 			/*
3670 			 * We don't want to rescan or reset the xpt bus.
3671 			 * See above.
3672 			 */
3673 			if (bus_result->path_id == CAM_XPT_PATH_ID)
3674 				continue;
3675 
3676 			ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3677 						       XPT_RESET_BUS;
3678 			ccb->ccb_h.path_id = bus_result->path_id;
3679 			ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3680 			ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3681 			ccb->crcn.flags = CAM_FLAG_NONE;
3682 
3683 			/* run this at a low priority */
3684 			ccb->ccb_h.pinfo.priority = 5;
3685 
3686 			if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3687 				warn("CAMIOCOMMAND ioctl failed");
3688 				retval = 1;
3689 				goto bailout;
3690 			}
3691 
3692 			if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3693 				fprintf(stdout, "%s of bus %d was successful\n",
3694 					rescan? "Re-scan" : "Reset",
3695 					bus_result->path_id);
3696 			} else {
3697 				/*
3698 				 * Don't bail out just yet, maybe the other
3699 				 * rescan or reset commands will complete
3700 				 * successfully.
3701 				 */
3702 				fprintf(stderr, "%s of bus %d returned error "
3703 					"%#x\n", rescan? "Re-scan" : "Reset",
3704 					bus_result->path_id,
3705 					ccb->ccb_h.status & CAM_STATUS_MASK);
3706 				retval = 1;
3707 			}
3708 		}
3709 	} while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3710 		 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3711 
3712 bailout:
3713 
3714 	if (fd != -1)
3715 		close(fd);
3716 
3717 	if (matchccb != NULL) {
3718 		free(matchccb->cdm.patterns);
3719 		free(matchccb->cdm.matches);
3720 		free(matchccb);
3721 	}
3722 	free(ccb);
3723 
3724 	return (retval);
3725 }
3726 
3727 static int
3728 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3729 {
3730 	union ccb ccb;
3731 	struct cam_device *device;
3732 	int fd;
3733 
3734 	device = NULL;
3735 
3736 	if (bus == CAM_BUS_WILDCARD) {
3737 		warnx("invalid bus number %d", bus);
3738 		return (1);
3739 	}
3740 
3741 	if (target == CAM_TARGET_WILDCARD) {
3742 		warnx("invalid target number %d", target);
3743 		return (1);
3744 	}
3745 
3746 	if (lun == CAM_LUN_WILDCARD) {
3747 		warnx("invalid lun number %jx", (uintmax_t)lun);
3748 		return (1);
3749 	}
3750 
3751 	fd = -1;
3752 
3753 	bzero(&ccb, sizeof(union ccb));
3754 
3755 	if (scan) {
3756 		if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3757 			warnx("error opening transport layer device %s\n",
3758 			    XPT_DEVICE);
3759 			warn("%s", XPT_DEVICE);
3760 			return (1);
3761 		}
3762 	} else {
3763 		device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3764 		if (device == NULL) {
3765 			warnx("%s", cam_errbuf);
3766 			return (1);
3767 		}
3768 	}
3769 
3770 	ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3771 	ccb.ccb_h.path_id = bus;
3772 	ccb.ccb_h.target_id = target;
3773 	ccb.ccb_h.target_lun = lun;
3774 	ccb.ccb_h.timeout = 5000;
3775 	ccb.crcn.flags = CAM_FLAG_NONE;
3776 
3777 	/* run this at a low priority */
3778 	ccb.ccb_h.pinfo.priority = 5;
3779 
3780 	if (scan) {
3781 		if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3782 			warn("CAMIOCOMMAND ioctl failed");
3783 			close(fd);
3784 			return (1);
3785 		}
3786 	} else {
3787 		if (cam_send_ccb(device, &ccb) < 0) {
3788 			warn("error sending XPT_RESET_DEV CCB");
3789 			cam_close_device(device);
3790 			return (1);
3791 		}
3792 	}
3793 
3794 	if (scan)
3795 		close(fd);
3796 	else
3797 		cam_close_device(device);
3798 
3799 	/*
3800 	 * An error code of CAM_BDR_SENT is normal for a BDR request.
3801 	 */
3802 	if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3803 	 || ((!scan)
3804 	  && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3805 		fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3806 		    scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3807 		return (0);
3808 	} else {
3809 		fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3810 		    scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3811 		    ccb.ccb_h.status & CAM_STATUS_MASK);
3812 		return (1);
3813 	}
3814 }
3815 
3816 
3817 static struct scsi_nv defect_list_type_map[] = {
3818 	{ "block", SRDD10_BLOCK_FORMAT },
3819 	{ "extbfi", SRDD10_EXT_BFI_FORMAT },
3820 	{ "extphys", SRDD10_EXT_PHYS_FORMAT },
3821 	{ "longblock", SRDD10_LONG_BLOCK_FORMAT },
3822 	{ "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3823 	{ "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3824 };
3825 
3826 static int
3827 readdefects(struct cam_device *device, int argc, char **argv,
3828 	    char *combinedopt, int task_attr, int retry_count, int timeout)
3829 {
3830 	union ccb *ccb = NULL;
3831 	struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3832 	struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3833 	size_t hdr_size = 0, entry_size = 0;
3834 	int use_12byte = 0;
3835 	int hex_format = 0;
3836 	u_int8_t *defect_list = NULL;
3837 	u_int8_t list_format = 0;
3838 	int list_type_set = 0;
3839 	u_int32_t dlist_length = 0;
3840 	u_int32_t returned_length = 0, valid_len = 0;
3841 	u_int32_t num_returned = 0, num_valid = 0;
3842 	u_int32_t max_possible_size = 0, hdr_max = 0;
3843 	u_int32_t starting_offset = 0;
3844 	u_int8_t returned_format, returned_type;
3845 	unsigned int i;
3846 	int summary = 0, quiet = 0;
3847 	int c, error = 0;
3848 	int lists_specified = 0;
3849 	int get_length = 1, first_pass = 1;
3850 	int mads = 0;
3851 
3852 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3853 		switch(c){
3854 		case 'f':
3855 		{
3856 			scsi_nv_status status;
3857 			int entry_num = 0;
3858 
3859 			status = scsi_get_nv(defect_list_type_map,
3860 			    sizeof(defect_list_type_map) /
3861 			    sizeof(defect_list_type_map[0]), optarg,
3862 			    &entry_num, SCSI_NV_FLAG_IG_CASE);
3863 
3864 			if (status == SCSI_NV_FOUND) {
3865 				list_format = defect_list_type_map[
3866 				    entry_num].value;
3867 				list_type_set = 1;
3868 			} else {
3869 				warnx("%s: %s %s option %s", __func__,
3870 				    (status == SCSI_NV_AMBIGUOUS) ?
3871 				    "ambiguous" : "invalid", "defect list type",
3872 				    optarg);
3873 				error = 1;
3874 				goto defect_bailout;
3875 			}
3876 			break;
3877 		}
3878 		case 'G':
3879 			arglist |= CAM_ARG_GLIST;
3880 			break;
3881 		case 'P':
3882 			arglist |= CAM_ARG_PLIST;
3883 			break;
3884 		case 'q':
3885 			quiet = 1;
3886 			break;
3887 		case 's':
3888 			summary = 1;
3889 			break;
3890 		case 'S': {
3891 			char *endptr;
3892 
3893 			starting_offset = strtoul(optarg, &endptr, 0);
3894 			if (*endptr != '\0') {
3895 				error = 1;
3896 				warnx("invalid starting offset %s", optarg);
3897 				goto defect_bailout;
3898 			}
3899 			break;
3900 		}
3901 		case 'X':
3902 			hex_format = 1;
3903 			break;
3904 		default:
3905 			break;
3906 		}
3907 	}
3908 
3909 	if (list_type_set == 0) {
3910 		error = 1;
3911 		warnx("no defect list format specified");
3912 		goto defect_bailout;
3913 	}
3914 
3915 	if (arglist & CAM_ARG_PLIST) {
3916 		list_format |= SRDD10_PLIST;
3917 		lists_specified++;
3918 	}
3919 
3920 	if (arglist & CAM_ARG_GLIST) {
3921 		list_format |= SRDD10_GLIST;
3922 		lists_specified++;
3923 	}
3924 
3925 	/*
3926 	 * This implies a summary, and was the previous behavior.
3927 	 */
3928 	if (lists_specified == 0)
3929 		summary = 1;
3930 
3931 	ccb = cam_getccb(device);
3932 
3933 retry_12byte:
3934 
3935 	/*
3936 	 * We start off asking for just the header to determine how much
3937 	 * defect data is available.  Some Hitachi drives return an error
3938 	 * if you ask for more data than the drive has.  Once we know the
3939 	 * length, we retry the command with the returned length.
3940 	 */
3941 	if (use_12byte == 0)
3942 		dlist_length = sizeof(*hdr10);
3943 	else
3944 		dlist_length = sizeof(*hdr12);
3945 
3946 retry:
3947 	if (defect_list != NULL) {
3948 		free(defect_list);
3949 		defect_list = NULL;
3950 	}
3951 	defect_list = malloc(dlist_length);
3952 	if (defect_list == NULL) {
3953 		warnx("can't malloc memory for defect list");
3954 		error = 1;
3955 		goto defect_bailout;
3956 	}
3957 
3958 next_batch:
3959 	bzero(defect_list, dlist_length);
3960 
3961 	/*
3962 	 * cam_getccb() zeros the CCB header only.  So we need to zero the
3963 	 * payload portion of the ccb.
3964 	 */
3965 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3966 
3967 	scsi_read_defects(&ccb->csio,
3968 			  /*retries*/ retry_count,
3969 			  /*cbfcnp*/ NULL,
3970 			  /*tag_action*/ task_attr,
3971 			  /*list_format*/ list_format,
3972 			  /*addr_desc_index*/ starting_offset,
3973 			  /*data_ptr*/ defect_list,
3974 			  /*dxfer_len*/ dlist_length,
3975 			  /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3976 			  /*sense_len*/ SSD_FULL_SIZE,
3977 			  /*timeout*/ timeout ? timeout : 5000);
3978 
3979 	/* Disable freezing the device queue */
3980 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3981 
3982 	if (cam_send_ccb(device, ccb) < 0) {
3983 		warn("error sending READ DEFECT DATA command");
3984 		error = 1;
3985 		goto defect_bailout;
3986 	}
3987 
3988 	valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3989 
3990 	if (use_12byte == 0) {
3991 		hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3992 		hdr_size = sizeof(*hdr10);
3993 		hdr_max = SRDDH10_MAX_LENGTH;
3994 
3995 		if (valid_len >= hdr_size) {
3996 			returned_length = scsi_2btoul(hdr10->length);
3997 			returned_format = hdr10->format;
3998 		} else {
3999 			returned_length = 0;
4000 			returned_format = 0;
4001 		}
4002 	} else {
4003 		hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4004 		hdr_size = sizeof(*hdr12);
4005 		hdr_max = SRDDH12_MAX_LENGTH;
4006 
4007 		if (valid_len >= hdr_size) {
4008 			returned_length = scsi_4btoul(hdr12->length);
4009 			returned_format = hdr12->format;
4010 		} else {
4011 			returned_length = 0;
4012 			returned_format = 0;
4013 		}
4014 	}
4015 
4016 	returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4017 	switch (returned_type) {
4018 	case SRDD10_BLOCK_FORMAT:
4019 		entry_size = sizeof(struct scsi_defect_desc_block);
4020 		break;
4021 	case SRDD10_LONG_BLOCK_FORMAT:
4022 		entry_size = sizeof(struct scsi_defect_desc_long_block);
4023 		break;
4024 	case SRDD10_EXT_PHYS_FORMAT:
4025 	case SRDD10_PHYSICAL_SECTOR_FORMAT:
4026 		entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4027 		break;
4028 	case SRDD10_EXT_BFI_FORMAT:
4029 	case SRDD10_BYTES_FROM_INDEX_FORMAT:
4030 		entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4031 		break;
4032 	default:
4033 		warnx("Unknown defect format 0x%x\n", returned_type);
4034 		error = 1;
4035 		goto defect_bailout;
4036 		break;
4037 	}
4038 
4039 	max_possible_size = (hdr_max / entry_size) * entry_size;
4040 	num_returned = returned_length / entry_size;
4041 	num_valid = min(returned_length, valid_len - hdr_size);
4042 	num_valid /= entry_size;
4043 
4044 	if (get_length != 0) {
4045 		get_length = 0;
4046 
4047 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4048 		     CAM_SCSI_STATUS_ERROR) {
4049 			struct scsi_sense_data *sense;
4050 			int error_code, sense_key, asc, ascq;
4051 
4052 			sense = &ccb->csio.sense_data;
4053 			scsi_extract_sense_len(sense, ccb->csio.sense_len -
4054 			    ccb->csio.sense_resid, &error_code, &sense_key,
4055 			    &asc, &ascq, /*show_errors*/ 1);
4056 
4057 			/*
4058 			 * If the drive is reporting that it just doesn't
4059 			 * support the defect list format, go ahead and use
4060 			 * the length it reported.  Otherwise, the length
4061 			 * may not be valid, so use the maximum.
4062 			 */
4063 			if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4064 			 && (asc == 0x1c) && (ascq == 0x00)
4065 			 && (returned_length > 0)) {
4066 				if ((use_12byte == 0)
4067 				 && (returned_length >= max_possible_size)) {
4068 					get_length = 1;
4069 					use_12byte = 1;
4070 					goto retry_12byte;
4071 				}
4072 				dlist_length = returned_length + hdr_size;
4073 			} else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4074 				&& (asc == 0x1f) && (ascq == 0x00)
4075 				&& (returned_length > 0)) {
4076 				/* Partial defect list transfer */
4077 				/*
4078 				 * Hitachi drives return this error
4079 				 * along with a partial defect list if they
4080 				 * have more defects than the 10 byte
4081 				 * command can support.  Retry with the 12
4082 				 * byte command.
4083 				 */
4084 				if (use_12byte == 0) {
4085 					get_length = 1;
4086 					use_12byte = 1;
4087 					goto retry_12byte;
4088 				}
4089 				dlist_length = returned_length + hdr_size;
4090 			} else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4091 				&& (asc == 0x24) && (ascq == 0x00)) {
4092 				/* Invalid field in CDB */
4093 				/*
4094 				 * SBC-3 says that if the drive has more
4095 				 * defects than can be reported with the
4096 				 * 10 byte command, it should return this
4097 	 			 * error and no data.  Retry with the 12
4098 				 * byte command.
4099 				 */
4100 				if (use_12byte == 0) {
4101 					get_length = 1;
4102 					use_12byte = 1;
4103 					goto retry_12byte;
4104 				}
4105 				dlist_length = returned_length + hdr_size;
4106 			} else {
4107 				/*
4108 				 * If we got a SCSI error and no valid length,
4109 				 * just use the 10 byte maximum.  The 12
4110 				 * byte maximum is too large.
4111 				 */
4112 				if (returned_length == 0)
4113 					dlist_length = SRDD10_MAX_LENGTH;
4114 				else {
4115 					if ((use_12byte == 0)
4116 					 && (returned_length >=
4117 					     max_possible_size)) {
4118 						get_length = 1;
4119 						use_12byte = 1;
4120 						goto retry_12byte;
4121 					}
4122 					dlist_length = returned_length +
4123 					    hdr_size;
4124 				}
4125 			}
4126 		} else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4127 			    CAM_REQ_CMP){
4128 			error = 1;
4129 			warnx("Error reading defect header");
4130 			if (arglist & CAM_ARG_VERBOSE)
4131 				cam_error_print(device, ccb, CAM_ESF_ALL,
4132 						CAM_EPF_ALL, stderr);
4133 			goto defect_bailout;
4134 		} else {
4135 			if ((use_12byte == 0)
4136 			 && (returned_length >= max_possible_size)) {
4137 				get_length = 1;
4138 				use_12byte = 1;
4139 				goto retry_12byte;
4140 			}
4141 			dlist_length = returned_length + hdr_size;
4142 		}
4143 		if (summary != 0) {
4144 			fprintf(stdout, "%u", num_returned);
4145 			if (quiet == 0) {
4146 				fprintf(stdout, " defect%s",
4147 					(num_returned != 1) ? "s" : "");
4148 			}
4149 			fprintf(stdout, "\n");
4150 
4151 			goto defect_bailout;
4152 		}
4153 
4154 		/*
4155 		 * We always limit the list length to the 10-byte maximum
4156 		 * length (0xffff).  The reason is that some controllers
4157 		 * can't handle larger I/Os, and we can transfer the entire
4158 		 * 10 byte list in one shot.  For drives that support the 12
4159 		 * byte read defects command, we'll step through the list
4160 		 * by specifying a starting offset.  For drives that don't
4161 		 * support the 12 byte command's starting offset, we'll
4162 		 * just display the first 64K.
4163 		 */
4164 		dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4165 
4166 		goto retry;
4167 	}
4168 
4169 
4170 	if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4171 	 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4172 	 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4173 		struct scsi_sense_data *sense;
4174 		int error_code, sense_key, asc, ascq;
4175 
4176 		sense = &ccb->csio.sense_data;
4177 		scsi_extract_sense_len(sense, ccb->csio.sense_len -
4178 		    ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4179 		    &ascq, /*show_errors*/ 1);
4180 
4181 		/*
4182 		 * According to the SCSI spec, if the disk doesn't support
4183 		 * the requested format, it will generally return a sense
4184 		 * key of RECOVERED ERROR, and an additional sense code
4185 		 * of "DEFECT LIST NOT FOUND".  HGST drives also return
4186 		 * Primary/Grown defect list not found errors.  So just
4187 		 * check for an ASC of 0x1c.
4188 		 */
4189 		if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4190 		 && (asc == 0x1c)) {
4191 			const char *format_str;
4192 
4193 			format_str = scsi_nv_to_str(defect_list_type_map,
4194 			    sizeof(defect_list_type_map) /
4195 			    sizeof(defect_list_type_map[0]),
4196 			    list_format & SRDD10_DLIST_FORMAT_MASK);
4197 			warnx("requested defect format %s not available",
4198 			    format_str ? format_str : "unknown");
4199 
4200 			format_str = scsi_nv_to_str(defect_list_type_map,
4201 			    sizeof(defect_list_type_map) /
4202 			    sizeof(defect_list_type_map[0]), returned_type);
4203 			if (format_str != NULL) {
4204 				warnx("Device returned %s format",
4205 				    format_str);
4206 			} else {
4207 				error = 1;
4208 				warnx("Device returned unknown defect"
4209 				     " data format %#x", returned_type);
4210 				goto defect_bailout;
4211 			}
4212 		} else {
4213 			error = 1;
4214 			warnx("Error returned from read defect data command");
4215 			if (arglist & CAM_ARG_VERBOSE)
4216 				cam_error_print(device, ccb, CAM_ESF_ALL,
4217 						CAM_EPF_ALL, stderr);
4218 			goto defect_bailout;
4219 		}
4220 	} else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4221 		error = 1;
4222 		warnx("Error returned from read defect data command");
4223 		if (arglist & CAM_ARG_VERBOSE)
4224 			cam_error_print(device, ccb, CAM_ESF_ALL,
4225 					CAM_EPF_ALL, stderr);
4226 		goto defect_bailout;
4227 	}
4228 
4229 	if (first_pass != 0) {
4230 		fprintf(stderr, "Got %d defect", num_returned);
4231 
4232 		if ((lists_specified == 0) || (num_returned == 0)) {
4233 			fprintf(stderr, "s.\n");
4234 			goto defect_bailout;
4235 		} else if (num_returned == 1)
4236 			fprintf(stderr, ":\n");
4237 		else
4238 			fprintf(stderr, "s:\n");
4239 
4240 		first_pass = 0;
4241 	}
4242 
4243 	/*
4244 	 * XXX KDM  I should probably clean up the printout format for the
4245 	 * disk defects.
4246 	 */
4247 	switch (returned_type) {
4248 	case SRDD10_PHYSICAL_SECTOR_FORMAT:
4249 	case SRDD10_EXT_PHYS_FORMAT:
4250 	{
4251 		struct scsi_defect_desc_phys_sector *dlist;
4252 
4253 		dlist = (struct scsi_defect_desc_phys_sector *)
4254 			(defect_list + hdr_size);
4255 
4256 		for (i = 0; i < num_valid; i++) {
4257 			uint32_t sector;
4258 
4259 			sector = scsi_4btoul(dlist[i].sector);
4260 			if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4261 				mads = (sector & SDD_EXT_PHYS_MADS) ?
4262 				       0 : 1;
4263 				sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4264 			}
4265 			if (hex_format == 0)
4266 				fprintf(stdout, "%d:%d:%d%s",
4267 					scsi_3btoul(dlist[i].cylinder),
4268 					dlist[i].head,
4269 					scsi_4btoul(dlist[i].sector),
4270 					mads ? " - " : "\n");
4271 			else
4272 				fprintf(stdout, "0x%x:0x%x:0x%x%s",
4273 					scsi_3btoul(dlist[i].cylinder),
4274 					dlist[i].head,
4275 					scsi_4btoul(dlist[i].sector),
4276 					mads ? " - " : "\n");
4277 			mads = 0;
4278 		}
4279 		if (num_valid < num_returned) {
4280 			starting_offset += num_valid;
4281 			goto next_batch;
4282 		}
4283 		break;
4284 	}
4285 	case SRDD10_BYTES_FROM_INDEX_FORMAT:
4286 	case SRDD10_EXT_BFI_FORMAT:
4287 	{
4288 		struct scsi_defect_desc_bytes_from_index *dlist;
4289 
4290 		dlist = (struct scsi_defect_desc_bytes_from_index *)
4291 			(defect_list + hdr_size);
4292 
4293 		for (i = 0; i < num_valid; i++) {
4294 			uint32_t bfi;
4295 
4296 			bfi = scsi_4btoul(dlist[i].bytes_from_index);
4297 			if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4298 				mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4299 				bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4300 			}
4301 			if (hex_format == 0)
4302 				fprintf(stdout, "%d:%d:%d%s",
4303 					scsi_3btoul(dlist[i].cylinder),
4304 					dlist[i].head,
4305 					scsi_4btoul(dlist[i].bytes_from_index),
4306 					mads ? " - " : "\n");
4307 			else
4308 				fprintf(stdout, "0x%x:0x%x:0x%x%s",
4309 					scsi_3btoul(dlist[i].cylinder),
4310 					dlist[i].head,
4311 					scsi_4btoul(dlist[i].bytes_from_index),
4312 					mads ? " - " : "\n");
4313 
4314 			mads = 0;
4315 		}
4316 		if (num_valid < num_returned) {
4317 			starting_offset += num_valid;
4318 			goto next_batch;
4319 		}
4320 		break;
4321 	}
4322 	case SRDDH10_BLOCK_FORMAT:
4323 	{
4324 		struct scsi_defect_desc_block *dlist;
4325 
4326 		dlist = (struct scsi_defect_desc_block *)
4327 			(defect_list + hdr_size);
4328 
4329 		for (i = 0; i < num_valid; i++) {
4330 			if (hex_format == 0)
4331 				fprintf(stdout, "%u\n",
4332 					scsi_4btoul(dlist[i].address));
4333 			else
4334 				fprintf(stdout, "0x%x\n",
4335 					scsi_4btoul(dlist[i].address));
4336 		}
4337 
4338 		if (num_valid < num_returned) {
4339 			starting_offset += num_valid;
4340 			goto next_batch;
4341 		}
4342 
4343 		break;
4344 	}
4345 	case SRDD10_LONG_BLOCK_FORMAT:
4346 	{
4347 		struct scsi_defect_desc_long_block *dlist;
4348 
4349 		dlist = (struct scsi_defect_desc_long_block *)
4350 			(defect_list + hdr_size);
4351 
4352 		for (i = 0; i < num_valid; i++) {
4353 			if (hex_format == 0)
4354 				fprintf(stdout, "%ju\n",
4355 					(uintmax_t)scsi_8btou64(
4356 					dlist[i].address));
4357 			else
4358 				fprintf(stdout, "0x%jx\n",
4359 					(uintmax_t)scsi_8btou64(
4360 					dlist[i].address));
4361 		}
4362 
4363 		if (num_valid < num_returned) {
4364 			starting_offset += num_valid;
4365 			goto next_batch;
4366 		}
4367 		break;
4368 	}
4369 	default:
4370 		fprintf(stderr, "Unknown defect format 0x%x\n",
4371 			returned_type);
4372 		error = 1;
4373 		break;
4374 	}
4375 defect_bailout:
4376 
4377 	if (defect_list != NULL)
4378 		free(defect_list);
4379 
4380 	if (ccb != NULL)
4381 		cam_freeccb(ccb);
4382 
4383 	return (error);
4384 }
4385 
4386 #if 0
4387 void
4388 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4389 {
4390 	union ccb *ccb;
4391 
4392 	ccb = cam_getccb(device);
4393 
4394 	cam_freeccb(ccb);
4395 }
4396 #endif
4397 
4398 void
4399 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4400     int page, int subpage, int task_attr, int retry_count, int timeout,
4401     u_int8_t *data, int datalen)
4402 {
4403 	union ccb *ccb;
4404 	int error_code, sense_key, asc, ascq;
4405 
4406 	ccb = cam_getccb(device);
4407 	if (ccb == NULL)
4408 		errx(1, "mode_sense: couldn't allocate CCB");
4409 
4410 retry:
4411 	/*
4412 	 * MODE SENSE(6) can't handle more then 255 bytes.  If there are more,
4413 	 * device must return error, so we should not get trucated data.
4414 	 */
4415 	if (*cdb_len == 6 && datalen > 255)
4416 		datalen = 255;
4417 
4418 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4419 
4420 	scsi_mode_sense_subpage(&ccb->csio,
4421 			/* retries */ retry_count,
4422 			/* cbfcnp */ NULL,
4423 			/* tag_action */ task_attr,
4424 			/* dbd */ dbd,
4425 			/* pc */ pc << 6,
4426 			/* page */ page,
4427 			/* subpage */ subpage,
4428 			/* param_buf */ data,
4429 			/* param_len */ datalen,
4430 			/* minimum_cmd_size */ *cdb_len,
4431 			/* sense_len */ SSD_FULL_SIZE,
4432 			/* timeout */ timeout ? timeout : 5000);
4433 	if (llbaa && ccb->csio.cdb_len == 10) {
4434 		struct scsi_mode_sense_10 *cdb =
4435 		    (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4436 		cdb->byte2 |= SMS10_LLBAA;
4437 	}
4438 
4439 	/* Record what CDB size the above function really set. */
4440 	*cdb_len = ccb->csio.cdb_len;
4441 
4442 	if (arglist & CAM_ARG_ERR_RECOVER)
4443 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4444 
4445 	/* Disable freezing the device queue */
4446 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4447 
4448 	if (cam_send_ccb(device, ccb) < 0)
4449 		err(1, "error sending mode sense command");
4450 
4451 	/* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4452 	if (*cdb_len != 6 &&
4453 	    ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4454 	     (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4455 	      && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4456 		*cdb_len = 6;
4457 		goto retry;
4458 	}
4459 
4460 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4461 		if (arglist & CAM_ARG_VERBOSE) {
4462 			cam_error_print(device, ccb, CAM_ESF_ALL,
4463 					CAM_EPF_ALL, stderr);
4464 		}
4465 		cam_freeccb(ccb);
4466 		cam_close_device(device);
4467 		errx(1, "mode sense command returned error");
4468 	}
4469 
4470 	cam_freeccb(ccb);
4471 }
4472 
4473 void
4474 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4475     int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4476 {
4477 	union ccb *ccb;
4478 	int retval;
4479 
4480 	ccb = cam_getccb(device);
4481 
4482 	if (ccb == NULL)
4483 		errx(1, "mode_select: couldn't allocate CCB");
4484 
4485 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4486 
4487 	scsi_mode_select_len(&ccb->csio,
4488 			 /* retries */ retry_count,
4489 			 /* cbfcnp */ NULL,
4490 			 /* tag_action */ task_attr,
4491 			 /* scsi_page_fmt */ 1,
4492 			 /* save_pages */ save_pages,
4493 			 /* param_buf */ data,
4494 			 /* param_len */ datalen,
4495 			 /* minimum_cmd_size */ cdb_len,
4496 			 /* sense_len */ SSD_FULL_SIZE,
4497 			 /* timeout */ timeout ? timeout : 5000);
4498 
4499 	if (arglist & CAM_ARG_ERR_RECOVER)
4500 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4501 
4502 	/* Disable freezing the device queue */
4503 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4504 
4505 	if (((retval = cam_send_ccb(device, ccb)) < 0)
4506 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4507 		if (arglist & CAM_ARG_VERBOSE) {
4508 			cam_error_print(device, ccb, CAM_ESF_ALL,
4509 					CAM_EPF_ALL, stderr);
4510 		}
4511 		cam_freeccb(ccb);
4512 		cam_close_device(device);
4513 
4514 		if (retval < 0)
4515 			err(1, "error sending mode select command");
4516 		else
4517 			errx(1, "error sending mode select command");
4518 
4519 	}
4520 
4521 	cam_freeccb(ccb);
4522 }
4523 
4524 void
4525 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4526 	 int task_attr, int retry_count, int timeout)
4527 {
4528 	char *str_subpage;
4529 	int c, page = -1, subpage = 0, pc = 0, llbaa = 0;
4530 	int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4531 
4532 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
4533 		switch(c) {
4534 		case '6':
4535 			cdb_len = 6;
4536 			break;
4537 		case 'b':
4538 			binary = 1;
4539 			break;
4540 		case 'd':
4541 			dbd = 1;
4542 			break;
4543 		case 'e':
4544 			edit = 1;
4545 			break;
4546 		case 'l':
4547 			list++;
4548 			break;
4549 		case 'm':
4550 			str_subpage = optarg;
4551 			strsep(&str_subpage, ",");
4552 			page = strtol(optarg, NULL, 0);
4553 			if (str_subpage)
4554 			    subpage = strtol(str_subpage, NULL, 0);
4555 			if (page < 0 || page > 0x3f)
4556 				errx(1, "invalid mode page %d", page);
4557 			if (subpage < 0 || subpage > 0xff)
4558 				errx(1, "invalid mode subpage %d", subpage);
4559 			break;
4560 		case 'D':
4561 			desc = 1;
4562 			break;
4563 		case 'L':
4564 			llbaa = 1;
4565 			break;
4566 		case 'P':
4567 			pc = strtol(optarg, NULL, 0);
4568 			if ((pc < 0) || (pc > 3))
4569 				errx(1, "invalid page control field %d", pc);
4570 			break;
4571 		default:
4572 			break;
4573 		}
4574 	}
4575 
4576 	if (desc && page == -1)
4577 		page = SMS_ALL_PAGES_PAGE;
4578 
4579 	if (page == -1 && list == 0)
4580 		errx(1, "you must specify a mode page!");
4581 
4582 	if (dbd && desc)
4583 		errx(1, "-d and -D are incompatible!");
4584 
4585 	if (llbaa && cdb_len != 10)
4586 		errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4587 
4588 	if (list != 0) {
4589 		mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4590 		    retry_count, timeout);
4591 	} else {
4592 		mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4593 		    edit, binary, task_attr, retry_count, timeout);
4594 	}
4595 }
4596 
4597 static int
4598 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4599 	int task_attr, int retry_count, int timeout)
4600 {
4601 	union ccb *ccb;
4602 	u_int32_t flags = CAM_DIR_NONE;
4603 	u_int8_t *data_ptr = NULL;
4604 	u_int8_t cdb[20];
4605 	u_int8_t atacmd[12];
4606 	struct get_hook hook;
4607 	int c, data_bytes = 0, valid_bytes;
4608 	int cdb_len = 0;
4609 	int atacmd_len = 0;
4610 	int dmacmd = 0;
4611 	int fpdmacmd = 0;
4612 	int need_res = 0;
4613 	char *datastr = NULL, *tstr, *resstr = NULL;
4614 	int error = 0;
4615 	int fd_data = 0, fd_res = 0;
4616 	int retval;
4617 
4618 	ccb = cam_getccb(device);
4619 
4620 	if (ccb == NULL) {
4621 		warnx("scsicmd: error allocating ccb");
4622 		return (1);
4623 	}
4624 
4625 	CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4626 
4627 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
4628 		switch(c) {
4629 		case 'a':
4630 			tstr = optarg;
4631 			while (isspace(*tstr) && (*tstr != '\0'))
4632 				tstr++;
4633 			hook.argc = argc - optind;
4634 			hook.argv = argv + optind;
4635 			hook.got = 0;
4636 			atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4637 						    iget, &hook);
4638 			/*
4639 			 * Increment optind by the number of arguments the
4640 			 * encoding routine processed.  After each call to
4641 			 * getopt(3), optind points to the argument that
4642 			 * getopt should process _next_.  In this case,
4643 			 * that means it points to the first command string
4644 			 * argument, if there is one.  Once we increment
4645 			 * this, it should point to either the next command
4646 			 * line argument, or it should be past the end of
4647 			 * the list.
4648 			 */
4649 			optind += hook.got;
4650 			break;
4651 		case 'c':
4652 			tstr = optarg;
4653 			while (isspace(*tstr) && (*tstr != '\0'))
4654 				tstr++;
4655 			hook.argc = argc - optind;
4656 			hook.argv = argv + optind;
4657 			hook.got = 0;
4658 			cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4659 						    iget, &hook);
4660 			/*
4661 			 * Increment optind by the number of arguments the
4662 			 * encoding routine processed.  After each call to
4663 			 * getopt(3), optind points to the argument that
4664 			 * getopt should process _next_.  In this case,
4665 			 * that means it points to the first command string
4666 			 * argument, if there is one.  Once we increment
4667 			 * this, it should point to either the next command
4668 			 * line argument, or it should be past the end of
4669 			 * the list.
4670 			 */
4671 			optind += hook.got;
4672 			break;
4673 		case 'd':
4674 			dmacmd = 1;
4675 			break;
4676 		case 'f':
4677 			fpdmacmd = 1;
4678 			break;
4679 		case 'i':
4680 			if (arglist & CAM_ARG_CMD_OUT) {
4681 				warnx("command must either be "
4682 				      "read or write, not both");
4683 				error = 1;
4684 				goto scsicmd_bailout;
4685 			}
4686 			arglist |= CAM_ARG_CMD_IN;
4687 			flags = CAM_DIR_IN;
4688 			data_bytes = strtol(optarg, NULL, 0);
4689 			if (data_bytes <= 0) {
4690 				warnx("invalid number of input bytes %d",
4691 				      data_bytes);
4692 				error = 1;
4693 				goto scsicmd_bailout;
4694 			}
4695 			hook.argc = argc - optind;
4696 			hook.argv = argv + optind;
4697 			hook.got = 0;
4698 			optind++;
4699 			datastr = cget(&hook, NULL);
4700 			/*
4701 			 * If the user supplied "-" instead of a format, he
4702 			 * wants the data to be written to stdout.
4703 			 */
4704 			if ((datastr != NULL)
4705 			 && (datastr[0] == '-'))
4706 				fd_data = 1;
4707 
4708 			data_ptr = (u_int8_t *)malloc(data_bytes);
4709 			if (data_ptr == NULL) {
4710 				warnx("can't malloc memory for data_ptr");
4711 				error = 1;
4712 				goto scsicmd_bailout;
4713 			}
4714 			break;
4715 		case 'o':
4716 			if (arglist & CAM_ARG_CMD_IN) {
4717 				warnx("command must either be "
4718 				      "read or write, not both");
4719 				error = 1;
4720 				goto scsicmd_bailout;
4721 			}
4722 			arglist |= CAM_ARG_CMD_OUT;
4723 			flags = CAM_DIR_OUT;
4724 			data_bytes = strtol(optarg, NULL, 0);
4725 			if (data_bytes <= 0) {
4726 				warnx("invalid number of output bytes %d",
4727 				      data_bytes);
4728 				error = 1;
4729 				goto scsicmd_bailout;
4730 			}
4731 			hook.argc = argc - optind;
4732 			hook.argv = argv + optind;
4733 			hook.got = 0;
4734 			datastr = cget(&hook, NULL);
4735 			data_ptr = (u_int8_t *)malloc(data_bytes);
4736 			if (data_ptr == NULL) {
4737 				warnx("can't malloc memory for data_ptr");
4738 				error = 1;
4739 				goto scsicmd_bailout;
4740 			}
4741 			bzero(data_ptr, data_bytes);
4742 			/*
4743 			 * If the user supplied "-" instead of a format, he
4744 			 * wants the data to be read from stdin.
4745 			 */
4746 			if ((datastr != NULL)
4747 			 && (datastr[0] == '-'))
4748 				fd_data = 1;
4749 			else
4750 				buff_encode_visit(data_ptr, data_bytes, datastr,
4751 						  iget, &hook);
4752 			optind += hook.got;
4753 			break;
4754 		case 'r':
4755 			need_res = 1;
4756 			hook.argc = argc - optind;
4757 			hook.argv = argv + optind;
4758 			hook.got = 0;
4759 			resstr = cget(&hook, NULL);
4760 			if ((resstr != NULL) && (resstr[0] == '-'))
4761 				fd_res = 1;
4762 			optind += hook.got;
4763 			break;
4764 		default:
4765 			break;
4766 		}
4767 	}
4768 
4769 	/*
4770 	 * If fd_data is set, and we're writing to the device, we need to
4771 	 * read the data the user wants written from stdin.
4772 	 */
4773 	if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4774 		ssize_t amt_read;
4775 		int amt_to_read = data_bytes;
4776 		u_int8_t *buf_ptr = data_ptr;
4777 
4778 		for (amt_read = 0; amt_to_read > 0;
4779 		     amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4780 			if (amt_read == -1) {
4781 				warn("error reading data from stdin");
4782 				error = 1;
4783 				goto scsicmd_bailout;
4784 			}
4785 			amt_to_read -= amt_read;
4786 			buf_ptr += amt_read;
4787 		}
4788 	}
4789 
4790 	if (arglist & CAM_ARG_ERR_RECOVER)
4791 		flags |= CAM_PASS_ERR_RECOVER;
4792 
4793 	/* Disable freezing the device queue */
4794 	flags |= CAM_DEV_QFRZDIS;
4795 
4796 	if (cdb_len) {
4797 		/*
4798 		 * This is taken from the SCSI-3 draft spec.
4799 		 * (T10/1157D revision 0.3)
4800 		 * The top 3 bits of an opcode are the group code.
4801 		 * The next 5 bits are the command code.
4802 		 * Group 0:  six byte commands
4803 		 * Group 1:  ten byte commands
4804 		 * Group 2:  ten byte commands
4805 		 * Group 3:  reserved
4806 		 * Group 4:  sixteen byte commands
4807 		 * Group 5:  twelve byte commands
4808 		 * Group 6:  vendor specific
4809 		 * Group 7:  vendor specific
4810 		 */
4811 		switch((cdb[0] >> 5) & 0x7) {
4812 			case 0:
4813 				cdb_len = 6;
4814 				break;
4815 			case 1:
4816 			case 2:
4817 				cdb_len = 10;
4818 				break;
4819 			case 3:
4820 			case 6:
4821 			case 7:
4822 				/* computed by buff_encode_visit */
4823 				break;
4824 			case 4:
4825 				cdb_len = 16;
4826 				break;
4827 			case 5:
4828 				cdb_len = 12;
4829 				break;
4830 		}
4831 
4832 		/*
4833 		 * We should probably use csio_build_visit or something like that
4834 		 * here, but it's easier to encode arguments as you go.  The
4835 		 * alternative would be skipping the CDB argument and then encoding
4836 		 * it here, since we've got the data buffer argument by now.
4837 		 */
4838 		bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4839 
4840 		cam_fill_csio(&ccb->csio,
4841 		      /*retries*/ retry_count,
4842 		      /*cbfcnp*/ NULL,
4843 		      /*flags*/ flags,
4844 		      /*tag_action*/ task_attr,
4845 		      /*data_ptr*/ data_ptr,
4846 		      /*dxfer_len*/ data_bytes,
4847 		      /*sense_len*/ SSD_FULL_SIZE,
4848 		      /*cdb_len*/ cdb_len,
4849 		      /*timeout*/ timeout ? timeout : 5000);
4850 	} else {
4851 		atacmd_len = 12;
4852 		bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4853 		if (need_res)
4854 			ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4855 		if (dmacmd)
4856 			ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4857 		if (fpdmacmd)
4858 			ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4859 
4860 		cam_fill_ataio(&ccb->ataio,
4861 		      /*retries*/ retry_count,
4862 		      /*cbfcnp*/ NULL,
4863 		      /*flags*/ flags,
4864 		      /*tag_action*/ 0,
4865 		      /*data_ptr*/ data_ptr,
4866 		      /*dxfer_len*/ data_bytes,
4867 		      /*timeout*/ timeout ? timeout : 5000);
4868 	}
4869 
4870 	if (((retval = cam_send_ccb(device, ccb)) < 0)
4871 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4872 		const char warnstr[] = "error sending command";
4873 
4874 		if (retval < 0)
4875 			warn(warnstr);
4876 		else
4877 			warnx(warnstr);
4878 
4879 		if (arglist & CAM_ARG_VERBOSE) {
4880 			cam_error_print(device, ccb, CAM_ESF_ALL,
4881 					CAM_EPF_ALL, stderr);
4882 		}
4883 
4884 		error = 1;
4885 		goto scsicmd_bailout;
4886 	}
4887 
4888 	if (atacmd_len && need_res) {
4889 		if (fd_res == 0) {
4890 			buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4891 					  arg_put, NULL);
4892 			fprintf(stdout, "\n");
4893 		} else {
4894 			fprintf(stdout,
4895 			    "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4896 			    ccb->ataio.res.status,
4897 			    ccb->ataio.res.error,
4898 			    ccb->ataio.res.lba_low,
4899 			    ccb->ataio.res.lba_mid,
4900 			    ccb->ataio.res.lba_high,
4901 			    ccb->ataio.res.device,
4902 			    ccb->ataio.res.lba_low_exp,
4903 			    ccb->ataio.res.lba_mid_exp,
4904 			    ccb->ataio.res.lba_high_exp,
4905 			    ccb->ataio.res.sector_count,
4906 			    ccb->ataio.res.sector_count_exp);
4907 			fflush(stdout);
4908 		}
4909 	}
4910 
4911 	if (cdb_len)
4912 		valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4913 	else
4914 		valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4915 	if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4916 	 && (arglist & CAM_ARG_CMD_IN)
4917 	 && (valid_bytes > 0)) {
4918 		if (fd_data == 0) {
4919 			buff_decode_visit(data_ptr, valid_bytes, datastr,
4920 					  arg_put, NULL);
4921 			fprintf(stdout, "\n");
4922 		} else {
4923 			ssize_t amt_written;
4924 			int amt_to_write = valid_bytes;
4925 			u_int8_t *buf_ptr = data_ptr;
4926 
4927 			for (amt_written = 0; (amt_to_write > 0) &&
4928 			     (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4929 				amt_to_write -= amt_written;
4930 				buf_ptr += amt_written;
4931 			}
4932 			if (amt_written == -1) {
4933 				warn("error writing data to stdout");
4934 				error = 1;
4935 				goto scsicmd_bailout;
4936 			} else if ((amt_written == 0)
4937 				&& (amt_to_write > 0)) {
4938 				warnx("only wrote %u bytes out of %u",
4939 				      valid_bytes - amt_to_write, valid_bytes);
4940 			}
4941 		}
4942 	}
4943 
4944 scsicmd_bailout:
4945 
4946 	if ((data_bytes > 0) && (data_ptr != NULL))
4947 		free(data_ptr);
4948 
4949 	cam_freeccb(ccb);
4950 
4951 	return (error);
4952 }
4953 
4954 static int
4955 camdebug(int argc, char **argv, char *combinedopt)
4956 {
4957 	int c, fd;
4958 	path_id_t bus = CAM_BUS_WILDCARD;
4959 	target_id_t target = CAM_TARGET_WILDCARD;
4960 	lun_id_t lun = CAM_LUN_WILDCARD;
4961 	char *tstr;
4962 	union ccb ccb;
4963 	int error = 0, rv;
4964 
4965 	bzero(&ccb, sizeof(union ccb));
4966 
4967 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
4968 		switch(c) {
4969 		case 'I':
4970 			arglist |= CAM_ARG_DEBUG_INFO;
4971 			ccb.cdbg.flags |= CAM_DEBUG_INFO;
4972 			break;
4973 		case 'P':
4974 			arglist |= CAM_ARG_DEBUG_PERIPH;
4975 			ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4976 			break;
4977 		case 'S':
4978 			arglist |= CAM_ARG_DEBUG_SUBTRACE;
4979 			ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4980 			break;
4981 		case 'T':
4982 			arglist |= CAM_ARG_DEBUG_TRACE;
4983 			ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4984 			break;
4985 		case 'X':
4986 			arglist |= CAM_ARG_DEBUG_XPT;
4987 			ccb.cdbg.flags |= CAM_DEBUG_XPT;
4988 			break;
4989 		case 'c':
4990 			arglist |= CAM_ARG_DEBUG_CDB;
4991 			ccb.cdbg.flags |= CAM_DEBUG_CDB;
4992 			break;
4993 		case 'p':
4994 			arglist |= CAM_ARG_DEBUG_PROBE;
4995 			ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4996 			break;
4997 		default:
4998 			break;
4999 		}
5000 	}
5001 
5002 	argc -= optind;
5003 	argv += optind;
5004 
5005 	if (argc <= 0) {
5006 		warnx("you must specify \"off\", \"all\" or a bus,");
5007 		warnx("bus:target, bus:target:lun or periph");
5008 		return (1);
5009 	}
5010 
5011 	tstr = *argv;
5012 	while (isspace(*tstr) && (*tstr != '\0'))
5013 		tstr++;
5014 
5015 	if (strncmp(tstr, "off", 3) == 0) {
5016 		ccb.cdbg.flags = CAM_DEBUG_NONE;
5017 		arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5018 			     CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5019 			     CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5020 	} else {
5021 		rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5022 		if (rv < 1) {
5023 			warnx("you must specify \"all\", \"off\", or a bus,");
5024 			warnx("bus:target, bus:target:lun or periph to debug");
5025 			return (1);
5026 		}
5027 	}
5028 
5029 	if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5030 		warnx("error opening transport layer device %s", XPT_DEVICE);
5031 		warn("%s", XPT_DEVICE);
5032 		return (1);
5033 	}
5034 
5035 	ccb.ccb_h.func_code = XPT_DEBUG;
5036 	ccb.ccb_h.path_id = bus;
5037 	ccb.ccb_h.target_id = target;
5038 	ccb.ccb_h.target_lun = lun;
5039 
5040 	if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5041 		warn("CAMIOCOMMAND ioctl failed");
5042 		error = 1;
5043 	} else {
5044 		if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5045 		     CAM_FUNC_NOTAVAIL) {
5046 			warnx("CAM debugging not available");
5047 			warnx("you need to put options CAMDEBUG in"
5048 			      " your kernel config file!");
5049 			error = 1;
5050 		} else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5051 			    CAM_REQ_CMP) {
5052 			warnx("XPT_DEBUG CCB failed with status %#x",
5053 			      ccb.ccb_h.status);
5054 			error = 1;
5055 		} else {
5056 			if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5057 				fprintf(stderr,
5058 					"Debugging turned off\n");
5059 			} else {
5060 				fprintf(stderr,
5061 					"Debugging enabled for "
5062 					"%d:%d:%jx\n",
5063 					bus, target, (uintmax_t)lun);
5064 			}
5065 		}
5066 	}
5067 	close(fd);
5068 
5069 	return (error);
5070 }
5071 
5072 static int
5073 tagcontrol(struct cam_device *device, int argc, char **argv,
5074 	   char *combinedopt)
5075 {
5076 	int c;
5077 	union ccb *ccb;
5078 	int numtags = -1;
5079 	int retval = 0;
5080 	int quiet = 0;
5081 	char pathstr[1024];
5082 
5083 	ccb = cam_getccb(device);
5084 
5085 	if (ccb == NULL) {
5086 		warnx("tagcontrol: error allocating ccb");
5087 		return (1);
5088 	}
5089 
5090 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
5091 		switch(c) {
5092 		case 'N':
5093 			numtags = strtol(optarg, NULL, 0);
5094 			if (numtags < 0) {
5095 				warnx("tag count %d is < 0", numtags);
5096 				retval = 1;
5097 				goto tagcontrol_bailout;
5098 			}
5099 			break;
5100 		case 'q':
5101 			quiet++;
5102 			break;
5103 		default:
5104 			break;
5105 		}
5106 	}
5107 
5108 	cam_path_string(device, pathstr, sizeof(pathstr));
5109 
5110 	if (numtags >= 0) {
5111 		CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5112 		ccb->ccb_h.func_code = XPT_REL_SIMQ;
5113 		ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5114 		ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5115 		ccb->crs.openings = numtags;
5116 
5117 
5118 		if (cam_send_ccb(device, ccb) < 0) {
5119 			warn("error sending XPT_REL_SIMQ CCB");
5120 			retval = 1;
5121 			goto tagcontrol_bailout;
5122 		}
5123 
5124 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5125 			warnx("XPT_REL_SIMQ CCB failed");
5126 			cam_error_print(device, ccb, CAM_ESF_ALL,
5127 					CAM_EPF_ALL, stderr);
5128 			retval = 1;
5129 			goto tagcontrol_bailout;
5130 		}
5131 
5132 
5133 		if (quiet == 0)
5134 			fprintf(stdout, "%stagged openings now %d\n",
5135 				pathstr, ccb->crs.openings);
5136 	}
5137 
5138 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5139 
5140 	ccb->ccb_h.func_code = XPT_GDEV_STATS;
5141 
5142 	if (cam_send_ccb(device, ccb) < 0) {
5143 		warn("error sending XPT_GDEV_STATS CCB");
5144 		retval = 1;
5145 		goto tagcontrol_bailout;
5146 	}
5147 
5148 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5149 		warnx("XPT_GDEV_STATS CCB failed");
5150 		cam_error_print(device, ccb, CAM_ESF_ALL,
5151 				CAM_EPF_ALL, stderr);
5152 		retval = 1;
5153 		goto tagcontrol_bailout;
5154 	}
5155 
5156 	if (arglist & CAM_ARG_VERBOSE) {
5157 		fprintf(stdout, "%s", pathstr);
5158 		fprintf(stdout, "dev_openings  %d\n", ccb->cgds.dev_openings);
5159 		fprintf(stdout, "%s", pathstr);
5160 		fprintf(stdout, "dev_active    %d\n", ccb->cgds.dev_active);
5161 		fprintf(stdout, "%s", pathstr);
5162 		fprintf(stdout, "allocated     %d\n", ccb->cgds.allocated);
5163 		fprintf(stdout, "%s", pathstr);
5164 		fprintf(stdout, "queued        %d\n", ccb->cgds.queued);
5165 		fprintf(stdout, "%s", pathstr);
5166 		fprintf(stdout, "held          %d\n", ccb->cgds.held);
5167 		fprintf(stdout, "%s", pathstr);
5168 		fprintf(stdout, "mintags       %d\n", ccb->cgds.mintags);
5169 		fprintf(stdout, "%s", pathstr);
5170 		fprintf(stdout, "maxtags       %d\n", ccb->cgds.maxtags);
5171 	} else {
5172 		if (quiet == 0) {
5173 			fprintf(stdout, "%s", pathstr);
5174 			fprintf(stdout, "device openings: ");
5175 		}
5176 		fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5177 			ccb->cgds.dev_active);
5178 	}
5179 
5180 tagcontrol_bailout:
5181 
5182 	cam_freeccb(ccb);
5183 	return (retval);
5184 }
5185 
5186 static void
5187 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5188 {
5189 	char pathstr[1024];
5190 
5191 	cam_path_string(device, pathstr, sizeof(pathstr));
5192 
5193 	if (cts->transport == XPORT_SPI) {
5194 		struct ccb_trans_settings_spi *spi =
5195 		    &cts->xport_specific.spi;
5196 
5197 		if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5198 
5199 			fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5200 				spi->sync_period);
5201 
5202 			if (spi->sync_offset != 0) {
5203 				u_int freq;
5204 
5205 				freq = scsi_calc_syncsrate(spi->sync_period);
5206 				fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5207 					pathstr, freq / 1000, freq % 1000);
5208 			}
5209 		}
5210 
5211 		if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5212 			fprintf(stdout, "%soffset: %d\n", pathstr,
5213 			    spi->sync_offset);
5214 		}
5215 
5216 		if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5217 			fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5218 				(0x01 << spi->bus_width) * 8);
5219 		}
5220 
5221 		if (spi->valid & CTS_SPI_VALID_DISC) {
5222 			fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5223 				(spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5224 				"enabled" : "disabled");
5225 		}
5226 	}
5227 	if (cts->transport == XPORT_FC) {
5228 		struct ccb_trans_settings_fc *fc =
5229 		    &cts->xport_specific.fc;
5230 
5231 		if (fc->valid & CTS_FC_VALID_WWNN)
5232 			fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5233 			    (long long) fc->wwnn);
5234 		if (fc->valid & CTS_FC_VALID_WWPN)
5235 			fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5236 			    (long long) fc->wwpn);
5237 		if (fc->valid & CTS_FC_VALID_PORT)
5238 			fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5239 		if (fc->valid & CTS_FC_VALID_SPEED)
5240 			fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5241 			    pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5242 	}
5243 	if (cts->transport == XPORT_SAS) {
5244 		struct ccb_trans_settings_sas *sas =
5245 		    &cts->xport_specific.sas;
5246 
5247 		if (sas->valid & CTS_SAS_VALID_SPEED)
5248 			fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5249 			    pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5250 	}
5251 	if (cts->transport == XPORT_ATA) {
5252 		struct ccb_trans_settings_pata *pata =
5253 		    &cts->xport_specific.ata;
5254 
5255 		if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5256 			fprintf(stdout, "%sATA mode: %s\n", pathstr,
5257 				ata_mode2string(pata->mode));
5258 		}
5259 		if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5260 			fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5261 				pata->atapi);
5262 		}
5263 		if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5264 			fprintf(stdout, "%sPIO transaction length: %d\n",
5265 				pathstr, pata->bytecount);
5266 		}
5267 	}
5268 	if (cts->transport == XPORT_SATA) {
5269 		struct ccb_trans_settings_sata *sata =
5270 		    &cts->xport_specific.sata;
5271 
5272 		if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5273 			fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5274 				sata->revision);
5275 		}
5276 		if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5277 			fprintf(stdout, "%sATA mode: %s\n", pathstr,
5278 				ata_mode2string(sata->mode));
5279 		}
5280 		if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5281 			fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5282 				sata->atapi);
5283 		}
5284 		if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5285 			fprintf(stdout, "%sPIO transaction length: %d\n",
5286 				pathstr, sata->bytecount);
5287 		}
5288 		if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5289 			fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5290 				sata->pm_present);
5291 		}
5292 		if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5293 			fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5294 				sata->tags);
5295 		}
5296 		if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5297 			fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5298 				sata->caps);
5299 		}
5300 	}
5301 	if (cts->protocol == PROTO_ATA) {
5302 		struct ccb_trans_settings_ata *ata=
5303 		    &cts->proto_specific.ata;
5304 
5305 		if (ata->valid & CTS_ATA_VALID_TQ) {
5306 			fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5307 				(ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5308 				"enabled" : "disabled");
5309 		}
5310 	}
5311 	if (cts->protocol == PROTO_SCSI) {
5312 		struct ccb_trans_settings_scsi *scsi=
5313 		    &cts->proto_specific.scsi;
5314 
5315 		if (scsi->valid & CTS_SCSI_VALID_TQ) {
5316 			fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5317 				(scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5318 				"enabled" : "disabled");
5319 		}
5320 	}
5321 #ifdef WITH_NVME
5322 	if (cts->protocol == PROTO_NVME) {
5323 		struct ccb_trans_settings_nvme *nvmex =
5324 		    &cts->xport_specific.nvme;
5325 
5326 		if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5327 			fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5328 			    NVME_MAJOR(nvmex->spec),
5329 			    NVME_MINOR(nvmex->spec));
5330 		}
5331 		if (nvmex->valid & CTS_NVME_VALID_LINK) {
5332 			fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5333 			    nvmex->lanes, nvmex->max_lanes);
5334 			fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5335 			    nvmex->speed, nvmex->max_speed);
5336 		}
5337 	}
5338 #endif
5339 }
5340 
5341 /*
5342  * Get a path inquiry CCB for the specified device.
5343  */
5344 static int
5345 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5346 {
5347 	union ccb *ccb;
5348 	int retval = 0;
5349 
5350 	ccb = cam_getccb(device);
5351 	if (ccb == NULL) {
5352 		warnx("get_cpi: couldn't allocate CCB");
5353 		return (1);
5354 	}
5355 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5356 	ccb->ccb_h.func_code = XPT_PATH_INQ;
5357 	if (cam_send_ccb(device, ccb) < 0) {
5358 		warn("get_cpi: error sending Path Inquiry CCB");
5359 		retval = 1;
5360 		goto get_cpi_bailout;
5361 	}
5362 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5363 		if (arglist & CAM_ARG_VERBOSE)
5364 			cam_error_print(device, ccb, CAM_ESF_ALL,
5365 					CAM_EPF_ALL, stderr);
5366 		retval = 1;
5367 		goto get_cpi_bailout;
5368 	}
5369 	bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5370 
5371 get_cpi_bailout:
5372 	cam_freeccb(ccb);
5373 	return (retval);
5374 }
5375 
5376 /*
5377  * Get a get device CCB for the specified device.
5378  */
5379 static int
5380 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5381 {
5382 	union ccb *ccb;
5383 	int retval = 0;
5384 
5385 	ccb = cam_getccb(device);
5386 	if (ccb == NULL) {
5387 		warnx("get_cgd: couldn't allocate CCB");
5388 		return (1);
5389 	}
5390 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5391 	ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5392 	if (cam_send_ccb(device, ccb) < 0) {
5393 		warn("get_cgd: error sending Get type information CCB");
5394 		retval = 1;
5395 		goto get_cgd_bailout;
5396 	}
5397 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5398 		if (arglist & CAM_ARG_VERBOSE)
5399 			cam_error_print(device, ccb, CAM_ESF_ALL,
5400 					CAM_EPF_ALL, stderr);
5401 		retval = 1;
5402 		goto get_cgd_bailout;
5403 	}
5404 	bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5405 
5406 get_cgd_bailout:
5407 	cam_freeccb(ccb);
5408 	return (retval);
5409 }
5410 
5411 /*
5412  * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5413  * error.
5414  */
5415 int
5416 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5417 		 int timeout, int verbosemode)
5418 {
5419 	union ccb *ccb = NULL;
5420 	struct scsi_vpd_supported_page_list sup_pages;
5421 	int i;
5422 	int retval = 0;
5423 
5424 	ccb = cam_getccb(dev);
5425 	if (ccb == NULL) {
5426 		warn("Unable to allocate CCB");
5427 		retval = -1;
5428 		goto bailout;
5429 	}
5430 
5431 	/* cam_getccb cleans up the header, caller has to zero the payload */
5432 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5433 
5434 	bzero(&sup_pages, sizeof(sup_pages));
5435 
5436 	scsi_inquiry(&ccb->csio,
5437 		     /*retries*/ retry_count,
5438 		     /*cbfcnp*/ NULL,
5439 		     /* tag_action */ MSG_SIMPLE_Q_TAG,
5440 		     /* inq_buf */ (u_int8_t *)&sup_pages,
5441 		     /* inq_len */ sizeof(sup_pages),
5442 		     /* evpd */ 1,
5443 		     /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5444 		     /* sense_len */ SSD_FULL_SIZE,
5445 		     /* timeout */ timeout ? timeout : 5000);
5446 
5447 	/* Disable freezing the device queue */
5448 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5449 
5450 	if (retry_count != 0)
5451 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5452 
5453 	if (cam_send_ccb(dev, ccb) < 0) {
5454 		cam_freeccb(ccb);
5455 		ccb = NULL;
5456 		retval = -1;
5457 		goto bailout;
5458 	}
5459 
5460 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5461 		if (verbosemode != 0)
5462 			cam_error_print(dev, ccb, CAM_ESF_ALL,
5463 					CAM_EPF_ALL, stderr);
5464 		retval = -1;
5465 		goto bailout;
5466 	}
5467 
5468 	for (i = 0; i < sup_pages.length; i++) {
5469 		if (sup_pages.list[i] == page_id) {
5470 			retval = 1;
5471 			goto bailout;
5472 		}
5473 	}
5474 bailout:
5475 	if (ccb != NULL)
5476 		cam_freeccb(ccb);
5477 
5478 	return (retval);
5479 }
5480 
5481 /*
5482  * devtype is filled in with the type of device.
5483  * Returns 0 for success, non-zero for failure.
5484  */
5485 int
5486 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5487 		    int verbosemode, camcontrol_devtype *devtype)
5488 {
5489 	struct ccb_getdev cgd;
5490 	int retval;
5491 
5492 	retval = get_cgd(dev, &cgd);
5493 	if (retval != 0)
5494 		goto bailout;
5495 
5496 	switch (cgd.protocol) {
5497 	case PROTO_SCSI:
5498 		break;
5499 	case PROTO_ATA:
5500 	case PROTO_ATAPI:
5501 	case PROTO_SATAPM:
5502 		*devtype = CC_DT_ATA;
5503 		goto bailout;
5504 		break; /*NOTREACHED*/
5505 	case PROTO_NVME:
5506 		*devtype = CC_DT_NVME;
5507 		goto bailout;
5508 		break; /*NOTREACHED*/
5509 	case PROTO_MMCSD:
5510 		*devtype = CC_DT_MMCSD;
5511 		goto bailout;
5512 		break; /*NOTREACHED*/
5513 	default:
5514 		*devtype = CC_DT_UNKNOWN;
5515 		goto bailout;
5516 		break; /*NOTREACHED*/
5517 	}
5518 
5519 	if (retry_count == -1) {
5520 		/*
5521 		 * For a retry count of -1, used only the cached data to avoid
5522 		 * I/O to the drive. Sending the identify command to the drive
5523 		 * can cause issues for SATL attachaed drives since identify is
5524 		 * not an NCQ command.
5525 		 */
5526 		if (cgd.ident_data.config != 0)
5527 			*devtype = CC_DT_SATL;
5528 		else
5529 			*devtype = CC_DT_SCSI;
5530 	} else {
5531 		/*
5532 		 * Check for the ATA Information VPD page (0x89).  If this is an
5533 		 * ATA device behind a SCSI to ATA translation layer (SATL),
5534 		 * this VPD page should be present.
5535 		 *
5536 		 * If that VPD page isn't present, or we get an error back from
5537 		 * the INQUIRY command, we'll just treat it as a normal SCSI
5538 		 * device.
5539 		 */
5540 		retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5541 		    timeout, verbosemode);
5542 		if (retval == 1)
5543 			*devtype = CC_DT_SATL;
5544 		else
5545 			*devtype = CC_DT_SCSI;
5546 	}
5547 	retval = 0;
5548 
5549 bailout:
5550 	return (retval);
5551 }
5552 
5553 int
5554 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5555     uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5556     uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5557     uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5558     size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5559     int is48bit, camcontrol_devtype devtype)
5560 {
5561 	int retval = 0;
5562 
5563 	if (devtype == CC_DT_ATA) {
5564 		cam_fill_ataio(&ccb->ataio,
5565 		    /*retries*/ retry_count,
5566 		    /*cbfcnp*/ NULL,
5567 		    /*flags*/ flags,
5568 		    /*tag_action*/ tag_action,
5569 		    /*data_ptr*/ data_ptr,
5570 		    /*dxfer_len*/ dxfer_len,
5571 		    /*timeout*/ timeout);
5572 		if (is48bit || lba > ATA_MAX_28BIT_LBA)
5573 			ata_48bit_cmd(&ccb->ataio, command, features, lba,
5574 			    sector_count);
5575 		else
5576 			ata_28bit_cmd(&ccb->ataio, command, features, lba,
5577 			    sector_count);
5578 
5579 		if (auxiliary != 0) {
5580 			ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5581 			ccb->ataio.aux = auxiliary;
5582 		}
5583 
5584 		if (ata_flags & AP_FLAG_CHK_COND)
5585 			ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5586 
5587 		if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5588 			ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5589 		else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5590 			ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5591 	} else {
5592 		if (is48bit || lba > ATA_MAX_28BIT_LBA)
5593 			protocol |= AP_EXTEND;
5594 
5595 		retval = scsi_ata_pass(&ccb->csio,
5596 		    /*retries*/ retry_count,
5597 		    /*cbfcnp*/ NULL,
5598 		    /*flags*/ flags,
5599 		    /*tag_action*/ tag_action,
5600 		    /*protocol*/ protocol,
5601 		    /*ata_flags*/ ata_flags,
5602 		    /*features*/ features,
5603 		    /*sector_count*/ sector_count,
5604 		    /*lba*/ lba,
5605 		    /*command*/ command,
5606 		    /*device*/ 0,
5607 		    /*icc*/ 0,
5608 		    /*auxiliary*/ auxiliary,
5609 		    /*control*/ 0,
5610 		    /*data_ptr*/ data_ptr,
5611 		    /*dxfer_len*/ dxfer_len,
5612 		    /*cdb_storage*/ cdb_storage,
5613 		    /*cdb_storage_len*/ cdb_storage_len,
5614 		    /*minimum_cmd_size*/ 0,
5615 		    /*sense_len*/ sense_len,
5616 		    /*timeout*/ timeout);
5617 	}
5618 
5619 	return (retval);
5620 }
5621 
5622 /*
5623  * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5624  *	    4 -- count truncated, 6 -- lba and count truncated.
5625  */
5626 int
5627 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5628 	       uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5629 {
5630 	int retval;
5631 
5632 	switch (ccb->ccb_h.func_code) {
5633 	case XPT_SCSI_IO: {
5634 		uint8_t opcode;
5635 		int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5636 		u_int sense_len;
5637 
5638 		/*
5639 		 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5640 		 * or 16 byte, and need to see what
5641 		 */
5642 		if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5643 			opcode = ccb->csio.cdb_io.cdb_ptr[0];
5644 		else
5645 			opcode = ccb->csio.cdb_io.cdb_bytes[0];
5646 		if ((opcode != ATA_PASS_12)
5647 		 && (opcode != ATA_PASS_16)) {
5648 			warnx("%s: unsupported opcode %02x", __func__, opcode);
5649 			return (1);
5650 		}
5651 
5652 		retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5653 						&asc, &ascq);
5654 		/* Note: the _ccb() variant returns 0 for an error */
5655 		if (retval == 0)
5656 			return (1);
5657 
5658 		sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5659 		switch (error_code) {
5660 		case SSD_DESC_CURRENT_ERROR:
5661 		case SSD_DESC_DEFERRED_ERROR: {
5662 			struct scsi_sense_data_desc *sense;
5663 			struct scsi_sense_ata_ret_desc *desc;
5664 			uint8_t *desc_ptr;
5665 
5666 			sense = (struct scsi_sense_data_desc *)
5667 			    &ccb->csio.sense_data;
5668 
5669 			desc_ptr = scsi_find_desc(sense, sense_len,
5670 			    SSD_DESC_ATA);
5671 			if (desc_ptr == NULL) {
5672 				cam_error_print(dev, ccb, CAM_ESF_ALL,
5673 				    CAM_EPF_ALL, stderr);
5674 				return (1);
5675 			}
5676 			desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5677 
5678 			*error = desc->error;
5679 			*count = (desc->count_15_8 << 8) |
5680 				  desc->count_7_0;
5681 			*lba = ((uint64_t)desc->lba_47_40 << 40) |
5682 			       ((uint64_t)desc->lba_39_32 << 32) |
5683 			       ((uint64_t)desc->lba_31_24 << 24) |
5684 			       (desc->lba_23_16 << 16) |
5685 			       (desc->lba_15_8  <<  8) |
5686 				desc->lba_7_0;
5687 			*device = desc->device;
5688 			*status = desc->status;
5689 
5690 			/*
5691 			 * If the extend bit isn't set, the result is for a
5692 			 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5693 			 * command without the extend bit set.  This means
5694 			 * that the device is supposed to return 28-bit
5695 			 * status.  The count field is only 8 bits, and the
5696 			 * LBA field is only 8 bits.
5697 			 */
5698 			if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5699 				*count &= 0xff;
5700 				*lba &= 0x0fffffff;
5701 			}
5702 			break;
5703 		}
5704 		case SSD_CURRENT_ERROR:
5705 		case SSD_DEFERRED_ERROR: {
5706 			uint64_t val;
5707 
5708 			/*
5709 			 * In my understanding of SAT-5 specification, saying:
5710 			 * "without interpreting the contents of the STATUS",
5711 			 * this should not happen if CK_COND was set, but it
5712 			 * does at least for some devices, so try to revert.
5713 			 */
5714 			if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5715 			    (asc == 0) && (ascq == 0)) {
5716 				*status = ATA_STATUS_ERROR;
5717 				*error = ATA_ERROR_ABORT;
5718 				*device = 0;
5719 				*count = 0;
5720 				*lba = 0;
5721 				return (0);
5722 			}
5723 
5724 			if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5725 			    (asc != 0x00) || (ascq != 0x1d))
5726 				return (1);
5727 
5728 			val = 0;
5729 			scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5730 			    SSD_DESC_INFO, &val, NULL);
5731 			*error = (val >> 24) & 0xff;
5732 			*status = (val >> 16) & 0xff;
5733 			*device = (val >> 8) & 0xff;
5734 			*count = val & 0xff;
5735 
5736 			val = 0;
5737 			scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5738 			    SSD_DESC_COMMAND, &val, NULL);
5739 			*lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5740 				((val & 0xff) << 16);
5741 
5742 			/* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5743 			return ((val >> 28) & 0x06);
5744 		}
5745 		default:
5746 			return (1);
5747 		}
5748 
5749 		break;
5750 	}
5751 	case XPT_ATA_IO: {
5752 		struct ata_res *res;
5753 
5754 		/* Only some statuses return ATA result register set. */
5755 		if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5756 		    cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5757 			return (1);
5758 
5759 		res = &ccb->ataio.res;
5760 		*error = res->error;
5761 		*status = res->status;
5762 		*device = res->device;
5763 		*count = res->sector_count;
5764 		*lba = (res->lba_high << 16) |
5765 		       (res->lba_mid << 8) |
5766 		       (res->lba_low);
5767 		if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5768 			*count |= (res->sector_count_exp << 8);
5769 			*lba |= ((uint64_t)res->lba_low_exp << 24) |
5770 				((uint64_t)res->lba_mid_exp << 32) |
5771 				((uint64_t)res->lba_high_exp << 40);
5772 		} else {
5773 			*lba |= (res->device & 0xf) << 24;
5774 		}
5775 		break;
5776 	}
5777 	default:
5778 		return (1);
5779 	}
5780 	return (0);
5781 }
5782 
5783 static void
5784 cpi_print(struct ccb_pathinq *cpi)
5785 {
5786 	char adapter_str[1024];
5787 	uint64_t i;
5788 
5789 	snprintf(adapter_str, sizeof(adapter_str),
5790 		 "%s%d:", cpi->dev_name, cpi->unit_number);
5791 
5792 	fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5793 		cpi->version_num);
5794 
5795 	for (i = 1; i < UINT8_MAX; i = i << 1) {
5796 		const char *str;
5797 
5798 		if ((i & cpi->hba_inquiry) == 0)
5799 			continue;
5800 
5801 		fprintf(stdout, "%s supports ", adapter_str);
5802 
5803 		switch(i) {
5804 		case PI_MDP_ABLE:
5805 			str = "MDP message";
5806 			break;
5807 		case PI_WIDE_32:
5808 			str = "32 bit wide SCSI";
5809 			break;
5810 		case PI_WIDE_16:
5811 			str = "16 bit wide SCSI";
5812 			break;
5813 		case PI_SDTR_ABLE:
5814 			str = "SDTR message";
5815 			break;
5816 		case PI_LINKED_CDB:
5817 			str = "linked CDBs";
5818 			break;
5819 		case PI_TAG_ABLE:
5820 			str = "tag queue messages";
5821 			break;
5822 		case PI_SOFT_RST:
5823 			str = "soft reset alternative";
5824 			break;
5825 		case PI_SATAPM:
5826 			str = "SATA Port Multiplier";
5827 			break;
5828 		default:
5829 			str = "unknown PI bit set";
5830 			break;
5831 		}
5832 		fprintf(stdout, "%s\n", str);
5833 	}
5834 
5835 	for (i = 1; i < UINT32_MAX; i = i << 1) {
5836 		const char *str;
5837 
5838 		if ((i & cpi->hba_misc) == 0)
5839 			continue;
5840 
5841 		fprintf(stdout, "%s ", adapter_str);
5842 
5843 		switch(i) {
5844 		case PIM_ATA_EXT:
5845 			str = "can understand ata_ext requests";
5846 			break;
5847 		case PIM_EXTLUNS:
5848 			str = "64bit extended LUNs supported";
5849 			break;
5850 		case PIM_SCANHILO:
5851 			str = "bus scans from high ID to low ID";
5852 			break;
5853 		case PIM_NOREMOVE:
5854 			str = "removable devices not included in scan";
5855 			break;
5856 		case PIM_NOINITIATOR:
5857 			str = "initiator role not supported";
5858 			break;
5859 		case PIM_NOBUSRESET:
5860 			str = "user has disabled initial BUS RESET or"
5861 			      " controller is in target/mixed mode";
5862 			break;
5863 		case PIM_NO_6_BYTE:
5864 			str = "do not send 6-byte commands";
5865 			break;
5866 		case PIM_SEQSCAN:
5867 			str = "scan bus sequentially";
5868 			break;
5869 		case PIM_UNMAPPED:
5870 			str = "unmapped I/O supported";
5871 			break;
5872 		case PIM_NOSCAN:
5873 			str = "does its own scanning";
5874 			break;
5875 		default:
5876 			str = "unknown PIM bit set";
5877 			break;
5878 		}
5879 		fprintf(stdout, "%s\n", str);
5880 	}
5881 
5882 	for (i = 1; i < UINT16_MAX; i = i << 1) {
5883 		const char *str;
5884 
5885 		if ((i & cpi->target_sprt) == 0)
5886 			continue;
5887 
5888 		fprintf(stdout, "%s supports ", adapter_str);
5889 		switch(i) {
5890 		case PIT_PROCESSOR:
5891 			str = "target mode processor mode";
5892 			break;
5893 		case PIT_PHASE:
5894 			str = "target mode phase cog. mode";
5895 			break;
5896 		case PIT_DISCONNECT:
5897 			str = "disconnects in target mode";
5898 			break;
5899 		case PIT_TERM_IO:
5900 			str = "terminate I/O message in target mode";
5901 			break;
5902 		case PIT_GRP_6:
5903 			str = "group 6 commands in target mode";
5904 			break;
5905 		case PIT_GRP_7:
5906 			str = "group 7 commands in target mode";
5907 			break;
5908 		default:
5909 			str = "unknown PIT bit set";
5910 			break;
5911 		}
5912 
5913 		fprintf(stdout, "%s\n", str);
5914 	}
5915 	fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5916 		cpi->hba_eng_cnt);
5917 	fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5918 		cpi->max_target);
5919 	fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5920 		cpi->max_lun);
5921 	fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5922 		adapter_str, cpi->hpath_id);
5923 	fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5924 		cpi->initiator_id);
5925 	fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5926 	fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5927 	fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5928 	    adapter_str, cpi->hba_vendor);
5929 	fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5930 	    adapter_str, cpi->hba_device);
5931 	fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5932 	    adapter_str, cpi->hba_subvendor);
5933 	fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5934 	    adapter_str, cpi->hba_subdevice);
5935 	fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5936 	fprintf(stdout, "%s base transfer speed: ", adapter_str);
5937 	if (cpi->base_transfer_speed > 1000)
5938 		fprintf(stdout, "%d.%03dMB/sec\n",
5939 			cpi->base_transfer_speed / 1000,
5940 			cpi->base_transfer_speed % 1000);
5941 	else
5942 		fprintf(stdout, "%dKB/sec\n",
5943 			(cpi->base_transfer_speed % 1000) * 1000);
5944 	fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5945 	    adapter_str, cpi->maxio);
5946 }
5947 
5948 static int
5949 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5950 	      struct ccb_trans_settings *cts)
5951 {
5952 	int retval;
5953 	union ccb *ccb;
5954 
5955 	retval = 0;
5956 	ccb = cam_getccb(device);
5957 
5958 	if (ccb == NULL) {
5959 		warnx("get_print_cts: error allocating ccb");
5960 		return (1);
5961 	}
5962 
5963 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5964 
5965 	ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5966 
5967 	if (user_settings == 0)
5968 		ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5969 	else
5970 		ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5971 
5972 	if (cam_send_ccb(device, ccb) < 0) {
5973 		warn("error sending XPT_GET_TRAN_SETTINGS CCB");
5974 		retval = 1;
5975 		goto get_print_cts_bailout;
5976 	}
5977 
5978 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5979 		warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5980 		if (arglist & CAM_ARG_VERBOSE)
5981 			cam_error_print(device, ccb, CAM_ESF_ALL,
5982 					CAM_EPF_ALL, stderr);
5983 		retval = 1;
5984 		goto get_print_cts_bailout;
5985 	}
5986 
5987 	if (quiet == 0)
5988 		cts_print(device, &ccb->cts);
5989 
5990 	if (cts != NULL)
5991 		bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5992 
5993 get_print_cts_bailout:
5994 
5995 	cam_freeccb(ccb);
5996 
5997 	return (retval);
5998 }
5999 
6000 static int
6001 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6002 	    int timeout, int argc, char **argv, char *combinedopt)
6003 {
6004 	int c;
6005 	union ccb *ccb;
6006 	int user_settings = 0;
6007 	int retval = 0;
6008 	int disc_enable = -1, tag_enable = -1;
6009 	int mode = -1;
6010 	int offset = -1;
6011 	double syncrate = -1;
6012 	int bus_width = -1;
6013 	int quiet = 0;
6014 	int change_settings = 0, send_tur = 0;
6015 	struct ccb_pathinq cpi;
6016 
6017 	ccb = cam_getccb(device);
6018 	if (ccb == NULL) {
6019 		warnx("ratecontrol: error allocating ccb");
6020 		return (1);
6021 	}
6022 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
6023 		switch(c){
6024 		case 'a':
6025 			send_tur = 1;
6026 			break;
6027 		case 'c':
6028 			user_settings = 0;
6029 			break;
6030 		case 'D':
6031 			if (strncasecmp(optarg, "enable", 6) == 0)
6032 				disc_enable = 1;
6033 			else if (strncasecmp(optarg, "disable", 7) == 0)
6034 				disc_enable = 0;
6035 			else {
6036 				warnx("-D argument \"%s\" is unknown", optarg);
6037 				retval = 1;
6038 				goto ratecontrol_bailout;
6039 			}
6040 			change_settings = 1;
6041 			break;
6042 		case 'M':
6043 			mode = ata_string2mode(optarg);
6044 			if (mode < 0) {
6045 				warnx("unknown mode '%s'", optarg);
6046 				retval = 1;
6047 				goto ratecontrol_bailout;
6048 			}
6049 			change_settings = 1;
6050 			break;
6051 		case 'O':
6052 			offset = strtol(optarg, NULL, 0);
6053 			if (offset < 0) {
6054 				warnx("offset value %d is < 0", offset);
6055 				retval = 1;
6056 				goto ratecontrol_bailout;
6057 			}
6058 			change_settings = 1;
6059 			break;
6060 		case 'q':
6061 			quiet++;
6062 			break;
6063 		case 'R':
6064 			syncrate = atof(optarg);
6065 			if (syncrate < 0) {
6066 				warnx("sync rate %f is < 0", syncrate);
6067 				retval = 1;
6068 				goto ratecontrol_bailout;
6069 			}
6070 			change_settings = 1;
6071 			break;
6072 		case 'T':
6073 			if (strncasecmp(optarg, "enable", 6) == 0)
6074 				tag_enable = 1;
6075 			else if (strncasecmp(optarg, "disable", 7) == 0)
6076 				tag_enable = 0;
6077 			else {
6078 				warnx("-T argument \"%s\" is unknown", optarg);
6079 				retval = 1;
6080 				goto ratecontrol_bailout;
6081 			}
6082 			change_settings = 1;
6083 			break;
6084 		case 'U':
6085 			user_settings = 1;
6086 			break;
6087 		case 'W':
6088 			bus_width = strtol(optarg, NULL, 0);
6089 			if (bus_width < 0) {
6090 				warnx("bus width %d is < 0", bus_width);
6091 				retval = 1;
6092 				goto ratecontrol_bailout;
6093 			}
6094 			change_settings = 1;
6095 			break;
6096 		default:
6097 			break;
6098 		}
6099 	}
6100 	/*
6101 	 * Grab path inquiry information, so we can determine whether
6102 	 * or not the initiator is capable of the things that the user
6103 	 * requests.
6104 	 */
6105 	if ((retval = get_cpi(device, &cpi)) != 0)
6106 		goto ratecontrol_bailout;
6107 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6108 	if (quiet == 0) {
6109 		fprintf(stdout, "%s parameters:\n",
6110 		    user_settings ? "User" : "Current");
6111 	}
6112 	retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6113 	if (retval != 0)
6114 		goto ratecontrol_bailout;
6115 
6116 	if (arglist & CAM_ARG_VERBOSE)
6117 		cpi_print(&cpi);
6118 
6119 	if (change_settings) {
6120 		int didsettings = 0;
6121 		struct ccb_trans_settings_spi *spi = NULL;
6122 		struct ccb_trans_settings_pata *pata = NULL;
6123 		struct ccb_trans_settings_sata *sata = NULL;
6124 		struct ccb_trans_settings_ata *ata = NULL;
6125 		struct ccb_trans_settings_scsi *scsi = NULL;
6126 
6127 		if (ccb->cts.transport == XPORT_SPI)
6128 			spi = &ccb->cts.xport_specific.spi;
6129 		if (ccb->cts.transport == XPORT_ATA)
6130 			pata = &ccb->cts.xport_specific.ata;
6131 		if (ccb->cts.transport == XPORT_SATA)
6132 			sata = &ccb->cts.xport_specific.sata;
6133 		if (ccb->cts.protocol == PROTO_ATA)
6134 			ata = &ccb->cts.proto_specific.ata;
6135 		if (ccb->cts.protocol == PROTO_SCSI)
6136 			scsi = &ccb->cts.proto_specific.scsi;
6137 		ccb->cts.xport_specific.valid = 0;
6138 		ccb->cts.proto_specific.valid = 0;
6139 		if (spi && disc_enable != -1) {
6140 			spi->valid |= CTS_SPI_VALID_DISC;
6141 			if (disc_enable == 0)
6142 				spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6143 			else
6144 				spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6145 			didsettings++;
6146 		}
6147 		if (tag_enable != -1) {
6148 			if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6149 				warnx("HBA does not support tagged queueing, "
6150 				      "so you cannot modify tag settings");
6151 				retval = 1;
6152 				goto ratecontrol_bailout;
6153 			}
6154 			if (ata) {
6155 				ata->valid |= CTS_SCSI_VALID_TQ;
6156 				if (tag_enable == 0)
6157 					ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6158 				else
6159 					ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6160 				didsettings++;
6161 			} else if (scsi) {
6162 				scsi->valid |= CTS_SCSI_VALID_TQ;
6163 				if (tag_enable == 0)
6164 					scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6165 				else
6166 					scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6167 				didsettings++;
6168 			}
6169 		}
6170 		if (spi && offset != -1) {
6171 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6172 				warnx("HBA is not capable of changing offset");
6173 				retval = 1;
6174 				goto ratecontrol_bailout;
6175 			}
6176 			spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6177 			spi->sync_offset = offset;
6178 			didsettings++;
6179 		}
6180 		if (spi && syncrate != -1) {
6181 			int prelim_sync_period;
6182 
6183 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6184 				warnx("HBA is not capable of changing "
6185 				      "transfer rates");
6186 				retval = 1;
6187 				goto ratecontrol_bailout;
6188 			}
6189 			spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6190 			/*
6191 			 * The sync rate the user gives us is in MHz.
6192 			 * We need to translate it into KHz for this
6193 			 * calculation.
6194 			 */
6195 			syncrate *= 1000;
6196 			/*
6197 			 * Next, we calculate a "preliminary" sync period
6198 			 * in tenths of a nanosecond.
6199 			 */
6200 			if (syncrate == 0)
6201 				prelim_sync_period = 0;
6202 			else
6203 				prelim_sync_period = 10000000 / syncrate;
6204 			spi->sync_period =
6205 				scsi_calc_syncparam(prelim_sync_period);
6206 			didsettings++;
6207 		}
6208 		if (sata && syncrate != -1) {
6209 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6210 				warnx("HBA is not capable of changing "
6211 				      "transfer rates");
6212 				retval = 1;
6213 				goto ratecontrol_bailout;
6214 			}
6215 			if  (!user_settings) {
6216 				warnx("You can modify only user rate "
6217 				    "settings for SATA");
6218 				retval = 1;
6219 				goto ratecontrol_bailout;
6220 			}
6221 			sata->revision = ata_speed2revision(syncrate * 100);
6222 			if (sata->revision < 0) {
6223 				warnx("Invalid rate %f", syncrate);
6224 				retval = 1;
6225 				goto ratecontrol_bailout;
6226 			}
6227 			sata->valid |= CTS_SATA_VALID_REVISION;
6228 			didsettings++;
6229 		}
6230 		if ((pata || sata) && mode != -1) {
6231 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6232 				warnx("HBA is not capable of changing "
6233 				      "transfer rates");
6234 				retval = 1;
6235 				goto ratecontrol_bailout;
6236 			}
6237 			if  (!user_settings) {
6238 				warnx("You can modify only user mode "
6239 				    "settings for ATA/SATA");
6240 				retval = 1;
6241 				goto ratecontrol_bailout;
6242 			}
6243 			if (pata) {
6244 				pata->mode = mode;
6245 				pata->valid |= CTS_ATA_VALID_MODE;
6246 			} else {
6247 				sata->mode = mode;
6248 				sata->valid |= CTS_SATA_VALID_MODE;
6249 			}
6250 			didsettings++;
6251 		}
6252 		/*
6253 		 * The bus_width argument goes like this:
6254 		 * 0 == 8 bit
6255 		 * 1 == 16 bit
6256 		 * 2 == 32 bit
6257 		 * Therefore, if you shift the number of bits given on the
6258 		 * command line right by 4, you should get the correct
6259 		 * number.
6260 		 */
6261 		if (spi && bus_width != -1) {
6262 			/*
6263 			 * We might as well validate things here with a
6264 			 * decipherable error message, rather than what
6265 			 * will probably be an indecipherable error message
6266 			 * by the time it gets back to us.
6267 			 */
6268 			if ((bus_width == 16)
6269 			 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6270 				warnx("HBA does not support 16 bit bus width");
6271 				retval = 1;
6272 				goto ratecontrol_bailout;
6273 			} else if ((bus_width == 32)
6274 				&& ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6275 				warnx("HBA does not support 32 bit bus width");
6276 				retval = 1;
6277 				goto ratecontrol_bailout;
6278 			} else if ((bus_width != 8)
6279 				&& (bus_width != 16)
6280 				&& (bus_width != 32)) {
6281 				warnx("Invalid bus width %d", bus_width);
6282 				retval = 1;
6283 				goto ratecontrol_bailout;
6284 			}
6285 			spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6286 			spi->bus_width = bus_width >> 4;
6287 			didsettings++;
6288 		}
6289 		if  (didsettings == 0) {
6290 			goto ratecontrol_bailout;
6291 		}
6292 		ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6293 		if (cam_send_ccb(device, ccb) < 0) {
6294 			warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6295 			retval = 1;
6296 			goto ratecontrol_bailout;
6297 		}
6298 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6299 			warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6300 			if (arglist & CAM_ARG_VERBOSE) {
6301 				cam_error_print(device, ccb, CAM_ESF_ALL,
6302 						CAM_EPF_ALL, stderr);
6303 			}
6304 			retval = 1;
6305 			goto ratecontrol_bailout;
6306 		}
6307 	}
6308 	if (send_tur) {
6309 		retval = testunitready(device, task_attr, retry_count, timeout,
6310 				       (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6311 		/*
6312 		 * If the TUR didn't succeed, just bail.
6313 		 */
6314 		if (retval != 0) {
6315 			if (quiet == 0)
6316 				fprintf(stderr, "Test Unit Ready failed\n");
6317 			goto ratecontrol_bailout;
6318 		}
6319 	}
6320 	if ((change_settings || send_tur) && !quiet &&
6321 	    (ccb->cts.transport == XPORT_ATA ||
6322 	     ccb->cts.transport == XPORT_SATA || send_tur)) {
6323 		fprintf(stdout, "New parameters:\n");
6324 		retval = get_print_cts(device, user_settings, 0, NULL);
6325 	}
6326 
6327 ratecontrol_bailout:
6328 	cam_freeccb(ccb);
6329 	return (retval);
6330 }
6331 
6332 static int
6333 scsiformat(struct cam_device *device, int argc, char **argv,
6334 	   char *combinedopt, int task_attr, int retry_count, int timeout)
6335 {
6336 	union ccb *ccb;
6337 	int c;
6338 	int ycount = 0, quiet = 0;
6339 	int error = 0, retval = 0;
6340 	int use_timeout = 10800 * 1000;
6341 	int immediate = 1;
6342 	struct format_defect_list_header fh;
6343 	u_int8_t *data_ptr = NULL;
6344 	u_int32_t dxfer_len = 0;
6345 	u_int8_t byte2 = 0;
6346 	int num_warnings = 0;
6347 	int reportonly = 0;
6348 
6349 	ccb = cam_getccb(device);
6350 
6351 	if (ccb == NULL) {
6352 		warnx("scsiformat: error allocating ccb");
6353 		return (1);
6354 	}
6355 
6356 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6357 
6358 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
6359 		switch(c) {
6360 		case 'q':
6361 			quiet++;
6362 			break;
6363 		case 'r':
6364 			reportonly = 1;
6365 			break;
6366 		case 'w':
6367 			immediate = 0;
6368 			break;
6369 		case 'y':
6370 			ycount++;
6371 			break;
6372 		}
6373 	}
6374 
6375 	if (reportonly)
6376 		goto doreport;
6377 
6378 	if (quiet == 0 && ycount == 0) {
6379 		fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6380 			"following device:\n");
6381 
6382 		error = scsidoinquiry(device, argc, argv, combinedopt,
6383 				      task_attr, retry_count, timeout);
6384 
6385 		if (error != 0) {
6386 			warnx("scsiformat: error sending inquiry");
6387 			goto scsiformat_bailout;
6388 		}
6389 	}
6390 
6391 	if (ycount == 0) {
6392 		if (!get_confirmation()) {
6393 			error = 1;
6394 			goto scsiformat_bailout;
6395 		}
6396 	}
6397 
6398 	if (timeout != 0)
6399 		use_timeout = timeout;
6400 
6401 	if (quiet == 0) {
6402 		fprintf(stdout, "Current format timeout is %d seconds\n",
6403 			use_timeout / 1000);
6404 	}
6405 
6406 	/*
6407 	 * If the user hasn't disabled questions and didn't specify a
6408 	 * timeout on the command line, ask them if they want the current
6409 	 * timeout.
6410 	 */
6411 	if ((ycount == 0)
6412 	 && (timeout == 0)) {
6413 		char str[1024];
6414 		int new_timeout = 0;
6415 
6416 		fprintf(stdout, "Enter new timeout in seconds or press\n"
6417 			"return to keep the current timeout [%d] ",
6418 			use_timeout / 1000);
6419 
6420 		if (fgets(str, sizeof(str), stdin) != NULL) {
6421 			if (str[0] != '\0')
6422 				new_timeout = atoi(str);
6423 		}
6424 
6425 		if (new_timeout != 0) {
6426 			use_timeout = new_timeout * 1000;
6427 			fprintf(stdout, "Using new timeout value %d\n",
6428 				use_timeout / 1000);
6429 		}
6430 	}
6431 
6432 	/*
6433 	 * Keep this outside the if block below to silence any unused
6434 	 * variable warnings.
6435 	 */
6436 	bzero(&fh, sizeof(fh));
6437 
6438 	/*
6439 	 * If we're in immediate mode, we've got to include the format
6440 	 * header
6441 	 */
6442 	if (immediate != 0) {
6443 		fh.byte2 = FU_DLH_IMMED;
6444 		data_ptr = (u_int8_t *)&fh;
6445 		dxfer_len = sizeof(fh);
6446 		byte2 = FU_FMT_DATA;
6447 	} else if (quiet == 0) {
6448 		fprintf(stdout, "Formatting...");
6449 		fflush(stdout);
6450 	}
6451 
6452 	scsi_format_unit(&ccb->csio,
6453 			 /* retries */ retry_count,
6454 			 /* cbfcnp */ NULL,
6455 			 /* tag_action */ task_attr,
6456 			 /* byte2 */ byte2,
6457 			 /* ileave */ 0,
6458 			 /* data_ptr */ data_ptr,
6459 			 /* dxfer_len */ dxfer_len,
6460 			 /* sense_len */ SSD_FULL_SIZE,
6461 			 /* timeout */ use_timeout);
6462 
6463 	/* Disable freezing the device queue */
6464 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6465 
6466 	if (arglist & CAM_ARG_ERR_RECOVER)
6467 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6468 
6469 	if (((retval = cam_send_ccb(device, ccb)) < 0)
6470 	 || ((immediate == 0)
6471 	   && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6472 		const char errstr[] = "error sending format command";
6473 
6474 		if (retval < 0)
6475 			warn(errstr);
6476 		else
6477 			warnx(errstr);
6478 
6479 		if (arglist & CAM_ARG_VERBOSE) {
6480 			cam_error_print(device, ccb, CAM_ESF_ALL,
6481 					CAM_EPF_ALL, stderr);
6482 		}
6483 		error = 1;
6484 		goto scsiformat_bailout;
6485 	}
6486 
6487 	/*
6488 	 * If we ran in non-immediate mode, we already checked for errors
6489 	 * above and printed out any necessary information.  If we're in
6490 	 * immediate mode, we need to loop through and get status
6491 	 * information periodically.
6492 	 */
6493 	if (immediate == 0) {
6494 		if (quiet == 0) {
6495 			fprintf(stdout, "Format Complete\n");
6496 		}
6497 		goto scsiformat_bailout;
6498 	}
6499 
6500 doreport:
6501 	do {
6502 		cam_status status;
6503 
6504 		CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6505 
6506 		/*
6507 		 * There's really no need to do error recovery or
6508 		 * retries here, since we're just going to sit in a
6509 		 * loop and wait for the device to finish formatting.
6510 		 */
6511 		scsi_test_unit_ready(&ccb->csio,
6512 				     /* retries */ 0,
6513 				     /* cbfcnp */ NULL,
6514 				     /* tag_action */ task_attr,
6515 				     /* sense_len */ SSD_FULL_SIZE,
6516 				     /* timeout */ 5000);
6517 
6518 		/* Disable freezing the device queue */
6519 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6520 
6521 		retval = cam_send_ccb(device, ccb);
6522 
6523 		/*
6524 		 * If we get an error from the ioctl, bail out.  SCSI
6525 		 * errors are expected.
6526 		 */
6527 		if (retval < 0) {
6528 			warn("error sending TEST UNIT READY command");
6529 			error = 1;
6530 			goto scsiformat_bailout;
6531 		}
6532 
6533 		status = ccb->ccb_h.status & CAM_STATUS_MASK;
6534 
6535 		if ((status != CAM_REQ_CMP)
6536 		 && (status == CAM_SCSI_STATUS_ERROR)
6537 		 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6538 			struct scsi_sense_data *sense;
6539 			int error_code, sense_key, asc, ascq;
6540 
6541 			sense = &ccb->csio.sense_data;
6542 			scsi_extract_sense_len(sense, ccb->csio.sense_len -
6543 			    ccb->csio.sense_resid, &error_code, &sense_key,
6544 			    &asc, &ascq, /*show_errors*/ 1);
6545 
6546 			/*
6547 			 * According to the SCSI-2 and SCSI-3 specs, a
6548 			 * drive that is in the middle of a format should
6549 			 * return NOT READY with an ASC of "logical unit
6550 			 * not ready, format in progress".  The sense key
6551 			 * specific bytes will then be a progress indicator.
6552 			 */
6553 			if ((sense_key == SSD_KEY_NOT_READY)
6554 			 && (asc == 0x04) && (ascq == 0x04)) {
6555 				uint8_t sks[3];
6556 
6557 				if ((scsi_get_sks(sense, ccb->csio.sense_len -
6558 				     ccb->csio.sense_resid, sks) == 0)
6559 				 && (quiet == 0)) {
6560 					uint32_t val;
6561 					u_int64_t percentage;
6562 
6563 					val = scsi_2btoul(&sks[1]);
6564 					percentage = 10000ull * val;
6565 
6566 					fprintf(stdout,
6567 						"\rFormatting:  %ju.%02u %% "
6568 						"(%u/%d) done",
6569 						(uintmax_t)(percentage /
6570 						(0x10000 * 100)),
6571 						(unsigned)((percentage /
6572 						0x10000) % 100),
6573 						val, 0x10000);
6574 					fflush(stdout);
6575 				} else if ((quiet == 0)
6576 					&& (++num_warnings <= 1)) {
6577 					warnx("Unexpected SCSI Sense Key "
6578 					      "Specific value returned "
6579 					      "during format:");
6580 					scsi_sense_print(device, &ccb->csio,
6581 							 stderr);
6582 					warnx("Unable to print status "
6583 					      "information, but format will "
6584 					      "proceed.");
6585 					warnx("will exit when format is "
6586 					      "complete");
6587 				}
6588 				sleep(1);
6589 			} else {
6590 				warnx("Unexpected SCSI error during format");
6591 				cam_error_print(device, ccb, CAM_ESF_ALL,
6592 						CAM_EPF_ALL, stderr);
6593 				error = 1;
6594 				goto scsiformat_bailout;
6595 			}
6596 
6597 		} else if (status != CAM_REQ_CMP) {
6598 			warnx("Unexpected CAM status %#x", status);
6599 			if (arglist & CAM_ARG_VERBOSE)
6600 				cam_error_print(device, ccb, CAM_ESF_ALL,
6601 						CAM_EPF_ALL, stderr);
6602 			error = 1;
6603 			goto scsiformat_bailout;
6604 		}
6605 
6606 	} while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6607 
6608 	if (quiet == 0)
6609 		fprintf(stdout, "\nFormat Complete\n");
6610 
6611 scsiformat_bailout:
6612 
6613 	cam_freeccb(ccb);
6614 
6615 	return (error);
6616 }
6617 
6618 static int
6619 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6620     camcontrol_devtype devtype)
6621 {
6622 	int retval;
6623 	uint8_t error = 0, ata_device = 0, status = 0;
6624 	uint16_t count = 0;
6625 	uint64_t lba = 0;
6626 	u_int val, perc;
6627 
6628 	do {
6629 		retval = build_ata_cmd(ccb,
6630 			     /*retries*/ 0,
6631 			     /*flags*/ CAM_DIR_NONE,
6632 			     /*tag_action*/ MSG_SIMPLE_Q_TAG,
6633 			     /*protocol*/ AP_PROTO_NON_DATA,
6634 			     /*ata_flags*/ AP_FLAG_CHK_COND,
6635 			     /*features*/ 0x00, /* SANITIZE STATUS EXT */
6636 			     /*sector_count*/ 0,
6637 			     /*lba*/ 0,
6638 			     /*command*/ ATA_SANITIZE,
6639 			     /*auxiliary*/ 0,
6640 			     /*data_ptr*/ NULL,
6641 			     /*dxfer_len*/ 0,
6642 			     /*cdb_storage*/ NULL,
6643 			     /*cdb_storage_len*/ 0,
6644 			     /*sense_len*/ SSD_FULL_SIZE,
6645 			     /*timeout*/ 10000,
6646 			     /*is48bit*/ 1,
6647 			     /*devtype*/ devtype);
6648 		if (retval != 0) {
6649 			warnx("%s: build_ata_cmd() failed, likely "
6650 			    "programmer error", __func__);
6651 			return (1);
6652 		}
6653 
6654 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6655 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6656 		retval = cam_send_ccb(device, ccb);
6657 		if (retval != 0) {
6658 			warn("error sending SANITIZE STATUS EXT command");
6659 			return (1);
6660 		}
6661 
6662 		retval = get_ata_status(device, ccb, &error, &count, &lba,
6663 		    &ata_device, &status);
6664 		if (retval != 0) {
6665 			warnx("Can't get SANITIZE STATUS EXT status, "
6666 			    "sanitize may still run.");
6667 			return (retval);
6668 		}
6669 		if (status & ATA_STATUS_ERROR) {
6670 			if (error & ATA_ERROR_ABORT) {
6671 				switch (lba & 0xff) {
6672 				case 0x00:
6673 					warnx("Reason not reported or sanitize failed.");
6674 					return (1);
6675 				case 0x01:
6676 					warnx("Sanitize command unsuccessful.       ");
6677 					return (1);
6678 				case 0x02:
6679 					warnx("Unsupported sanitize device command. ");
6680 					return (1);
6681 				case 0x03:
6682 					warnx("Device is in sanitize frozen state.  ");
6683 					return (1);
6684 				case 0x04:
6685 					warnx("Sanitize antifreeze lock is enabled. ");
6686 					return (1);
6687 				}
6688 			}
6689 			warnx("SANITIZE STATUS EXT failed, "
6690 			    "sanitize may still run.");
6691 			return (1);
6692 		}
6693 		if (count & 0x4000) {
6694 			if (quiet == 0) {
6695 				val = lba & 0xffff;
6696 				perc = 10000 * val;
6697 				fprintf(stdout,
6698 				    "Sanitizing: %u.%02u%% (%d/%d)\r",
6699 				    (perc / (0x10000 * 100)),
6700 				    ((perc / 0x10000) % 100),
6701 				    val, 0x10000);
6702 				fflush(stdout);
6703 			}
6704 			sleep(1);
6705 		} else
6706 			break;
6707 	} while (1);
6708 	return (0);
6709 }
6710 
6711 static int
6712 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6713 {
6714 	int warnings = 0, retval;
6715 	cam_status status;
6716 	u_int val, perc;
6717 
6718 	do {
6719 		CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6720 
6721 		/*
6722 		 * There's really no need to do error recovery or
6723 		 * retries here, since we're just going to sit in a
6724 		 * loop and wait for the device to finish sanitizing.
6725 		 */
6726 		scsi_test_unit_ready(&ccb->csio,
6727 				     /* retries */ 0,
6728 				     /* cbfcnp */ NULL,
6729 				     /* tag_action */ task_attr,
6730 				     /* sense_len */ SSD_FULL_SIZE,
6731 				     /* timeout */ 5000);
6732 
6733 		/* Disable freezing the device queue */
6734 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6735 
6736 		retval = cam_send_ccb(device, ccb);
6737 
6738 		/*
6739 		 * If we get an error from the ioctl, bail out.  SCSI
6740 		 * errors are expected.
6741 		 */
6742 		if (retval < 0) {
6743 			warn("error sending TEST UNIT READY command");
6744 			return (1);
6745 		}
6746 
6747 		status = ccb->ccb_h.status & CAM_STATUS_MASK;
6748 		if ((status == CAM_SCSI_STATUS_ERROR) &&
6749 		    ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6750 			struct scsi_sense_data *sense;
6751 			int error_code, sense_key, asc, ascq;
6752 
6753 			sense = &ccb->csio.sense_data;
6754 			scsi_extract_sense_len(sense, ccb->csio.sense_len -
6755 			    ccb->csio.sense_resid, &error_code, &sense_key,
6756 			    &asc, &ascq, /*show_errors*/ 1);
6757 
6758 			/*
6759 			 * According to the SCSI-3 spec, a drive that is in the
6760 			 * middle of a sanitize should return NOT READY with an
6761 			 * ASC of "logical unit not ready, sanitize in
6762 			 * progress". The sense key specific bytes will then
6763 			 * be a progress indicator.
6764 			 */
6765 			if ((sense_key == SSD_KEY_NOT_READY)
6766 			 && (asc == 0x04) && (ascq == 0x1b)) {
6767 				uint8_t sks[3];
6768 
6769 				if ((scsi_get_sks(sense, ccb->csio.sense_len -
6770 				     ccb->csio.sense_resid, sks) == 0)
6771 				 && (quiet == 0)) {
6772 					val = scsi_2btoul(&sks[1]);
6773 					perc = 10000 * val;
6774 					fprintf(stdout,
6775 					    "Sanitizing: %u.%02u%% (%d/%d)\r",
6776 					    (perc / (0x10000 * 100)),
6777 					    ((perc / 0x10000) % 100),
6778 					    val, 0x10000);
6779 					fflush(stdout);
6780 				} else if ((quiet == 0) && (++warnings <= 1)) {
6781 					warnx("Unexpected SCSI Sense Key "
6782 					      "Specific value returned "
6783 					      "during sanitize:");
6784 					scsi_sense_print(device, &ccb->csio,
6785 							 stderr);
6786 					warnx("Unable to print status "
6787 					      "information, but sanitze will "
6788 					      "proceed.");
6789 					warnx("will exit when sanitize is "
6790 					      "complete");
6791 				}
6792 				sleep(1);
6793 			} else {
6794 				warnx("Unexpected SCSI error during sanitize");
6795 				cam_error_print(device, ccb, CAM_ESF_ALL,
6796 						CAM_EPF_ALL, stderr);
6797 				return (1);
6798 			}
6799 
6800 		} else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6801 			warnx("Unexpected CAM status %#x", status);
6802 			if (arglist & CAM_ARG_VERBOSE)
6803 				cam_error_print(device, ccb, CAM_ESF_ALL,
6804 						CAM_EPF_ALL, stderr);
6805 			return (1);
6806 		}
6807 	} while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6808 	return (0);
6809 }
6810 
6811 static int
6812 sanitize(struct cam_device *device, int argc, char **argv,
6813 	     char *combinedopt, int task_attr, int retry_count, int timeout)
6814 {
6815 	union ccb *ccb;
6816 	u_int8_t action = 0;
6817 	int c;
6818 	int ycount = 0, quiet = 0;
6819 	int error = 0;
6820 	int use_timeout;
6821 	int immediate = 1;
6822 	int invert = 0;
6823 	int passes = 0;
6824 	int ause = 0;
6825 	int fd = -1;
6826 	const char *pattern = NULL;
6827 	u_int8_t *data_ptr = NULL;
6828 	u_int32_t dxfer_len = 0;
6829 	uint8_t byte2;
6830 	uint16_t feature, count;
6831 	uint64_t lba;
6832 	int reportonly = 0;
6833 	camcontrol_devtype dt;
6834 
6835 	/*
6836 	 * Get the device type, request no I/O be done to do this.
6837 	 */
6838 	error = get_device_type(device, -1, 0, 0, &dt);
6839 	if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6840 		warnx("sanitize: can't get device type");
6841 		return (1);
6842 	}
6843 
6844 	ccb = cam_getccb(device);
6845 
6846 	if (ccb == NULL) {
6847 		warnx("sanitize: error allocating ccb");
6848 		return (1);
6849 	}
6850 
6851 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6852 
6853 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
6854 		switch(c) {
6855 		case 'a':
6856 			if (strcasecmp(optarg, "overwrite") == 0)
6857 				action = SSZ_SERVICE_ACTION_OVERWRITE;
6858 			else if (strcasecmp(optarg, "block") == 0)
6859 				action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6860 			else if (strcasecmp(optarg, "crypto") == 0)
6861 				action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6862 			else if (strcasecmp(optarg, "exitfailure") == 0)
6863 				action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6864 			else {
6865 				warnx("invalid service operation \"%s\"",
6866 				      optarg);
6867 				error = 1;
6868 				goto sanitize_bailout;
6869 			}
6870 			break;
6871 		case 'c':
6872 			passes = strtol(optarg, NULL, 0);
6873 			if (passes < 1 || passes > 31) {
6874 				warnx("invalid passes value %d", passes);
6875 				error = 1;
6876 				goto sanitize_bailout;
6877 			}
6878 			break;
6879 		case 'I':
6880 			invert = 1;
6881 			break;
6882 		case 'P':
6883 			pattern = optarg;
6884 			break;
6885 		case 'q':
6886 			quiet++;
6887 			break;
6888 		case 'U':
6889 			ause = 1;
6890 			break;
6891 		case 'r':
6892 			reportonly = 1;
6893 			break;
6894 		case 'w':
6895 			/* ATA supports only immediate commands. */
6896 			if (dt == CC_DT_SCSI)
6897 				immediate = 0;
6898 			break;
6899 		case 'y':
6900 			ycount++;
6901 			break;
6902 		}
6903 	}
6904 
6905 	if (reportonly)
6906 		goto doreport;
6907 
6908 	if (action == 0) {
6909 		warnx("an action is required");
6910 		error = 1;
6911 		goto sanitize_bailout;
6912 	} else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6913 		struct scsi_sanitize_parameter_list *pl;
6914 		struct stat sb;
6915 		ssize_t sz, amt;
6916 
6917 		if (pattern == NULL) {
6918 			warnx("overwrite action requires -P argument");
6919 			error = 1;
6920 			goto sanitize_bailout;
6921 		}
6922 		fd = open(pattern, O_RDONLY);
6923 		if (fd < 0) {
6924 			warn("cannot open pattern file %s", pattern);
6925 			error = 1;
6926 			goto sanitize_bailout;
6927 		}
6928 		if (fstat(fd, &sb) < 0) {
6929 			warn("cannot stat pattern file %s", pattern);
6930 			error = 1;
6931 			goto sanitize_bailout;
6932 		}
6933 		sz = sb.st_size;
6934 		if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6935 			warnx("pattern file size exceeds maximum value %d",
6936 			      SSZPL_MAX_PATTERN_LENGTH);
6937 			error = 1;
6938 			goto sanitize_bailout;
6939 		}
6940 		dxfer_len = sizeof(*pl) + sz;
6941 		data_ptr = calloc(1, dxfer_len);
6942 		if (data_ptr == NULL) {
6943 			warnx("cannot allocate parameter list buffer");
6944 			error = 1;
6945 			goto sanitize_bailout;
6946 		}
6947 
6948 		amt = read(fd, data_ptr + sizeof(*pl), sz);
6949 		if (amt < 0) {
6950 			warn("cannot read pattern file");
6951 			error = 1;
6952 			goto sanitize_bailout;
6953 		} else if (amt != sz) {
6954 			warnx("short pattern file read");
6955 			error = 1;
6956 			goto sanitize_bailout;
6957 		}
6958 
6959 		pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6960 		if (passes == 0)
6961 			pl->byte1 = 1;
6962 		else
6963 			pl->byte1 = passes;
6964 		if (invert != 0)
6965 			pl->byte1 |= SSZPL_INVERT;
6966 		scsi_ulto2b(sz, pl->length);
6967 	} else {
6968 		const char *arg;
6969 
6970 		if (passes != 0)
6971 			arg = "-c";
6972 		else if (invert != 0)
6973 			arg = "-I";
6974 		else if (pattern != NULL)
6975 			arg = "-P";
6976 		else
6977 			arg = NULL;
6978 		if (arg != NULL) {
6979 			warnx("%s argument only valid with overwrite "
6980 			      "operation", arg);
6981 			error = 1;
6982 			goto sanitize_bailout;
6983 		}
6984 	}
6985 
6986 	if (quiet == 0 && ycount == 0) {
6987 		fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6988 			"following device:\n");
6989 
6990 		if (dt == CC_DT_SCSI) {
6991 			error = scsidoinquiry(device, argc, argv, combinedopt,
6992 					      task_attr, retry_count, timeout);
6993 		} else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
6994 			struct ata_params *ident_buf;
6995 			error = ata_do_identify(device, retry_count, timeout,
6996 						ccb, &ident_buf);
6997 			if (error == 0) {
6998 				printf("%s%d: ", device->device_name,
6999 				    device->dev_unit_num);
7000 				ata_print_ident(ident_buf);
7001 				free(ident_buf);
7002 			}
7003 		} else
7004 			error = 1;
7005 
7006 		if (error != 0) {
7007 			warnx("sanitize: error sending inquiry");
7008 			goto sanitize_bailout;
7009 		}
7010 	}
7011 
7012 	if (ycount == 0) {
7013 		if (!get_confirmation()) {
7014 			error = 1;
7015 			goto sanitize_bailout;
7016 		}
7017 	}
7018 
7019 	if (timeout != 0)
7020 		use_timeout = timeout;
7021 	else
7022 		use_timeout = (immediate ? 10 : 10800) * 1000;
7023 
7024 	if (immediate == 0 && quiet == 0) {
7025 		fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7026 			use_timeout / 1000);
7027 	}
7028 
7029 	/*
7030 	 * If the user hasn't disabled questions and didn't specify a
7031 	 * timeout on the command line, ask them if they want the current
7032 	 * timeout.
7033 	 */
7034 	if (immediate == 0 && ycount == 0 && timeout == 0) {
7035 		char str[1024];
7036 		int new_timeout = 0;
7037 
7038 		fprintf(stdout, "Enter new timeout in seconds or press\n"
7039 			"return to keep the current timeout [%d] ",
7040 			use_timeout / 1000);
7041 
7042 		if (fgets(str, sizeof(str), stdin) != NULL) {
7043 			if (str[0] != '\0')
7044 				new_timeout = atoi(str);
7045 		}
7046 
7047 		if (new_timeout != 0) {
7048 			use_timeout = new_timeout * 1000;
7049 			fprintf(stdout, "Using new timeout value %d\n",
7050 				use_timeout / 1000);
7051 		}
7052 	}
7053 
7054 	if (dt == CC_DT_SCSI) {
7055 		byte2 = action;
7056 		if (ause != 0)
7057 			byte2 |= SSZ_UNRESTRICTED_EXIT;
7058 		if (immediate != 0)
7059 			byte2 |= SSZ_IMMED;
7060 		scsi_sanitize(&ccb->csio,
7061 			      /* retries */ retry_count,
7062 			      /* cbfcnp */ NULL,
7063 			      /* tag_action */ task_attr,
7064 			      /* byte2 */ byte2,
7065 			      /* control */ 0,
7066 			      /* data_ptr */ data_ptr,
7067 			      /* dxfer_len */ dxfer_len,
7068 			      /* sense_len */ SSD_FULL_SIZE,
7069 			      /* timeout */ use_timeout);
7070 
7071 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7072 		if (arglist & CAM_ARG_ERR_RECOVER)
7073 			ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7074 		if (cam_send_ccb(device, ccb) < 0) {
7075 			warn("error sending sanitize command");
7076 			error = 1;
7077 			goto sanitize_bailout;
7078 		}
7079 	} else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7080 		if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7081 			feature = 0x14; /* OVERWRITE EXT */
7082 			lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7083 			count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7084 			if (invert)
7085 				count |= 0x80; /* INVERT PATTERN */
7086 			if (ause)
7087 				count |= 0x10; /* FAILURE MODE */
7088 		} else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7089 			feature = 0x12; /* BLOCK ERASE EXT */
7090 			lba = 0x0000426B4572;
7091 			count = 0;
7092 			if (ause)
7093 				count |= 0x10; /* FAILURE MODE */
7094 		} else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7095 			feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7096 			lba = 0x000043727970;
7097 			count = 0;
7098 			if (ause)
7099 				count |= 0x10; /* FAILURE MODE */
7100 		} else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7101 			feature = 0x00; /* SANITIZE STATUS EXT */
7102 			lba = 0;
7103 			count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7104 		} else {
7105 			error = 1;
7106 			goto sanitize_bailout;
7107 		}
7108 
7109 		error = ata_do_cmd(device,
7110 				   ccb,
7111 				   retry_count,
7112 				   /*flags*/CAM_DIR_NONE,
7113 				   /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7114 				   /*ata_flags*/0,
7115 				   /*tag_action*/MSG_SIMPLE_Q_TAG,
7116 				   /*command*/ATA_SANITIZE,
7117 				   /*features*/feature,
7118 				   /*lba*/lba,
7119 				   /*sector_count*/count,
7120 				   /*data_ptr*/NULL,
7121 				   /*dxfer_len*/0,
7122 				   /*timeout*/ use_timeout,
7123 				   /*is48bit*/1);
7124 	}
7125 
7126 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7127 		struct scsi_sense_data *sense;
7128 		int error_code, sense_key, asc, ascq;
7129 
7130 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7131 		    CAM_SCSI_STATUS_ERROR) {
7132 			sense = &ccb->csio.sense_data;
7133 			scsi_extract_sense_len(sense, ccb->csio.sense_len -
7134 			    ccb->csio.sense_resid, &error_code, &sense_key,
7135 			    &asc, &ascq, /*show_errors*/ 1);
7136 
7137 			if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7138 			    asc == 0x20 && ascq == 0x00)
7139 				warnx("sanitize is not supported by "
7140 				      "this device");
7141 			else
7142 				warnx("error sanitizing this device");
7143 		} else
7144 			warnx("error sanitizing this device");
7145 
7146 		if (arglist & CAM_ARG_VERBOSE) {
7147 			cam_error_print(device, ccb, CAM_ESF_ALL,
7148 					CAM_EPF_ALL, stderr);
7149 		}
7150 		error = 1;
7151 		goto sanitize_bailout;
7152 	}
7153 
7154 	/*
7155 	 * If we ran in non-immediate mode, we already checked for errors
7156 	 * above and printed out any necessary information.  If we're in
7157 	 * immediate mode, we need to loop through and get status
7158 	 * information periodically.
7159 	 */
7160 	if (immediate == 0) {
7161 		if (quiet == 0) {
7162 			fprintf(stdout, "Sanitize Complete\n");
7163 		}
7164 		goto sanitize_bailout;
7165 	}
7166 
7167 doreport:
7168 	if (dt == CC_DT_SCSI) {
7169 		error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7170 	} else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7171 		error = sanitize_wait_ata(device, ccb, quiet, dt);
7172 	} else
7173 		error = 1;
7174 	if (error == 0 && quiet == 0)
7175 		fprintf(stdout, "Sanitize Complete                      \n");
7176 
7177 sanitize_bailout:
7178 	if (fd >= 0)
7179 		close(fd);
7180 	if (data_ptr != NULL)
7181 		free(data_ptr);
7182 	cam_freeccb(ccb);
7183 
7184 	return (error);
7185 }
7186 
7187 static int
7188 scsireportluns(struct cam_device *device, int argc, char **argv,
7189 	       char *combinedopt, int task_attr, int retry_count, int timeout)
7190 {
7191 	union ccb *ccb;
7192 	int c, countonly, lunsonly;
7193 	struct scsi_report_luns_data *lundata;
7194 	int alloc_len;
7195 	uint8_t report_type;
7196 	uint32_t list_len, i, j;
7197 	int retval;
7198 
7199 	retval = 0;
7200 	lundata = NULL;
7201 	report_type = RPL_REPORT_DEFAULT;
7202 	ccb = cam_getccb(device);
7203 
7204 	if (ccb == NULL) {
7205 		warnx("%s: error allocating ccb", __func__);
7206 		return (1);
7207 	}
7208 
7209 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7210 
7211 	countonly = 0;
7212 	lunsonly = 0;
7213 
7214 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
7215 		switch (c) {
7216 		case 'c':
7217 			countonly++;
7218 			break;
7219 		case 'l':
7220 			lunsonly++;
7221 			break;
7222 		case 'r':
7223 			if (strcasecmp(optarg, "default") == 0)
7224 				report_type = RPL_REPORT_DEFAULT;
7225 			else if (strcasecmp(optarg, "wellknown") == 0)
7226 				report_type = RPL_REPORT_WELLKNOWN;
7227 			else if (strcasecmp(optarg, "all") == 0)
7228 				report_type = RPL_REPORT_ALL;
7229 			else {
7230 				warnx("%s: invalid report type \"%s\"",
7231 				      __func__, optarg);
7232 				retval = 1;
7233 				goto bailout;
7234 			}
7235 			break;
7236 		default:
7237 			break;
7238 		}
7239 	}
7240 
7241 	if ((countonly != 0)
7242 	 && (lunsonly != 0)) {
7243 		warnx("%s: you can only specify one of -c or -l", __func__);
7244 		retval = 1;
7245 		goto bailout;
7246 	}
7247 	/*
7248 	 * According to SPC-4, the allocation length must be at least 16
7249 	 * bytes -- enough for the header and one LUN.
7250 	 */
7251 	alloc_len = sizeof(*lundata) + 8;
7252 
7253 retry:
7254 
7255 	lundata = malloc(alloc_len);
7256 
7257 	if (lundata == NULL) {
7258 		warn("%s: error mallocing %d bytes", __func__, alloc_len);
7259 		retval = 1;
7260 		goto bailout;
7261 	}
7262 
7263 	scsi_report_luns(&ccb->csio,
7264 			 /*retries*/ retry_count,
7265 			 /*cbfcnp*/ NULL,
7266 			 /*tag_action*/ task_attr,
7267 			 /*select_report*/ report_type,
7268 			 /*rpl_buf*/ lundata,
7269 			 /*alloc_len*/ alloc_len,
7270 			 /*sense_len*/ SSD_FULL_SIZE,
7271 			 /*timeout*/ timeout ? timeout : 5000);
7272 
7273 	/* Disable freezing the device queue */
7274 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7275 
7276 	if (arglist & CAM_ARG_ERR_RECOVER)
7277 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7278 
7279 	if (cam_send_ccb(device, ccb) < 0) {
7280 		warn("error sending REPORT LUNS command");
7281 		retval = 1;
7282 		goto bailout;
7283 	}
7284 
7285 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7286 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7287 		retval = 1;
7288 		goto bailout;
7289 	}
7290 
7291 
7292 	list_len = scsi_4btoul(lundata->length);
7293 
7294 	/*
7295 	 * If we need to list the LUNs, and our allocation
7296 	 * length was too short, reallocate and retry.
7297 	 */
7298 	if ((countonly == 0)
7299 	 && (list_len > (alloc_len - sizeof(*lundata)))) {
7300 		alloc_len = list_len + sizeof(*lundata);
7301 		free(lundata);
7302 		goto retry;
7303 	}
7304 
7305 	if (lunsonly == 0)
7306 		fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7307 			((list_len / 8) > 1) ? "s" : "");
7308 
7309 	if (countonly != 0)
7310 		goto bailout;
7311 
7312 	for (i = 0; i < (list_len / 8); i++) {
7313 		int no_more;
7314 
7315 		no_more = 0;
7316 		for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7317 			if (j != 0)
7318 				fprintf(stdout, ",");
7319 			switch (lundata->luns[i].lundata[j] &
7320 				RPL_LUNDATA_ATYP_MASK) {
7321 			case RPL_LUNDATA_ATYP_PERIPH:
7322 				if ((lundata->luns[i].lundata[j] &
7323 				    RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7324 					fprintf(stdout, "%d:",
7325 						lundata->luns[i].lundata[j] &
7326 						RPL_LUNDATA_PERIPH_BUS_MASK);
7327 				else if ((j == 0)
7328 				      && ((lundata->luns[i].lundata[j+2] &
7329 					  RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7330 					no_more = 1;
7331 
7332 				fprintf(stdout, "%d",
7333 					lundata->luns[i].lundata[j+1]);
7334 				break;
7335 			case RPL_LUNDATA_ATYP_FLAT: {
7336 				uint8_t tmplun[2];
7337 				tmplun[0] = lundata->luns[i].lundata[j] &
7338 					RPL_LUNDATA_FLAT_LUN_MASK;
7339 				tmplun[1] = lundata->luns[i].lundata[j+1];
7340 
7341 				fprintf(stdout, "%d", scsi_2btoul(tmplun));
7342 				no_more = 1;
7343 				break;
7344 			}
7345 			case RPL_LUNDATA_ATYP_LUN:
7346 				fprintf(stdout, "%d:%d:%d",
7347 					(lundata->luns[i].lundata[j+1] &
7348 					RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7349 					lundata->luns[i].lundata[j] &
7350 					RPL_LUNDATA_LUN_TARG_MASK,
7351 					lundata->luns[i].lundata[j+1] &
7352 					RPL_LUNDATA_LUN_LUN_MASK);
7353 				break;
7354 			case RPL_LUNDATA_ATYP_EXTLUN: {
7355 				int field_len_code, eam_code;
7356 
7357 				eam_code = lundata->luns[i].lundata[j] &
7358 					RPL_LUNDATA_EXT_EAM_MASK;
7359 				field_len_code = (lundata->luns[i].lundata[j] &
7360 					RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7361 
7362 				if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7363 				 && (field_len_code == 0x00)) {
7364 					fprintf(stdout, "%d",
7365 						lundata->luns[i].lundata[j+1]);
7366 				} else if ((eam_code ==
7367 					    RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7368 					&& (field_len_code == 0x03)) {
7369 					uint8_t tmp_lun[8];
7370 
7371 					/*
7372 					 * This format takes up all 8 bytes.
7373 					 * If we aren't starting at offset 0,
7374 					 * that's a bug.
7375 					 */
7376 					if (j != 0) {
7377 						fprintf(stdout, "Invalid "
7378 							"offset %d for "
7379 							"Extended LUN not "
7380 							"specified format", j);
7381 						no_more = 1;
7382 						break;
7383 					}
7384 					bzero(tmp_lun, sizeof(tmp_lun));
7385 					bcopy(&lundata->luns[i].lundata[j+1],
7386 					      &tmp_lun[1], sizeof(tmp_lun) - 1);
7387 					fprintf(stdout, "%#jx",
7388 					       (intmax_t)scsi_8btou64(tmp_lun));
7389 					no_more = 1;
7390 				} else {
7391 					fprintf(stderr, "Unknown Extended LUN"
7392 						"Address method %#x, length "
7393 						"code %#x", eam_code,
7394 						field_len_code);
7395 					no_more = 1;
7396 				}
7397 				break;
7398 			}
7399 			default:
7400 				fprintf(stderr, "Unknown LUN address method "
7401 					"%#x\n", lundata->luns[i].lundata[0] &
7402 					RPL_LUNDATA_ATYP_MASK);
7403 				break;
7404 			}
7405 			/*
7406 			 * For the flat addressing method, there are no
7407 			 * other levels after it.
7408 			 */
7409 			if (no_more != 0)
7410 				break;
7411 		}
7412 		fprintf(stdout, "\n");
7413 	}
7414 
7415 bailout:
7416 
7417 	cam_freeccb(ccb);
7418 
7419 	free(lundata);
7420 
7421 	return (retval);
7422 }
7423 
7424 static int
7425 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7426 		 char *combinedopt, int task_attr, int retry_count, int timeout)
7427 {
7428 	union ccb *ccb;
7429 	int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7430 	struct scsi_read_capacity_data rcap;
7431 	struct scsi_read_capacity_data_long rcaplong;
7432 	uint64_t maxsector;
7433 	uint32_t block_len;
7434 	int retval;
7435 	int c;
7436 
7437 	blocksizeonly = 0;
7438 	humanize = 0;
7439 	longonly = 0;
7440 	numblocks = 0;
7441 	quiet = 0;
7442 	sizeonly = 0;
7443 	baseten = 0;
7444 	retval = 0;
7445 
7446 	ccb = cam_getccb(device);
7447 
7448 	if (ccb == NULL) {
7449 		warnx("%s: error allocating ccb", __func__);
7450 		return (1);
7451 	}
7452 
7453 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7454 
7455 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
7456 		switch (c) {
7457 		case 'b':
7458 			blocksizeonly++;
7459 			break;
7460 		case 'h':
7461 			humanize++;
7462 			baseten = 0;
7463 			break;
7464 		case 'H':
7465 			humanize++;
7466 			baseten++;
7467 			break;
7468 		case 'l':
7469 			longonly++;
7470 			break;
7471 		case 'N':
7472 			numblocks++;
7473 			break;
7474 		case 'q':
7475 			quiet++;
7476 			break;
7477 		case 's':
7478 			sizeonly++;
7479 			break;
7480 		default:
7481 			break;
7482 		}
7483 	}
7484 
7485 	if ((blocksizeonly != 0)
7486 	 && (numblocks != 0)) {
7487 		warnx("%s: you can only specify one of -b or -N", __func__);
7488 		retval = 1;
7489 		goto bailout;
7490 	}
7491 
7492 	if ((blocksizeonly != 0)
7493 	 && (sizeonly != 0)) {
7494 		warnx("%s: you can only specify one of -b or -s", __func__);
7495 		retval = 1;
7496 		goto bailout;
7497 	}
7498 
7499 	if ((humanize != 0)
7500 	 && (quiet != 0)) {
7501 		warnx("%s: you can only specify one of -h/-H or -q", __func__);
7502 		retval = 1;
7503 		goto bailout;
7504 	}
7505 
7506 	if ((humanize != 0)
7507 	 && (blocksizeonly != 0)) {
7508 		warnx("%s: you can only specify one of -h/-H or -b", __func__);
7509 		retval = 1;
7510 		goto bailout;
7511 	}
7512 
7513 	if (longonly != 0)
7514 		goto long_only;
7515 
7516 	scsi_read_capacity(&ccb->csio,
7517 			   /*retries*/ retry_count,
7518 			   /*cbfcnp*/ NULL,
7519 			   /*tag_action*/ task_attr,
7520 			   &rcap,
7521 			   SSD_FULL_SIZE,
7522 			   /*timeout*/ timeout ? timeout : 5000);
7523 
7524 	/* Disable freezing the device queue */
7525 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7526 
7527 	if (arglist & CAM_ARG_ERR_RECOVER)
7528 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7529 
7530 	if (cam_send_ccb(device, ccb) < 0) {
7531 		warn("error sending READ CAPACITY command");
7532 		retval = 1;
7533 		goto bailout;
7534 	}
7535 
7536 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7537 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7538 		retval = 1;
7539 		goto bailout;
7540 	}
7541 
7542 	maxsector = scsi_4btoul(rcap.addr);
7543 	block_len = scsi_4btoul(rcap.length);
7544 
7545 	/*
7546 	 * A last block of 2^32-1 means that the true capacity is over 2TB,
7547 	 * and we need to issue the long READ CAPACITY to get the real
7548 	 * capacity.  Otherwise, we're all set.
7549 	 */
7550 	if (maxsector != 0xffffffff)
7551 		goto do_print;
7552 
7553 long_only:
7554 	scsi_read_capacity_16(&ccb->csio,
7555 			      /*retries*/ retry_count,
7556 			      /*cbfcnp*/ NULL,
7557 			      /*tag_action*/ task_attr,
7558 			      /*lba*/ 0,
7559 			      /*reladdr*/ 0,
7560 			      /*pmi*/ 0,
7561 			      /*rcap_buf*/ (uint8_t *)&rcaplong,
7562 			      /*rcap_buf_len*/ sizeof(rcaplong),
7563 			      /*sense_len*/ SSD_FULL_SIZE,
7564 			      /*timeout*/ timeout ? timeout : 5000);
7565 
7566 	/* Disable freezing the device queue */
7567 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7568 
7569 	if (arglist & CAM_ARG_ERR_RECOVER)
7570 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7571 
7572 	if (cam_send_ccb(device, ccb) < 0) {
7573 		warn("error sending READ CAPACITY (16) command");
7574 		retval = 1;
7575 		goto bailout;
7576 	}
7577 
7578 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7579 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7580 		retval = 1;
7581 		goto bailout;
7582 	}
7583 
7584 	maxsector = scsi_8btou64(rcaplong.addr);
7585 	block_len = scsi_4btoul(rcaplong.length);
7586 
7587 do_print:
7588 	if (blocksizeonly == 0) {
7589 		/*
7590 		 * Humanize implies !quiet, and also implies numblocks.
7591 		 */
7592 		if (humanize != 0) {
7593 			char tmpstr[6];
7594 			int64_t tmpbytes;
7595 			int ret;
7596 
7597 			tmpbytes = (maxsector + 1) * block_len;
7598 			ret = humanize_number(tmpstr, sizeof(tmpstr),
7599 					      tmpbytes, "", HN_AUTOSCALE,
7600 					      HN_B | HN_DECIMAL |
7601 					      ((baseten != 0) ?
7602 					      HN_DIVISOR_1000 : 0));
7603 			if (ret == -1) {
7604 				warnx("%s: humanize_number failed!", __func__);
7605 				retval = 1;
7606 				goto bailout;
7607 			}
7608 			fprintf(stdout, "Device Size: %s%s", tmpstr,
7609 				(sizeonly == 0) ?  ", " : "\n");
7610 		} else if (numblocks != 0) {
7611 			fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7612 				"Blocks: " : "", (uintmax_t)maxsector + 1,
7613 				(sizeonly == 0) ? ", " : "\n");
7614 		} else {
7615 			fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7616 				"Last Block: " : "", (uintmax_t)maxsector,
7617 				(sizeonly == 0) ? ", " : "\n");
7618 		}
7619 	}
7620 	if (sizeonly == 0)
7621 		fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7622 			"Block Length: " : "", block_len, (quiet == 0) ?
7623 			" bytes" : "");
7624 bailout:
7625 	cam_freeccb(ccb);
7626 
7627 	return (retval);
7628 }
7629 
7630 static int
7631 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7632        int retry_count, int timeout)
7633 {
7634 	int c, error = 0;
7635 	union ccb *ccb;
7636 	uint8_t *smp_request = NULL, *smp_response = NULL;
7637 	int request_size = 0, response_size = 0;
7638 	int fd_request = 0, fd_response = 0;
7639 	char *datastr = NULL;
7640 	struct get_hook hook;
7641 	int retval;
7642 	int flags = 0;
7643 
7644 	/*
7645 	 * Note that at the moment we don't support sending SMP CCBs to
7646 	 * devices that aren't probed by CAM.
7647 	 */
7648 	ccb = cam_getccb(device);
7649 	if (ccb == NULL) {
7650 		warnx("%s: error allocating CCB", __func__);
7651 		return (1);
7652 	}
7653 
7654 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7655 
7656 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
7657 		switch (c) {
7658 		case 'R':
7659 			arglist |= CAM_ARG_CMD_IN;
7660 			response_size = strtol(optarg, NULL, 0);
7661 			if (response_size <= 0) {
7662 				warnx("invalid number of response bytes %d",
7663 				      response_size);
7664 				error = 1;
7665 				goto smpcmd_bailout;
7666 			}
7667 			hook.argc = argc - optind;
7668 			hook.argv = argv + optind;
7669 			hook.got = 0;
7670 			optind++;
7671 			datastr = cget(&hook, NULL);
7672 			/*
7673 			 * If the user supplied "-" instead of a format, he
7674 			 * wants the data to be written to stdout.
7675 			 */
7676 			if ((datastr != NULL)
7677 			 && (datastr[0] == '-'))
7678 				fd_response = 1;
7679 
7680 			smp_response = (u_int8_t *)malloc(response_size);
7681 			if (smp_response == NULL) {
7682 				warn("can't malloc memory for SMP response");
7683 				error = 1;
7684 				goto smpcmd_bailout;
7685 			}
7686 			break;
7687 		case 'r':
7688 			arglist |= CAM_ARG_CMD_OUT;
7689 			request_size = strtol(optarg, NULL, 0);
7690 			if (request_size <= 0) {
7691 				warnx("invalid number of request bytes %d",
7692 				      request_size);
7693 				error = 1;
7694 				goto smpcmd_bailout;
7695 			}
7696 			hook.argc = argc - optind;
7697 			hook.argv = argv + optind;
7698 			hook.got = 0;
7699 			datastr = cget(&hook, NULL);
7700 			smp_request = (u_int8_t *)malloc(request_size);
7701 			if (smp_request == NULL) {
7702 				warn("can't malloc memory for SMP request");
7703 				error = 1;
7704 				goto smpcmd_bailout;
7705 			}
7706 			bzero(smp_request, request_size);
7707 			/*
7708 			 * If the user supplied "-" instead of a format, he
7709 			 * wants the data to be read from stdin.
7710 			 */
7711 			if ((datastr != NULL)
7712 			 && (datastr[0] == '-'))
7713 				fd_request = 1;
7714 			else
7715 				buff_encode_visit(smp_request, request_size,
7716 						  datastr,
7717 						  iget, &hook);
7718 			optind += hook.got;
7719 			break;
7720 		default:
7721 			break;
7722 		}
7723 	}
7724 
7725 	/*
7726 	 * If fd_data is set, and we're writing to the device, we need to
7727 	 * read the data the user wants written from stdin.
7728 	 */
7729 	if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7730 		ssize_t amt_read;
7731 		int amt_to_read = request_size;
7732 		u_int8_t *buf_ptr = smp_request;
7733 
7734 		for (amt_read = 0; amt_to_read > 0;
7735 		     amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7736 			if (amt_read == -1) {
7737 				warn("error reading data from stdin");
7738 				error = 1;
7739 				goto smpcmd_bailout;
7740 			}
7741 			amt_to_read -= amt_read;
7742 			buf_ptr += amt_read;
7743 		}
7744 	}
7745 
7746 	if (((arglist & CAM_ARG_CMD_IN) == 0)
7747 	 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7748 		warnx("%s: need both the request (-r) and response (-R) "
7749 		      "arguments", __func__);
7750 		error = 1;
7751 		goto smpcmd_bailout;
7752 	}
7753 
7754 	flags |= CAM_DEV_QFRZDIS;
7755 
7756 	cam_fill_smpio(&ccb->smpio,
7757 		       /*retries*/ retry_count,
7758 		       /*cbfcnp*/ NULL,
7759 		       /*flags*/ flags,
7760 		       /*smp_request*/ smp_request,
7761 		       /*smp_request_len*/ request_size,
7762 		       /*smp_response*/ smp_response,
7763 		       /*smp_response_len*/ response_size,
7764 		       /*timeout*/ timeout ? timeout : 5000);
7765 
7766 	ccb->smpio.flags = SMP_FLAG_NONE;
7767 
7768 	if (((retval = cam_send_ccb(device, ccb)) < 0)
7769 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7770 		const char warnstr[] = "error sending command";
7771 
7772 		if (retval < 0)
7773 			warn(warnstr);
7774 		else
7775 			warnx(warnstr);
7776 
7777 		if (arglist & CAM_ARG_VERBOSE) {
7778 			cam_error_print(device, ccb, CAM_ESF_ALL,
7779 					CAM_EPF_ALL, stderr);
7780 		}
7781 	}
7782 
7783 	if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7784 	 && (response_size > 0)) {
7785 		if (fd_response == 0) {
7786 			buff_decode_visit(smp_response, response_size,
7787 					  datastr, arg_put, NULL);
7788 			fprintf(stdout, "\n");
7789 		} else {
7790 			ssize_t amt_written;
7791 			int amt_to_write = response_size;
7792 			u_int8_t *buf_ptr = smp_response;
7793 
7794 			for (amt_written = 0; (amt_to_write > 0) &&
7795 			     (amt_written = write(STDOUT_FILENO, buf_ptr,
7796 						  amt_to_write)) > 0;){
7797 				amt_to_write -= amt_written;
7798 				buf_ptr += amt_written;
7799 			}
7800 			if (amt_written == -1) {
7801 				warn("error writing data to stdout");
7802 				error = 1;
7803 				goto smpcmd_bailout;
7804 			} else if ((amt_written == 0)
7805 				&& (amt_to_write > 0)) {
7806 				warnx("only wrote %u bytes out of %u",
7807 				      response_size - amt_to_write,
7808 				      response_size);
7809 			}
7810 		}
7811 	}
7812 smpcmd_bailout:
7813 	if (ccb != NULL)
7814 		cam_freeccb(ccb);
7815 
7816 	if (smp_request != NULL)
7817 		free(smp_request);
7818 
7819 	if (smp_response != NULL)
7820 		free(smp_response);
7821 
7822 	return (error);
7823 }
7824 
7825 static int
7826 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7827        int retry_count, int timeout)
7828 {
7829 	int c, error = 0;
7830 	union ccb *ccb;
7831 	int32_t mmc_opcode = 0, mmc_arg = 0;
7832 	int32_t mmc_flags = -1;
7833 	int retval;
7834 	int is_write = 0;
7835 	int is_bw_4 = 0, is_bw_1 = 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 
7841 	/* For IO_RW_EXTENDED command */
7842 	uint8_t *mmc_data = NULL;
7843 	struct mmc_data mmc_d;
7844 	int mmc_data_len = 0;
7845 
7846 	/*
7847 	 * Note that at the moment we don't support sending SMP CCBs to
7848 	 * devices that aren't probed by CAM.
7849 	 */
7850 	ccb = cam_getccb(device);
7851 	if (ccb == NULL) {
7852 		warnx("%s: error allocating CCB", __func__);
7853 		return (1);
7854 	}
7855 
7856 	bzero(&(&ccb->ccb_h)[1],
7857 	      sizeof(union ccb) - sizeof(struct ccb_hdr));
7858 
7859 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
7860 		switch (c) {
7861 		case '4':
7862 			is_bw_4 = 1;
7863 			break;
7864 		case '1':
7865 			is_bw_1 = 1;
7866 			break;
7867 		case 'S':
7868 			if (!strcmp(optarg, "high"))
7869 				is_highspeed = 1;
7870 			else
7871 				is_stdspeed = 1;
7872 			break;
7873 		case 'I':
7874 			is_info_request = 1;
7875 			break;
7876 		case 'c':
7877 			mmc_opcode = strtol(optarg, NULL, 0);
7878 			if (mmc_opcode < 0) {
7879 				warnx("invalid MMC opcode %d",
7880 				      mmc_opcode);
7881 				error = 1;
7882 				goto mmccmd_bailout;
7883 			}
7884 			break;
7885 		case 'a':
7886 			mmc_arg = strtol(optarg, NULL, 0);
7887 			if (mmc_arg < 0) {
7888 				warnx("invalid MMC arg %d",
7889 				      mmc_arg);
7890 				error = 1;
7891 				goto mmccmd_bailout;
7892 			}
7893 			break;
7894 		case 'f':
7895 			mmc_flags = strtol(optarg, NULL, 0);
7896 			if (mmc_flags < 0) {
7897 				warnx("invalid MMC flags %d",
7898 				      mmc_flags);
7899 				error = 1;
7900 				goto mmccmd_bailout;
7901 			}
7902 			break;
7903 		case 'l':
7904 			mmc_data_len = strtol(optarg, NULL, 0);
7905 			if (mmc_data_len <= 0) {
7906 				warnx("invalid MMC data len %d",
7907 				      mmc_data_len);
7908 				error = 1;
7909 				goto mmccmd_bailout;
7910 			}
7911 			break;
7912 		case 'W':
7913 			is_write = 1;
7914 			break;
7915 		case 'b':
7916 			mmc_data_byte = strtol(optarg, NULL, 0);
7917 			break;
7918 		default:
7919 			break;
7920 		}
7921 	}
7922 	flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7923 
7924 	/* If flags are left default, supply the right flags */
7925 	if (mmc_flags < 0)
7926 		switch (mmc_opcode) {
7927 		case MMC_GO_IDLE_STATE:
7928 			mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7929 			break;
7930 		case IO_SEND_OP_COND:
7931 			mmc_flags = MMC_RSP_R4;
7932 			break;
7933 		case SD_SEND_RELATIVE_ADDR:
7934 			mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7935 			break;
7936 		case MMC_SELECT_CARD:
7937 			mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7938 			mmc_arg = mmc_arg << 16;
7939 			break;
7940 		case SD_IO_RW_DIRECT:
7941 			mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7942 			mmc_arg = SD_IO_RW_ADR(mmc_arg);
7943 			if (is_write)
7944 				mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7945 			break;
7946 		case SD_IO_RW_EXTENDED:
7947 			mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7948 			mmc_arg = SD_IO_RW_ADR(mmc_arg);
7949 			int len_arg = mmc_data_len;
7950 			if (mmc_data_len == 512)
7951 				len_arg = 0;
7952 
7953 			// Byte mode
7954 			mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7955 			// Block mode
7956 //                        mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7957 			break;
7958 		default:
7959 			mmc_flags = MMC_RSP_R1;
7960 			break;
7961 		}
7962 
7963 	// Switch bus width instead of sending IO command
7964 	if (is_bw_4 || is_bw_1) {
7965 		struct ccb_trans_settings_mmc *cts;
7966 		ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7967 		ccb->ccb_h.flags = 0;
7968 		cts = &ccb->cts.proto_specific.mmc;
7969 		cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7970 		cts->ios_valid = MMC_BW;
7971 		if (((retval = cam_send_ccb(device, ccb)) < 0)
7972 		    || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7973 			warn("Error sending command");
7974 		} else {
7975 			printf("Parameters set OK\n");
7976 		}
7977 		cam_freeccb(ccb);
7978 		return (retval);
7979 	}
7980 
7981 	// Switch bus speed instead of sending IO command
7982 	if (is_stdspeed || is_highspeed) {
7983 		struct ccb_trans_settings_mmc *cts;
7984 		ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7985 		ccb->ccb_h.flags = 0;
7986 		cts = &ccb->cts.proto_specific.mmc;
7987 		cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7988 		cts->ios_valid = MMC_BT;
7989 		if (((retval = cam_send_ccb(device, ccb)) < 0)
7990 		    || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7991 			warn("Error sending command");
7992 		} else {
7993 			printf("Speed set OK (HS: %d)\n", is_highspeed);
7994 		}
7995 		cam_freeccb(ccb);
7996 		return (retval);
7997 	}
7998 
7999 	// Get information about controller and its settings
8000 	if (is_info_request) {
8001 		ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8002 		ccb->ccb_h.flags = 0;
8003 		struct ccb_trans_settings_mmc *cts;
8004 		cts = &ccb->cts.proto_specific.mmc;
8005 		if (((retval = cam_send_ccb(device, ccb)) < 0)
8006 		    || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8007 			warn("Error sending command");
8008 			return (retval);
8009 		}
8010 		printf("Host controller information\n");
8011 		printf("Host OCR: 0x%x\n", cts->host_ocr);
8012 		printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8013 		printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8014 		printf("Supported bus width: ");
8015 		if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8016 			printf(" 4 bit\n");
8017 		if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8018 			printf(" 8 bit\n");
8019 		printf("\nCurrent settings:\n");
8020 		printf("Bus width: ");
8021 		switch (cts->ios.bus_width) {
8022 		case bus_width_1:
8023 			printf("1 bit\n");
8024 			break;
8025 		case bus_width_4:
8026 			printf("4 bit\n");
8027 			break;
8028 		case bus_width_8:
8029 			printf("8 bit\n");
8030 			break;
8031 		}
8032 		printf("Freq: %d.%03d MHz%s\n",
8033 		       cts->ios.clock / 1000000,
8034 		       (cts->ios.clock / 1000) % 1000,
8035 		       cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8036 		return (0);
8037 	}
8038 
8039 	printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8040 
8041 	if (mmc_data_len > 0) {
8042 		flags |= CAM_DIR_IN;
8043 		mmc_data = malloc(mmc_data_len);
8044 		memset(mmc_data, 0, mmc_data_len);
8045 		memset(&mmc_d, 0, sizeof(mmc_d));
8046 		mmc_d.len = mmc_data_len;
8047 		mmc_d.data = mmc_data;
8048 		mmc_d.flags = MMC_DATA_READ;
8049 	} else flags |= CAM_DIR_NONE;
8050 
8051 	cam_fill_mmcio(&ccb->mmcio,
8052 		       /*retries*/ retry_count,
8053 		       /*cbfcnp*/ NULL,
8054 		       /*flags*/ flags,
8055 		       /*mmc_opcode*/ mmc_opcode,
8056 		       /*mmc_arg*/ mmc_arg,
8057 		       /*mmc_flags*/ mmc_flags,
8058 		       /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8059 		       /*timeout*/ timeout ? timeout : 5000);
8060 
8061 	if (((retval = cam_send_ccb(device, ccb)) < 0)
8062 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8063 		const char warnstr[] = "error sending command";
8064 
8065 		if (retval < 0)
8066 			warn(warnstr);
8067 		else
8068 			warnx(warnstr);
8069 
8070 		if (arglist & CAM_ARG_VERBOSE) {
8071 			cam_error_print(device, ccb, CAM_ESF_ALL,
8072 					CAM_EPF_ALL, stderr);
8073 		}
8074 	}
8075 
8076 	if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8077 		printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8078 		       ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8079 		       ccb->mmcio.cmd.resp[1],
8080 		       ccb->mmcio.cmd.resp[2],
8081 		       ccb->mmcio.cmd.resp[3]);
8082 
8083 		switch (mmc_opcode) {
8084 		case SD_IO_RW_DIRECT:
8085 			printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8086 			       SD_R5_DATA(ccb->mmcio.cmd.resp),
8087 			       (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8088 			break;
8089 		case SD_IO_RW_EXTENDED:
8090 			printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8091 			hexdump(mmc_data, mmc_data_len, NULL, 0);
8092 			break;
8093 		case SD_SEND_RELATIVE_ADDR:
8094 			printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8095 			break;
8096 		default:
8097 			printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8098 		}
8099 	}
8100 mmccmd_bailout:
8101 	if (ccb != NULL)
8102 		cam_freeccb(ccb);
8103 
8104 	if (mmc_data_len > 0 && mmc_data != NULL)
8105 		free(mmc_data);
8106 
8107 	return (error);
8108 }
8109 
8110 static int
8111 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8112 		 char *combinedopt, int retry_count, int timeout)
8113 {
8114 	union ccb *ccb;
8115 	struct smp_report_general_request *request = NULL;
8116 	struct smp_report_general_response *response = NULL;
8117 	struct sbuf *sb = NULL;
8118 	int error = 0;
8119 	int c, long_response = 0;
8120 	int retval;
8121 
8122 	/*
8123 	 * Note that at the moment we don't support sending SMP CCBs to
8124 	 * devices that aren't probed by CAM.
8125 	 */
8126 	ccb = cam_getccb(device);
8127 	if (ccb == NULL) {
8128 		warnx("%s: error allocating CCB", __func__);
8129 		return (1);
8130 	}
8131 
8132 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8133 
8134 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
8135 		switch (c) {
8136 		case 'l':
8137 			long_response = 1;
8138 			break;
8139 		default:
8140 			break;
8141 		}
8142 	}
8143 	request = malloc(sizeof(*request));
8144 	if (request == NULL) {
8145 		warn("%s: unable to allocate %zd bytes", __func__,
8146 		     sizeof(*request));
8147 		error = 1;
8148 		goto bailout;
8149 	}
8150 
8151 	response = malloc(sizeof(*response));
8152 	if (response == NULL) {
8153 		warn("%s: unable to allocate %zd bytes", __func__,
8154 		     sizeof(*response));
8155 		error = 1;
8156 		goto bailout;
8157 	}
8158 
8159 try_long:
8160 	smp_report_general(&ccb->smpio,
8161 			   retry_count,
8162 			   /*cbfcnp*/ NULL,
8163 			   request,
8164 			   /*request_len*/ sizeof(*request),
8165 			   (uint8_t *)response,
8166 			   /*response_len*/ sizeof(*response),
8167 			   /*long_response*/ long_response,
8168 			   timeout);
8169 
8170 	if (((retval = cam_send_ccb(device, ccb)) < 0)
8171 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8172 		const char warnstr[] = "error sending command";
8173 
8174 		if (retval < 0)
8175 			warn(warnstr);
8176 		else
8177 			warnx(warnstr);
8178 
8179 		if (arglist & CAM_ARG_VERBOSE) {
8180 			cam_error_print(device, ccb, CAM_ESF_ALL,
8181 					CAM_EPF_ALL, stderr);
8182 		}
8183 		error = 1;
8184 		goto bailout;
8185 	}
8186 
8187 	/*
8188 	 * If the device supports the long response bit, try again and see
8189 	 * if we can get all of the data.
8190 	 */
8191 	if ((response->long_response & SMP_RG_LONG_RESPONSE)
8192 	 && (long_response == 0)) {
8193 		ccb->ccb_h.status = CAM_REQ_INPROG;
8194 		CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8195 		long_response = 1;
8196 		goto try_long;
8197 	}
8198 
8199 	/*
8200 	 * XXX KDM detect and decode SMP errors here.
8201 	 */
8202 	sb = sbuf_new_auto();
8203 	if (sb == NULL) {
8204 		warnx("%s: error allocating sbuf", __func__);
8205 		goto bailout;
8206 	}
8207 
8208 	smp_report_general_sbuf(response, sizeof(*response), sb);
8209 
8210 	if (sbuf_finish(sb) != 0) {
8211 		warnx("%s: sbuf_finish", __func__);
8212 		goto bailout;
8213 	}
8214 
8215 	printf("%s", sbuf_data(sb));
8216 
8217 bailout:
8218 	if (ccb != NULL)
8219 		cam_freeccb(ccb);
8220 
8221 	if (request != NULL)
8222 		free(request);
8223 
8224 	if (response != NULL)
8225 		free(response);
8226 
8227 	if (sb != NULL)
8228 		sbuf_delete(sb);
8229 
8230 	return (error);
8231 }
8232 
8233 static struct camcontrol_opts phy_ops[] = {
8234 	{"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8235 	{"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8236 	{"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8237 	{"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8238 	{"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8239 	{"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8240 	{"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8241 	{"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8242 	{"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8243 	{NULL, 0, 0, NULL}
8244 };
8245 
8246 static int
8247 smpphycontrol(struct cam_device *device, int argc, char **argv,
8248 	      char *combinedopt, int retry_count, int timeout)
8249 {
8250 	union ccb *ccb;
8251 	struct smp_phy_control_request *request = NULL;
8252 	struct smp_phy_control_response *response = NULL;
8253 	int long_response = 0;
8254 	int retval = 0;
8255 	int phy = -1;
8256 	uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8257 	int phy_op_set = 0;
8258 	uint64_t attached_dev_name = 0;
8259 	int dev_name_set = 0;
8260 	uint32_t min_plr = 0, max_plr = 0;
8261 	uint32_t pp_timeout_val = 0;
8262 	int slumber_partial = 0;
8263 	int set_pp_timeout_val = 0;
8264 	int c;
8265 
8266 	/*
8267 	 * Note that at the moment we don't support sending SMP CCBs to
8268 	 * devices that aren't probed by CAM.
8269 	 */
8270 	ccb = cam_getccb(device);
8271 	if (ccb == NULL) {
8272 		warnx("%s: error allocating CCB", __func__);
8273 		return (1);
8274 	}
8275 
8276 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8277 
8278 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
8279 		switch (c) {
8280 		case 'a':
8281 		case 'A':
8282 		case 's':
8283 		case 'S': {
8284 			int enable = -1;
8285 
8286 			if (strcasecmp(optarg, "enable") == 0)
8287 				enable = 1;
8288 			else if (strcasecmp(optarg, "disable") == 0)
8289 				enable = 2;
8290 			else {
8291 				warnx("%s: Invalid argument %s", __func__,
8292 				      optarg);
8293 				retval = 1;
8294 				goto bailout;
8295 			}
8296 			switch (c) {
8297 			case 's':
8298 				slumber_partial |= enable <<
8299 						   SMP_PC_SAS_SLUMBER_SHIFT;
8300 				break;
8301 			case 'S':
8302 				slumber_partial |= enable <<
8303 						   SMP_PC_SAS_PARTIAL_SHIFT;
8304 				break;
8305 			case 'a':
8306 				slumber_partial |= enable <<
8307 						   SMP_PC_SATA_SLUMBER_SHIFT;
8308 				break;
8309 			case 'A':
8310 				slumber_partial |= enable <<
8311 						   SMP_PC_SATA_PARTIAL_SHIFT;
8312 				break;
8313 			default:
8314 				warnx("%s: programmer error", __func__);
8315 				retval = 1;
8316 				goto bailout;
8317 				break; /*NOTREACHED*/
8318 			}
8319 			break;
8320 		}
8321 		case 'd':
8322 			attached_dev_name = (uintmax_t)strtoumax(optarg,
8323 								 NULL,0);
8324 			dev_name_set = 1;
8325 			break;
8326 		case 'l':
8327 			long_response = 1;
8328 			break;
8329 		case 'm':
8330 			/*
8331 			 * We don't do extensive checking here, so this
8332 			 * will continue to work when new speeds come out.
8333 			 */
8334 			min_plr = strtoul(optarg, NULL, 0);
8335 			if ((min_plr == 0)
8336 			 || (min_plr > 0xf)) {
8337 				warnx("%s: invalid link rate %x",
8338 				      __func__, min_plr);
8339 				retval = 1;
8340 				goto bailout;
8341 			}
8342 			break;
8343 		case 'M':
8344 			/*
8345 			 * We don't do extensive checking here, so this
8346 			 * will continue to work when new speeds come out.
8347 			 */
8348 			max_plr = strtoul(optarg, NULL, 0);
8349 			if ((max_plr == 0)
8350 			 || (max_plr > 0xf)) {
8351 				warnx("%s: invalid link rate %x",
8352 				      __func__, max_plr);
8353 				retval = 1;
8354 				goto bailout;
8355 			}
8356 			break;
8357 		case 'o': {
8358 			camcontrol_optret optreturn;
8359 			cam_argmask argnums;
8360 			const char *subopt;
8361 
8362 			if (phy_op_set != 0) {
8363 				warnx("%s: only one phy operation argument "
8364 				      "(-o) allowed", __func__);
8365 				retval = 1;
8366 				goto bailout;
8367 			}
8368 
8369 			phy_op_set = 1;
8370 
8371 			/*
8372 			 * Allow the user to specify the phy operation
8373 			 * numerically, as well as with a name.  This will
8374 			 * future-proof it a bit, so options that are added
8375 			 * in future specs can be used.
8376 			 */
8377 			if (isdigit(optarg[0])) {
8378 				phy_operation = strtoul(optarg, NULL, 0);
8379 				if ((phy_operation == 0)
8380 				 || (phy_operation > 0xff)) {
8381 					warnx("%s: invalid phy operation %#x",
8382 					      __func__, phy_operation);
8383 					retval = 1;
8384 					goto bailout;
8385 				}
8386 				break;
8387 			}
8388 			optreturn = getoption(phy_ops, optarg, &phy_operation,
8389 					      &argnums, &subopt);
8390 
8391 			if (optreturn == CC_OR_AMBIGUOUS) {
8392 				warnx("%s: ambiguous option %s", __func__,
8393 				      optarg);
8394 				usage(0);
8395 				retval = 1;
8396 				goto bailout;
8397 			} else if (optreturn == CC_OR_NOT_FOUND) {
8398 				warnx("%s: option %s not found", __func__,
8399 				      optarg);
8400 				usage(0);
8401 				retval = 1;
8402 				goto bailout;
8403 			}
8404 			break;
8405 		}
8406 		case 'p':
8407 			phy = atoi(optarg);
8408 			break;
8409 		case 'T':
8410 			pp_timeout_val = strtoul(optarg, NULL, 0);
8411 			if (pp_timeout_val > 15) {
8412 				warnx("%s: invalid partial pathway timeout "
8413 				      "value %u, need a value less than 16",
8414 				      __func__, pp_timeout_val);
8415 				retval = 1;
8416 				goto bailout;
8417 			}
8418 			set_pp_timeout_val = 1;
8419 			break;
8420 		default:
8421 			break;
8422 		}
8423 	}
8424 
8425 	if (phy == -1) {
8426 		warnx("%s: a PHY (-p phy) argument is required",__func__);
8427 		retval = 1;
8428 		goto bailout;
8429 	}
8430 
8431 	if (((dev_name_set != 0)
8432 	  && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8433 	 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8434 	  && (dev_name_set == 0))) {
8435 		warnx("%s: -d name and -o setdevname arguments both "
8436 		      "required to set device name", __func__);
8437 		retval = 1;
8438 		goto bailout;
8439 	}
8440 
8441 	request = malloc(sizeof(*request));
8442 	if (request == NULL) {
8443 		warn("%s: unable to allocate %zd bytes", __func__,
8444 		     sizeof(*request));
8445 		retval = 1;
8446 		goto bailout;
8447 	}
8448 
8449 	response = malloc(sizeof(*response));
8450 	if (response == NULL) {
8451 		warn("%s: unable to allocate %zd bytes", __func__,
8452 		     sizeof(*response));
8453 		retval = 1;
8454 		goto bailout;
8455 	}
8456 
8457 	smp_phy_control(&ccb->smpio,
8458 			retry_count,
8459 			/*cbfcnp*/ NULL,
8460 			request,
8461 			sizeof(*request),
8462 			(uint8_t *)response,
8463 			sizeof(*response),
8464 			long_response,
8465 			/*expected_exp_change_count*/ 0,
8466 			phy,
8467 			phy_operation,
8468 			(set_pp_timeout_val != 0) ? 1 : 0,
8469 			attached_dev_name,
8470 			min_plr,
8471 			max_plr,
8472 			slumber_partial,
8473 			pp_timeout_val,
8474 			timeout);
8475 
8476 	if (((retval = cam_send_ccb(device, ccb)) < 0)
8477 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8478 		const char warnstr[] = "error sending command";
8479 
8480 		if (retval < 0)
8481 			warn(warnstr);
8482 		else
8483 			warnx(warnstr);
8484 
8485 		if (arglist & CAM_ARG_VERBOSE) {
8486 			/*
8487 			 * Use CAM_EPF_NORMAL so we only get one line of
8488 			 * SMP command decoding.
8489 			 */
8490 			cam_error_print(device, ccb, CAM_ESF_ALL,
8491 					CAM_EPF_NORMAL, stderr);
8492 		}
8493 		retval = 1;
8494 		goto bailout;
8495 	}
8496 
8497 	/* XXX KDM print out something here for success? */
8498 bailout:
8499 	if (ccb != NULL)
8500 		cam_freeccb(ccb);
8501 
8502 	if (request != NULL)
8503 		free(request);
8504 
8505 	if (response != NULL)
8506 		free(response);
8507 
8508 	return (retval);
8509 }
8510 
8511 static int
8512 smpmaninfo(struct cam_device *device, int argc, char **argv,
8513 	   char *combinedopt, int retry_count, int timeout)
8514 {
8515 	union ccb *ccb;
8516 	struct smp_report_manuf_info_request request;
8517 	struct smp_report_manuf_info_response response;
8518 	struct sbuf *sb = NULL;
8519 	int long_response = 0;
8520 	int retval = 0;
8521 	int c;
8522 
8523 	/*
8524 	 * Note that at the moment we don't support sending SMP CCBs to
8525 	 * devices that aren't probed by CAM.
8526 	 */
8527 	ccb = cam_getccb(device);
8528 	if (ccb == NULL) {
8529 		warnx("%s: error allocating CCB", __func__);
8530 		return (1);
8531 	}
8532 
8533 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8534 
8535 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
8536 		switch (c) {
8537 		case 'l':
8538 			long_response = 1;
8539 			break;
8540 		default:
8541 			break;
8542 		}
8543 	}
8544 	bzero(&request, sizeof(request));
8545 	bzero(&response, sizeof(response));
8546 
8547 	smp_report_manuf_info(&ccb->smpio,
8548 			      retry_count,
8549 			      /*cbfcnp*/ NULL,
8550 			      &request,
8551 			      sizeof(request),
8552 			      (uint8_t *)&response,
8553 			      sizeof(response),
8554 			      long_response,
8555 			      timeout);
8556 
8557 	if (((retval = cam_send_ccb(device, ccb)) < 0)
8558 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8559 		const char warnstr[] = "error sending command";
8560 
8561 		if (retval < 0)
8562 			warn(warnstr);
8563 		else
8564 			warnx(warnstr);
8565 
8566 		if (arglist & CAM_ARG_VERBOSE) {
8567 			cam_error_print(device, ccb, CAM_ESF_ALL,
8568 					CAM_EPF_ALL, stderr);
8569 		}
8570 		retval = 1;
8571 		goto bailout;
8572 	}
8573 
8574 	sb = sbuf_new_auto();
8575 	if (sb == NULL) {
8576 		warnx("%s: error allocating sbuf", __func__);
8577 		goto bailout;
8578 	}
8579 
8580 	smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8581 
8582 	if (sbuf_finish(sb) != 0) {
8583 		warnx("%s: sbuf_finish", __func__);
8584 		goto bailout;
8585 	}
8586 
8587 	printf("%s", sbuf_data(sb));
8588 
8589 bailout:
8590 
8591 	if (ccb != NULL)
8592 		cam_freeccb(ccb);
8593 
8594 	if (sb != NULL)
8595 		sbuf_delete(sb);
8596 
8597 	return (retval);
8598 }
8599 
8600 static int
8601 getdevid(struct cam_devitem *item)
8602 {
8603 	int retval = 0;
8604 	union ccb *ccb = NULL;
8605 
8606 	struct cam_device *dev;
8607 
8608 	dev = cam_open_btl(item->dev_match.path_id,
8609 			   item->dev_match.target_id,
8610 			   item->dev_match.target_lun, O_RDWR, NULL);
8611 
8612 	if (dev == NULL) {
8613 		warnx("%s", cam_errbuf);
8614 		retval = 1;
8615 		goto bailout;
8616 	}
8617 
8618 	item->device_id_len = 0;
8619 
8620 	ccb = cam_getccb(dev);
8621 	if (ccb == NULL) {
8622 		warnx("%s: error allocating CCB", __func__);
8623 		retval = 1;
8624 		goto bailout;
8625 	}
8626 
8627 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8628 
8629 	/*
8630 	 * On the first try, we just probe for the size of the data, and
8631 	 * then allocate that much memory and try again.
8632 	 */
8633 retry:
8634 	ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8635 	ccb->ccb_h.flags = CAM_DIR_IN;
8636 	ccb->cdai.flags = CDAI_FLAG_NONE;
8637 	ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8638 	ccb->cdai.bufsiz = item->device_id_len;
8639 	if (item->device_id_len != 0)
8640 		ccb->cdai.buf = (uint8_t *)item->device_id;
8641 
8642 	if (cam_send_ccb(dev, ccb) < 0) {
8643 		warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8644 		retval = 1;
8645 		goto bailout;
8646 	}
8647 
8648 	if (ccb->ccb_h.status != CAM_REQ_CMP) {
8649 		warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8650 		retval = 1;
8651 		goto bailout;
8652 	}
8653 
8654 	if (item->device_id_len == 0) {
8655 		/*
8656 		 * This is our first time through.  Allocate the buffer,
8657 		 * and then go back to get the data.
8658 		 */
8659 		if (ccb->cdai.provsiz == 0) {
8660 			warnx("%s: invalid .provsiz field returned with "
8661 			     "XPT_GDEV_ADVINFO CCB", __func__);
8662 			retval = 1;
8663 			goto bailout;
8664 		}
8665 		item->device_id_len = ccb->cdai.provsiz;
8666 		item->device_id = malloc(item->device_id_len);
8667 		if (item->device_id == NULL) {
8668 			warn("%s: unable to allocate %d bytes", __func__,
8669 			     item->device_id_len);
8670 			retval = 1;
8671 			goto bailout;
8672 		}
8673 		ccb->ccb_h.status = CAM_REQ_INPROG;
8674 		goto retry;
8675 	}
8676 
8677 bailout:
8678 	if (dev != NULL)
8679 		cam_close_device(dev);
8680 
8681 	if (ccb != NULL)
8682 		cam_freeccb(ccb);
8683 
8684 	return (retval);
8685 }
8686 
8687 /*
8688  * XXX KDM merge this code with getdevtree()?
8689  */
8690 static int
8691 buildbusdevlist(struct cam_devlist *devlist)
8692 {
8693 	union ccb ccb;
8694 	int bufsize, fd = -1;
8695 	struct dev_match_pattern *patterns;
8696 	struct cam_devitem *item = NULL;
8697 	int skip_device = 0;
8698 	int retval = 0;
8699 
8700 	if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8701 		warn("couldn't open %s", XPT_DEVICE);
8702 		return (1);
8703 	}
8704 
8705 	bzero(&ccb, sizeof(union ccb));
8706 
8707 	ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8708 	ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8709 	ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8710 
8711 	ccb.ccb_h.func_code = XPT_DEV_MATCH;
8712 	bufsize = sizeof(struct dev_match_result) * 100;
8713 	ccb.cdm.match_buf_len = bufsize;
8714 	ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8715 	if (ccb.cdm.matches == NULL) {
8716 		warnx("can't malloc memory for matches");
8717 		close(fd);
8718 		return (1);
8719 	}
8720 	ccb.cdm.num_matches = 0;
8721 	ccb.cdm.num_patterns = 2;
8722 	ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8723 		ccb.cdm.num_patterns;
8724 
8725 	patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8726 	if (patterns == NULL) {
8727 		warnx("can't malloc memory for patterns");
8728 		retval = 1;
8729 		goto bailout;
8730 	}
8731 
8732 	ccb.cdm.patterns = patterns;
8733 	bzero(patterns, ccb.cdm.pattern_buf_len);
8734 
8735 	patterns[0].type = DEV_MATCH_DEVICE;
8736 	patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8737 	patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8738 	patterns[1].type = DEV_MATCH_PERIPH;
8739 	patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8740 	patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8741 
8742 	/*
8743 	 * We do the ioctl multiple times if necessary, in case there are
8744 	 * more than 100 nodes in the EDT.
8745 	 */
8746 	do {
8747 		unsigned int i;
8748 
8749 		if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8750 			warn("error sending CAMIOCOMMAND ioctl");
8751 			retval = 1;
8752 			goto bailout;
8753 		}
8754 
8755 		if ((ccb.ccb_h.status != CAM_REQ_CMP)
8756 		 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8757 		    && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8758 			warnx("got CAM error %#x, CDM error %d\n",
8759 			      ccb.ccb_h.status, ccb.cdm.status);
8760 			retval = 1;
8761 			goto bailout;
8762 		}
8763 
8764 		for (i = 0; i < ccb.cdm.num_matches; i++) {
8765 			switch (ccb.cdm.matches[i].type) {
8766 			case DEV_MATCH_DEVICE: {
8767 				struct device_match_result *dev_result;
8768 
8769 				dev_result =
8770 				     &ccb.cdm.matches[i].result.device_result;
8771 
8772 				if (dev_result->flags &
8773 				    DEV_RESULT_UNCONFIGURED) {
8774 					skip_device = 1;
8775 					break;
8776 				} else
8777 					skip_device = 0;
8778 
8779 				item = malloc(sizeof(*item));
8780 				if (item == NULL) {
8781 					warn("%s: unable to allocate %zd bytes",
8782 					     __func__, sizeof(*item));
8783 					retval = 1;
8784 					goto bailout;
8785 				}
8786 				bzero(item, sizeof(*item));
8787 				bcopy(dev_result, &item->dev_match,
8788 				      sizeof(*dev_result));
8789 				STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8790 						   links);
8791 
8792 				if (getdevid(item) != 0) {
8793 					retval = 1;
8794 					goto bailout;
8795 				}
8796 				break;
8797 			}
8798 			case DEV_MATCH_PERIPH: {
8799 				struct periph_match_result *periph_result;
8800 
8801 				periph_result =
8802 				      &ccb.cdm.matches[i].result.periph_result;
8803 
8804 				if (skip_device != 0)
8805 					break;
8806 				item->num_periphs++;
8807 				item->periph_matches = realloc(
8808 					item->periph_matches,
8809 					item->num_periphs *
8810 					sizeof(struct periph_match_result));
8811 				if (item->periph_matches == NULL) {
8812 					warn("%s: error allocating periph "
8813 					     "list", __func__);
8814 					retval = 1;
8815 					goto bailout;
8816 				}
8817 				bcopy(periph_result, &item->periph_matches[
8818 				      item->num_periphs - 1],
8819 				      sizeof(*periph_result));
8820 				break;
8821 			}
8822 			default:
8823 				fprintf(stderr, "%s: unexpected match "
8824 					"type %d\n", __func__,
8825 					ccb.cdm.matches[i].type);
8826 				retval = 1;
8827 				goto bailout;
8828 				break; /*NOTREACHED*/
8829 			}
8830 		}
8831 	} while ((ccb.ccb_h.status == CAM_REQ_CMP)
8832 		&& (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8833 bailout:
8834 
8835 	if (fd != -1)
8836 		close(fd);
8837 
8838 	free(patterns);
8839 
8840 	free(ccb.cdm.matches);
8841 
8842 	if (retval != 0)
8843 		freebusdevlist(devlist);
8844 
8845 	return (retval);
8846 }
8847 
8848 static void
8849 freebusdevlist(struct cam_devlist *devlist)
8850 {
8851 	struct cam_devitem *item, *item2;
8852 
8853 	STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8854 		STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8855 			      links);
8856 		free(item->device_id);
8857 		free(item->periph_matches);
8858 		free(item);
8859 	}
8860 }
8861 
8862 static struct cam_devitem *
8863 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8864 {
8865 	struct cam_devitem *item;
8866 
8867 	STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8868 		struct scsi_vpd_id_descriptor *idd;
8869 
8870 		/*
8871 		 * XXX KDM look for LUN IDs as well?
8872 		 */
8873 		idd = scsi_get_devid(item->device_id,
8874 					   item->device_id_len,
8875 					   scsi_devid_is_sas_target);
8876 		if (idd == NULL)
8877 			continue;
8878 
8879 		if (scsi_8btou64(idd->identifier) == sasaddr)
8880 			return (item);
8881 	}
8882 
8883 	return (NULL);
8884 }
8885 
8886 static int
8887 smpphylist(struct cam_device *device, int argc, char **argv,
8888 	   char *combinedopt, int retry_count, int timeout)
8889 {
8890 	struct smp_report_general_request *rgrequest = NULL;
8891 	struct smp_report_general_response *rgresponse = NULL;
8892 	struct smp_discover_request *disrequest = NULL;
8893 	struct smp_discover_response *disresponse = NULL;
8894 	struct cam_devlist devlist;
8895 	union ccb *ccb;
8896 	int long_response = 0;
8897 	int num_phys = 0;
8898 	int quiet = 0;
8899 	int retval;
8900 	int i, c;
8901 
8902 	/*
8903 	 * Note that at the moment we don't support sending SMP CCBs to
8904 	 * devices that aren't probed by CAM.
8905 	 */
8906 	ccb = cam_getccb(device);
8907 	if (ccb == NULL) {
8908 		warnx("%s: error allocating CCB", __func__);
8909 		return (1);
8910 	}
8911 
8912 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8913 	STAILQ_INIT(&devlist.dev_queue);
8914 
8915 	rgrequest = malloc(sizeof(*rgrequest));
8916 	if (rgrequest == NULL) {
8917 		warn("%s: unable to allocate %zd bytes", __func__,
8918 		     sizeof(*rgrequest));
8919 		retval = 1;
8920 		goto bailout;
8921 	}
8922 
8923 	rgresponse = malloc(sizeof(*rgresponse));
8924 	if (rgresponse == NULL) {
8925 		warn("%s: unable to allocate %zd bytes", __func__,
8926 		     sizeof(*rgresponse));
8927 		retval = 1;
8928 		goto bailout;
8929 	}
8930 
8931 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
8932 		switch (c) {
8933 		case 'l':
8934 			long_response = 1;
8935 			break;
8936 		case 'q':
8937 			quiet = 1;
8938 			break;
8939 		default:
8940 			break;
8941 		}
8942 	}
8943 
8944 	smp_report_general(&ccb->smpio,
8945 			   retry_count,
8946 			   /*cbfcnp*/ NULL,
8947 			   rgrequest,
8948 			   /*request_len*/ sizeof(*rgrequest),
8949 			   (uint8_t *)rgresponse,
8950 			   /*response_len*/ sizeof(*rgresponse),
8951 			   /*long_response*/ long_response,
8952 			   timeout);
8953 
8954 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8955 
8956 	if (((retval = cam_send_ccb(device, ccb)) < 0)
8957 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8958 		const char warnstr[] = "error sending command";
8959 
8960 		if (retval < 0)
8961 			warn(warnstr);
8962 		else
8963 			warnx(warnstr);
8964 
8965 		if (arglist & CAM_ARG_VERBOSE) {
8966 			cam_error_print(device, ccb, CAM_ESF_ALL,
8967 					CAM_EPF_ALL, stderr);
8968 		}
8969 		retval = 1;
8970 		goto bailout;
8971 	}
8972 
8973 	num_phys = rgresponse->num_phys;
8974 
8975 	if (num_phys == 0) {
8976 		if (quiet == 0)
8977 			fprintf(stdout, "%s: No Phys reported\n", __func__);
8978 		retval = 1;
8979 		goto bailout;
8980 	}
8981 
8982 	devlist.path_id = device->path_id;
8983 
8984 	retval = buildbusdevlist(&devlist);
8985 	if (retval != 0)
8986 		goto bailout;
8987 
8988 	if (quiet == 0) {
8989 		fprintf(stdout, "%d PHYs:\n", num_phys);
8990 		fprintf(stdout, "PHY  Attached SAS Address\n");
8991 	}
8992 
8993 	disrequest = malloc(sizeof(*disrequest));
8994 	if (disrequest == NULL) {
8995 		warn("%s: unable to allocate %zd bytes", __func__,
8996 		     sizeof(*disrequest));
8997 		retval = 1;
8998 		goto bailout;
8999 	}
9000 
9001 	disresponse = malloc(sizeof(*disresponse));
9002 	if (disresponse == NULL) {
9003 		warn("%s: unable to allocate %zd bytes", __func__,
9004 		     sizeof(*disresponse));
9005 		retval = 1;
9006 		goto bailout;
9007 	}
9008 
9009 	for (i = 0; i < num_phys; i++) {
9010 		struct cam_devitem *item;
9011 		struct device_match_result *dev_match;
9012 		char vendor[16], product[48], revision[16];
9013 		char tmpstr[256];
9014 		int j;
9015 
9016 		CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9017 
9018 		ccb->ccb_h.status = CAM_REQ_INPROG;
9019 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9020 
9021 		smp_discover(&ccb->smpio,
9022 			     retry_count,
9023 			     /*cbfcnp*/ NULL,
9024 			     disrequest,
9025 			     sizeof(*disrequest),
9026 			     (uint8_t *)disresponse,
9027 			     sizeof(*disresponse),
9028 			     long_response,
9029 			     /*ignore_zone_group*/ 0,
9030 			     /*phy*/ i,
9031 			     timeout);
9032 
9033 		if (((retval = cam_send_ccb(device, ccb)) < 0)
9034 		 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9035 		  && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9036 			const char warnstr[] = "error sending command";
9037 
9038 			if (retval < 0)
9039 				warn(warnstr);
9040 			else
9041 				warnx(warnstr);
9042 
9043 			if (arglist & CAM_ARG_VERBOSE) {
9044 				cam_error_print(device, ccb, CAM_ESF_ALL,
9045 						CAM_EPF_ALL, stderr);
9046 			}
9047 			retval = 1;
9048 			goto bailout;
9049 		}
9050 
9051 		if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9052 			if (quiet == 0)
9053 				fprintf(stdout, "%3d  <vacant>\n", i);
9054 			continue;
9055 		}
9056 
9057 		if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9058 			item = NULL;
9059 		} else {
9060 			item = findsasdevice(&devlist,
9061 			    scsi_8btou64(disresponse->attached_sas_address));
9062 		}
9063 
9064 		if ((quiet == 0)
9065 		 || (item != NULL)) {
9066 			fprintf(stdout, "%3d  0x%016jx", i,
9067 				(uintmax_t)scsi_8btou64(
9068 				disresponse->attached_sas_address));
9069 			if (item == NULL) {
9070 				fprintf(stdout, "\n");
9071 				continue;
9072 			}
9073 		} else if (quiet != 0)
9074 			continue;
9075 
9076 		dev_match = &item->dev_match;
9077 
9078 		if (dev_match->protocol == PROTO_SCSI) {
9079 			cam_strvis(vendor, dev_match->inq_data.vendor,
9080 				   sizeof(dev_match->inq_data.vendor),
9081 				   sizeof(vendor));
9082 			cam_strvis(product, dev_match->inq_data.product,
9083 				   sizeof(dev_match->inq_data.product),
9084 				   sizeof(product));
9085 			cam_strvis(revision, dev_match->inq_data.revision,
9086 				   sizeof(dev_match->inq_data.revision),
9087 				   sizeof(revision));
9088 			sprintf(tmpstr, "<%s %s %s>", vendor, product,
9089 				revision);
9090 		} else if ((dev_match->protocol == PROTO_ATA)
9091 			|| (dev_match->protocol == PROTO_SATAPM)) {
9092 			cam_strvis(product, dev_match->ident_data.model,
9093 				   sizeof(dev_match->ident_data.model),
9094 				   sizeof(product));
9095 			cam_strvis(revision, dev_match->ident_data.revision,
9096 				   sizeof(dev_match->ident_data.revision),
9097 				   sizeof(revision));
9098 			sprintf(tmpstr, "<%s %s>", product, revision);
9099 		} else {
9100 			sprintf(tmpstr, "<>");
9101 		}
9102 		fprintf(stdout, "   %-33s ", tmpstr);
9103 
9104 		/*
9105 		 * If we have 0 periphs, that's a bug...
9106 		 */
9107 		if (item->num_periphs == 0) {
9108 			fprintf(stdout, "\n");
9109 			continue;
9110 		}
9111 
9112 		fprintf(stdout, "(");
9113 		for (j = 0; j < item->num_periphs; j++) {
9114 			if (j > 0)
9115 				fprintf(stdout, ",");
9116 
9117 			fprintf(stdout, "%s%d",
9118 				item->periph_matches[j].periph_name,
9119 				item->periph_matches[j].unit_number);
9120 
9121 		}
9122 		fprintf(stdout, ")\n");
9123 	}
9124 bailout:
9125 	if (ccb != NULL)
9126 		cam_freeccb(ccb);
9127 
9128 	free(rgrequest);
9129 
9130 	free(rgresponse);
9131 
9132 	free(disrequest);
9133 
9134 	free(disresponse);
9135 
9136 	freebusdevlist(&devlist);
9137 
9138 	return (retval);
9139 }
9140 
9141 static int
9142 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9143 {
9144 	uint8_t error = 0, ata_device = 0, status = 0;
9145 	uint16_t count = 0;
9146 	uint64_t lba = 0;
9147 	int retval;
9148 
9149 	retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9150 	    &status);
9151 	if (retval == 1) {
9152 		if (arglist & CAM_ARG_VERBOSE) {
9153 			cam_error_print(device, ccb, CAM_ESF_ALL,
9154 					CAM_EPF_ALL, stderr);
9155 		}
9156 		warnx("Can't get ATA command status");
9157 		return (retval);
9158 	}
9159 
9160 	if (status & ATA_STATUS_ERROR) {
9161 		cam_error_print(device, ccb, CAM_ESF_ALL,
9162 		    CAM_EPF_ALL, stderr);
9163 	        return (1);
9164 	}
9165 
9166 	printf("%s%d: ", device->device_name, device->dev_unit_num);
9167 	switch (count) {
9168 	case 0x00:
9169 		printf("Standby mode\n");
9170 		break;
9171 	case 0x01:
9172 		printf("Standby_y mode\n");
9173 		break;
9174 	case 0x40:
9175 		printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9176 		break;
9177 	case 0x41:
9178 		printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9179 		break;
9180 	case 0x80:
9181 		printf("Idle mode\n");
9182 		break;
9183 	case 0x81:
9184 		printf("Idle_a mode\n");
9185 		break;
9186 	case 0x82:
9187 		printf("Idle_b mode\n");
9188 		break;
9189 	case 0x83:
9190 		printf("Idle_c mode\n");
9191 		break;
9192 	case 0xff:
9193 		printf("Active or Idle mode\n");
9194 		break;
9195 	default:
9196 		printf("Unknown mode 0x%02x\n", count);
9197 		break;
9198 	}
9199 
9200 	return (0);
9201 }
9202 
9203 static int
9204 atapm(struct cam_device *device, int argc, char **argv,
9205 		 char *combinedopt, int retry_count, int timeout)
9206 {
9207 	union ccb *ccb;
9208 	int retval = 0;
9209 	int t = -1;
9210 	int c;
9211 	u_int8_t ata_flags = 0;
9212 	u_char cmd, sc;
9213 
9214 	ccb = cam_getccb(device);
9215 
9216 	if (ccb == NULL) {
9217 		warnx("%s: error allocating ccb", __func__);
9218 		return (1);
9219 	}
9220 
9221 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
9222 		switch (c) {
9223 		case 't':
9224 			t = atoi(optarg);
9225 			break;
9226 		default:
9227 			break;
9228 		}
9229 	}
9230 	if (strcmp(argv[1], "idle") == 0) {
9231 		if (t == -1)
9232 			cmd = ATA_IDLE_IMMEDIATE;
9233 		else
9234 			cmd = ATA_IDLE_CMD;
9235 	} else if (strcmp(argv[1], "standby") == 0) {
9236 		if (t == -1)
9237 			cmd = ATA_STANDBY_IMMEDIATE;
9238 		else
9239 			cmd = ATA_STANDBY_CMD;
9240 	} else if (strcmp(argv[1], "powermode") == 0) {
9241 		cmd = ATA_CHECK_POWER_MODE;
9242 		ata_flags = AP_FLAG_CHK_COND;
9243 		t = -1;
9244 	} else {
9245 		cmd = ATA_SLEEP;
9246 		t = -1;
9247 	}
9248 
9249 	if (t < 0)
9250 		sc = 0;
9251 	else if (t <= (240 * 5))
9252 		sc = (t + 4) / 5;
9253 	else if (t <= (252 * 5))
9254 		/* special encoding for 21 minutes */
9255 		sc = 252;
9256 	else if (t <= (11 * 30 * 60))
9257 		sc = (t - 1) / (30 * 60) + 241;
9258 	else
9259 		sc = 253;
9260 
9261 	retval = ata_do_cmd(device,
9262 	    ccb,
9263 	    /*retries*/retry_count,
9264 	    /*flags*/CAM_DIR_NONE,
9265 	    /*protocol*/AP_PROTO_NON_DATA,
9266 	    /*ata_flags*/ata_flags,
9267 	    /*tag_action*/MSG_SIMPLE_Q_TAG,
9268 	    /*command*/cmd,
9269 	    /*features*/0,
9270 	    /*lba*/0,
9271 	    /*sector_count*/sc,
9272 	    /*data_ptr*/NULL,
9273 	    /*dxfer_len*/0,
9274 	    /*timeout*/timeout ? timeout : 30 * 1000,
9275 	    /*force48bit*/0);
9276 
9277 	cam_freeccb(ccb);
9278 
9279 	if (retval || cmd != ATA_CHECK_POWER_MODE)
9280 		return (retval);
9281 
9282 	return (atapm_proc_resp(device, ccb));
9283 }
9284 
9285 static int
9286 ataaxm(struct cam_device *device, int argc, char **argv,
9287 		 char *combinedopt, int retry_count, int timeout)
9288 {
9289 	union ccb *ccb;
9290 	int retval = 0;
9291 	int l = -1;
9292 	int c;
9293 	u_char cmd, sc;
9294 
9295 	ccb = cam_getccb(device);
9296 
9297 	if (ccb == NULL) {
9298 		warnx("%s: error allocating ccb", __func__);
9299 		return (1);
9300 	}
9301 
9302 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
9303 		switch (c) {
9304 		case 'l':
9305 			l = atoi(optarg);
9306 			break;
9307 		default:
9308 			break;
9309 		}
9310 	}
9311 	sc = 0;
9312 	if (strcmp(argv[1], "apm") == 0) {
9313 		if (l == -1)
9314 			cmd = 0x85;
9315 		else {
9316 			cmd = 0x05;
9317 			sc = l;
9318 		}
9319 	} else /* aam */ {
9320 		if (l == -1)
9321 			cmd = 0xC2;
9322 		else {
9323 			cmd = 0x42;
9324 			sc = l;
9325 		}
9326 	}
9327 
9328 	retval = ata_do_cmd(device,
9329 	    ccb,
9330 	    /*retries*/retry_count,
9331 	    /*flags*/CAM_DIR_NONE,
9332 	    /*protocol*/AP_PROTO_NON_DATA,
9333 	    /*ata_flags*/0,
9334 	    /*tag_action*/MSG_SIMPLE_Q_TAG,
9335 	    /*command*/ATA_SETFEATURES,
9336 	    /*features*/cmd,
9337 	    /*lba*/0,
9338 	    /*sector_count*/sc,
9339 	    /*data_ptr*/NULL,
9340 	    /*dxfer_len*/0,
9341 	    /*timeout*/timeout ? timeout : 30 * 1000,
9342 	    /*force48bit*/0);
9343 
9344 	cam_freeccb(ccb);
9345 	return (retval);
9346 }
9347 
9348 int
9349 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9350 	       int show_sa_errors, int sa_set, int service_action,
9351 	       int timeout_desc, int task_attr, int retry_count, int timeout,
9352 	       int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9353 {
9354 	union ccb *ccb = NULL;
9355 	uint8_t *buf = NULL;
9356 	uint32_t alloc_len = 0, num_opcodes;
9357 	uint32_t valid_len = 0;
9358 	uint32_t avail_len = 0;
9359 	struct scsi_report_supported_opcodes_all *all_hdr;
9360 	struct scsi_report_supported_opcodes_one *one;
9361 	int options = 0;
9362 	int retval = 0;
9363 
9364 	/*
9365 	 * Make it clear that we haven't yet allocated or filled anything.
9366 	 */
9367 	*fill_len = 0;
9368 	*data_ptr = NULL;
9369 
9370 	ccb = cam_getccb(device);
9371 	if (ccb == NULL) {
9372 		warnx("couldn't allocate CCB");
9373 		retval = 1;
9374 		goto bailout;
9375 	}
9376 
9377 	/* cam_getccb cleans up the header, caller has to zero the payload */
9378 	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9379 
9380 	if (opcode_set != 0) {
9381 		options |= RSO_OPTIONS_OC;
9382 		num_opcodes = 1;
9383 		alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9384 	} else {
9385 		num_opcodes = 256;
9386 		alloc_len = sizeof(*all_hdr) + (num_opcodes *
9387 		    sizeof(struct scsi_report_supported_opcodes_descr));
9388 	}
9389 
9390 	if (timeout_desc != 0) {
9391 		options |= RSO_RCTD;
9392 		alloc_len += num_opcodes *
9393 		    sizeof(struct scsi_report_supported_opcodes_timeout);
9394 	}
9395 
9396 	if (sa_set != 0) {
9397 		options |= RSO_OPTIONS_OC_SA;
9398 		if (show_sa_errors != 0)
9399 			options &= ~RSO_OPTIONS_OC;
9400 	}
9401 
9402 retry_alloc:
9403 	if (buf != NULL) {
9404 		free(buf);
9405 		buf = NULL;
9406 	}
9407 
9408 	buf = malloc(alloc_len);
9409 	if (buf == NULL) {
9410 		warn("Unable to allocate %u bytes", alloc_len);
9411 		retval = 1;
9412 		goto bailout;
9413 	}
9414 	bzero(buf, alloc_len);
9415 
9416 	scsi_report_supported_opcodes(&ccb->csio,
9417 				      /*retries*/ retry_count,
9418 				      /*cbfcnp*/ NULL,
9419 				      /*tag_action*/ task_attr,
9420 				      /*options*/ options,
9421 				      /*req_opcode*/ opcode,
9422 				      /*req_service_action*/ service_action,
9423 				      /*data_ptr*/ buf,
9424 				      /*dxfer_len*/ alloc_len,
9425 				      /*sense_len*/ SSD_FULL_SIZE,
9426 				      /*timeout*/ timeout ? timeout : 10000);
9427 
9428 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9429 
9430 	if (retry_count != 0)
9431 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9432 
9433 	if (cam_send_ccb(device, ccb) < 0) {
9434 		warn("error sending REPORT SUPPORTED OPERATION CODES command");
9435 		retval = 1;
9436 		goto bailout;
9437 	}
9438 
9439 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9440 		if (verbosemode != 0)
9441 			cam_error_print(device, ccb, CAM_ESF_ALL,
9442 					CAM_EPF_ALL, stderr);
9443 		retval = 1;
9444 		goto bailout;
9445 	}
9446 
9447 	valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9448 
9449 	if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9450 	 && (valid_len >= sizeof(*all_hdr))) {
9451 		all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9452 		avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9453 	} else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9454 		&& (valid_len >= sizeof(*one))) {
9455 		uint32_t cdb_length;
9456 
9457 		one = (struct scsi_report_supported_opcodes_one *)buf;
9458 		cdb_length = scsi_2btoul(one->cdb_length);
9459 		avail_len = sizeof(*one) + cdb_length;
9460 		if (one->support & RSO_ONE_CTDP) {
9461 			struct scsi_report_supported_opcodes_timeout *td;
9462 
9463 			td = (struct scsi_report_supported_opcodes_timeout *)
9464 			    &buf[avail_len];
9465 			if (valid_len >= (avail_len + sizeof(td->length))) {
9466 				avail_len += scsi_2btoul(td->length) +
9467 				    sizeof(td->length);
9468 			} else {
9469 				avail_len += sizeof(*td);
9470 			}
9471 		}
9472 	}
9473 
9474 	/*
9475 	 * avail_len could be zero if we didn't get enough data back from
9476 	 * thet target to determine
9477 	 */
9478 	if ((avail_len != 0)
9479 	 && (avail_len > valid_len)) {
9480 		alloc_len = avail_len;
9481 		goto retry_alloc;
9482 	}
9483 
9484 	*fill_len = valid_len;
9485 	*data_ptr = buf;
9486 bailout:
9487 	if (retval != 0)
9488 		free(buf);
9489 
9490 	cam_freeccb(ccb);
9491 
9492 	return (retval);
9493 }
9494 
9495 static int
9496 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9497 		   int req_sa, uint8_t *buf, uint32_t valid_len)
9498 {
9499 	struct scsi_report_supported_opcodes_one *one;
9500 	struct scsi_report_supported_opcodes_timeout *td;
9501 	uint32_t cdb_len = 0, td_len = 0;
9502 	const char *op_desc = NULL;
9503 	unsigned int i;
9504 	int retval = 0;
9505 
9506 	one = (struct scsi_report_supported_opcodes_one *)buf;
9507 
9508 	/*
9509 	 * If we don't have the full single opcode descriptor, no point in
9510 	 * continuing.
9511 	 */
9512 	if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9513 	    cdb_length)) {
9514 		warnx("Only %u bytes returned, not enough to verify support",
9515 		      valid_len);
9516 		retval = 1;
9517 		goto bailout;
9518 	}
9519 
9520 	op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9521 
9522 	printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9523 	       req_opcode);
9524 	if (sa_set != 0)
9525 		printf(", SA 0x%x", req_sa);
9526 	printf(": ");
9527 
9528 	switch (one->support & RSO_ONE_SUP_MASK) {
9529 	case RSO_ONE_SUP_UNAVAIL:
9530 		printf("No command support information currently available\n");
9531 		break;
9532 	case RSO_ONE_SUP_NOT_SUP:
9533 		printf("Command not supported\n");
9534 		retval = 1;
9535 		goto bailout;
9536 		break; /*NOTREACHED*/
9537 	case RSO_ONE_SUP_AVAIL:
9538 		printf("Command is supported, complies with a SCSI standard\n");
9539 		break;
9540 	case RSO_ONE_SUP_VENDOR:
9541 		printf("Command is supported, vendor-specific "
9542 		       "implementation\n");
9543 		break;
9544 	default:
9545 		printf("Unknown command support flags 0x%#x\n",
9546 		       one->support & RSO_ONE_SUP_MASK);
9547 		break;
9548 	}
9549 
9550 	/*
9551 	 * If we don't have the CDB length, it isn't exactly an error, the
9552 	 * command probably isn't supported.
9553 	 */
9554 	if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9555 	    cdb_usage))
9556 		goto bailout;
9557 
9558 	cdb_len = scsi_2btoul(one->cdb_length);
9559 
9560 	/*
9561 	 * If our valid data doesn't include the full reported length,
9562 	 * return.  The caller should have detected this and adjusted his
9563 	 * allocation length to get all of the available data.
9564 	 */
9565 	if (valid_len < sizeof(*one) + cdb_len) {
9566 		retval = 1;
9567 		goto bailout;
9568 	}
9569 
9570 	/*
9571 	 * If all we have is the opcode, there is no point in printing out
9572 	 * the usage bitmap.
9573 	 */
9574 	if (cdb_len <= 1) {
9575 		retval = 1;
9576 		goto bailout;
9577 	}
9578 
9579 	printf("CDB usage bitmap:");
9580 	for (i = 0; i < cdb_len; i++) {
9581 		printf(" %02x", one->cdb_usage[i]);
9582 	}
9583 	printf("\n");
9584 
9585 	/*
9586 	 * If we don't have a timeout descriptor, we're done.
9587 	 */
9588 	if ((one->support & RSO_ONE_CTDP) == 0)
9589 		goto bailout;
9590 
9591 	/*
9592 	 * If we don't have enough valid length to include the timeout
9593 	 * descriptor length, we're done.
9594 	 */
9595 	if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9596 		goto bailout;
9597 
9598 	td = (struct scsi_report_supported_opcodes_timeout *)
9599 	    &buf[sizeof(*one) + cdb_len];
9600 	td_len = scsi_2btoul(td->length);
9601 	td_len += sizeof(td->length);
9602 
9603 	/*
9604 	 * If we don't have the full timeout descriptor, we're done.
9605 	 */
9606 	if (td_len < sizeof(*td))
9607 		goto bailout;
9608 
9609 	/*
9610 	 * If we don't have enough valid length to contain the full timeout
9611 	 * descriptor, we're done.
9612 	 */
9613 	if (valid_len < (sizeof(*one) + cdb_len + td_len))
9614 		goto bailout;
9615 
9616 	printf("Timeout information:\n");
9617 	printf("Command-specific:    0x%02x\n", td->cmd_specific);
9618 	printf("Nominal timeout:     %u seconds\n",
9619 	       scsi_4btoul(td->nominal_time));
9620 	printf("Recommended timeout: %u seconds\n",
9621 	       scsi_4btoul(td->recommended_time));
9622 
9623 bailout:
9624 	return (retval);
9625 }
9626 
9627 static int
9628 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9629 		 uint32_t valid_len)
9630 {
9631 	struct scsi_report_supported_opcodes_all *hdr;
9632 	struct scsi_report_supported_opcodes_descr *desc;
9633 	uint32_t avail_len = 0, used_len = 0;
9634 	uint8_t *cur_ptr;
9635 	int retval = 0;
9636 
9637 	if (valid_len < sizeof(*hdr)) {
9638 		warnx("%s: not enough returned data (%u bytes) opcode list",
9639 		      __func__, valid_len);
9640 		retval = 1;
9641 		goto bailout;
9642 	}
9643 	hdr = (struct scsi_report_supported_opcodes_all *)buf;
9644 	avail_len = scsi_4btoul(hdr->length);
9645 	avail_len += sizeof(hdr->length);
9646 	/*
9647 	 * Take the lesser of the amount of data the drive claims is
9648 	 * available, and the amount of data the HBA says was returned.
9649 	 */
9650 	avail_len = MIN(avail_len, valid_len);
9651 
9652 	used_len = sizeof(hdr->length);
9653 
9654 	printf("%-6s %4s %8s ",
9655 	       "Opcode", "SA", "CDB len" );
9656 
9657 	if (td_req != 0)
9658 		printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9659 	printf(" Description\n");
9660 
9661 	while ((avail_len - used_len) > sizeof(*desc)) {
9662 		struct scsi_report_supported_opcodes_timeout *td;
9663 		uint32_t td_len;
9664 		const char *op_desc = NULL;
9665 
9666 		cur_ptr = &buf[used_len];
9667 		desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9668 
9669 		op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9670 		if (op_desc == NULL)
9671 			op_desc = "UNKNOWN";
9672 
9673 		printf("0x%02x   %#4x %8u ", desc->opcode,
9674 		       scsi_2btoul(desc->service_action),
9675 		       scsi_2btoul(desc->cdb_length));
9676 
9677 		used_len += sizeof(*desc);
9678 
9679 		if ((desc->flags & RSO_CTDP) == 0) {
9680 			printf(" %s\n", op_desc);
9681 			continue;
9682 		}
9683 
9684 		/*
9685 		 * If we don't have enough space to fit a timeout
9686 		 * descriptor, then we're done.
9687 		 */
9688 		if (avail_len - used_len < sizeof(*td)) {
9689 			used_len = avail_len;
9690 			printf(" %s\n", op_desc);
9691 			continue;
9692 		}
9693 		cur_ptr = &buf[used_len];
9694 		td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9695 		td_len = scsi_2btoul(td->length);
9696 		td_len += sizeof(td->length);
9697 
9698 		used_len += td_len;
9699 		/*
9700 		 * If the given timeout descriptor length is less than what
9701 		 * we understand, skip it.
9702 		 */
9703 		if (td_len < sizeof(*td)) {
9704 			printf(" %s\n", op_desc);
9705 			continue;
9706 		}
9707 
9708 		printf(" 0x%02x %6u %6u  %s\n", td->cmd_specific,
9709 		       scsi_4btoul(td->nominal_time),
9710 		       scsi_4btoul(td->recommended_time), op_desc);
9711 	}
9712 bailout:
9713 	return (retval);
9714 }
9715 
9716 static int
9717 scsiopcodes(struct cam_device *device, int argc, char **argv,
9718 	    char *combinedopt, int task_attr, int retry_count, int timeout,
9719 	    int verbosemode)
9720 {
9721 	int c;
9722 	uint32_t opcode = 0, service_action = 0;
9723 	int td_set = 0, opcode_set = 0, sa_set = 0;
9724 	int show_sa_errors = 1;
9725 	uint32_t valid_len = 0;
9726 	uint8_t *buf = NULL;
9727 	char *endptr;
9728 	int retval = 0;
9729 
9730 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
9731 		switch (c) {
9732 		case 'N':
9733 			show_sa_errors = 0;
9734 			break;
9735 		case 'o':
9736 			opcode = strtoul(optarg, &endptr, 0);
9737 			if (*endptr != '\0') {
9738 				warnx("Invalid opcode \"%s\", must be a number",
9739 				      optarg);
9740 				retval = 1;
9741 				goto bailout;
9742 			}
9743 			if (opcode > 0xff) {
9744 				warnx("Invalid opcode 0x%#x, must be between"
9745 				      "0 and 0xff inclusive", opcode);
9746 				retval = 1;
9747 				goto bailout;
9748 			}
9749 			opcode_set = 1;
9750 			break;
9751 		case 's':
9752 			service_action = strtoul(optarg, &endptr, 0);
9753 			if (*endptr != '\0') {
9754 				warnx("Invalid service action \"%s\", must "
9755 				      "be a number", optarg);
9756 				retval = 1;
9757 				goto bailout;
9758 			}
9759 			if (service_action > 0xffff) {
9760 				warnx("Invalid service action 0x%#x, must "
9761 				      "be between 0 and 0xffff inclusive",
9762 				      service_action);
9763 				retval = 1;
9764 			}
9765 			sa_set = 1;
9766 			break;
9767 		case 'T':
9768 			td_set = 1;
9769 			break;
9770 		default:
9771 			break;
9772 		}
9773 	}
9774 
9775 	if ((sa_set != 0)
9776 	 && (opcode_set == 0)) {
9777 		warnx("You must specify an opcode with -o if a service "
9778 		      "action is given");
9779 		retval = 1;
9780 		goto bailout;
9781 	}
9782 	retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9783 				sa_set, service_action, td_set, task_attr,
9784 				retry_count, timeout, verbosemode, &valid_len,
9785 				&buf);
9786 	if (retval != 0)
9787 		goto bailout;
9788 
9789 	if ((opcode_set != 0)
9790 	 || (sa_set != 0)) {
9791 		retval = scsiprintoneopcode(device, opcode, sa_set,
9792 					    service_action, buf, valid_len);
9793 	} else {
9794 		retval = scsiprintopcodes(device, td_set, buf, valid_len);
9795 	}
9796 
9797 bailout:
9798 	free(buf);
9799 
9800 	return (retval);
9801 }
9802 
9803 
9804 static int
9805 reprobe(struct cam_device *device)
9806 {
9807 	union ccb *ccb;
9808 	int retval = 0;
9809 
9810 	ccb = cam_getccb(device);
9811 
9812 	if (ccb == NULL) {
9813 		warnx("%s: error allocating ccb", __func__);
9814 		return (1);
9815 	}
9816 
9817 	CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9818 
9819 	ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9820 
9821 	if (cam_send_ccb(device, ccb) < 0) {
9822 		warn("error sending XPT_REPROBE_LUN CCB");
9823 		retval = 1;
9824 		goto bailout;
9825 	}
9826 
9827 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9828 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9829 		retval = 1;
9830 		goto bailout;
9831 	}
9832 
9833 bailout:
9834 	cam_freeccb(ccb);
9835 
9836 	return (retval);
9837 }
9838 
9839 void
9840 usage(int printlong)
9841 {
9842 
9843 	fprintf(printlong ? stdout : stderr,
9844 "usage:  camcontrol <command>  [device id][generic args][command args]\n"
9845 "        camcontrol devlist    [-b] [-v]\n"
9846 "        camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9847 "        camcontrol tur        [dev_id][generic args]\n"
9848 "        camcontrol inquiry    [dev_id][generic args] [-D] [-S] [-R]\n"
9849 "        camcontrol identify   [dev_id][generic args] [-v]\n"
9850 "        camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9851 "        camcontrol readcap    [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9852 "                              [-q] [-s] [-l]\n"
9853 "        camcontrol start      [dev_id][generic args]\n"
9854 "        camcontrol stop       [dev_id][generic args]\n"
9855 "        camcontrol load       [dev_id][generic args]\n"
9856 "        camcontrol eject      [dev_id][generic args]\n"
9857 "        camcontrol reprobe    [dev_id][generic args]\n"
9858 "        camcontrol rescan     <all | bus[:target:lun] | dev_id>\n"
9859 "        camcontrol reset      <all | bus[:target:lun] | dev_id>\n"
9860 "        camcontrol defects    [dev_id][generic args] <-f format> [-P][-G]\n"
9861 "                              [-q][-s][-S offset][-X]\n"
9862 "        camcontrol modepage   [dev_id][generic args] <-m page | -l>\n"
9863 "                              [-P pagectl][-e | -b][-d]\n"
9864 "        camcontrol cmd        [dev_id][generic args]\n"
9865 "                              <-a cmd [args] | -c cmd [args]>\n"
9866 "                              [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9867 "        camcontrol smpcmd     [dev_id][generic args]\n"
9868 "                              <-r len fmt [args]> <-R len fmt [args]>\n"
9869 "        camcontrol smprg      [dev_id][generic args][-l]\n"
9870 "        camcontrol smppc      [dev_id][generic args] <-p phy> [-l]\n"
9871 "                              [-o operation][-d name][-m rate][-M rate]\n"
9872 "                              [-T pp_timeout][-a enable|disable]\n"
9873 "                              [-A enable|disable][-s enable|disable]\n"
9874 "                              [-S enable|disable]\n"
9875 "        camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9876 "        camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9877 "        camcontrol debug      [-I][-P][-T][-S][-X][-c]\n"
9878 "                              <all|dev_id|bus[:target[:lun]]|off>\n"
9879 "        camcontrol tags       [dev_id][generic args] [-N tags] [-q] [-v]\n"
9880 "        camcontrol negotiate  [dev_id][generic args] [-a][-c]\n"
9881 "                              [-D <enable|disable>][-M mode][-O offset]\n"
9882 "                              [-q][-R syncrate][-v][-T <enable|disable>]\n"
9883 "                              [-U][-W bus_width]\n"
9884 "        camcontrol format     [dev_id][generic args][-q][-r][-w][-y]\n"
9885 "        camcontrol sanitize   [dev_id][generic args]\n"
9886 "                              [-a overwrite|block|crypto|exitfailure]\n"
9887 "                              [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9888 "                              [-y]\n"
9889 "        camcontrol idle       [dev_id][generic args][-t time]\n"
9890 "        camcontrol standby    [dev_id][generic args][-t time]\n"
9891 "        camcontrol sleep      [dev_id][generic args]\n"
9892 "        camcontrol powermode  [dev_id][generic args]\n"
9893 "        camcontrol apm        [dev_id][generic args][-l level]\n"
9894 "        camcontrol aam        [dev_id][generic args][-l level]\n"
9895 "        camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9896 "                              [-s][-y]\n"
9897 "        camcontrol security   [dev_id][generic args]\n"
9898 "                              <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9899 "                              [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9900 "                              [-U <user|master>] [-y]\n"
9901 "        camcontrol hpa        [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9902 "                              [-q] [-s max_sectors] [-U pwd] [-y]\n"
9903 "        camcontrol ama        [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9904 "        camcontrol persist    [dev_id][generic args] <-i action|-o action>\n"
9905 "                              [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9906 "                              [-s scope][-S][-T type][-U]\n"
9907 "        camcontrol attrib     [dev_id][generic args] <-r action|-w attr>\n"
9908 "                              [-a attr_num][-c][-e elem][-F form1,form1]\n"
9909 "                              [-p part][-s start][-T type][-V vol]\n"
9910 "        camcontrol opcodes    [dev_id][generic args][-o opcode][-s SA]\n"
9911 "                              [-N][-T]\n"
9912 "        camcontrol zone       [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9913 "                              [-o rep_opts] [-P print_opts]\n"
9914 "        camcontrol epc        [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9915 "                              [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9916 "                              [-S power_src] [-T timer]\n"
9917 "        camcontrol timestamp  [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9918 "                              <-s <-f format -T time | -U >>\n"
9919 "        camcontrol devtype    [dev_id]\n"
9920 "                              \n"
9921 "        camcontrol help\n");
9922 	if (!printlong)
9923 		return;
9924 	fprintf(stdout,
9925 "Specify one of the following options:\n"
9926 "devlist     list all CAM devices\n"
9927 "periphlist  list all CAM peripheral drivers attached to a device\n"
9928 "tur         send a test unit ready to the named device\n"
9929 "inquiry     send a SCSI inquiry command to the named device\n"
9930 "identify    send a ATA identify command to the named device\n"
9931 "reportluns  send a SCSI report luns command to the device\n"
9932 "readcap     send a SCSI read capacity command to the device\n"
9933 "start       send a Start Unit command to the device\n"
9934 "stop        send a Stop Unit command to the device\n"
9935 "load        send a Start Unit command to the device with the load bit set\n"
9936 "eject       send a Stop Unit command to the device with the eject bit set\n"
9937 "reprobe     update capacity information of the given device\n"
9938 "rescan      rescan all buses, the given bus, bus:target:lun or device\n"
9939 "reset       reset all buses, the given bus, bus:target:lun or device\n"
9940 "defects     read the defect list of the specified device\n"
9941 "modepage    display or edit (-e) the given mode page\n"
9942 "cmd         send the given SCSI command, may need -i or -o as well\n"
9943 "smpcmd      send the given SMP command, requires -o and -i\n"
9944 "smprg       send the SMP Report General command\n"
9945 "smppc       send the SMP PHY Control command, requires -p\n"
9946 "smpphylist  display phys attached to a SAS expander\n"
9947 "smpmaninfo  send the SMP Report Manufacturer Info command\n"
9948 "debug       turn debugging on/off for a bus, target, or lun, or all devices\n"
9949 "tags        report or set the number of transaction slots for a device\n"
9950 "negotiate   report or set device negotiation parameters\n"
9951 "format      send the SCSI FORMAT UNIT command to the named device\n"
9952 "sanitize    send the SCSI SANITIZE command to the named device\n"
9953 "idle        send the ATA IDLE command to the named device\n"
9954 "standby     send the ATA STANDBY command to the named device\n"
9955 "sleep       send the ATA SLEEP command to the named device\n"
9956 "powermode   send the ATA CHECK POWER MODE command to the named device\n"
9957 "fwdownload  program firmware of the named device with the given image\n"
9958 "security    report or send ATA security commands to the named device\n"
9959 "persist     send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9960 "attrib      send the SCSI READ or WRITE ATTRIBUTE commands\n"
9961 "opcodes     send the SCSI REPORT SUPPORTED OPCODES command\n"
9962 "zone        manage Zoned Block (Shingled) devices\n"
9963 "epc         send ATA Extended Power Conditions commands\n"
9964 "timestamp   report or set the device's timestamp\n"
9965 "devtype     report the type of device\n"
9966 "help        this message\n"
9967 "Device Identifiers:\n"
9968 "bus:target        specify the bus and target, lun defaults to 0\n"
9969 "bus:target:lun    specify the bus, target and lun\n"
9970 "deviceUNIT        specify the device name, like \"da4\" or \"cd2\"\n"
9971 "Generic arguments:\n"
9972 "-v                be verbose, print out sense information\n"
9973 "-t timeout        command timeout in seconds, overrides default timeout\n"
9974 "-n dev_name       specify device name, e.g. \"da\", \"cd\"\n"
9975 "-u unit           specify unit number, e.g. \"0\", \"5\"\n"
9976 "-E                have the kernel attempt to perform SCSI error recovery\n"
9977 "-C count          specify the SCSI command retry count (needs -E to work)\n"
9978 "-Q task_attr      specify ordered, simple or head tag type for SCSI cmds\n"
9979 "modepage arguments:\n"
9980 "-l                list all available mode pages\n"
9981 "-m page           specify the mode page to view or edit\n"
9982 "-e                edit the specified mode page\n"
9983 "-b                force view to binary mode\n"
9984 "-d                disable block descriptors for mode sense\n"
9985 "-P pgctl          page control field 0-3\n"
9986 "defects arguments:\n"
9987 "-f format         specify defect list format (block, bfi or phys)\n"
9988 "-G                get the grown defect list\n"
9989 "-P                get the permanent defect list\n"
9990 "inquiry arguments:\n"
9991 "-D                get the standard inquiry data\n"
9992 "-S                get the serial number\n"
9993 "-R                get the transfer rate, etc.\n"
9994 "reportluns arguments:\n"
9995 "-c                only report a count of available LUNs\n"
9996 "-l                only print out luns, and not a count\n"
9997 "-r <reporttype>   specify \"default\", \"wellknown\" or \"all\"\n"
9998 "readcap arguments\n"
9999 "-b                only report the blocksize\n"
10000 "-h                human readable device size, base 2\n"
10001 "-H                human readable device size, base 10\n"
10002 "-N                print the number of blocks instead of last block\n"
10003 "-q                quiet, print numbers only\n"
10004 "-s                only report the last block/device size\n"
10005 "cmd arguments:\n"
10006 "-c cdb [args]     specify the SCSI CDB\n"
10007 "-i len fmt        specify input data and input data format\n"
10008 "-o len fmt [args] specify output data and output data fmt\n"
10009 "smpcmd arguments:\n"
10010 "-r len fmt [args] specify the SMP command to be sent\n"
10011 "-R len fmt [args] specify SMP response format\n"
10012 "smprg arguments:\n"
10013 "-l                specify the long response format\n"
10014 "smppc arguments:\n"
10015 "-p phy            specify the PHY to operate on\n"
10016 "-l                specify the long request/response format\n"
10017 "-o operation      specify the phy control operation\n"
10018 "-d name           set the attached device name\n"
10019 "-m rate           set the minimum physical link rate\n"
10020 "-M rate           set the maximum physical link rate\n"
10021 "-T pp_timeout     set the partial pathway timeout value\n"
10022 "-a enable|disable enable or disable SATA slumber\n"
10023 "-A enable|disable enable or disable SATA partial phy power\n"
10024 "-s enable|disable enable or disable SAS slumber\n"
10025 "-S enable|disable enable or disable SAS partial phy power\n"
10026 "smpphylist arguments:\n"
10027 "-l                specify the long response format\n"
10028 "-q                only print phys with attached devices\n"
10029 "smpmaninfo arguments:\n"
10030 "-l                specify the long response format\n"
10031 "debug arguments:\n"
10032 "-I                CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10033 "-T                CAM_DEBUG_TRACE -- routine flow tracking\n"
10034 "-S                CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10035 "-c                CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10036 "tags arguments:\n"
10037 "-N tags           specify the number of tags to use for this device\n"
10038 "-q                be quiet, don't report the number of tags\n"
10039 "-v                report a number of tag-related parameters\n"
10040 "negotiate arguments:\n"
10041 "-a                send a test unit ready after negotiation\n"
10042 "-c                report/set current negotiation settings\n"
10043 "-D <arg>          \"enable\" or \"disable\" disconnection\n"
10044 "-M mode           set ATA mode\n"
10045 "-O offset         set command delay offset\n"
10046 "-q                be quiet, don't report anything\n"
10047 "-R syncrate       synchronization rate in MHz\n"
10048 "-T <arg>          \"enable\" or \"disable\" tagged queueing\n"
10049 "-U                report/set user negotiation settings\n"
10050 "-W bus_width      set the bus width in bits (8, 16 or 32)\n"
10051 "-v                also print a Path Inquiry CCB for the controller\n"
10052 "format arguments:\n"
10053 "-q                be quiet, don't print status messages\n"
10054 "-r                run in report only mode\n"
10055 "-w                don't send immediate format command\n"
10056 "-y                don't ask any questions\n"
10057 "sanitize arguments:\n"
10058 "-a operation      operation mode: overwrite, block, crypto or exitfailure\n"
10059 "-c passes         overwrite passes to perform (1 to 31)\n"
10060 "-I                invert overwrite pattern after each pass\n"
10061 "-P pattern        path to overwrite pattern file\n"
10062 "-q                be quiet, don't print status messages\n"
10063 "-r                run in report only mode\n"
10064 "-U                run operation in unrestricted completion exit mode\n"
10065 "-w                don't send immediate sanitize command\n"
10066 "-y                don't ask any questions\n"
10067 "idle/standby arguments:\n"
10068 "-t <arg>          number of seconds before respective state.\n"
10069 "fwdownload arguments:\n"
10070 "-f fw_image       path to firmware image file\n"
10071 "-q                don't print informational messages, only errors\n"
10072 "-s                run in simulation mode\n"
10073 "-v                print info for every firmware segment sent to device\n"
10074 "-y                don't ask any questions\n"
10075 "security arguments:\n"
10076 "-d pwd            disable security using the given password for the selected\n"
10077 "                  user\n"
10078 "-e pwd            erase the device using the given pwd for the selected user\n"
10079 "-f                freeze the security configuration of the specified device\n"
10080 "-h pwd            enhanced erase the device using the given pwd for the\n"
10081 "                  selected user\n"
10082 "-k pwd            unlock the device using the given pwd for the selected\n"
10083 "                  user\n"
10084 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10085 "-q                be quiet, do not print any status messages\n"
10086 "-s pwd            password the device (enable security) using the given\n"
10087 "                  pwd for the selected user\n"
10088 "-T timeout        overrides the timeout (seconds) used for erase operation\n"
10089 "-U <user|master>  specifies which user to set: user or master\n"
10090 "-y                don't ask any questions\n"
10091 "hpa arguments:\n"
10092 "-f                freeze the HPA configuration of the device\n"
10093 "-l                lock the HPA configuration of the device\n"
10094 "-P                make the HPA max sectors persist\n"
10095 "-p pwd            Set the HPA configuration password required for unlock\n"
10096 "                  calls\n"
10097 "-q                be quiet, do not print any status messages\n"
10098 "-s sectors        configures the maximum user accessible sectors of the\n"
10099 "                  device\n"
10100 "-U pwd            unlock the HPA configuration of the device\n"
10101 "-y                don't ask any questions\n"
10102 "ama arguments:\n"
10103 "-f                freeze the AMA configuration of the device\n"
10104 "-q                be quiet, do not print any status messages\n"
10105 "-s sectors        configures the maximum user accessible sectors of the\n"
10106 "                  device\n"
10107 "persist arguments:\n"
10108 "-i action         specify read_keys, read_reservation, report_cap, or\n"
10109 "                  read_full_status\n"
10110 "-o action         specify register, register_ignore, reserve, release,\n"
10111 "                  clear, preempt, preempt_abort, register_move, replace_lost\n"
10112 "-a                set the All Target Ports (ALL_TG_PT) bit\n"
10113 "-I tid            specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10114 "-k key            specify the Reservation Key\n"
10115 "-K sa_key         specify the Service Action Reservation Key\n"
10116 "-p                set the Activate Persist Through Power Loss bit\n"
10117 "-R rtp            specify the Relative Target Port\n"
10118 "-s scope          specify the scope: lun, extent, element or a number\n"
10119 "-S                specify Transport ID for register, requires -I\n"
10120 "-T res_type       specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10121 "                  ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10122 "-U                unregister the current initiator for register_move\n"
10123 "attrib arguments:\n"
10124 "-r action         specify attr_values, attr_list, lv_list, part_list, or\n"
10125 "                  supp_attr\n"
10126 "-w attr           specify an attribute to write, one -w argument per attr\n"
10127 "-a attr_num       only display this attribute number\n"
10128 "-c                get cached attributes\n"
10129 "-e elem_addr      request attributes for the given element in a changer\n"
10130 "-F form1,form2    output format, comma separated list: text_esc, text_raw,\n"
10131 "                  nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10132 "                  field_none, field_desc, field_num, field_size, field_rw\n"
10133 "-p partition      request attributes for the given partition\n"
10134 "-s start_attr     request attributes starting at the given number\n"
10135 "-T elem_type      specify the element type (used with -e)\n"
10136 "-V logical_vol    specify the logical volume ID\n"
10137 "opcodes arguments:\n"
10138 "-o opcode         specify the individual opcode to list\n"
10139 "-s service_action specify the service action for the opcode\n"
10140 "-N                do not return SCSI error for unsupported SA\n"
10141 "-T                request nominal and recommended timeout values\n"
10142 "zone arguments:\n"
10143 "-c cmd            required: rz, open, close, finish, or rwp\n"
10144 "-a                apply the action to all zones\n"
10145 "-l LBA            specify the zone starting LBA\n"
10146 "-o rep_opts       report zones options: all, empty, imp_open, exp_open,\n"
10147 "                  closed, full, ro, offline, reset, nonseq, nonwp\n"
10148 "-P print_opt      report zones printing:  normal, summary, script\n"
10149 "epc arguments:\n"
10150 "-c cmd            required: restore, goto, timer, state, enable, disable,\n"
10151 "                  source, status, list\n"
10152 "-d                disable power mode (timer, state)\n"
10153 "-D                delayed entry (goto)\n"
10154 "-e                enable power mode (timer, state)\n"
10155 "-H                hold power mode (goto)\n"
10156 "-p power_cond     Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10157 "                  state, goto)\n"
10158 "-P                only display power mode (status)\n"
10159 "-r rst_src        restore settings from: default, saved (restore)\n"
10160 "-s                save mode (timer, state, restore)\n"
10161 "-S power_src      set power source: battery, nonbattery (source)\n"
10162 "-T timer          set timer, seconds, .1 sec resolution (timer)\n"
10163 "timestamp arguments:\n"
10164 "-r                report the timestamp of the device\n"
10165 "-f format         report the timestamp of the device with the given\n"
10166 "                  strftime(3) format string\n"
10167 "-m                report the timestamp of the device as milliseconds since\n"
10168 "                  January 1st, 1970\n"
10169 "-U                report the time with UTC instead of the local time zone\n"
10170 "-s                set the timestamp of the device\n"
10171 "-f format         the format of the time string passed into strptime(3)\n"
10172 "-T time           the time value passed into strptime(3)\n"
10173 "-U                set the timestamp of the device to UTC time\n"
10174 );
10175 }
10176 
10177 int
10178 main(int argc, char **argv)
10179 {
10180 	int c;
10181 	char *device = NULL;
10182 	int unit = 0;
10183 	struct cam_device *cam_dev = NULL;
10184 	int timeout = 0, retry_count = 1;
10185 	camcontrol_optret optreturn;
10186 	char *tstr;
10187 	const char *mainopt = "C:En:Q:t:u:v";
10188 	const char *subopt = NULL;
10189 	char combinedopt[256];
10190 	int error = 0, optstart = 2;
10191 	int task_attr = MSG_SIMPLE_Q_TAG;
10192 	int devopen = 1;
10193 	path_id_t bus;
10194 	target_id_t target;
10195 	lun_id_t lun;
10196 
10197 	cmdlist = CAM_CMD_NONE;
10198 	arglist = CAM_ARG_NONE;
10199 
10200 	if (argc < 2) {
10201 		usage(0);
10202 		exit(1);
10203 	}
10204 
10205 	/*
10206 	 * Get the base option.
10207 	 */
10208 	optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10209 
10210 	if (optreturn == CC_OR_AMBIGUOUS) {
10211 		warnx("ambiguous option %s", argv[1]);
10212 		usage(0);
10213 		exit(1);
10214 	} else if (optreturn == CC_OR_NOT_FOUND) {
10215 		warnx("option %s not found", argv[1]);
10216 		usage(0);
10217 		exit(1);
10218 	}
10219 
10220 	/*
10221 	 * Ahh, getopt(3) is a pain.
10222 	 *
10223 	 * This is a gross hack.  There really aren't many other good
10224 	 * options (excuse the pun) for parsing options in a situation like
10225 	 * this.  getopt is kinda braindead, so you end up having to run
10226 	 * through the options twice, and give each invocation of getopt
10227 	 * the option string for the other invocation.
10228 	 *
10229 	 * You would think that you could just have two groups of options.
10230 	 * The first group would get parsed by the first invocation of
10231 	 * getopt, and the second group would get parsed by the second
10232 	 * invocation of getopt.  It doesn't quite work out that way.  When
10233 	 * the first invocation of getopt finishes, it leaves optind pointing
10234 	 * to the argument _after_ the first argument in the second group.
10235 	 * So when the second invocation of getopt comes around, it doesn't
10236 	 * recognize the first argument it gets and then bails out.
10237 	 *
10238 	 * A nice alternative would be to have a flag for getopt that says
10239 	 * "just keep parsing arguments even when you encounter an unknown
10240 	 * argument", but there isn't one.  So there's no real clean way to
10241 	 * easily parse two sets of arguments without having one invocation
10242 	 * of getopt know about the other.
10243 	 *
10244 	 * Without this hack, the first invocation of getopt would work as
10245 	 * long as the generic arguments are first, but the second invocation
10246 	 * (in the subfunction) would fail in one of two ways.  In the case
10247 	 * where you don't set optreset, it would fail because optind may be
10248 	 * pointing to the argument after the one it should be pointing at.
10249 	 * In the case where you do set optreset, and reset optind, it would
10250 	 * fail because getopt would run into the first set of options, which
10251 	 * it doesn't understand.
10252 	 *
10253 	 * All of this would "sort of" work if you could somehow figure out
10254 	 * whether optind had been incremented one option too far.  The
10255 	 * mechanics of that, however, are more daunting than just giving
10256 	 * both invocations all of the expect options for either invocation.
10257 	 *
10258 	 * Needless to say, I wouldn't mind if someone invented a better
10259 	 * (non-GPL!) command line parsing interface than getopt.  I
10260 	 * wouldn't mind if someone added more knobs to getopt to make it
10261 	 * work better.  Who knows, I may talk myself into doing it someday,
10262 	 * if the standards weenies let me.  As it is, it just leads to
10263 	 * hackery like this and causes people to avoid it in some cases.
10264 	 *
10265 	 * KDM, September 8th, 1998
10266 	 */
10267 	if (subopt != NULL)
10268 		sprintf(combinedopt, "%s%s", mainopt, subopt);
10269 	else
10270 		sprintf(combinedopt, "%s", mainopt);
10271 
10272 	/*
10273 	 * For these options we do not parse optional device arguments and
10274 	 * we do not open a passthrough device.
10275 	 */
10276 	if ((cmdlist == CAM_CMD_RESCAN)
10277 	 || (cmdlist == CAM_CMD_RESET)
10278 	 || (cmdlist == CAM_CMD_DEVTREE)
10279 	 || (cmdlist == CAM_CMD_USAGE)
10280 	 || (cmdlist == CAM_CMD_DEBUG))
10281 		devopen = 0;
10282 
10283 	if ((devopen == 1)
10284 	 && (argc > 2 && argv[2][0] != '-')) {
10285 		char name[30];
10286 		int rv;
10287 
10288 		if (isdigit(argv[2][0])) {
10289 			/* device specified as bus:target[:lun] */
10290 			rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10291 			if (rv < 2)
10292 				errx(1, "numeric device specification must "
10293 				     "be either bus:target, or "
10294 				     "bus:target:lun");
10295 			/* default to 0 if lun was not specified */
10296 			if ((arglist & CAM_ARG_LUN) == 0) {
10297 				lun = 0;
10298 				arglist |= CAM_ARG_LUN;
10299 			}
10300 			optstart++;
10301 		} else {
10302 			if (cam_get_device(argv[2], name, sizeof name, &unit)
10303 			    == -1)
10304 				errx(1, "%s", cam_errbuf);
10305 			device = strdup(name);
10306 			arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10307 			optstart++;
10308 		}
10309 	}
10310 	/*
10311 	 * Start getopt processing at argv[2/3], since we've already
10312 	 * accepted argv[1..2] as the command name, and as a possible
10313 	 * device name.
10314 	 */
10315 	optind = optstart;
10316 
10317 	/*
10318 	 * Now we run through the argument list looking for generic
10319 	 * options, and ignoring options that possibly belong to
10320 	 * subfunctions.
10321 	 */
10322 	while ((c = getopt(argc, argv, combinedopt))!= -1){
10323 		switch(c) {
10324 			case 'C':
10325 				retry_count = strtol(optarg, NULL, 0);
10326 				if (retry_count < 0)
10327 					errx(1, "retry count %d is < 0",
10328 					     retry_count);
10329 				arglist |= CAM_ARG_RETRIES;
10330 				break;
10331 			case 'E':
10332 				arglist |= CAM_ARG_ERR_RECOVER;
10333 				break;
10334 			case 'n':
10335 				arglist |= CAM_ARG_DEVICE;
10336 				tstr = optarg;
10337 				while (isspace(*tstr) && (*tstr != '\0'))
10338 					tstr++;
10339 				device = (char *)strdup(tstr);
10340 				break;
10341 			case 'Q': {
10342 				char *endptr;
10343 				int table_entry = 0;
10344 
10345 				tstr = optarg;
10346 				while (isspace(*tstr) && (*tstr != '\0'))
10347 					tstr++;
10348 				if (isdigit(*tstr)) {
10349 					task_attr = strtol(tstr, &endptr, 0);
10350 					if (*endptr != '\0') {
10351 						errx(1, "Invalid queue option "
10352 						    "%s", tstr);
10353 					}
10354 				} else {
10355 					size_t table_size;
10356 					scsi_nv_status status;
10357 
10358 					table_size = sizeof(task_attrs) /
10359 						     sizeof(task_attrs[0]);
10360 					status = scsi_get_nv(task_attrs,
10361 					    table_size, tstr, &table_entry,
10362 					    SCSI_NV_FLAG_IG_CASE);
10363 					if (status == SCSI_NV_FOUND)
10364 						task_attr = task_attrs[
10365 						    table_entry].value;
10366 					else {
10367 						errx(1, "%s option %s",
10368 						  (status == SCSI_NV_AMBIGUOUS)?
10369 						    "ambiguous" : "invalid",
10370 						    tstr);
10371 					}
10372 				}
10373 				break;
10374 			}
10375 			case 't':
10376 				timeout = strtol(optarg, NULL, 0);
10377 				if (timeout < 0)
10378 					errx(1, "invalid timeout %d", timeout);
10379 				/* Convert the timeout from seconds to ms */
10380 				timeout *= 1000;
10381 				arglist |= CAM_ARG_TIMEOUT;
10382 				break;
10383 			case 'u':
10384 				arglist |= CAM_ARG_UNIT;
10385 				unit = strtol(optarg, NULL, 0);
10386 				break;
10387 			case 'v':
10388 				arglist |= CAM_ARG_VERBOSE;
10389 				break;
10390 			default:
10391 				break;
10392 		}
10393 	}
10394 
10395 	/*
10396 	 * For most commands we'll want to open the passthrough device
10397 	 * associated with the specified device.  In the case of the rescan
10398 	 * commands, we don't use a passthrough device at all, just the
10399 	 * transport layer device.
10400 	 */
10401 	if (devopen == 1) {
10402 		if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10403 		 && (((arglist & CAM_ARG_DEVICE) == 0)
10404 		  || ((arglist & CAM_ARG_UNIT) == 0))) {
10405 			errx(1, "subcommand \"%s\" requires a valid device "
10406 			     "identifier", argv[1]);
10407 		}
10408 
10409 		if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10410 				cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10411 				cam_open_spec_device(device,unit,O_RDWR,NULL)))
10412 		     == NULL)
10413 			errx(1,"%s", cam_errbuf);
10414 	}
10415 
10416 	/*
10417 	 * Reset optind to 2, and reset getopt, so these routines can parse
10418 	 * the arguments again.
10419 	 */
10420 	optind = optstart;
10421 	optreset = 1;
10422 
10423 	switch(cmdlist) {
10424 	case CAM_CMD_DEVLIST:
10425 		error = getdevlist(cam_dev);
10426 		break;
10427 	case CAM_CMD_HPA:
10428 		error = atahpa(cam_dev, retry_count, timeout,
10429 			       argc, argv, combinedopt);
10430 		break;
10431 	case CAM_CMD_AMA:
10432 		error = ataama(cam_dev, retry_count, timeout,
10433 			       argc, argv, combinedopt);
10434 		break;
10435 	case CAM_CMD_DEVTREE:
10436 		error = getdevtree(argc, argv, combinedopt);
10437 		break;
10438 	case CAM_CMD_DEVTYPE:
10439 		error = getdevtype(cam_dev);
10440 		break;
10441 	case CAM_CMD_TUR:
10442 		error = testunitready(cam_dev, task_attr, retry_count,
10443 		    timeout, 0);
10444 		break;
10445 	case CAM_CMD_INQUIRY:
10446 		error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10447 				      task_attr, retry_count, timeout);
10448 		break;
10449 	case CAM_CMD_IDENTIFY:
10450 		error = identify(cam_dev, retry_count, timeout);
10451 		break;
10452 	case CAM_CMD_STARTSTOP:
10453 		error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10454 				  arglist & CAM_ARG_EJECT, task_attr,
10455 				  retry_count, timeout);
10456 		break;
10457 	case CAM_CMD_RESCAN:
10458 		error = dorescan_or_reset(argc, argv, 1);
10459 		break;
10460 	case CAM_CMD_RESET:
10461 		error = dorescan_or_reset(argc, argv, 0);
10462 		break;
10463 	case CAM_CMD_READ_DEFECTS:
10464 		error = readdefects(cam_dev, argc, argv, combinedopt,
10465 				    task_attr, retry_count, timeout);
10466 		break;
10467 	case CAM_CMD_MODE_PAGE:
10468 		modepage(cam_dev, argc, argv, combinedopt,
10469 			 task_attr, retry_count, timeout);
10470 		break;
10471 	case CAM_CMD_SCSI_CMD:
10472 		error = scsicmd(cam_dev, argc, argv, combinedopt,
10473 				task_attr, retry_count, timeout);
10474 		break;
10475 	case CAM_CMD_MMCSD_CMD:
10476 		error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10477 					retry_count, timeout);
10478 		break;
10479 	case CAM_CMD_SMP_CMD:
10480 		error = smpcmd(cam_dev, argc, argv, combinedopt,
10481 			       retry_count, timeout);
10482 		break;
10483 	case CAM_CMD_SMP_RG:
10484 		error = smpreportgeneral(cam_dev, argc, argv,
10485 					 combinedopt, retry_count,
10486 					 timeout);
10487 		break;
10488 	case CAM_CMD_SMP_PC:
10489 		error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10490 				      retry_count, timeout);
10491 		break;
10492 	case CAM_CMD_SMP_PHYLIST:
10493 		error = smpphylist(cam_dev, argc, argv, combinedopt,
10494 				   retry_count, timeout);
10495 		break;
10496 	case CAM_CMD_SMP_MANINFO:
10497 		error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10498 				   retry_count, timeout);
10499 		break;
10500 	case CAM_CMD_DEBUG:
10501 		error = camdebug(argc, argv, combinedopt);
10502 		break;
10503 	case CAM_CMD_TAG:
10504 		error = tagcontrol(cam_dev, argc, argv, combinedopt);
10505 		break;
10506 	case CAM_CMD_RATE:
10507 		error = ratecontrol(cam_dev, task_attr, retry_count,
10508 				    timeout, argc, argv, combinedopt);
10509 		break;
10510 	case CAM_CMD_FORMAT:
10511 		error = scsiformat(cam_dev, argc, argv,
10512 				   combinedopt, task_attr, retry_count,
10513 				   timeout);
10514 		break;
10515 	case CAM_CMD_REPORTLUNS:
10516 		error = scsireportluns(cam_dev, argc, argv,
10517 				       combinedopt, task_attr,
10518 				       retry_count, timeout);
10519 		break;
10520 	case CAM_CMD_READCAP:
10521 		error = scsireadcapacity(cam_dev, argc, argv,
10522 					 combinedopt, task_attr,
10523 					 retry_count, timeout);
10524 		break;
10525 	case CAM_CMD_IDLE:
10526 	case CAM_CMD_STANDBY:
10527 	case CAM_CMD_SLEEP:
10528 	case CAM_CMD_POWER_MODE:
10529 		error = atapm(cam_dev, argc, argv,
10530 			      combinedopt, retry_count, timeout);
10531 		break;
10532 	case CAM_CMD_APM:
10533 	case CAM_CMD_AAM:
10534 		error = ataaxm(cam_dev, argc, argv,
10535 			      combinedopt, retry_count, timeout);
10536 		break;
10537 	case CAM_CMD_SECURITY:
10538 		error = atasecurity(cam_dev, retry_count, timeout,
10539 				    argc, argv, combinedopt);
10540 		break;
10541 	case CAM_CMD_DOWNLOAD_FW:
10542 		error = fwdownload(cam_dev, argc, argv, combinedopt,
10543 		    arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10544 		    timeout);
10545 		break;
10546 	case CAM_CMD_SANITIZE:
10547 		error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10548 				 retry_count, timeout);
10549 		break;
10550 	case CAM_CMD_PERSIST:
10551 		error = scsipersist(cam_dev, argc, argv, combinedopt,
10552 		    task_attr, retry_count, timeout,
10553 		    arglist & CAM_ARG_VERBOSE,
10554 		    arglist & CAM_ARG_ERR_RECOVER);
10555 		break;
10556 	case CAM_CMD_ATTRIB:
10557 		error = scsiattrib(cam_dev, argc, argv, combinedopt,
10558 		    task_attr, retry_count, timeout,
10559 		    arglist & CAM_ARG_VERBOSE,
10560 		    arglist & CAM_ARG_ERR_RECOVER);
10561 		break;
10562 	case CAM_CMD_OPCODES:
10563 		error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10564 		    task_attr, retry_count, timeout,
10565 		    arglist & CAM_ARG_VERBOSE);
10566 		break;
10567 	case CAM_CMD_REPROBE:
10568 		error = reprobe(cam_dev);
10569 		break;
10570 	case CAM_CMD_ZONE:
10571 		error = zone(cam_dev, argc, argv, combinedopt,
10572 		    task_attr, retry_count, timeout,
10573 		    arglist & CAM_ARG_VERBOSE);
10574 		break;
10575 	case CAM_CMD_EPC:
10576 		error = epc(cam_dev, argc, argv, combinedopt,
10577 		    retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10578 		break;
10579 	case CAM_CMD_TIMESTAMP:
10580 		error = timestamp(cam_dev, argc, argv, combinedopt,
10581 		    task_attr, retry_count, timeout,
10582 		    arglist & CAM_ARG_VERBOSE);
10583 		break;
10584 	case CAM_CMD_USAGE:
10585 		usage(1);
10586 		break;
10587 	default:
10588 		usage(0);
10589 		error = 1;
10590 		break;
10591 	}
10592 
10593 	if (cam_dev != NULL)
10594 		cam_close_device(cam_dev);
10595 
10596 	exit(error);
10597 }
10598