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