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