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