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