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