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