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