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