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