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