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