xref: /freebsd/sbin/camcontrol/camcontrol.c (revision 8be96e101f2691b80ff9562b72f874da82e735aa)
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/endian.h>
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <fcntl.h>
42 #include <ctype.h>
43 #include <err.h>
44 #include <libutil.h>
45 
46 #include <cam/cam.h>
47 #include <cam/cam_debug.h>
48 #include <cam/cam_ccb.h>
49 #include <cam/scsi/scsi_all.h>
50 #include <cam/scsi/scsi_da.h>
51 #include <cam/scsi/scsi_pass.h>
52 #include <cam/scsi/scsi_message.h>
53 #include <cam/ata/ata_all.h>
54 #include <camlib.h>
55 #include "camcontrol.h"
56 
57 typedef enum {
58 	CAM_CMD_NONE		= 0x00000000,
59 	CAM_CMD_DEVLIST		= 0x00000001,
60 	CAM_CMD_TUR		= 0x00000002,
61 	CAM_CMD_INQUIRY		= 0x00000003,
62 	CAM_CMD_STARTSTOP	= 0x00000004,
63 	CAM_CMD_RESCAN		= 0x00000005,
64 	CAM_CMD_READ_DEFECTS	= 0x00000006,
65 	CAM_CMD_MODE_PAGE	= 0x00000007,
66 	CAM_CMD_SCSI_CMD	= 0x00000008,
67 	CAM_CMD_DEVTREE		= 0x00000009,
68 	CAM_CMD_USAGE		= 0x0000000a,
69 	CAM_CMD_DEBUG		= 0x0000000b,
70 	CAM_CMD_RESET		= 0x0000000c,
71 	CAM_CMD_FORMAT		= 0x0000000d,
72 	CAM_CMD_TAG		= 0x0000000e,
73 	CAM_CMD_RATE		= 0x0000000f,
74 	CAM_CMD_DETACH		= 0x00000010,
75 	CAM_CMD_REPORTLUNS	= 0x00000011,
76 	CAM_CMD_READCAP		= 0x00000012,
77 	CAM_CMD_IDENTIFY	= 0x00000013,
78 	CAM_CMD_IDLE		= 0x00000014,
79 	CAM_CMD_STANDBY		= 0x00000015,
80 	CAM_CMD_SLEEP		= 0x00000016
81 } cam_cmdmask;
82 
83 typedef enum {
84 	CAM_ARG_NONE		= 0x00000000,
85 	CAM_ARG_VERBOSE		= 0x00000001,
86 	CAM_ARG_DEVICE		= 0x00000002,
87 	CAM_ARG_BUS		= 0x00000004,
88 	CAM_ARG_TARGET		= 0x00000008,
89 	CAM_ARG_LUN		= 0x00000010,
90 	CAM_ARG_EJECT		= 0x00000020,
91 	CAM_ARG_UNIT		= 0x00000040,
92 	CAM_ARG_FORMAT_BLOCK	= 0x00000080,
93 	CAM_ARG_FORMAT_BFI	= 0x00000100,
94 	CAM_ARG_FORMAT_PHYS	= 0x00000200,
95 	CAM_ARG_PLIST		= 0x00000400,
96 	CAM_ARG_GLIST		= 0x00000800,
97 	CAM_ARG_GET_SERIAL	= 0x00001000,
98 	CAM_ARG_GET_STDINQ	= 0x00002000,
99 	CAM_ARG_GET_XFERRATE	= 0x00004000,
100 	CAM_ARG_INQ_MASK	= 0x00007000,
101 	CAM_ARG_MODE_EDIT	= 0x00008000,
102 	CAM_ARG_PAGE_CNTL	= 0x00010000,
103 	CAM_ARG_TIMEOUT		= 0x00020000,
104 	CAM_ARG_CMD_IN		= 0x00040000,
105 	CAM_ARG_CMD_OUT		= 0x00080000,
106 	CAM_ARG_DBD		= 0x00100000,
107 	CAM_ARG_ERR_RECOVER	= 0x00200000,
108 	CAM_ARG_RETRIES		= 0x00400000,
109 	CAM_ARG_START_UNIT	= 0x00800000,
110 	CAM_ARG_DEBUG_INFO	= 0x01000000,
111 	CAM_ARG_DEBUG_TRACE	= 0x02000000,
112 	CAM_ARG_DEBUG_SUBTRACE	= 0x04000000,
113 	CAM_ARG_DEBUG_CDB	= 0x08000000,
114 	CAM_ARG_DEBUG_XPT	= 0x10000000,
115 	CAM_ARG_DEBUG_PERIPH	= 0x20000000,
116 } cam_argmask;
117 
118 struct camcontrol_opts {
119 	const char	*optname;
120 	cam_cmdmask	cmdnum;
121 	cam_argmask	argnum;
122 	const char	*subopt;
123 };
124 
125 #ifndef MINIMALISTIC
126 static const char scsicmd_opts[] = "a:c:dfi:o:r";
127 static const char readdefect_opts[] = "f:GP";
128 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
129 #endif
130 
131 struct camcontrol_opts option_table[] = {
132 #ifndef MINIMALISTIC
133 	{"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
134 	{"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
135 	{"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
136 	{"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
137 	{"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
138 	{"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
139 	{"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
140 	{"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
141 	{"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
142 #endif /* MINIMALISTIC */
143 	{"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
144 	{"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
145 #ifndef MINIMALISTIC
146 	{"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
147 	{"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
148 	{"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
149 	{"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
150 #endif /* MINIMALISTIC */
151 	{"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL},
152 #ifndef MINIMALISTIC
153 	{"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
154 	{"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
155 	{"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
156 	{"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
157 	{"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
158 	{"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXc"},
159 	{"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
160 	{"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
161 	{"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
162 	{"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
163 #endif /* MINIMALISTIC */
164 	{"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
165 	{"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
166 	{"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
167 	{NULL, 0, 0, NULL}
168 };
169 
170 typedef enum {
171 	CC_OR_NOT_FOUND,
172 	CC_OR_AMBIGUOUS,
173 	CC_OR_FOUND
174 } camcontrol_optret;
175 
176 cam_cmdmask cmdlist;
177 cam_argmask arglist;
178 
179 
180 camcontrol_optret getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
181 			    const char **subopt);
182 #ifndef MINIMALISTIC
183 static int getdevlist(struct cam_device *device);
184 #endif /* MINIMALISTIC */
185 static int getdevtree(void);
186 #ifndef MINIMALISTIC
187 static int testunitready(struct cam_device *device, int retry_count,
188 			 int timeout, int quiet);
189 static int scsistart(struct cam_device *device, int startstop, int loadeject,
190 		     int retry_count, int timeout);
191 static int scsidoinquiry(struct cam_device *device, int argc, char **argv,
192 			 char *combinedopt, int retry_count, int timeout);
193 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
194 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
195 static int camxferrate(struct cam_device *device);
196 #endif /* MINIMALISTIC */
197 static int parse_btl(char *tstr, int *bus, int *target, int *lun,
198 		     cam_argmask *arglst);
199 static int dorescan_or_reset(int argc, char **argv, int rescan);
200 static int rescan_or_reset_bus(int bus, int rescan);
201 static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
202 #ifndef MINIMALISTIC
203 static int readdefects(struct cam_device *device, int argc, char **argv,
204 		       char *combinedopt, int retry_count, int timeout);
205 static void modepage(struct cam_device *device, int argc, char **argv,
206 		     char *combinedopt, int retry_count, int timeout);
207 static int scsicmd(struct cam_device *device, int argc, char **argv,
208 		   char *combinedopt, int retry_count, int timeout);
209 static int tagcontrol(struct cam_device *device, int argc, char **argv,
210 		      char *combinedopt);
211 static void cts_print(struct cam_device *device,
212 		      struct ccb_trans_settings *cts);
213 static void cpi_print(struct ccb_pathinq *cpi);
214 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
215 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
216 static int get_print_cts(struct cam_device *device, int user_settings,
217 			 int quiet, struct ccb_trans_settings *cts);
218 static int ratecontrol(struct cam_device *device, int retry_count,
219 		       int timeout, int argc, char **argv, char *combinedopt);
220 static int scsiformat(struct cam_device *device, int argc, char **argv,
221 		      char *combinedopt, int retry_count, int timeout);
222 static int scsireportluns(struct cam_device *device, int argc, char **argv,
223 			  char *combinedopt, int retry_count, int timeout);
224 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
225 			    char *combinedopt, int retry_count, int timeout);
226 static int atapm(struct cam_device *device, int argc, char **argv,
227 			    char *combinedopt, int retry_count, int timeout);
228 #endif /* MINIMALISTIC */
229 #ifndef min
230 #define min(a,b) (((a)<(b))?(a):(b))
231 #endif
232 #ifndef max
233 #define max(a,b) (((a)>(b))?(a):(b))
234 #endif
235 
236 camcontrol_optret
237 getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
238 	  const char **subopt)
239 {
240 	struct camcontrol_opts *opts;
241 	int num_matches = 0;
242 
243 	for (opts = option_table; (opts != NULL) && (opts->optname != NULL);
244 	     opts++) {
245 		if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
246 			*cmdnum = opts->cmdnum;
247 			*argnum = opts->argnum;
248 			*subopt = opts->subopt;
249 			if (++num_matches > 1)
250 				return(CC_OR_AMBIGUOUS);
251 		}
252 	}
253 
254 	if (num_matches > 0)
255 		return(CC_OR_FOUND);
256 	else
257 		return(CC_OR_NOT_FOUND);
258 }
259 
260 #ifndef MINIMALISTIC
261 static int
262 getdevlist(struct cam_device *device)
263 {
264 	union ccb *ccb;
265 	char status[32];
266 	int error = 0;
267 
268 	ccb = cam_getccb(device);
269 
270 	ccb->ccb_h.func_code = XPT_GDEVLIST;
271 	ccb->ccb_h.flags = CAM_DIR_NONE;
272 	ccb->ccb_h.retry_count = 1;
273 	ccb->cgdl.index = 0;
274 	ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
275 	while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
276 		if (cam_send_ccb(device, ccb) < 0) {
277 			perror("error getting device list");
278 			cam_freeccb(ccb);
279 			return(1);
280 		}
281 
282 		status[0] = '\0';
283 
284 		switch (ccb->cgdl.status) {
285 			case CAM_GDEVLIST_MORE_DEVS:
286 				strcpy(status, "MORE");
287 				break;
288 			case CAM_GDEVLIST_LAST_DEVICE:
289 				strcpy(status, "LAST");
290 				break;
291 			case CAM_GDEVLIST_LIST_CHANGED:
292 				strcpy(status, "CHANGED");
293 				break;
294 			case CAM_GDEVLIST_ERROR:
295 				strcpy(status, "ERROR");
296 				error = 1;
297 				break;
298 		}
299 
300 		fprintf(stdout, "%s%d:  generation: %d index: %d status: %s\n",
301 			ccb->cgdl.periph_name,
302 			ccb->cgdl.unit_number,
303 			ccb->cgdl.generation,
304 			ccb->cgdl.index,
305 			status);
306 
307 		/*
308 		 * If the list has changed, we need to start over from the
309 		 * beginning.
310 		 */
311 		if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
312 			ccb->cgdl.index = 0;
313 	}
314 
315 	cam_freeccb(ccb);
316 
317 	return(error);
318 }
319 #endif /* MINIMALISTIC */
320 
321 static int
322 getdevtree(void)
323 {
324 	union ccb ccb;
325 	int bufsize, fd;
326 	unsigned int i;
327 	int need_close = 0;
328 	int error = 0;
329 	int skip_device = 0;
330 
331 	if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
332 		warn("couldn't open %s", XPT_DEVICE);
333 		return(1);
334 	}
335 
336 	bzero(&ccb, sizeof(union ccb));
337 
338 	ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
339 	ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
340 	ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
341 
342 	ccb.ccb_h.func_code = XPT_DEV_MATCH;
343 	bufsize = sizeof(struct dev_match_result) * 100;
344 	ccb.cdm.match_buf_len = bufsize;
345 	ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
346 	if (ccb.cdm.matches == NULL) {
347 		warnx("can't malloc memory for matches");
348 		close(fd);
349 		return(1);
350 	}
351 	ccb.cdm.num_matches = 0;
352 
353 	/*
354 	 * We fetch all nodes, since we display most of them in the default
355 	 * case, and all in the verbose case.
356 	 */
357 	ccb.cdm.num_patterns = 0;
358 	ccb.cdm.pattern_buf_len = 0;
359 
360 	/*
361 	 * We do the ioctl multiple times if necessary, in case there are
362 	 * more than 100 nodes in the EDT.
363 	 */
364 	do {
365 		if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
366 			warn("error sending CAMIOCOMMAND ioctl");
367 			error = 1;
368 			break;
369 		}
370 
371 		if ((ccb.ccb_h.status != CAM_REQ_CMP)
372 		 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
373 		    && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
374 			warnx("got CAM error %#x, CDM error %d\n",
375 			      ccb.ccb_h.status, ccb.cdm.status);
376 			error = 1;
377 			break;
378 		}
379 
380 		for (i = 0; i < ccb.cdm.num_matches; i++) {
381 			switch (ccb.cdm.matches[i].type) {
382 			case DEV_MATCH_BUS: {
383 				struct bus_match_result *bus_result;
384 
385 				/*
386 				 * Only print the bus information if the
387 				 * user turns on the verbose flag.
388 				 */
389 				if ((arglist & CAM_ARG_VERBOSE) == 0)
390 					break;
391 
392 				bus_result =
393 					&ccb.cdm.matches[i].result.bus_result;
394 
395 				if (need_close) {
396 					fprintf(stdout, ")\n");
397 					need_close = 0;
398 				}
399 
400 				fprintf(stdout, "scbus%d on %s%d bus %d:\n",
401 					bus_result->path_id,
402 					bus_result->dev_name,
403 					bus_result->unit_number,
404 					bus_result->bus_id);
405 				break;
406 			}
407 			case DEV_MATCH_DEVICE: {
408 				struct device_match_result *dev_result;
409 				char vendor[16], product[48], revision[16];
410 				char tmpstr[256];
411 
412 				dev_result =
413 				     &ccb.cdm.matches[i].result.device_result;
414 
415 				if ((dev_result->flags
416 				     & DEV_RESULT_UNCONFIGURED)
417 				 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
418 					skip_device = 1;
419 					break;
420 				} else
421 					skip_device = 0;
422 
423 				if (dev_result->protocol == PROTO_SCSI) {
424 				    cam_strvis(vendor, dev_result->inq_data.vendor,
425 					   sizeof(dev_result->inq_data.vendor),
426 					   sizeof(vendor));
427 				    cam_strvis(product,
428 					   dev_result->inq_data.product,
429 					   sizeof(dev_result->inq_data.product),
430 					   sizeof(product));
431 				    cam_strvis(revision,
432 					   dev_result->inq_data.revision,
433 					  sizeof(dev_result->inq_data.revision),
434 					   sizeof(revision));
435 				    sprintf(tmpstr, "<%s %s %s>", vendor, product,
436 					revision);
437 				} else if (dev_result->protocol == PROTO_ATA ||
438 				    dev_result->protocol == PROTO_SATAPM) {
439 				    cam_strvis(product,
440 					   dev_result->ident_data.model,
441 					   sizeof(dev_result->ident_data.model),
442 					   sizeof(product));
443 				    cam_strvis(revision,
444 					   dev_result->ident_data.revision,
445 					  sizeof(dev_result->ident_data.revision),
446 					   sizeof(revision));
447 				    sprintf(tmpstr, "<%s %s>", product,
448 					revision);
449 				} else {
450 				    sprintf(tmpstr, "<>");
451 				}
452 				if (need_close) {
453 					fprintf(stdout, ")\n");
454 					need_close = 0;
455 				}
456 
457 				fprintf(stdout, "%-33s  at scbus%d "
458 					"target %d lun %d (",
459 					tmpstr,
460 					dev_result->path_id,
461 					dev_result->target_id,
462 					dev_result->target_lun);
463 
464 				need_close = 1;
465 
466 				break;
467 			}
468 			case DEV_MATCH_PERIPH: {
469 				struct periph_match_result *periph_result;
470 
471 				periph_result =
472 				      &ccb.cdm.matches[i].result.periph_result;
473 
474 				if (skip_device != 0)
475 					break;
476 
477 				if (need_close > 1)
478 					fprintf(stdout, ",");
479 
480 				fprintf(stdout, "%s%d",
481 					periph_result->periph_name,
482 					periph_result->unit_number);
483 
484 				need_close++;
485 				break;
486 			}
487 			default:
488 				fprintf(stdout, "unknown match type\n");
489 				break;
490 			}
491 		}
492 
493 	} while ((ccb.ccb_h.status == CAM_REQ_CMP)
494 		&& (ccb.cdm.status == CAM_DEV_MATCH_MORE));
495 
496 	if (need_close)
497 		fprintf(stdout, ")\n");
498 
499 	close(fd);
500 
501 	return(error);
502 }
503 
504 #ifndef MINIMALISTIC
505 static int
506 testunitready(struct cam_device *device, int retry_count, int timeout,
507 	      int quiet)
508 {
509 	int error = 0;
510 	union ccb *ccb;
511 
512 	ccb = cam_getccb(device);
513 
514 	scsi_test_unit_ready(&ccb->csio,
515 			     /* retries */ retry_count,
516 			     /* cbfcnp */ NULL,
517 			     /* tag_action */ MSG_SIMPLE_Q_TAG,
518 			     /* sense_len */ SSD_FULL_SIZE,
519 			     /* timeout */ timeout ? timeout : 5000);
520 
521 	/* Disable freezing the device queue */
522 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
523 
524 	if (arglist & CAM_ARG_ERR_RECOVER)
525 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
526 
527 	if (cam_send_ccb(device, ccb) < 0) {
528 		if (quiet == 0)
529 			perror("error sending test unit ready");
530 
531 		if (arglist & CAM_ARG_VERBOSE) {
532 			cam_error_print(device, ccb, CAM_ESF_ALL,
533 					CAM_EPF_ALL, stderr);
534 		}
535 
536 		cam_freeccb(ccb);
537 		return(1);
538 	}
539 
540 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
541 		if (quiet == 0)
542 			fprintf(stdout, "Unit is ready\n");
543 	} else {
544 		if (quiet == 0)
545 			fprintf(stdout, "Unit is not ready\n");
546 		error = 1;
547 
548 		if (arglist & CAM_ARG_VERBOSE) {
549 			cam_error_print(device, ccb, CAM_ESF_ALL,
550 					CAM_EPF_ALL, stderr);
551 		}
552 	}
553 
554 	cam_freeccb(ccb);
555 
556 	return(error);
557 }
558 
559 static int
560 scsistart(struct cam_device *device, int startstop, int loadeject,
561 	  int retry_count, int timeout)
562 {
563 	union ccb *ccb;
564 	int error = 0;
565 
566 	ccb = cam_getccb(device);
567 
568 	/*
569 	 * If we're stopping, send an ordered tag so the drive in question
570 	 * will finish any previously queued writes before stopping.  If
571 	 * the device isn't capable of tagged queueing, or if tagged
572 	 * queueing is turned off, the tag action is a no-op.
573 	 */
574 	scsi_start_stop(&ccb->csio,
575 			/* retries */ retry_count,
576 			/* cbfcnp */ NULL,
577 			/* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
578 						     MSG_ORDERED_Q_TAG,
579 			/* start/stop */ startstop,
580 			/* load_eject */ loadeject,
581 			/* immediate */ 0,
582 			/* sense_len */ SSD_FULL_SIZE,
583 			/* timeout */ timeout ? timeout : 120000);
584 
585 	/* Disable freezing the device queue */
586 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
587 
588 	if (arglist & CAM_ARG_ERR_RECOVER)
589 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
590 
591 	if (cam_send_ccb(device, ccb) < 0) {
592 		perror("error sending start unit");
593 
594 		if (arglist & CAM_ARG_VERBOSE) {
595 			cam_error_print(device, ccb, CAM_ESF_ALL,
596 					CAM_EPF_ALL, stderr);
597 		}
598 
599 		cam_freeccb(ccb);
600 		return(1);
601 	}
602 
603 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
604 		if (startstop) {
605 			fprintf(stdout, "Unit started successfully");
606 			if (loadeject)
607 				fprintf(stdout,", Media loaded\n");
608 			else
609 				fprintf(stdout,"\n");
610 		} else {
611 			fprintf(stdout, "Unit stopped successfully");
612 			if (loadeject)
613 				fprintf(stdout, ", Media ejected\n");
614 			else
615 				fprintf(stdout, "\n");
616 		}
617 	else {
618 		error = 1;
619 		if (startstop)
620 			fprintf(stdout,
621 				"Error received from start unit command\n");
622 		else
623 			fprintf(stdout,
624 				"Error received from stop unit command\n");
625 
626 		if (arglist & CAM_ARG_VERBOSE) {
627 			cam_error_print(device, ccb, CAM_ESF_ALL,
628 					CAM_EPF_ALL, stderr);
629 		}
630 	}
631 
632 	cam_freeccb(ccb);
633 
634 	return(error);
635 }
636 
637 static int
638 scsidoinquiry(struct cam_device *device, int argc, char **argv,
639 	      char *combinedopt, int retry_count, int timeout)
640 {
641 	int c;
642 	int error = 0;
643 
644 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
645 		switch(c) {
646 		case 'D':
647 			arglist |= CAM_ARG_GET_STDINQ;
648 			break;
649 		case 'R':
650 			arglist |= CAM_ARG_GET_XFERRATE;
651 			break;
652 		case 'S':
653 			arglist |= CAM_ARG_GET_SERIAL;
654 			break;
655 		default:
656 			break;
657 		}
658 	}
659 
660 	/*
661 	 * If the user didn't specify any inquiry options, he wants all of
662 	 * them.
663 	 */
664 	if ((arglist & CAM_ARG_INQ_MASK) == 0)
665 		arglist |= CAM_ARG_INQ_MASK;
666 
667 	if (arglist & CAM_ARG_GET_STDINQ)
668 		error = scsiinquiry(device, retry_count, timeout);
669 
670 	if (error != 0)
671 		return(error);
672 
673 	if (arglist & CAM_ARG_GET_SERIAL)
674 		scsiserial(device, retry_count, timeout);
675 
676 	if (error != 0)
677 		return(error);
678 
679 	if (arglist & CAM_ARG_GET_XFERRATE)
680 		error = camxferrate(device);
681 
682 	return(error);
683 }
684 
685 static int
686 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
687 {
688 	union ccb *ccb;
689 	struct scsi_inquiry_data *inq_buf;
690 	int error = 0;
691 
692 	ccb = cam_getccb(device);
693 
694 	if (ccb == NULL) {
695 		warnx("couldn't allocate CCB");
696 		return(1);
697 	}
698 
699 	/* cam_getccb cleans up the header, caller has to zero the payload */
700 	bzero(&(&ccb->ccb_h)[1],
701 	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
702 
703 	inq_buf = (struct scsi_inquiry_data *)malloc(
704 		sizeof(struct scsi_inquiry_data));
705 
706 	if (inq_buf == NULL) {
707 		cam_freeccb(ccb);
708 		warnx("can't malloc memory for inquiry\n");
709 		return(1);
710 	}
711 	bzero(inq_buf, sizeof(*inq_buf));
712 
713 	/*
714 	 * Note that although the size of the inquiry buffer is the full
715 	 * 256 bytes specified in the SCSI spec, we only tell the device
716 	 * that we have allocated SHORT_INQUIRY_LENGTH bytes.  There are
717 	 * two reasons for this:
718 	 *
719 	 *  - The SCSI spec says that when a length field is only 1 byte,
720 	 *    a value of 0 will be interpreted as 256.  Therefore
721 	 *    scsi_inquiry() will convert an inq_len (which is passed in as
722 	 *    a u_int32_t, but the field in the CDB is only 1 byte) of 256
723 	 *    to 0.  Evidently, very few devices meet the spec in that
724 	 *    regard.  Some devices, like many Seagate disks, take the 0 as
725 	 *    0, and don't return any data.  One Pioneer DVD-R drive
726 	 *    returns more data than the command asked for.
727 	 *
728 	 *    So, since there are numerous devices that just don't work
729 	 *    right with the full inquiry size, we don't send the full size.
730 	 *
731 	 *  - The second reason not to use the full inquiry data length is
732 	 *    that we don't need it here.  The only reason we issue a
733 	 *    standard inquiry is to get the vendor name, device name,
734 	 *    and revision so scsi_print_inquiry() can print them.
735 	 *
736 	 * If, at some point in the future, more inquiry data is needed for
737 	 * some reason, this code should use a procedure similar to the
738 	 * probe code.  i.e., issue a short inquiry, and determine from
739 	 * the additional length passed back from the device how much
740 	 * inquiry data the device supports.  Once the amount the device
741 	 * supports is determined, issue an inquiry for that amount and no
742 	 * more.
743 	 *
744 	 * KDM, 2/18/2000
745 	 */
746 	scsi_inquiry(&ccb->csio,
747 		     /* retries */ retry_count,
748 		     /* cbfcnp */ NULL,
749 		     /* tag_action */ MSG_SIMPLE_Q_TAG,
750 		     /* inq_buf */ (u_int8_t *)inq_buf,
751 		     /* inq_len */ SHORT_INQUIRY_LENGTH,
752 		     /* evpd */ 0,
753 		     /* page_code */ 0,
754 		     /* sense_len */ SSD_FULL_SIZE,
755 		     /* timeout */ timeout ? timeout : 5000);
756 
757 	/* Disable freezing the device queue */
758 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
759 
760 	if (arglist & CAM_ARG_ERR_RECOVER)
761 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
762 
763 	if (cam_send_ccb(device, ccb) < 0) {
764 		perror("error sending SCSI inquiry");
765 
766 		if (arglist & CAM_ARG_VERBOSE) {
767 			cam_error_print(device, ccb, CAM_ESF_ALL,
768 					CAM_EPF_ALL, stderr);
769 		}
770 
771 		cam_freeccb(ccb);
772 		return(1);
773 	}
774 
775 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
776 		error = 1;
777 
778 		if (arglist & CAM_ARG_VERBOSE) {
779 			cam_error_print(device, ccb, CAM_ESF_ALL,
780 					CAM_EPF_ALL, stderr);
781 		}
782 	}
783 
784 	cam_freeccb(ccb);
785 
786 	if (error != 0) {
787 		free(inq_buf);
788 		return(error);
789 	}
790 
791 	fprintf(stdout, "%s%d: ", device->device_name,
792 		device->dev_unit_num);
793 	scsi_print_inquiry(inq_buf);
794 
795 	free(inq_buf);
796 
797 	return(0);
798 }
799 
800 static int
801 scsiserial(struct cam_device *device, int retry_count, int timeout)
802 {
803 	union ccb *ccb;
804 	struct scsi_vpd_unit_serial_number *serial_buf;
805 	char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
806 	int error = 0;
807 
808 	ccb = cam_getccb(device);
809 
810 	if (ccb == NULL) {
811 		warnx("couldn't allocate CCB");
812 		return(1);
813 	}
814 
815 	/* cam_getccb cleans up the header, caller has to zero the payload */
816 	bzero(&(&ccb->ccb_h)[1],
817 	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
818 
819 	serial_buf = (struct scsi_vpd_unit_serial_number *)
820 		malloc(sizeof(*serial_buf));
821 
822 	if (serial_buf == NULL) {
823 		cam_freeccb(ccb);
824 		warnx("can't malloc memory for serial number");
825 		return(1);
826 	}
827 
828 	scsi_inquiry(&ccb->csio,
829 		     /*retries*/ retry_count,
830 		     /*cbfcnp*/ NULL,
831 		     /* tag_action */ MSG_SIMPLE_Q_TAG,
832 		     /* inq_buf */ (u_int8_t *)serial_buf,
833 		     /* inq_len */ sizeof(*serial_buf),
834 		     /* evpd */ 1,
835 		     /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
836 		     /* sense_len */ SSD_FULL_SIZE,
837 		     /* timeout */ timeout ? timeout : 5000);
838 
839 	/* Disable freezing the device queue */
840 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
841 
842 	if (arglist & CAM_ARG_ERR_RECOVER)
843 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
844 
845 	if (cam_send_ccb(device, ccb) < 0) {
846 		warn("error getting serial number");
847 
848 		if (arglist & CAM_ARG_VERBOSE) {
849 			cam_error_print(device, ccb, CAM_ESF_ALL,
850 					CAM_EPF_ALL, stderr);
851 		}
852 
853 		cam_freeccb(ccb);
854 		free(serial_buf);
855 		return(1);
856 	}
857 
858 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
859 		error = 1;
860 
861 		if (arglist & CAM_ARG_VERBOSE) {
862 			cam_error_print(device, ccb, CAM_ESF_ALL,
863 					CAM_EPF_ALL, stderr);
864 		}
865 	}
866 
867 	cam_freeccb(ccb);
868 
869 	if (error != 0) {
870 		free(serial_buf);
871 		return(error);
872 	}
873 
874 	bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
875 	serial_num[serial_buf->length] = '\0';
876 
877 	if ((arglist & CAM_ARG_GET_STDINQ)
878 	 || (arglist & CAM_ARG_GET_XFERRATE))
879 		fprintf(stdout, "%s%d: Serial Number ",
880 			device->device_name, device->dev_unit_num);
881 
882 	fprintf(stdout, "%.60s\n", serial_num);
883 
884 	free(serial_buf);
885 
886 	return(0);
887 }
888 
889 static int
890 camxferrate(struct cam_device *device)
891 {
892 	struct ccb_pathinq cpi;
893 	u_int32_t freq = 0;
894 	u_int32_t speed = 0;
895 	union ccb *ccb;
896 	u_int mb;
897 	int retval = 0;
898 
899 	if ((retval = get_cpi(device, &cpi)) != 0)
900 		return (1);
901 
902 	ccb = cam_getccb(device);
903 
904 	if (ccb == NULL) {
905 		warnx("couldn't allocate CCB");
906 		return(1);
907 	}
908 
909 	bzero(&(&ccb->ccb_h)[1],
910 	      sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
911 
912 	ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
913 	ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
914 
915 	if (((retval = cam_send_ccb(device, ccb)) < 0)
916 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
917 		const char error_string[] = "error getting transfer settings";
918 
919 		if (retval < 0)
920 			warn(error_string);
921 		else
922 			warnx(error_string);
923 
924 		if (arglist & CAM_ARG_VERBOSE)
925 			cam_error_print(device, ccb, CAM_ESF_ALL,
926 					CAM_EPF_ALL, stderr);
927 
928 		retval = 1;
929 
930 		goto xferrate_bailout;
931 
932 	}
933 
934 	speed = cpi.base_transfer_speed;
935 	freq = 0;
936 	if (ccb->cts.transport == XPORT_SPI) {
937 		struct ccb_trans_settings_spi *spi =
938 		    &ccb->cts.xport_specific.spi;
939 
940 		if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
941 			freq = scsi_calc_syncsrate(spi->sync_period);
942 			speed = freq;
943 		}
944 		if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
945 			speed *= (0x01 << spi->bus_width);
946 		}
947 	} else if (ccb->cts.transport == XPORT_FC) {
948 		struct ccb_trans_settings_fc *fc =
949 		    &ccb->cts.xport_specific.fc;
950 
951 		if (fc->valid & CTS_FC_VALID_SPEED)
952 			speed = fc->bitrate;
953 	} else if (ccb->cts.transport == XPORT_SAS) {
954 		struct ccb_trans_settings_sas *sas =
955 		    &ccb->cts.xport_specific.sas;
956 
957 		if (sas->valid & CTS_SAS_VALID_SPEED)
958 			speed = sas->bitrate;
959 	} else if (ccb->cts.transport == XPORT_ATA) {
960 		struct ccb_trans_settings_ata *ata =
961 		    &ccb->cts.xport_specific.ata;
962 
963 		if (ata->valid & CTS_ATA_VALID_MODE)
964 			speed = ata_mode2speed(ata->mode);
965 	} else if (ccb->cts.transport == XPORT_SATA) {
966 		struct	ccb_trans_settings_sata *sata =
967 		    &ccb->cts.xport_specific.sata;
968 
969 		if (sata->valid & CTS_SATA_VALID_REVISION)
970 			speed = ata_revision2speed(sata->revision);
971 	}
972 
973 	mb = speed / 1000;
974 	if (mb > 0) {
975 		fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
976 			device->device_name, device->dev_unit_num,
977 			mb, speed % 1000);
978 	} else {
979 		fprintf(stdout, "%s%d: %dKB/s transfers",
980 			device->device_name, device->dev_unit_num,
981 			speed);
982 	}
983 
984 	if (ccb->cts.transport == XPORT_SPI) {
985 		struct ccb_trans_settings_spi *spi =
986 		    &ccb->cts.xport_specific.spi;
987 
988 		if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
989 		 && (spi->sync_offset != 0))
990 			fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
991 				freq % 1000, spi->sync_offset);
992 
993 		if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
994 		 && (spi->bus_width > 0)) {
995 			if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
996 			 && (spi->sync_offset != 0)) {
997 				fprintf(stdout, ", ");
998 			} else {
999 				fprintf(stdout, " (");
1000 			}
1001 			fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1002 		} else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1003 		 && (spi->sync_offset != 0)) {
1004 			fprintf(stdout, ")");
1005 		}
1006 	} else if (ccb->cts.transport == XPORT_ATA) {
1007 		struct ccb_trans_settings_ata *ata =
1008 		    &ccb->cts.xport_specific.ata;
1009 
1010 		printf(" (");
1011 		if (ata->valid & CTS_ATA_VALID_MODE)
1012 			printf("%s, ", ata_mode2string(ata->mode));
1013 		if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0)
1014 			printf("ATAPI %dbytes, ", ata->atapi);
1015 		if (ata->valid & CTS_ATA_VALID_BYTECOUNT)
1016 			printf("PIO %dbytes", ata->bytecount);
1017 		printf(")");
1018 	} else if (ccb->cts.transport == XPORT_SATA) {
1019 		struct ccb_trans_settings_sata *sata =
1020 		    &ccb->cts.xport_specific.sata;
1021 
1022 		printf(" (");
1023 		if (sata->valid & CTS_SATA_VALID_REVISION)
1024 			printf("SATA %d.x, ", sata->revision);
1025 		else
1026 			printf("SATA, ");
1027 		if (sata->valid & CTS_SATA_VALID_MODE)
1028 			printf("%s, ", ata_mode2string(sata->mode));
1029 		if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1030 			printf("ATAPI %dbytes, ", sata->atapi);
1031 		if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1032 			printf("PIO %dbytes", sata->bytecount);
1033 		printf(")");
1034 	}
1035 
1036 	if (ccb->cts.protocol == PROTO_SCSI) {
1037 		struct ccb_trans_settings_scsi *scsi =
1038 		    &ccb->cts.proto_specific.scsi;
1039 		if (scsi->valid & CTS_SCSI_VALID_TQ) {
1040 			if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1041 				fprintf(stdout, ", Command Queueing Enabled");
1042 			}
1043 		}
1044 	}
1045 
1046         fprintf(stdout, "\n");
1047 
1048 xferrate_bailout:
1049 
1050 	cam_freeccb(ccb);
1051 
1052 	return(retval);
1053 }
1054 
1055 static void
1056 atacapprint(struct ata_params *parm)
1057 {
1058 	u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1059 				((u_int32_t)parm->lba_size_2 << 16);
1060 
1061 	u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1062 				((u_int64_t)parm->lba_size48_2 << 16) |
1063 				((u_int64_t)parm->lba_size48_3 << 32) |
1064 				((u_int64_t)parm->lba_size48_4 << 48);
1065 
1066 	printf("\n");
1067 	printf("protocol              ");
1068 	printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1069 	if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1070 		if (parm->satacapabilities & ATA_SATA_GEN3)
1071 			printf(" SATA 3.x\n");
1072 		else if (parm->satacapabilities & ATA_SATA_GEN2)
1073 			printf(" SATA 2.x\n");
1074 		else if (parm->satacapabilities & ATA_SATA_GEN1)
1075 			printf(" SATA 1.x\n");
1076 		else
1077 			printf(" SATA\n");
1078 	}
1079 	else
1080 		printf("\n");
1081 	printf("device model          %.40s\n", parm->model);
1082 	printf("firmware revision     %.8s\n", parm->revision);
1083 	printf("serial number         %.20s\n", parm->serial);
1084 	if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1085 		printf("WWN                   %02x%02x%02x%02x\n",
1086 		    parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1087 	}
1088 	if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1089 		printf("media serial number   %.30s\n",
1090 		    parm->media_serial);
1091 	}
1092 
1093 	printf("cylinders             %d\n", parm->cylinders);
1094 	printf("heads                 %d\n", parm->heads);
1095 	printf("sectors/track         %d\n", parm->sectors);
1096 	printf("sector size           logical %u, physical %lu, offset %lu\n",
1097 	    ata_logical_sector_size(parm),
1098 	    (unsigned long)ata_physical_sector_size(parm),
1099 	    (unsigned long)ata_logical_sector_offset(parm));
1100 
1101 	if (parm->config == ATA_PROTO_CFA ||
1102 	    (parm->support.command2 & ATA_SUPPORT_CFA))
1103 		printf("CFA supported\n");
1104 
1105 	printf("LBA%ssupported         ",
1106 		parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1107 	if (lbasize)
1108 		printf("%d sectors\n", lbasize);
1109 	else
1110 		printf("\n");
1111 
1112 	printf("LBA48%ssupported       ",
1113 		parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1114 	if (lbasize48)
1115 		printf("%ju sectors\n", (uintmax_t)lbasize48);
1116 	else
1117 		printf("\n");
1118 
1119 	printf("PIO supported         PIO");
1120 	switch (ata_max_pmode(parm)) {
1121 	case ATA_PIO4:
1122 		printf("4");
1123 		break;
1124 	case ATA_PIO3:
1125 		printf("3");
1126 		break;
1127 	case ATA_PIO2:
1128 		printf("2");
1129 		break;
1130 	case ATA_PIO1:
1131 		printf("1");
1132 		break;
1133 	default:
1134 		printf("0");
1135 	}
1136 	if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1137 		printf(" w/o IORDY");
1138 	printf("\n");
1139 
1140 	printf("DMA%ssupported         ",
1141 		parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1142 	if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1143 		if (parm->mwdmamodes & 0xff) {
1144 			printf("WDMA");
1145 			if (parm->mwdmamodes & 0x04)
1146 				printf("2");
1147 			else if (parm->mwdmamodes & 0x02)
1148 				printf("1");
1149 			else if (parm->mwdmamodes & 0x01)
1150 				printf("0");
1151 			printf(" ");
1152 		}
1153 		if ((parm->atavalid & ATA_FLAG_88) &&
1154 		    (parm->udmamodes & 0xff)) {
1155 			printf("UDMA");
1156 			if (parm->udmamodes & 0x40)
1157 				printf("6");
1158 			else if (parm->udmamodes & 0x20)
1159 				printf("5");
1160 			else if (parm->udmamodes & 0x10)
1161 				printf("4");
1162 			else if (parm->udmamodes & 0x08)
1163 				printf("3");
1164 			else if (parm->udmamodes & 0x04)
1165 				printf("2");
1166 			else if (parm->udmamodes & 0x02)
1167 				printf("1");
1168 			else if (parm->udmamodes & 0x01)
1169 				printf("0");
1170 			printf(" ");
1171 		}
1172 	}
1173 	printf("\n");
1174 
1175 	if (parm->media_rotation_rate == 1) {
1176 		printf("media RPM             non-rotating\n");
1177 	} else if (parm->media_rotation_rate >= 0x0401 &&
1178 	    parm->media_rotation_rate <= 0xFFFE) {
1179 		printf("media RPM             %d\n",
1180 			parm->media_rotation_rate);
1181 	}
1182 
1183 	printf("\nFeature                      "
1184 		"Support  Enable    Value           Vendor\n");
1185 	printf("read ahead                     %s	%s\n",
1186 		parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1187 		parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1188 	printf("write cache                    %s	%s\n",
1189 		parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1190 		parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1191 	printf("flush cache                    %s	%s\n",
1192 		parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1193 		parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1194 	printf("overlap                        %s\n",
1195 		parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1196 	printf("Tagged Command Queuing (TCQ)   %s	%s",
1197 		parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1198 		parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1199 		if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1200 			printf("	%d tags\n",
1201 			    ATA_QUEUE_LEN(parm->queue) + 1);
1202 		} else
1203 			printf("\n");
1204 	if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1205 		printf("Native Command Queuing (NCQ)   %s	",
1206 			parm->satacapabilities & ATA_SUPPORT_NCQ ?
1207 				"yes" : "no");
1208 		if (parm->satacapabilities & ATA_SUPPORT_NCQ) {
1209 			printf("	%d tags\n",
1210 			    ATA_QUEUE_LEN(parm->queue) + 1);
1211 		} else
1212 			printf("\n");
1213 	}
1214 	printf("SMART                          %s	%s\n",
1215 		parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1216 		parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1217 	printf("microcode download             %s	%s\n",
1218 		parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1219 		parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1220 	printf("security                       %s	%s\n",
1221 		parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1222 		parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1223 	printf("power management               %s	%s\n",
1224 		parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1225 		parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1226 	printf("advanced power management      %s	%s	%d/0x%02X\n",
1227 		parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1228 		parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1229 		parm->apm_value, parm->apm_value);
1230 	printf("automatic acoustic management  %s	%s	"
1231 		"%d/0x%02X	%d/0x%02X\n",
1232 		parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1233 		parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1234 		ATA_ACOUSTIC_CURRENT(parm->acoustic),
1235 		ATA_ACOUSTIC_CURRENT(parm->acoustic),
1236 		ATA_ACOUSTIC_VENDOR(parm->acoustic),
1237 		ATA_ACOUSTIC_VENDOR(parm->acoustic));
1238 	printf("media status notification      %s	%s\n",
1239 		parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1240 		parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1241 	printf("power-up in Standby            %s	%s\n",
1242 		parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1243 		parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1244 	printf("write-read-verify              %s	%s	%d/0x%x\n",
1245 		parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1246 		parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1247 		parm->wrv_mode, parm->wrv_mode);
1248 	printf("unload                         %s	%s\n",
1249 		parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1250 		parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1251 	printf("free-fall                      %s	%s\n",
1252 		parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1253 		parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1254 	printf("data set management (TRIM)     %s\n",
1255 		parm->support_dsm & ATA_SUPPORT_DSM_TRIM ? "yes" : "no");
1256 }
1257 
1258 
1259 static int
1260 ataidentify(struct cam_device *device, int retry_count, int timeout)
1261 {
1262 	union ccb *ccb;
1263 	struct ata_params *ident_buf;
1264 	struct ccb_getdev cgd;
1265 	u_int i, error = 0;
1266 	int16_t *ptr;
1267 
1268 	if (get_cgd(device, &cgd) != 0) {
1269 		warnx("couldn't get CGD");
1270 		return(1);
1271 	}
1272 	ccb = cam_getccb(device);
1273 
1274 	if (ccb == NULL) {
1275 		warnx("couldn't allocate CCB");
1276 		return(1);
1277 	}
1278 
1279 	/* cam_getccb cleans up the header, caller has to zero the payload */
1280 	bzero(&(&ccb->ccb_h)[1],
1281 	      sizeof(struct ccb_ataio) - sizeof(struct ccb_hdr));
1282 
1283 	ptr = (uint16_t *)malloc(sizeof(struct ata_params));
1284 
1285 	if (ptr == NULL) {
1286 		cam_freeccb(ccb);
1287 		warnx("can't malloc memory for identify\n");
1288 		return(1);
1289 	}
1290 	bzero(ptr, sizeof(struct ata_params));
1291 
1292 	cam_fill_ataio(&ccb->ataio,
1293 		      retry_count,
1294 		      NULL,
1295 		      /*flags*/CAM_DIR_IN,
1296 		      MSG_SIMPLE_Q_TAG,
1297 		      /*data_ptr*/(u_int8_t *)ptr,
1298 		      /*dxfer_len*/sizeof(struct ata_params),
1299 		      timeout ? timeout : 30 * 1000);
1300 	if (cgd.protocol == PROTO_ATA)
1301 		ata_28bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
1302 	else
1303 		ata_28bit_cmd(&ccb->ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
1304 
1305 	/* Disable freezing the device queue */
1306 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1307 
1308 	if (arglist & CAM_ARG_ERR_RECOVER)
1309 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1310 
1311 	if (cam_send_ccb(device, ccb) < 0) {
1312 		perror("error sending ATA identify");
1313 
1314 		if (arglist & CAM_ARG_VERBOSE) {
1315 			cam_error_print(device, ccb, CAM_ESF_ALL,
1316 					CAM_EPF_ALL, stderr);
1317 		}
1318 
1319 		free(ptr);
1320 		cam_freeccb(ccb);
1321 		return(1);
1322 	}
1323 
1324 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1325 		error = 1;
1326 
1327 		if (arglist & CAM_ARG_VERBOSE) {
1328 			cam_error_print(device, ccb, CAM_ESF_ALL,
1329 					CAM_EPF_ALL, stderr);
1330 		}
1331 	}
1332 
1333 	cam_freeccb(ccb);
1334 
1335 	if (error != 0) {
1336 		free(ptr);
1337 		return(error);
1338 	}
1339 
1340 	for (i = 0; i < sizeof(struct ata_params) / 2; i++)
1341 		ptr[i] = le16toh(ptr[i]);
1342 	if (arglist & CAM_ARG_VERBOSE) {
1343 		fprintf(stdout, "%s%d: Raw identify data:\n",
1344 		    device->device_name, device->dev_unit_num);
1345 		for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
1346 			if ((i % 8) == 0)
1347 			    fprintf(stdout, " %3d: ", i);
1348 			fprintf(stdout, "%04x ", (uint16_t)ptr[i]);
1349 			if ((i % 8) == 7)
1350 			    fprintf(stdout, "\n");
1351 		}
1352 	}
1353 	ident_buf = (struct ata_params *)ptr;
1354 	if (strncmp(ident_buf->model, "FX", 2) &&
1355 	    strncmp(ident_buf->model, "NEC", 3) &&
1356 	    strncmp(ident_buf->model, "Pioneer", 7) &&
1357 	    strncmp(ident_buf->model, "SHARP", 5)) {
1358 		ata_bswap(ident_buf->model, sizeof(ident_buf->model));
1359 		ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
1360 		ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
1361 		ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1362 	}
1363 	ata_btrim(ident_buf->model, sizeof(ident_buf->model));
1364 	ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
1365 	ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
1366 	ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
1367 	ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
1368 	ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
1369 	ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1370 	ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
1371 	    sizeof(ident_buf->media_serial));
1372 
1373 	fprintf(stdout, "%s%d: ", device->device_name,
1374 		device->dev_unit_num);
1375 	ata_print_ident(ident_buf);
1376 	camxferrate(device);
1377 	atacapprint(ident_buf);
1378 
1379 	free(ident_buf);
1380 
1381 	return(0);
1382 }
1383 #endif /* MINIMALISTIC */
1384 
1385 /*
1386  * Parse out a bus, or a bus, target and lun in the following
1387  * format:
1388  * bus
1389  * bus:target
1390  * bus:target:lun
1391  *
1392  * Returns the number of parsed components, or 0.
1393  */
1394 static int
1395 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
1396 {
1397 	char *tmpstr;
1398 	int convs = 0;
1399 
1400 	while (isspace(*tstr) && (*tstr != '\0'))
1401 		tstr++;
1402 
1403 	tmpstr = (char *)strtok(tstr, ":");
1404 	if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1405 		*bus = strtol(tmpstr, NULL, 0);
1406 		*arglst |= CAM_ARG_BUS;
1407 		convs++;
1408 		tmpstr = (char *)strtok(NULL, ":");
1409 		if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1410 			*target = strtol(tmpstr, NULL, 0);
1411 			*arglst |= CAM_ARG_TARGET;
1412 			convs++;
1413 			tmpstr = (char *)strtok(NULL, ":");
1414 			if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1415 				*lun = strtol(tmpstr, NULL, 0);
1416 				*arglst |= CAM_ARG_LUN;
1417 				convs++;
1418 			}
1419 		}
1420 	}
1421 
1422 	return convs;
1423 }
1424 
1425 static int
1426 dorescan_or_reset(int argc, char **argv, int rescan)
1427 {
1428 	static const char must[] =
1429 		"you must specify \"all\", a bus, or a bus:target:lun to %s";
1430 	int rv, error = 0;
1431 	int bus = -1, target = -1, lun = -1;
1432 	char *tstr;
1433 
1434 	if (argc < 3) {
1435 		warnx(must, rescan? "rescan" : "reset");
1436 		return(1);
1437 	}
1438 
1439 	tstr = argv[optind];
1440 	while (isspace(*tstr) && (*tstr != '\0'))
1441 		tstr++;
1442 	if (strncasecmp(tstr, "all", strlen("all")) == 0)
1443 		arglist |= CAM_ARG_BUS;
1444 	else {
1445 		rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
1446 		if (rv != 1 && rv != 3) {
1447 			warnx(must, rescan? "rescan" : "reset");
1448 			return(1);
1449 		}
1450 	}
1451 
1452 	if ((arglist & CAM_ARG_BUS)
1453 	    && (arglist & CAM_ARG_TARGET)
1454 	    && (arglist & CAM_ARG_LUN))
1455 		error = scanlun_or_reset_dev(bus, target, lun, rescan);
1456 	else
1457 		error = rescan_or_reset_bus(bus, rescan);
1458 
1459 	return(error);
1460 }
1461 
1462 static int
1463 rescan_or_reset_bus(int bus, int rescan)
1464 {
1465 	union ccb ccb, matchccb;
1466 	int fd, retval;
1467 	int bufsize;
1468 
1469 	retval = 0;
1470 
1471 	if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1472 		warnx("error opening transport layer device %s", XPT_DEVICE);
1473 		warn("%s", XPT_DEVICE);
1474 		return(1);
1475 	}
1476 
1477 	if (bus != -1) {
1478 		ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
1479 		ccb.ccb_h.path_id = bus;
1480 		ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1481 		ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1482 		ccb.crcn.flags = CAM_FLAG_NONE;
1483 
1484 		/* run this at a low priority */
1485 		ccb.ccb_h.pinfo.priority = 5;
1486 
1487 		if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1488 			warn("CAMIOCOMMAND ioctl failed");
1489 			close(fd);
1490 			return(1);
1491 		}
1492 
1493 		if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1494 			fprintf(stdout, "%s of bus %d was successful\n",
1495 			    rescan ? "Re-scan" : "Reset", bus);
1496 		} else {
1497 			fprintf(stdout, "%s of bus %d returned error %#x\n",
1498 				rescan ? "Re-scan" : "Reset", bus,
1499 				ccb.ccb_h.status & CAM_STATUS_MASK);
1500 			retval = 1;
1501 		}
1502 
1503 		close(fd);
1504 		return(retval);
1505 
1506 	}
1507 
1508 
1509 	/*
1510 	 * The right way to handle this is to modify the xpt so that it can
1511 	 * handle a wildcarded bus in a rescan or reset CCB.  At the moment
1512 	 * that isn't implemented, so instead we enumerate the busses and
1513 	 * send the rescan or reset to those busses in the case where the
1514 	 * given bus is -1 (wildcard).  We don't send a rescan or reset
1515 	 * to the xpt bus; sending a rescan to the xpt bus is effectively a
1516 	 * no-op, sending a rescan to the xpt bus would result in a status of
1517 	 * CAM_REQ_INVALID.
1518 	 */
1519 	bzero(&(&matchccb.ccb_h)[1],
1520 	      sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
1521 	matchccb.ccb_h.func_code = XPT_DEV_MATCH;
1522 	bufsize = sizeof(struct dev_match_result) * 20;
1523 	matchccb.cdm.match_buf_len = bufsize;
1524 	matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
1525 	if (matchccb.cdm.matches == NULL) {
1526 		warnx("can't malloc memory for matches");
1527 		retval = 1;
1528 		goto bailout;
1529 	}
1530 	matchccb.cdm.num_matches = 0;
1531 
1532 	matchccb.cdm.num_patterns = 1;
1533 	matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
1534 
1535 	matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
1536 		matchccb.cdm.pattern_buf_len);
1537 	if (matchccb.cdm.patterns == NULL) {
1538 		warnx("can't malloc memory for patterns");
1539 		retval = 1;
1540 		goto bailout;
1541 	}
1542 	matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
1543 	matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
1544 
1545 	do {
1546 		unsigned int i;
1547 
1548 		if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
1549 			warn("CAMIOCOMMAND ioctl failed");
1550 			retval = 1;
1551 			goto bailout;
1552 		}
1553 
1554 		if ((matchccb.ccb_h.status != CAM_REQ_CMP)
1555 		 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
1556 		   && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
1557 			warnx("got CAM error %#x, CDM error %d\n",
1558 			      matchccb.ccb_h.status, matchccb.cdm.status);
1559 			retval = 1;
1560 			goto bailout;
1561 		}
1562 
1563 		for (i = 0; i < matchccb.cdm.num_matches; i++) {
1564 			struct bus_match_result *bus_result;
1565 
1566 			/* This shouldn't happen. */
1567 			if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
1568 				continue;
1569 
1570 			bus_result = &matchccb.cdm.matches[i].result.bus_result;
1571 
1572 			/*
1573 			 * We don't want to rescan or reset the xpt bus.
1574 			 * See above.
1575 			 */
1576 			if ((int)bus_result->path_id == -1)
1577 				continue;
1578 
1579 			ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
1580 						       XPT_RESET_BUS;
1581 			ccb.ccb_h.path_id = bus_result->path_id;
1582 			ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1583 			ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1584 			ccb.crcn.flags = CAM_FLAG_NONE;
1585 
1586 			/* run this at a low priority */
1587 			ccb.ccb_h.pinfo.priority = 5;
1588 
1589 			if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1590 				warn("CAMIOCOMMAND ioctl failed");
1591 				retval = 1;
1592 				goto bailout;
1593 			}
1594 
1595 			if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
1596 				fprintf(stdout, "%s of bus %d was successful\n",
1597 					rescan? "Re-scan" : "Reset",
1598 					bus_result->path_id);
1599 			} else {
1600 				/*
1601 				 * Don't bail out just yet, maybe the other
1602 				 * rescan or reset commands will complete
1603 				 * successfully.
1604 				 */
1605 				fprintf(stderr, "%s of bus %d returned error "
1606 					"%#x\n", rescan? "Re-scan" : "Reset",
1607 					bus_result->path_id,
1608 					ccb.ccb_h.status & CAM_STATUS_MASK);
1609 				retval = 1;
1610 			}
1611 		}
1612 	} while ((matchccb.ccb_h.status == CAM_REQ_CMP)
1613 		 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
1614 
1615 bailout:
1616 
1617 	if (fd != -1)
1618 		close(fd);
1619 
1620 	if (matchccb.cdm.patterns != NULL)
1621 		free(matchccb.cdm.patterns);
1622 	if (matchccb.cdm.matches != NULL)
1623 		free(matchccb.cdm.matches);
1624 
1625 	return(retval);
1626 }
1627 
1628 static int
1629 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
1630 {
1631 	union ccb ccb;
1632 	struct cam_device *device;
1633 	int fd;
1634 
1635 	device = NULL;
1636 
1637 	if (bus < 0) {
1638 		warnx("invalid bus number %d", bus);
1639 		return(1);
1640 	}
1641 
1642 	if (target < 0) {
1643 		warnx("invalid target number %d", target);
1644 		return(1);
1645 	}
1646 
1647 	if (lun < 0) {
1648 		warnx("invalid lun number %d", lun);
1649 		return(1);
1650 	}
1651 
1652 	fd = -1;
1653 
1654 	bzero(&ccb, sizeof(union ccb));
1655 
1656 	if (scan) {
1657 		if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1658 			warnx("error opening transport layer device %s\n",
1659 			    XPT_DEVICE);
1660 			warn("%s", XPT_DEVICE);
1661 			return(1);
1662 		}
1663 	} else {
1664 		device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
1665 		if (device == NULL) {
1666 			warnx("%s", cam_errbuf);
1667 			return(1);
1668 		}
1669 	}
1670 
1671 	ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
1672 	ccb.ccb_h.path_id = bus;
1673 	ccb.ccb_h.target_id = target;
1674 	ccb.ccb_h.target_lun = lun;
1675 	ccb.ccb_h.timeout = 5000;
1676 	ccb.crcn.flags = CAM_FLAG_NONE;
1677 
1678 	/* run this at a low priority */
1679 	ccb.ccb_h.pinfo.priority = 5;
1680 
1681 	if (scan) {
1682 		if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
1683 			warn("CAMIOCOMMAND ioctl failed");
1684 			close(fd);
1685 			return(1);
1686 		}
1687 	} else {
1688 		if (cam_send_ccb(device, &ccb) < 0) {
1689 			warn("error sending XPT_RESET_DEV CCB");
1690 			cam_close_device(device);
1691 			return(1);
1692 		}
1693 	}
1694 
1695 	if (scan)
1696 		close(fd);
1697 	else
1698 		cam_close_device(device);
1699 
1700 	/*
1701 	 * An error code of CAM_BDR_SENT is normal for a BDR request.
1702 	 */
1703 	if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
1704 	 || ((!scan)
1705 	  && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
1706 		fprintf(stdout, "%s of %d:%d:%d was successful\n",
1707 		    scan? "Re-scan" : "Reset", bus, target, lun);
1708 		return(0);
1709 	} else {
1710 		fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
1711 		    scan? "Re-scan" : "Reset", bus, target, lun,
1712 		    ccb.ccb_h.status & CAM_STATUS_MASK);
1713 		return(1);
1714 	}
1715 }
1716 
1717 #ifndef MINIMALISTIC
1718 static int
1719 readdefects(struct cam_device *device, int argc, char **argv,
1720 	    char *combinedopt, int retry_count, int timeout)
1721 {
1722 	union ccb *ccb = NULL;
1723 	struct scsi_read_defect_data_10 *rdd_cdb;
1724 	u_int8_t *defect_list = NULL;
1725 	u_int32_t dlist_length = 65000;
1726 	u_int32_t returned_length = 0;
1727 	u_int32_t num_returned = 0;
1728 	u_int8_t returned_format;
1729 	unsigned int i;
1730 	int c, error = 0;
1731 	int lists_specified = 0;
1732 
1733 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
1734 		switch(c){
1735 		case 'f':
1736 		{
1737 			char *tstr;
1738 			tstr = optarg;
1739 			while (isspace(*tstr) && (*tstr != '\0'))
1740 				tstr++;
1741 			if (strcmp(tstr, "block") == 0)
1742 				arglist |= CAM_ARG_FORMAT_BLOCK;
1743 			else if (strcmp(tstr, "bfi") == 0)
1744 				arglist |= CAM_ARG_FORMAT_BFI;
1745 			else if (strcmp(tstr, "phys") == 0)
1746 				arglist |= CAM_ARG_FORMAT_PHYS;
1747 			else {
1748 				error = 1;
1749 				warnx("invalid defect format %s", tstr);
1750 				goto defect_bailout;
1751 			}
1752 			break;
1753 		}
1754 		case 'G':
1755 			arglist |= CAM_ARG_GLIST;
1756 			break;
1757 		case 'P':
1758 			arglist |= CAM_ARG_PLIST;
1759 			break;
1760 		default:
1761 			break;
1762 		}
1763 	}
1764 
1765 	ccb = cam_getccb(device);
1766 
1767 	/*
1768 	 * Hopefully 65000 bytes is enough to hold the defect list.  If it
1769 	 * isn't, the disk is probably dead already.  We'd have to go with
1770 	 * 12 byte command (i.e. alloc_length is 32 bits instead of 16)
1771 	 * to hold them all.
1772 	 */
1773 	defect_list = malloc(dlist_length);
1774 	if (defect_list == NULL) {
1775 		warnx("can't malloc memory for defect list");
1776 		error = 1;
1777 		goto defect_bailout;
1778 	}
1779 
1780 	rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
1781 
1782 	/*
1783 	 * cam_getccb() zeros the CCB header only.  So we need to zero the
1784 	 * payload portion of the ccb.
1785 	 */
1786 	bzero(&(&ccb->ccb_h)[1],
1787 	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1788 
1789 	cam_fill_csio(&ccb->csio,
1790 		      /*retries*/ retry_count,
1791 		      /*cbfcnp*/ NULL,
1792 		      /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
1793 					      CAM_PASS_ERR_RECOVER : 0),
1794 		      /*tag_action*/ MSG_SIMPLE_Q_TAG,
1795 		      /*data_ptr*/ defect_list,
1796 		      /*dxfer_len*/ dlist_length,
1797 		      /*sense_len*/ SSD_FULL_SIZE,
1798 		      /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
1799 		      /*timeout*/ timeout ? timeout : 5000);
1800 
1801 	rdd_cdb->opcode = READ_DEFECT_DATA_10;
1802 	if (arglist & CAM_ARG_FORMAT_BLOCK)
1803 		rdd_cdb->format = SRDD10_BLOCK_FORMAT;
1804 	else if (arglist & CAM_ARG_FORMAT_BFI)
1805 		rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
1806 	else if (arglist & CAM_ARG_FORMAT_PHYS)
1807 		rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
1808 	else {
1809 		error = 1;
1810 		warnx("no defect list format specified");
1811 		goto defect_bailout;
1812 	}
1813 	if (arglist & CAM_ARG_PLIST) {
1814 		rdd_cdb->format |= SRDD10_PLIST;
1815 		lists_specified++;
1816 	}
1817 
1818 	if (arglist & CAM_ARG_GLIST) {
1819 		rdd_cdb->format |= SRDD10_GLIST;
1820 		lists_specified++;
1821 	}
1822 
1823 	scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
1824 
1825 	/* Disable freezing the device queue */
1826 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1827 
1828 	if (cam_send_ccb(device, ccb) < 0) {
1829 		perror("error reading defect list");
1830 
1831 		if (arglist & CAM_ARG_VERBOSE) {
1832 			cam_error_print(device, ccb, CAM_ESF_ALL,
1833 					CAM_EPF_ALL, stderr);
1834 		}
1835 
1836 		error = 1;
1837 		goto defect_bailout;
1838 	}
1839 
1840 	returned_length = scsi_2btoul(((struct
1841 		scsi_read_defect_data_hdr_10 *)defect_list)->length);
1842 
1843 	returned_format = ((struct scsi_read_defect_data_hdr_10 *)
1844 			defect_list)->format;
1845 
1846 	if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
1847 	 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
1848 	 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
1849 		struct scsi_sense_data *sense;
1850 		int error_code, sense_key, asc, ascq;
1851 
1852 		sense = &ccb->csio.sense_data;
1853 		scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq);
1854 
1855 		/*
1856 		 * According to the SCSI spec, if the disk doesn't support
1857 		 * the requested format, it will generally return a sense
1858 		 * key of RECOVERED ERROR, and an additional sense code
1859 		 * of "DEFECT LIST NOT FOUND".  So, we check for that, and
1860 		 * also check to make sure that the returned length is
1861 		 * greater than 0, and then print out whatever format the
1862 		 * disk gave us.
1863 		 */
1864 		if ((sense_key == SSD_KEY_RECOVERED_ERROR)
1865 		 && (asc == 0x1c) && (ascq == 0x00)
1866 		 && (returned_length > 0)) {
1867 			warnx("requested defect format not available");
1868 			switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
1869 			case SRDD10_BLOCK_FORMAT:
1870 				warnx("Device returned block format");
1871 				break;
1872 			case SRDD10_BYTES_FROM_INDEX_FORMAT:
1873 				warnx("Device returned bytes from index"
1874 				      " format");
1875 				break;
1876 			case SRDD10_PHYSICAL_SECTOR_FORMAT:
1877 				warnx("Device returned physical sector format");
1878 				break;
1879 			default:
1880 				error = 1;
1881 				warnx("Device returned unknown defect"
1882 				     " data format %#x", returned_format);
1883 				goto defect_bailout;
1884 				break; /* NOTREACHED */
1885 			}
1886 		} else {
1887 			error = 1;
1888 			warnx("Error returned from read defect data command");
1889 			if (arglist & CAM_ARG_VERBOSE)
1890 				cam_error_print(device, ccb, CAM_ESF_ALL,
1891 						CAM_EPF_ALL, stderr);
1892 			goto defect_bailout;
1893 		}
1894 	} else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1895 		error = 1;
1896 		warnx("Error returned from read defect data command");
1897 		if (arglist & CAM_ARG_VERBOSE)
1898 			cam_error_print(device, ccb, CAM_ESF_ALL,
1899 					CAM_EPF_ALL, stderr);
1900 		goto defect_bailout;
1901 	}
1902 
1903 	/*
1904 	 * XXX KDM  I should probably clean up the printout format for the
1905 	 * disk defects.
1906 	 */
1907 	switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
1908 		case SRDDH10_PHYSICAL_SECTOR_FORMAT:
1909 		{
1910 			struct scsi_defect_desc_phys_sector *dlist;
1911 
1912 			dlist = (struct scsi_defect_desc_phys_sector *)
1913 				(defect_list +
1914 				sizeof(struct scsi_read_defect_data_hdr_10));
1915 
1916 			num_returned = returned_length /
1917 				sizeof(struct scsi_defect_desc_phys_sector);
1918 
1919 			fprintf(stderr, "Got %d defect", num_returned);
1920 
1921 			if ((lists_specified == 0) || (num_returned == 0)) {
1922 				fprintf(stderr, "s.\n");
1923 				break;
1924 			} else if (num_returned == 1)
1925 				fprintf(stderr, ":\n");
1926 			else
1927 				fprintf(stderr, "s:\n");
1928 
1929 			for (i = 0; i < num_returned; i++) {
1930 				fprintf(stdout, "%d:%d:%d\n",
1931 					scsi_3btoul(dlist[i].cylinder),
1932 					dlist[i].head,
1933 					scsi_4btoul(dlist[i].sector));
1934 			}
1935 			break;
1936 		}
1937 		case SRDDH10_BYTES_FROM_INDEX_FORMAT:
1938 		{
1939 			struct scsi_defect_desc_bytes_from_index *dlist;
1940 
1941 			dlist = (struct scsi_defect_desc_bytes_from_index *)
1942 				(defect_list +
1943 				sizeof(struct scsi_read_defect_data_hdr_10));
1944 
1945 			num_returned = returned_length /
1946 			      sizeof(struct scsi_defect_desc_bytes_from_index);
1947 
1948 			fprintf(stderr, "Got %d defect", num_returned);
1949 
1950 			if ((lists_specified == 0) || (num_returned == 0)) {
1951 				fprintf(stderr, "s.\n");
1952 				break;
1953 			} else if (num_returned == 1)
1954 				fprintf(stderr, ":\n");
1955 			else
1956 				fprintf(stderr, "s:\n");
1957 
1958 			for (i = 0; i < num_returned; i++) {
1959 				fprintf(stdout, "%d:%d:%d\n",
1960 					scsi_3btoul(dlist[i].cylinder),
1961 					dlist[i].head,
1962 					scsi_4btoul(dlist[i].bytes_from_index));
1963 			}
1964 			break;
1965 		}
1966 		case SRDDH10_BLOCK_FORMAT:
1967 		{
1968 			struct scsi_defect_desc_block *dlist;
1969 
1970 			dlist = (struct scsi_defect_desc_block *)(defect_list +
1971 				sizeof(struct scsi_read_defect_data_hdr_10));
1972 
1973 			num_returned = returned_length /
1974 			      sizeof(struct scsi_defect_desc_block);
1975 
1976 			fprintf(stderr, "Got %d defect", num_returned);
1977 
1978 			if ((lists_specified == 0) || (num_returned == 0)) {
1979 				fprintf(stderr, "s.\n");
1980 				break;
1981 			} else if (num_returned == 1)
1982 				fprintf(stderr, ":\n");
1983 			else
1984 				fprintf(stderr, "s:\n");
1985 
1986 			for (i = 0; i < num_returned; i++)
1987 				fprintf(stdout, "%u\n",
1988 					scsi_4btoul(dlist[i].address));
1989 			break;
1990 		}
1991 		default:
1992 			fprintf(stderr, "Unknown defect format %d\n",
1993 				returned_format & SRDDH10_DLIST_FORMAT_MASK);
1994 			error = 1;
1995 			break;
1996 	}
1997 defect_bailout:
1998 
1999 	if (defect_list != NULL)
2000 		free(defect_list);
2001 
2002 	if (ccb != NULL)
2003 		cam_freeccb(ccb);
2004 
2005 	return(error);
2006 }
2007 #endif /* MINIMALISTIC */
2008 
2009 #if 0
2010 void
2011 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
2012 {
2013 	union ccb *ccb;
2014 
2015 	ccb = cam_getccb(device);
2016 
2017 	cam_freeccb(ccb);
2018 }
2019 #endif
2020 
2021 #ifndef MINIMALISTIC
2022 void
2023 mode_sense(struct cam_device *device, int mode_page, int page_control,
2024 	   int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
2025 {
2026 	union ccb *ccb;
2027 	int retval;
2028 
2029 	ccb = cam_getccb(device);
2030 
2031 	if (ccb == NULL)
2032 		errx(1, "mode_sense: couldn't allocate CCB");
2033 
2034 	bzero(&(&ccb->ccb_h)[1],
2035 	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2036 
2037 	scsi_mode_sense(&ccb->csio,
2038 			/* retries */ retry_count,
2039 			/* cbfcnp */ NULL,
2040 			/* tag_action */ MSG_SIMPLE_Q_TAG,
2041 			/* dbd */ dbd,
2042 			/* page_code */ page_control << 6,
2043 			/* page */ mode_page,
2044 			/* param_buf */ data,
2045 			/* param_len */ datalen,
2046 			/* sense_len */ SSD_FULL_SIZE,
2047 			/* timeout */ timeout ? timeout : 5000);
2048 
2049 	if (arglist & CAM_ARG_ERR_RECOVER)
2050 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2051 
2052 	/* Disable freezing the device queue */
2053 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2054 
2055 	if (((retval = cam_send_ccb(device, ccb)) < 0)
2056 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2057 		if (arglist & CAM_ARG_VERBOSE) {
2058 			cam_error_print(device, ccb, CAM_ESF_ALL,
2059 					CAM_EPF_ALL, stderr);
2060 		}
2061 		cam_freeccb(ccb);
2062 		cam_close_device(device);
2063 		if (retval < 0)
2064 			err(1, "error sending mode sense command");
2065 		else
2066 			errx(1, "error sending mode sense command");
2067 	}
2068 
2069 	cam_freeccb(ccb);
2070 }
2071 
2072 void
2073 mode_select(struct cam_device *device, int save_pages, int retry_count,
2074 	   int timeout, u_int8_t *data, int datalen)
2075 {
2076 	union ccb *ccb;
2077 	int retval;
2078 
2079 	ccb = cam_getccb(device);
2080 
2081 	if (ccb == NULL)
2082 		errx(1, "mode_select: couldn't allocate CCB");
2083 
2084 	bzero(&(&ccb->ccb_h)[1],
2085 	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2086 
2087 	scsi_mode_select(&ccb->csio,
2088 			 /* retries */ retry_count,
2089 			 /* cbfcnp */ NULL,
2090 			 /* tag_action */ MSG_SIMPLE_Q_TAG,
2091 			 /* scsi_page_fmt */ 1,
2092 			 /* save_pages */ save_pages,
2093 			 /* param_buf */ data,
2094 			 /* param_len */ datalen,
2095 			 /* sense_len */ SSD_FULL_SIZE,
2096 			 /* timeout */ timeout ? timeout : 5000);
2097 
2098 	if (arglist & CAM_ARG_ERR_RECOVER)
2099 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2100 
2101 	/* Disable freezing the device queue */
2102 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2103 
2104 	if (((retval = cam_send_ccb(device, ccb)) < 0)
2105 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2106 		if (arglist & CAM_ARG_VERBOSE) {
2107 			cam_error_print(device, ccb, CAM_ESF_ALL,
2108 					CAM_EPF_ALL, stderr);
2109 		}
2110 		cam_freeccb(ccb);
2111 		cam_close_device(device);
2112 
2113 		if (retval < 0)
2114 			err(1, "error sending mode select command");
2115 		else
2116 			errx(1, "error sending mode select command");
2117 
2118 	}
2119 
2120 	cam_freeccb(ccb);
2121 }
2122 
2123 void
2124 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
2125 	 int retry_count, int timeout)
2126 {
2127 	int c, mode_page = -1, page_control = 0;
2128 	int binary = 0, list = 0;
2129 
2130 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
2131 		switch(c) {
2132 		case 'b':
2133 			binary = 1;
2134 			break;
2135 		case 'd':
2136 			arglist |= CAM_ARG_DBD;
2137 			break;
2138 		case 'e':
2139 			arglist |= CAM_ARG_MODE_EDIT;
2140 			break;
2141 		case 'l':
2142 			list = 1;
2143 			break;
2144 		case 'm':
2145 			mode_page = strtol(optarg, NULL, 0);
2146 			if (mode_page < 0)
2147 				errx(1, "invalid mode page %d", mode_page);
2148 			break;
2149 		case 'P':
2150 			page_control = strtol(optarg, NULL, 0);
2151 			if ((page_control < 0) || (page_control > 3))
2152 				errx(1, "invalid page control field %d",
2153 				     page_control);
2154 			arglist |= CAM_ARG_PAGE_CNTL;
2155 			break;
2156 		default:
2157 			break;
2158 		}
2159 	}
2160 
2161 	if (mode_page == -1 && list == 0)
2162 		errx(1, "you must specify a mode page!");
2163 
2164 	if (list) {
2165 		mode_list(device, page_control, arglist & CAM_ARG_DBD,
2166 		    retry_count, timeout);
2167 	} else {
2168 		mode_edit(device, mode_page, page_control,
2169 		    arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
2170 		    retry_count, timeout);
2171 	}
2172 }
2173 
2174 static int
2175 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
2176 	int retry_count, int timeout)
2177 {
2178 	union ccb *ccb;
2179 	u_int32_t flags = CAM_DIR_NONE;
2180 	u_int8_t *data_ptr = NULL;
2181 	u_int8_t cdb[20];
2182 	u_int8_t atacmd[12];
2183 	struct get_hook hook;
2184 	int c, data_bytes = 0;
2185 	int cdb_len = 0;
2186 	int atacmd_len = 0;
2187 	int dmacmd = 0;
2188 	int fpdmacmd = 0;
2189 	int need_res = 0;
2190 	char *datastr = NULL, *tstr, *resstr = NULL;
2191 	int error = 0;
2192 	int fd_data = 0, fd_res = 0;
2193 	int retval;
2194 
2195 	ccb = cam_getccb(device);
2196 
2197 	if (ccb == NULL) {
2198 		warnx("scsicmd: error allocating ccb");
2199 		return(1);
2200 	}
2201 
2202 	bzero(&(&ccb->ccb_h)[1],
2203 	      sizeof(union ccb) - sizeof(struct ccb_hdr));
2204 
2205 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
2206 		switch(c) {
2207 		case 'a':
2208 			tstr = optarg;
2209 			while (isspace(*tstr) && (*tstr != '\0'))
2210 				tstr++;
2211 			hook.argc = argc - optind;
2212 			hook.argv = argv + optind;
2213 			hook.got = 0;
2214 			atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
2215 						    iget, &hook);
2216 			/*
2217 			 * Increment optind by the number of arguments the
2218 			 * encoding routine processed.  After each call to
2219 			 * getopt(3), optind points to the argument that
2220 			 * getopt should process _next_.  In this case,
2221 			 * that means it points to the first command string
2222 			 * argument, if there is one.  Once we increment
2223 			 * this, it should point to either the next command
2224 			 * line argument, or it should be past the end of
2225 			 * the list.
2226 			 */
2227 			optind += hook.got;
2228 			break;
2229 		case 'c':
2230 			tstr = optarg;
2231 			while (isspace(*tstr) && (*tstr != '\0'))
2232 				tstr++;
2233 			hook.argc = argc - optind;
2234 			hook.argv = argv + optind;
2235 			hook.got = 0;
2236 			cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
2237 						    iget, &hook);
2238 			/*
2239 			 * Increment optind by the number of arguments the
2240 			 * encoding routine processed.  After each call to
2241 			 * getopt(3), optind points to the argument that
2242 			 * getopt should process _next_.  In this case,
2243 			 * that means it points to the first command string
2244 			 * argument, if there is one.  Once we increment
2245 			 * this, it should point to either the next command
2246 			 * line argument, or it should be past the end of
2247 			 * the list.
2248 			 */
2249 			optind += hook.got;
2250 			break;
2251 		case 'd':
2252 			dmacmd = 1;
2253 			break;
2254 		case 'f':
2255 			fpdmacmd = 1;
2256 			break;
2257 		case 'i':
2258 			if (arglist & CAM_ARG_CMD_OUT) {
2259 				warnx("command must either be "
2260 				      "read or write, not both");
2261 				error = 1;
2262 				goto scsicmd_bailout;
2263 			}
2264 			arglist |= CAM_ARG_CMD_IN;
2265 			flags = CAM_DIR_IN;
2266 			data_bytes = strtol(optarg, NULL, 0);
2267 			if (data_bytes <= 0) {
2268 				warnx("invalid number of input bytes %d",
2269 				      data_bytes);
2270 				error = 1;
2271 				goto scsicmd_bailout;
2272 			}
2273 			hook.argc = argc - optind;
2274 			hook.argv = argv + optind;
2275 			hook.got = 0;
2276 			optind++;
2277 			datastr = cget(&hook, NULL);
2278 			/*
2279 			 * If the user supplied "-" instead of a format, he
2280 			 * wants the data to be written to stdout.
2281 			 */
2282 			if ((datastr != NULL)
2283 			 && (datastr[0] == '-'))
2284 				fd_data = 1;
2285 
2286 			data_ptr = (u_int8_t *)malloc(data_bytes);
2287 			if (data_ptr == NULL) {
2288 				warnx("can't malloc memory for data_ptr");
2289 				error = 1;
2290 				goto scsicmd_bailout;
2291 			}
2292 			break;
2293 		case 'o':
2294 			if (arglist & CAM_ARG_CMD_IN) {
2295 				warnx("command must either be "
2296 				      "read or write, not both");
2297 				error = 1;
2298 				goto scsicmd_bailout;
2299 			}
2300 			arglist |= CAM_ARG_CMD_OUT;
2301 			flags = CAM_DIR_OUT;
2302 			data_bytes = strtol(optarg, NULL, 0);
2303 			if (data_bytes <= 0) {
2304 				warnx("invalid number of output bytes %d",
2305 				      data_bytes);
2306 				error = 1;
2307 				goto scsicmd_bailout;
2308 			}
2309 			hook.argc = argc - optind;
2310 			hook.argv = argv + optind;
2311 			hook.got = 0;
2312 			datastr = cget(&hook, NULL);
2313 			data_ptr = (u_int8_t *)malloc(data_bytes);
2314 			if (data_ptr == NULL) {
2315 				warnx("can't malloc memory for data_ptr");
2316 				error = 1;
2317 				goto scsicmd_bailout;
2318 			}
2319 			bzero(data_ptr, data_bytes);
2320 			/*
2321 			 * If the user supplied "-" instead of a format, he
2322 			 * wants the data to be read from stdin.
2323 			 */
2324 			if ((datastr != NULL)
2325 			 && (datastr[0] == '-'))
2326 				fd_data = 1;
2327 			else
2328 				buff_encode_visit(data_ptr, data_bytes, datastr,
2329 						  iget, &hook);
2330 			optind += hook.got;
2331 			break;
2332 		case 'r':
2333 			need_res = 1;
2334 			hook.argc = argc - optind;
2335 			hook.argv = argv + optind;
2336 			hook.got = 0;
2337 			resstr = cget(&hook, NULL);
2338 			if ((resstr != NULL) && (resstr[0] == '-'))
2339 				fd_res = 1;
2340 			optind += hook.got;
2341 			break;
2342 		default:
2343 			break;
2344 		}
2345 	}
2346 
2347 	/*
2348 	 * If fd_data is set, and we're writing to the device, we need to
2349 	 * read the data the user wants written from stdin.
2350 	 */
2351 	if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
2352 		ssize_t amt_read;
2353 		int amt_to_read = data_bytes;
2354 		u_int8_t *buf_ptr = data_ptr;
2355 
2356 		for (amt_read = 0; amt_to_read > 0;
2357 		     amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
2358 			if (amt_read == -1) {
2359 				warn("error reading data from stdin");
2360 				error = 1;
2361 				goto scsicmd_bailout;
2362 			}
2363 			amt_to_read -= amt_read;
2364 			buf_ptr += amt_read;
2365 		}
2366 	}
2367 
2368 	if (arglist & CAM_ARG_ERR_RECOVER)
2369 		flags |= CAM_PASS_ERR_RECOVER;
2370 
2371 	/* Disable freezing the device queue */
2372 	flags |= CAM_DEV_QFRZDIS;
2373 
2374 	if (cdb_len) {
2375 		/*
2376 		 * This is taken from the SCSI-3 draft spec.
2377 		 * (T10/1157D revision 0.3)
2378 		 * The top 3 bits of an opcode are the group code.
2379 		 * The next 5 bits are the command code.
2380 		 * Group 0:  six byte commands
2381 		 * Group 1:  ten byte commands
2382 		 * Group 2:  ten byte commands
2383 		 * Group 3:  reserved
2384 		 * Group 4:  sixteen byte commands
2385 		 * Group 5:  twelve byte commands
2386 		 * Group 6:  vendor specific
2387 		 * Group 7:  vendor specific
2388 		 */
2389 		switch((cdb[0] >> 5) & 0x7) {
2390 			case 0:
2391 				cdb_len = 6;
2392 				break;
2393 			case 1:
2394 			case 2:
2395 				cdb_len = 10;
2396 				break;
2397 			case 3:
2398 			case 6:
2399 			case 7:
2400 			        /* computed by buff_encode_visit */
2401 				break;
2402 			case 4:
2403 				cdb_len = 16;
2404 				break;
2405 			case 5:
2406 				cdb_len = 12;
2407 				break;
2408 		}
2409 
2410 		/*
2411 		 * We should probably use csio_build_visit or something like that
2412 		 * here, but it's easier to encode arguments as you go.  The
2413 		 * alternative would be skipping the CDB argument and then encoding
2414 		 * it here, since we've got the data buffer argument by now.
2415 		 */
2416 		bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
2417 
2418 		cam_fill_csio(&ccb->csio,
2419 		      /*retries*/ retry_count,
2420 		      /*cbfcnp*/ NULL,
2421 		      /*flags*/ flags,
2422 		      /*tag_action*/ MSG_SIMPLE_Q_TAG,
2423 		      /*data_ptr*/ data_ptr,
2424 		      /*dxfer_len*/ data_bytes,
2425 		      /*sense_len*/ SSD_FULL_SIZE,
2426 		      /*cdb_len*/ cdb_len,
2427 		      /*timeout*/ timeout ? timeout : 5000);
2428 	} else {
2429 		atacmd_len = 12;
2430 		bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
2431 		if (need_res)
2432 			ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
2433 		if (dmacmd)
2434 			ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
2435 		if (fpdmacmd)
2436 			ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
2437 
2438 		cam_fill_ataio(&ccb->ataio,
2439 		      /*retries*/ retry_count,
2440 		      /*cbfcnp*/ NULL,
2441 		      /*flags*/ flags,
2442 		      /*tag_action*/ 0,
2443 		      /*data_ptr*/ data_ptr,
2444 		      /*dxfer_len*/ data_bytes,
2445 		      /*timeout*/ timeout ? timeout : 5000);
2446 	}
2447 
2448 	if (((retval = cam_send_ccb(device, ccb)) < 0)
2449 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2450 		if (retval < 0)
2451 			warn("error sending command");
2452 		else
2453 			warnx("error sending command");
2454 
2455 		if (arglist & CAM_ARG_VERBOSE) {
2456 			cam_error_print(device, ccb, CAM_ESF_ALL,
2457 					CAM_EPF_ALL, stderr);
2458 		}
2459 
2460 		error = 1;
2461 		goto scsicmd_bailout;
2462 	}
2463 
2464 	if (atacmd_len && need_res) {
2465 		if (fd_res == 0) {
2466 			buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
2467 					  arg_put, NULL);
2468 			fprintf(stdout, "\n");
2469 		} else {
2470 			fprintf(stdout,
2471 			    "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
2472 			    ccb->ataio.res.status,
2473 			    ccb->ataio.res.error,
2474 			    ccb->ataio.res.lba_low,
2475 			    ccb->ataio.res.lba_mid,
2476 			    ccb->ataio.res.lba_high,
2477 			    ccb->ataio.res.device,
2478 			    ccb->ataio.res.lba_low_exp,
2479 			    ccb->ataio.res.lba_mid_exp,
2480 			    ccb->ataio.res.lba_high_exp,
2481 			    ccb->ataio.res.sector_count,
2482 			    ccb->ataio.res.sector_count_exp);
2483 			fflush(stdout);
2484 		}
2485 	}
2486 
2487 	if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
2488 	 && (arglist & CAM_ARG_CMD_IN)
2489 	 && (data_bytes > 0)) {
2490 		if (fd_data == 0) {
2491 			buff_decode_visit(data_ptr, data_bytes, datastr,
2492 					  arg_put, NULL);
2493 			fprintf(stdout, "\n");
2494 		} else {
2495 			ssize_t amt_written;
2496 			int amt_to_write = data_bytes;
2497 			u_int8_t *buf_ptr = data_ptr;
2498 
2499 			for (amt_written = 0; (amt_to_write > 0) &&
2500 			     (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
2501 				amt_to_write -= amt_written;
2502 				buf_ptr += amt_written;
2503 			}
2504 			if (amt_written == -1) {
2505 				warn("error writing data to stdout");
2506 				error = 1;
2507 				goto scsicmd_bailout;
2508 			} else if ((amt_written == 0)
2509 				&& (amt_to_write > 0)) {
2510 				warnx("only wrote %u bytes out of %u",
2511 				      data_bytes - amt_to_write, data_bytes);
2512 			}
2513 		}
2514 	}
2515 
2516 scsicmd_bailout:
2517 
2518 	if ((data_bytes > 0) && (data_ptr != NULL))
2519 		free(data_ptr);
2520 
2521 	cam_freeccb(ccb);
2522 
2523 	return(error);
2524 }
2525 
2526 static int
2527 camdebug(int argc, char **argv, char *combinedopt)
2528 {
2529 	int c, fd;
2530 	int bus = -1, target = -1, lun = -1;
2531 	char *tstr, *tmpstr = NULL;
2532 	union ccb ccb;
2533 	int error = 0;
2534 
2535 	bzero(&ccb, sizeof(union ccb));
2536 
2537 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
2538 		switch(c) {
2539 		case 'I':
2540 			arglist |= CAM_ARG_DEBUG_INFO;
2541 			ccb.cdbg.flags |= CAM_DEBUG_INFO;
2542 			break;
2543 		case 'P':
2544 			arglist |= CAM_ARG_DEBUG_PERIPH;
2545 			ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
2546 			break;
2547 		case 'S':
2548 			arglist |= CAM_ARG_DEBUG_SUBTRACE;
2549 			ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
2550 			break;
2551 		case 'T':
2552 			arglist |= CAM_ARG_DEBUG_TRACE;
2553 			ccb.cdbg.flags |= CAM_DEBUG_TRACE;
2554 			break;
2555 		case 'X':
2556 			arglist |= CAM_ARG_DEBUG_XPT;
2557 			ccb.cdbg.flags |= CAM_DEBUG_XPT;
2558 			break;
2559 		case 'c':
2560 			arglist |= CAM_ARG_DEBUG_CDB;
2561 			ccb.cdbg.flags |= CAM_DEBUG_CDB;
2562 			break;
2563 		default:
2564 			break;
2565 		}
2566 	}
2567 
2568 	if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
2569 		warnx("error opening transport layer device %s", XPT_DEVICE);
2570 		warn("%s", XPT_DEVICE);
2571 		return(1);
2572 	}
2573 	argc -= optind;
2574 	argv += optind;
2575 
2576 	if (argc <= 0) {
2577 		warnx("you must specify \"off\", \"all\" or a bus,");
2578 		warnx("bus:target, or bus:target:lun");
2579 		close(fd);
2580 		return(1);
2581 	}
2582 
2583 	tstr = *argv;
2584 
2585 	while (isspace(*tstr) && (*tstr != '\0'))
2586 		tstr++;
2587 
2588 	if (strncmp(tstr, "off", 3) == 0) {
2589 		ccb.cdbg.flags = CAM_DEBUG_NONE;
2590 		arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
2591 			     CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
2592 			     CAM_ARG_DEBUG_XPT);
2593 	} else if (strncmp(tstr, "all", 3) != 0) {
2594 		tmpstr = (char *)strtok(tstr, ":");
2595 		if ((tmpstr != NULL) && (*tmpstr != '\0')){
2596 			bus = strtol(tmpstr, NULL, 0);
2597 			arglist |= CAM_ARG_BUS;
2598 			tmpstr = (char *)strtok(NULL, ":");
2599 			if ((tmpstr != NULL) && (*tmpstr != '\0')){
2600 				target = strtol(tmpstr, NULL, 0);
2601 				arglist |= CAM_ARG_TARGET;
2602 				tmpstr = (char *)strtok(NULL, ":");
2603 				if ((tmpstr != NULL) && (*tmpstr != '\0')){
2604 					lun = strtol(tmpstr, NULL, 0);
2605 					arglist |= CAM_ARG_LUN;
2606 				}
2607 			}
2608 		} else {
2609 			error = 1;
2610 			warnx("you must specify \"all\", \"off\", or a bus,");
2611 			warnx("bus:target, or bus:target:lun to debug");
2612 		}
2613 	}
2614 
2615 	if (error == 0) {
2616 
2617 		ccb.ccb_h.func_code = XPT_DEBUG;
2618 		ccb.ccb_h.path_id = bus;
2619 		ccb.ccb_h.target_id = target;
2620 		ccb.ccb_h.target_lun = lun;
2621 
2622 		if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
2623 			warn("CAMIOCOMMAND ioctl failed");
2624 			error = 1;
2625 		}
2626 
2627 		if (error == 0) {
2628 			if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
2629 			     CAM_FUNC_NOTAVAIL) {
2630 				warnx("CAM debugging not available");
2631 				warnx("you need to put options CAMDEBUG in"
2632 				      " your kernel config file!");
2633 				error = 1;
2634 			} else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
2635 				    CAM_REQ_CMP) {
2636 				warnx("XPT_DEBUG CCB failed with status %#x",
2637 				      ccb.ccb_h.status);
2638 				error = 1;
2639 			} else {
2640 				if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
2641 					fprintf(stderr,
2642 						"Debugging turned off\n");
2643 				} else {
2644 					fprintf(stderr,
2645 						"Debugging enabled for "
2646 						"%d:%d:%d\n",
2647 						bus, target, lun);
2648 				}
2649 			}
2650 		}
2651 		close(fd);
2652 	}
2653 
2654 	return(error);
2655 }
2656 
2657 static int
2658 tagcontrol(struct cam_device *device, int argc, char **argv,
2659 	   char *combinedopt)
2660 {
2661 	int c;
2662 	union ccb *ccb;
2663 	int numtags = -1;
2664 	int retval = 0;
2665 	int quiet = 0;
2666 	char pathstr[1024];
2667 
2668 	ccb = cam_getccb(device);
2669 
2670 	if (ccb == NULL) {
2671 		warnx("tagcontrol: error allocating ccb");
2672 		return(1);
2673 	}
2674 
2675 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
2676 		switch(c) {
2677 		case 'N':
2678 			numtags = strtol(optarg, NULL, 0);
2679 			if (numtags < 0) {
2680 				warnx("tag count %d is < 0", numtags);
2681 				retval = 1;
2682 				goto tagcontrol_bailout;
2683 			}
2684 			break;
2685 		case 'q':
2686 			quiet++;
2687 			break;
2688 		default:
2689 			break;
2690 		}
2691 	}
2692 
2693 	cam_path_string(device, pathstr, sizeof(pathstr));
2694 
2695 	if (numtags >= 0) {
2696 		bzero(&(&ccb->ccb_h)[1],
2697 		      sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
2698 		ccb->ccb_h.func_code = XPT_REL_SIMQ;
2699 		ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
2700 		ccb->crs.openings = numtags;
2701 
2702 
2703 		if (cam_send_ccb(device, ccb) < 0) {
2704 			perror("error sending XPT_REL_SIMQ CCB");
2705 			retval = 1;
2706 			goto tagcontrol_bailout;
2707 		}
2708 
2709 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2710 			warnx("XPT_REL_SIMQ CCB failed");
2711 			cam_error_print(device, ccb, CAM_ESF_ALL,
2712 					CAM_EPF_ALL, stderr);
2713 			retval = 1;
2714 			goto tagcontrol_bailout;
2715 		}
2716 
2717 
2718 		if (quiet == 0)
2719 			fprintf(stdout, "%stagged openings now %d\n",
2720 				pathstr, ccb->crs.openings);
2721 	}
2722 
2723 	bzero(&(&ccb->ccb_h)[1],
2724 	      sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
2725 
2726 	ccb->ccb_h.func_code = XPT_GDEV_STATS;
2727 
2728 	if (cam_send_ccb(device, ccb) < 0) {
2729 		perror("error sending XPT_GDEV_STATS CCB");
2730 		retval = 1;
2731 		goto tagcontrol_bailout;
2732 	}
2733 
2734 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2735 		warnx("XPT_GDEV_STATS CCB failed");
2736 		cam_error_print(device, ccb, CAM_ESF_ALL,
2737 				CAM_EPF_ALL, stderr);
2738 		retval = 1;
2739 		goto tagcontrol_bailout;
2740 	}
2741 
2742 	if (arglist & CAM_ARG_VERBOSE) {
2743 		fprintf(stdout, "%s", pathstr);
2744 		fprintf(stdout, "dev_openings  %d\n", ccb->cgds.dev_openings);
2745 		fprintf(stdout, "%s", pathstr);
2746 		fprintf(stdout, "dev_active    %d\n", ccb->cgds.dev_active);
2747 		fprintf(stdout, "%s", pathstr);
2748 		fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
2749 		fprintf(stdout, "%s", pathstr);
2750 		fprintf(stdout, "devq_queued   %d\n", ccb->cgds.devq_queued);
2751 		fprintf(stdout, "%s", pathstr);
2752 		fprintf(stdout, "held          %d\n", ccb->cgds.held);
2753 		fprintf(stdout, "%s", pathstr);
2754 		fprintf(stdout, "mintags       %d\n", ccb->cgds.mintags);
2755 		fprintf(stdout, "%s", pathstr);
2756 		fprintf(stdout, "maxtags       %d\n", ccb->cgds.maxtags);
2757 	} else {
2758 		if (quiet == 0) {
2759 			fprintf(stdout, "%s", pathstr);
2760 			fprintf(stdout, "device openings: ");
2761 		}
2762 		fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
2763 			ccb->cgds.dev_active);
2764 	}
2765 
2766 tagcontrol_bailout:
2767 
2768 	cam_freeccb(ccb);
2769 	return(retval);
2770 }
2771 
2772 static void
2773 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
2774 {
2775 	char pathstr[1024];
2776 
2777 	cam_path_string(device, pathstr, sizeof(pathstr));
2778 
2779 	if (cts->transport == XPORT_SPI) {
2780 		struct ccb_trans_settings_spi *spi =
2781 		    &cts->xport_specific.spi;
2782 
2783 		if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
2784 
2785 			fprintf(stdout, "%ssync parameter: %d\n", pathstr,
2786 				spi->sync_period);
2787 
2788 			if (spi->sync_offset != 0) {
2789 				u_int freq;
2790 
2791 				freq = scsi_calc_syncsrate(spi->sync_period);
2792 				fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
2793 					pathstr, freq / 1000, freq % 1000);
2794 			}
2795 		}
2796 
2797 		if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
2798 			fprintf(stdout, "%soffset: %d\n", pathstr,
2799 			    spi->sync_offset);
2800 		}
2801 
2802 		if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
2803 			fprintf(stdout, "%sbus width: %d bits\n", pathstr,
2804 				(0x01 << spi->bus_width) * 8);
2805 		}
2806 
2807 		if (spi->valid & CTS_SPI_VALID_DISC) {
2808 			fprintf(stdout, "%sdisconnection is %s\n", pathstr,
2809 				(spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
2810 				"enabled" : "disabled");
2811 		}
2812 	}
2813 	if (cts->transport == XPORT_ATA) {
2814 		struct ccb_trans_settings_ata *ata =
2815 		    &cts->xport_specific.ata;
2816 
2817 		if ((ata->valid & CTS_ATA_VALID_MODE) != 0) {
2818 			fprintf(stdout, "%sATA mode: %s\n", pathstr,
2819 				ata_mode2string(ata->mode));
2820 		}
2821 		if ((ata->valid & CTS_ATA_VALID_ATAPI) != 0) {
2822 			fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2823 				ata->atapi);
2824 		}
2825 		if ((ata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
2826 			fprintf(stdout, "%sPIO transaction length: %d\n",
2827 				pathstr, ata->bytecount);
2828 		}
2829 	}
2830 	if (cts->transport == XPORT_SATA) {
2831 		struct ccb_trans_settings_sata *sata =
2832 		    &cts->xport_specific.sata;
2833 
2834 		if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
2835 			fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
2836 				sata->revision);
2837 		}
2838 		if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
2839 			fprintf(stdout, "%sATA mode: %s\n", pathstr,
2840 				ata_mode2string(sata->mode));
2841 		}
2842 		if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
2843 			fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2844 				sata->atapi);
2845 		}
2846 		if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
2847 			fprintf(stdout, "%sPIO transaction length: %d\n",
2848 				pathstr, sata->bytecount);
2849 		}
2850 		if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
2851 			fprintf(stdout, "%sPMP presence: %d\n", pathstr,
2852 				sata->pm_present);
2853 		}
2854 		if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
2855 			fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
2856 				sata->tags);
2857 		}
2858 		if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
2859 			fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
2860 				sata->caps);
2861 		}
2862 	}
2863 	if (cts->protocol == PROTO_SCSI) {
2864 		struct ccb_trans_settings_scsi *scsi=
2865 		    &cts->proto_specific.scsi;
2866 
2867 		if (scsi->valid & CTS_SCSI_VALID_TQ) {
2868 			fprintf(stdout, "%stagged queueing is %s\n", pathstr,
2869 				(scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
2870 				"enabled" : "disabled");
2871 		}
2872 	}
2873 
2874 }
2875 
2876 /*
2877  * Get a path inquiry CCB for the specified device.
2878  */
2879 static int
2880 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
2881 {
2882 	union ccb *ccb;
2883 	int retval = 0;
2884 
2885 	ccb = cam_getccb(device);
2886 	if (ccb == NULL) {
2887 		warnx("get_cpi: couldn't allocate CCB");
2888 		return(1);
2889 	}
2890 	bzero(&(&ccb->ccb_h)[1],
2891 	      sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2892 	ccb->ccb_h.func_code = XPT_PATH_INQ;
2893 	if (cam_send_ccb(device, ccb) < 0) {
2894 		warn("get_cpi: error sending Path Inquiry CCB");
2895 		if (arglist & CAM_ARG_VERBOSE)
2896 			cam_error_print(device, ccb, CAM_ESF_ALL,
2897 					CAM_EPF_ALL, stderr);
2898 		retval = 1;
2899 		goto get_cpi_bailout;
2900 	}
2901 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2902 		if (arglist & CAM_ARG_VERBOSE)
2903 			cam_error_print(device, ccb, CAM_ESF_ALL,
2904 					CAM_EPF_ALL, stderr);
2905 		retval = 1;
2906 		goto get_cpi_bailout;
2907 	}
2908 	bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
2909 
2910 get_cpi_bailout:
2911 	cam_freeccb(ccb);
2912 	return(retval);
2913 }
2914 
2915 /*
2916  * Get a get device CCB for the specified device.
2917  */
2918 static int
2919 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
2920 {
2921 	union ccb *ccb;
2922 	int retval = 0;
2923 
2924 	ccb = cam_getccb(device);
2925 	if (ccb == NULL) {
2926 		warnx("get_cgd: couldn't allocate CCB");
2927 		return(1);
2928 	}
2929 	bzero(&(&ccb->ccb_h)[1],
2930 	      sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2931 	ccb->ccb_h.func_code = XPT_GDEV_TYPE;
2932 	if (cam_send_ccb(device, ccb) < 0) {
2933 		warn("get_cgd: error sending Path Inquiry CCB");
2934 		if (arglist & CAM_ARG_VERBOSE)
2935 			cam_error_print(device, ccb, CAM_ESF_ALL,
2936 					CAM_EPF_ALL, stderr);
2937 		retval = 1;
2938 		goto get_cgd_bailout;
2939 	}
2940 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2941 		if (arglist & CAM_ARG_VERBOSE)
2942 			cam_error_print(device, ccb, CAM_ESF_ALL,
2943 					CAM_EPF_ALL, stderr);
2944 		retval = 1;
2945 		goto get_cgd_bailout;
2946 	}
2947 	bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
2948 
2949 get_cgd_bailout:
2950 	cam_freeccb(ccb);
2951 	return(retval);
2952 }
2953 
2954 static void
2955 cpi_print(struct ccb_pathinq *cpi)
2956 {
2957 	char adapter_str[1024];
2958 	int i;
2959 
2960 	snprintf(adapter_str, sizeof(adapter_str),
2961 		 "%s%d:", cpi->dev_name, cpi->unit_number);
2962 
2963 	fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
2964 		cpi->version_num);
2965 
2966 	for (i = 1; i < 0xff; i = i << 1) {
2967 		const char *str;
2968 
2969 		if ((i & cpi->hba_inquiry) == 0)
2970 			continue;
2971 
2972 		fprintf(stdout, "%s supports ", adapter_str);
2973 
2974 		switch(i) {
2975 		case PI_MDP_ABLE:
2976 			str = "MDP message";
2977 			break;
2978 		case PI_WIDE_32:
2979 			str = "32 bit wide SCSI";
2980 			break;
2981 		case PI_WIDE_16:
2982 			str = "16 bit wide SCSI";
2983 			break;
2984 		case PI_SDTR_ABLE:
2985 			str = "SDTR message";
2986 			break;
2987 		case PI_LINKED_CDB:
2988 			str = "linked CDBs";
2989 			break;
2990 		case PI_TAG_ABLE:
2991 			str = "tag queue messages";
2992 			break;
2993 		case PI_SOFT_RST:
2994 			str = "soft reset alternative";
2995 			break;
2996 		case PI_SATAPM:
2997 			str = "SATA Port Multiplier";
2998 			break;
2999 		default:
3000 			str = "unknown PI bit set";
3001 			break;
3002 		}
3003 		fprintf(stdout, "%s\n", str);
3004 	}
3005 
3006 	for (i = 1; i < 0xff; i = i << 1) {
3007 		const char *str;
3008 
3009 		if ((i & cpi->hba_misc) == 0)
3010 			continue;
3011 
3012 		fprintf(stdout, "%s ", adapter_str);
3013 
3014 		switch(i) {
3015 		case PIM_SCANHILO:
3016 			str = "bus scans from high ID to low ID";
3017 			break;
3018 		case PIM_NOREMOVE:
3019 			str = "removable devices not included in scan";
3020 			break;
3021 		case PIM_NOINITIATOR:
3022 			str = "initiator role not supported";
3023 			break;
3024 		case PIM_NOBUSRESET:
3025 			str = "user has disabled initial BUS RESET or"
3026 			      " controller is in target/mixed mode";
3027 			break;
3028 		case PIM_NO_6_BYTE:
3029 			str = "do not send 6-byte commands";
3030 			break;
3031 		case PIM_SEQSCAN:
3032 			str = "scan bus sequentially";
3033 			break;
3034 		default:
3035 			str = "unknown PIM bit set";
3036 			break;
3037 		}
3038 		fprintf(stdout, "%s\n", str);
3039 	}
3040 
3041 	for (i = 1; i < 0xff; i = i << 1) {
3042 		const char *str;
3043 
3044 		if ((i & cpi->target_sprt) == 0)
3045 			continue;
3046 
3047 		fprintf(stdout, "%s supports ", adapter_str);
3048 		switch(i) {
3049 		case PIT_PROCESSOR:
3050 			str = "target mode processor mode";
3051 			break;
3052 		case PIT_PHASE:
3053 			str = "target mode phase cog. mode";
3054 			break;
3055 		case PIT_DISCONNECT:
3056 			str = "disconnects in target mode";
3057 			break;
3058 		case PIT_TERM_IO:
3059 			str = "terminate I/O message in target mode";
3060 			break;
3061 		case PIT_GRP_6:
3062 			str = "group 6 commands in target mode";
3063 			break;
3064 		case PIT_GRP_7:
3065 			str = "group 7 commands in target mode";
3066 			break;
3067 		default:
3068 			str = "unknown PIT bit set";
3069 			break;
3070 		}
3071 
3072 		fprintf(stdout, "%s\n", str);
3073 	}
3074 	fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
3075 		cpi->hba_eng_cnt);
3076 	fprintf(stdout, "%s maximum target: %d\n", adapter_str,
3077 		cpi->max_target);
3078 	fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
3079 		cpi->max_lun);
3080 	fprintf(stdout, "%s highest path ID in subsystem: %d\n",
3081 		adapter_str, cpi->hpath_id);
3082 	fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
3083 		cpi->initiator_id);
3084 	fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
3085 	fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
3086 	fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
3087 	    adapter_str, cpi->hba_vendor);
3088 	fprintf(stdout, "%s HBA device ID: 0x%04x\n",
3089 	    adapter_str, cpi->hba_device);
3090 	fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
3091 	    adapter_str, cpi->hba_subvendor);
3092 	fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
3093 	    adapter_str, cpi->hba_subdevice);
3094 	fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
3095 	fprintf(stdout, "%s base transfer speed: ", adapter_str);
3096 	if (cpi->base_transfer_speed > 1000)
3097 		fprintf(stdout, "%d.%03dMB/sec\n",
3098 			cpi->base_transfer_speed / 1000,
3099 			cpi->base_transfer_speed % 1000);
3100 	else
3101 		fprintf(stdout, "%dKB/sec\n",
3102 			(cpi->base_transfer_speed % 1000) * 1000);
3103 	fprintf(stdout, "%s maximum transfer size: %u bytes\n",
3104 	    adapter_str, cpi->maxio);
3105 }
3106 
3107 static int
3108 get_print_cts(struct cam_device *device, int user_settings, int quiet,
3109 	      struct ccb_trans_settings *cts)
3110 {
3111 	int retval;
3112 	union ccb *ccb;
3113 
3114 	retval = 0;
3115 	ccb = cam_getccb(device);
3116 
3117 	if (ccb == NULL) {
3118 		warnx("get_print_cts: error allocating ccb");
3119 		return(1);
3120 	}
3121 
3122 	bzero(&(&ccb->ccb_h)[1],
3123 	      sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3124 
3125 	ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
3126 
3127 	if (user_settings == 0)
3128 		ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
3129 	else
3130 		ccb->cts.type = CTS_TYPE_USER_SETTINGS;
3131 
3132 	if (cam_send_ccb(device, ccb) < 0) {
3133 		perror("error sending XPT_GET_TRAN_SETTINGS CCB");
3134 		if (arglist & CAM_ARG_VERBOSE)
3135 			cam_error_print(device, ccb, CAM_ESF_ALL,
3136 					CAM_EPF_ALL, stderr);
3137 		retval = 1;
3138 		goto get_print_cts_bailout;
3139 	}
3140 
3141 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3142 		warnx("XPT_GET_TRANS_SETTINGS CCB failed");
3143 		if (arglist & CAM_ARG_VERBOSE)
3144 			cam_error_print(device, ccb, CAM_ESF_ALL,
3145 					CAM_EPF_ALL, stderr);
3146 		retval = 1;
3147 		goto get_print_cts_bailout;
3148 	}
3149 
3150 	if (quiet == 0)
3151 		cts_print(device, &ccb->cts);
3152 
3153 	if (cts != NULL)
3154 		bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
3155 
3156 get_print_cts_bailout:
3157 
3158 	cam_freeccb(ccb);
3159 
3160 	return(retval);
3161 }
3162 
3163 static int
3164 ratecontrol(struct cam_device *device, int retry_count, int timeout,
3165 	    int argc, char **argv, char *combinedopt)
3166 {
3167 	int c;
3168 	union ccb *ccb;
3169 	int user_settings = 0;
3170 	int retval = 0;
3171 	int disc_enable = -1, tag_enable = -1;
3172 	int mode = -1;
3173 	int offset = -1;
3174 	double syncrate = -1;
3175 	int bus_width = -1;
3176 	int quiet = 0;
3177 	int change_settings = 0, send_tur = 0;
3178 	struct ccb_pathinq cpi;
3179 
3180 	ccb = cam_getccb(device);
3181 	if (ccb == NULL) {
3182 		warnx("ratecontrol: error allocating ccb");
3183 		return(1);
3184 	}
3185 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3186 		switch(c){
3187 		case 'a':
3188 			send_tur = 1;
3189 			break;
3190 		case 'c':
3191 			user_settings = 0;
3192 			break;
3193 		case 'D':
3194 			if (strncasecmp(optarg, "enable", 6) == 0)
3195 				disc_enable = 1;
3196 			else if (strncasecmp(optarg, "disable", 7) == 0)
3197 				disc_enable = 0;
3198 			else {
3199 				warnx("-D argument \"%s\" is unknown", optarg);
3200 				retval = 1;
3201 				goto ratecontrol_bailout;
3202 			}
3203 			change_settings = 1;
3204 			break;
3205 		case 'M':
3206 			mode = ata_string2mode(optarg);
3207 			if (mode < 0) {
3208 				warnx("unknown mode '%s'", optarg);
3209 				retval = 1;
3210 				goto ratecontrol_bailout;
3211 			}
3212 			change_settings = 1;
3213 			break;
3214 		case 'O':
3215 			offset = strtol(optarg, NULL, 0);
3216 			if (offset < 0) {
3217 				warnx("offset value %d is < 0", offset);
3218 				retval = 1;
3219 				goto ratecontrol_bailout;
3220 			}
3221 			change_settings = 1;
3222 			break;
3223 		case 'q':
3224 			quiet++;
3225 			break;
3226 		case 'R':
3227 			syncrate = atof(optarg);
3228 			if (syncrate < 0) {
3229 				warnx("sync rate %f is < 0", syncrate);
3230 				retval = 1;
3231 				goto ratecontrol_bailout;
3232 			}
3233 			change_settings = 1;
3234 			break;
3235 		case 'T':
3236 			if (strncasecmp(optarg, "enable", 6) == 0)
3237 				tag_enable = 1;
3238 			else if (strncasecmp(optarg, "disable", 7) == 0)
3239 				tag_enable = 0;
3240 			else {
3241 				warnx("-T argument \"%s\" is unknown", optarg);
3242 				retval = 1;
3243 				goto ratecontrol_bailout;
3244 			}
3245 			change_settings = 1;
3246 			break;
3247 		case 'U':
3248 			user_settings = 1;
3249 			break;
3250 		case 'W':
3251 			bus_width = strtol(optarg, NULL, 0);
3252 			if (bus_width < 0) {
3253 				warnx("bus width %d is < 0", bus_width);
3254 				retval = 1;
3255 				goto ratecontrol_bailout;
3256 			}
3257 			change_settings = 1;
3258 			break;
3259 		default:
3260 			break;
3261 		}
3262 	}
3263 	bzero(&(&ccb->ccb_h)[1],
3264 	      sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
3265 	/*
3266 	 * Grab path inquiry information, so we can determine whether
3267 	 * or not the initiator is capable of the things that the user
3268 	 * requests.
3269 	 */
3270 	ccb->ccb_h.func_code = XPT_PATH_INQ;
3271 	if (cam_send_ccb(device, ccb) < 0) {
3272 		perror("error sending XPT_PATH_INQ CCB");
3273 		if (arglist & CAM_ARG_VERBOSE) {
3274 			cam_error_print(device, ccb, CAM_ESF_ALL,
3275 					CAM_EPF_ALL, stderr);
3276 		}
3277 		retval = 1;
3278 		goto ratecontrol_bailout;
3279 	}
3280 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3281 		warnx("XPT_PATH_INQ CCB failed");
3282 		if (arglist & CAM_ARG_VERBOSE) {
3283 			cam_error_print(device, ccb, CAM_ESF_ALL,
3284 					CAM_EPF_ALL, stderr);
3285 		}
3286 		retval = 1;
3287 		goto ratecontrol_bailout;
3288 	}
3289 	bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
3290 	bzero(&(&ccb->ccb_h)[1],
3291 	      sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3292 	if (quiet == 0) {
3293 		fprintf(stdout, "%s parameters:\n",
3294 		    user_settings ? "User" : "Current");
3295 	}
3296 	retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
3297 	if (retval != 0)
3298 		goto ratecontrol_bailout;
3299 
3300 	if (arglist & CAM_ARG_VERBOSE)
3301 		cpi_print(&cpi);
3302 
3303 	if (change_settings) {
3304 		int didsettings = 0;
3305 		struct ccb_trans_settings_spi *spi = NULL;
3306 		struct ccb_trans_settings_ata *ata = NULL;
3307 		struct ccb_trans_settings_sata *sata = NULL;
3308 		struct ccb_trans_settings_scsi *scsi = NULL;
3309 
3310 		if (ccb->cts.transport == XPORT_SPI)
3311 			spi = &ccb->cts.xport_specific.spi;
3312 		if (ccb->cts.transport == XPORT_ATA)
3313 			ata = &ccb->cts.xport_specific.ata;
3314 		if (ccb->cts.transport == XPORT_SATA)
3315 			sata = &ccb->cts.xport_specific.sata;
3316 		if (ccb->cts.protocol == PROTO_SCSI)
3317 			scsi = &ccb->cts.proto_specific.scsi;
3318 		ccb->cts.xport_specific.valid = 0;
3319 		ccb->cts.proto_specific.valid = 0;
3320 		if (spi && disc_enable != -1) {
3321 			spi->valid |= CTS_SPI_VALID_DISC;
3322 			if (disc_enable == 0)
3323 				spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
3324 			else
3325 				spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3326 		}
3327 		if (scsi && tag_enable != -1) {
3328 			if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
3329 				warnx("HBA does not support tagged queueing, "
3330 				      "so you cannot modify tag settings");
3331 				retval = 1;
3332 				goto ratecontrol_bailout;
3333 			}
3334 			scsi->valid |= CTS_SCSI_VALID_TQ;
3335 			if (tag_enable == 0)
3336 				scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
3337 			else
3338 				scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3339 			didsettings++;
3340 		}
3341 		if (spi && offset != -1) {
3342 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3343 				warnx("HBA is not capable of changing offset");
3344 				retval = 1;
3345 				goto ratecontrol_bailout;
3346 			}
3347 			spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3348 			spi->sync_offset = offset;
3349 			didsettings++;
3350 		}
3351 		if (spi && syncrate != -1) {
3352 			int prelim_sync_period;
3353 			u_int freq;
3354 
3355 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3356 				warnx("HBA is not capable of changing "
3357 				      "transfer rates");
3358 				retval = 1;
3359 				goto ratecontrol_bailout;
3360 			}
3361 			spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3362 			/*
3363 			 * The sync rate the user gives us is in MHz.
3364 			 * We need to translate it into KHz for this
3365 			 * calculation.
3366 			 */
3367 			syncrate *= 1000;
3368 			/*
3369 			 * Next, we calculate a "preliminary" sync period
3370 			 * in tenths of a nanosecond.
3371 			 */
3372 			if (syncrate == 0)
3373 				prelim_sync_period = 0;
3374 			else
3375 				prelim_sync_period = 10000000 / syncrate;
3376 			spi->sync_period =
3377 				scsi_calc_syncparam(prelim_sync_period);
3378 			freq = scsi_calc_syncsrate(spi->sync_period);
3379 			didsettings++;
3380 		}
3381 		if (sata && syncrate != -1) {
3382 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3383 				warnx("HBA is not capable of changing "
3384 				      "transfer rates");
3385 				retval = 1;
3386 				goto ratecontrol_bailout;
3387 			}
3388 			sata->revision = ata_speed2revision(syncrate * 100);
3389 			if (sata->revision < 0) {
3390 				warnx("Invalid rate %f", syncrate);
3391 				retval = 1;
3392 				goto ratecontrol_bailout;
3393 			}
3394 			sata->valid |= CTS_SATA_VALID_REVISION;
3395 			didsettings++;
3396 		}
3397 		if ((ata || sata) && mode != -1) {
3398 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3399 				warnx("HBA is not capable of changing "
3400 				      "transfer rates");
3401 				retval = 1;
3402 				goto ratecontrol_bailout;
3403 			}
3404 			if (ata) {
3405 				ata->mode = mode;
3406 				ata->valid |= CTS_ATA_VALID_MODE;
3407 			} else {
3408 				sata->mode = mode;
3409 				sata->valid |= CTS_SATA_VALID_MODE;
3410 			}
3411 			didsettings++;
3412 		}
3413 		/*
3414 		 * The bus_width argument goes like this:
3415 		 * 0 == 8 bit
3416 		 * 1 == 16 bit
3417 		 * 2 == 32 bit
3418 		 * Therefore, if you shift the number of bits given on the
3419 		 * command line right by 4, you should get the correct
3420 		 * number.
3421 		 */
3422 		if (spi && bus_width != -1) {
3423 			/*
3424 			 * We might as well validate things here with a
3425 			 * decipherable error message, rather than what
3426 			 * will probably be an indecipherable error message
3427 			 * by the time it gets back to us.
3428 			 */
3429 			if ((bus_width == 16)
3430 			 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
3431 				warnx("HBA does not support 16 bit bus width");
3432 				retval = 1;
3433 				goto ratecontrol_bailout;
3434 			} else if ((bus_width == 32)
3435 				&& ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
3436 				warnx("HBA does not support 32 bit bus width");
3437 				retval = 1;
3438 				goto ratecontrol_bailout;
3439 			} else if ((bus_width != 8)
3440 				&& (bus_width != 16)
3441 				&& (bus_width != 32)) {
3442 				warnx("Invalid bus width %d", bus_width);
3443 				retval = 1;
3444 				goto ratecontrol_bailout;
3445 			}
3446 			spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
3447 			spi->bus_width = bus_width >> 4;
3448 			didsettings++;
3449 		}
3450 		if  (didsettings == 0) {
3451 			goto ratecontrol_bailout;
3452 		}
3453 		if  (!user_settings && (ata || sata)) {
3454 			warnx("You can modify only user settings for ATA/SATA");
3455 			retval = 1;
3456 			goto ratecontrol_bailout;
3457 		}
3458 		ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
3459 		if (cam_send_ccb(device, ccb) < 0) {
3460 			perror("error sending XPT_SET_TRAN_SETTINGS CCB");
3461 			if (arglist & CAM_ARG_VERBOSE) {
3462 				cam_error_print(device, ccb, CAM_ESF_ALL,
3463 						CAM_EPF_ALL, stderr);
3464 			}
3465 			retval = 1;
3466 			goto ratecontrol_bailout;
3467 		}
3468 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3469 			warnx("XPT_SET_TRANS_SETTINGS CCB failed");
3470 			if (arglist & CAM_ARG_VERBOSE) {
3471 				cam_error_print(device, ccb, CAM_ESF_ALL,
3472 						CAM_EPF_ALL, stderr);
3473 			}
3474 			retval = 1;
3475 			goto ratecontrol_bailout;
3476 		}
3477 	}
3478 	if (send_tur) {
3479 		retval = testunitready(device, retry_count, timeout,
3480 				       (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
3481 		/*
3482 		 * If the TUR didn't succeed, just bail.
3483 		 */
3484 		if (retval != 0) {
3485 			if (quiet == 0)
3486 				fprintf(stderr, "Test Unit Ready failed\n");
3487 			goto ratecontrol_bailout;
3488 		}
3489 		/*
3490 		 * If the user wants things quiet, there's no sense in
3491 		 * getting the transfer settings, if we're not going
3492 		 * to print them.
3493 		 */
3494 		if (quiet != 0)
3495 			goto ratecontrol_bailout;
3496 		fprintf(stdout, "New parameters:\n");
3497 		retval = get_print_cts(device, user_settings, 0, NULL);
3498 	}
3499 
3500 ratecontrol_bailout:
3501 	cam_freeccb(ccb);
3502 	return(retval);
3503 }
3504 
3505 static int
3506 scsiformat(struct cam_device *device, int argc, char **argv,
3507 	   char *combinedopt, int retry_count, int timeout)
3508 {
3509 	union ccb *ccb;
3510 	int c;
3511 	int ycount = 0, quiet = 0;
3512 	int error = 0, response = 0, retval = 0;
3513 	int use_timeout = 10800 * 1000;
3514 	int immediate = 1;
3515 	struct format_defect_list_header fh;
3516 	u_int8_t *data_ptr = NULL;
3517 	u_int32_t dxfer_len = 0;
3518 	u_int8_t byte2 = 0;
3519 	int num_warnings = 0;
3520 	int reportonly = 0;
3521 
3522 	ccb = cam_getccb(device);
3523 
3524 	if (ccb == NULL) {
3525 		warnx("scsiformat: error allocating ccb");
3526 		return(1);
3527 	}
3528 
3529 	bzero(&(&ccb->ccb_h)[1],
3530 	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3531 
3532 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3533 		switch(c) {
3534 		case 'q':
3535 			quiet++;
3536 			break;
3537 		case 'r':
3538 			reportonly = 1;
3539 			break;
3540 		case 'w':
3541 			immediate = 0;
3542 			break;
3543 		case 'y':
3544 			ycount++;
3545 			break;
3546 		}
3547 	}
3548 
3549 	if (reportonly)
3550 		goto doreport;
3551 
3552 	if (quiet == 0) {
3553 		fprintf(stdout, "You are about to REMOVE ALL DATA from the "
3554 			"following device:\n");
3555 
3556 		error = scsidoinquiry(device, argc, argv, combinedopt,
3557 				      retry_count, timeout);
3558 
3559 		if (error != 0) {
3560 			warnx("scsiformat: error sending inquiry");
3561 			goto scsiformat_bailout;
3562 		}
3563 	}
3564 
3565 	if (ycount == 0) {
3566 
3567 		do {
3568 			char str[1024];
3569 
3570 			fprintf(stdout, "Are you SURE you want to do "
3571 				"this? (yes/no) ");
3572 
3573 			if (fgets(str, sizeof(str), stdin) != NULL) {
3574 
3575 				if (strncasecmp(str, "yes", 3) == 0)
3576 					response = 1;
3577 				else if (strncasecmp(str, "no", 2) == 0)
3578 					response = -1;
3579 				else {
3580 					fprintf(stdout, "Please answer"
3581 						" \"yes\" or \"no\"\n");
3582 				}
3583 			}
3584 		} while (response == 0);
3585 
3586 		if (response == -1) {
3587 			error = 1;
3588 			goto scsiformat_bailout;
3589 		}
3590 	}
3591 
3592 	if (timeout != 0)
3593 		use_timeout = timeout;
3594 
3595 	if (quiet == 0) {
3596 		fprintf(stdout, "Current format timeout is %d seconds\n",
3597 			use_timeout / 1000);
3598 	}
3599 
3600 	/*
3601 	 * If the user hasn't disabled questions and didn't specify a
3602 	 * timeout on the command line, ask them if they want the current
3603 	 * timeout.
3604 	 */
3605 	if ((ycount == 0)
3606 	 && (timeout == 0)) {
3607 		char str[1024];
3608 		int new_timeout = 0;
3609 
3610 		fprintf(stdout, "Enter new timeout in seconds or press\n"
3611 			"return to keep the current timeout [%d] ",
3612 			use_timeout / 1000);
3613 
3614 		if (fgets(str, sizeof(str), stdin) != NULL) {
3615 			if (str[0] != '\0')
3616 				new_timeout = atoi(str);
3617 		}
3618 
3619 		if (new_timeout != 0) {
3620 			use_timeout = new_timeout * 1000;
3621 			fprintf(stdout, "Using new timeout value %d\n",
3622 				use_timeout / 1000);
3623 		}
3624 	}
3625 
3626 	/*
3627 	 * Keep this outside the if block below to silence any unused
3628 	 * variable warnings.
3629 	 */
3630 	bzero(&fh, sizeof(fh));
3631 
3632 	/*
3633 	 * If we're in immediate mode, we've got to include the format
3634 	 * header
3635 	 */
3636 	if (immediate != 0) {
3637 		fh.byte2 = FU_DLH_IMMED;
3638 		data_ptr = (u_int8_t *)&fh;
3639 		dxfer_len = sizeof(fh);
3640 		byte2 = FU_FMT_DATA;
3641 	} else if (quiet == 0) {
3642 		fprintf(stdout, "Formatting...");
3643 		fflush(stdout);
3644 	}
3645 
3646 	scsi_format_unit(&ccb->csio,
3647 			 /* retries */ retry_count,
3648 			 /* cbfcnp */ NULL,
3649 			 /* tag_action */ MSG_SIMPLE_Q_TAG,
3650 			 /* byte2 */ byte2,
3651 			 /* ileave */ 0,
3652 			 /* data_ptr */ data_ptr,
3653 			 /* dxfer_len */ dxfer_len,
3654 			 /* sense_len */ SSD_FULL_SIZE,
3655 			 /* timeout */ use_timeout);
3656 
3657 	/* Disable freezing the device queue */
3658 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3659 
3660 	if (arglist & CAM_ARG_ERR_RECOVER)
3661 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3662 
3663 	if (((retval = cam_send_ccb(device, ccb)) < 0)
3664 	 || ((immediate == 0)
3665 	   && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
3666 		const char errstr[] = "error sending format command";
3667 
3668 		if (retval < 0)
3669 			warn(errstr);
3670 		else
3671 			warnx(errstr);
3672 
3673 		if (arglist & CAM_ARG_VERBOSE) {
3674 			cam_error_print(device, ccb, CAM_ESF_ALL,
3675 					CAM_EPF_ALL, stderr);
3676 		}
3677 		error = 1;
3678 		goto scsiformat_bailout;
3679 	}
3680 
3681 	/*
3682 	 * If we ran in non-immediate mode, we already checked for errors
3683 	 * above and printed out any necessary information.  If we're in
3684 	 * immediate mode, we need to loop through and get status
3685 	 * information periodically.
3686 	 */
3687 	if (immediate == 0) {
3688 		if (quiet == 0) {
3689 			fprintf(stdout, "Format Complete\n");
3690 		}
3691 		goto scsiformat_bailout;
3692 	}
3693 
3694 doreport:
3695 	do {
3696 		cam_status status;
3697 
3698 		bzero(&(&ccb->ccb_h)[1],
3699 		      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3700 
3701 		/*
3702 		 * There's really no need to do error recovery or
3703 		 * retries here, since we're just going to sit in a
3704 		 * loop and wait for the device to finish formatting.
3705 		 */
3706 		scsi_test_unit_ready(&ccb->csio,
3707 				     /* retries */ 0,
3708 				     /* cbfcnp */ NULL,
3709 				     /* tag_action */ MSG_SIMPLE_Q_TAG,
3710 				     /* sense_len */ SSD_FULL_SIZE,
3711 				     /* timeout */ 5000);
3712 
3713 		/* Disable freezing the device queue */
3714 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3715 
3716 		retval = cam_send_ccb(device, ccb);
3717 
3718 		/*
3719 		 * If we get an error from the ioctl, bail out.  SCSI
3720 		 * errors are expected.
3721 		 */
3722 		if (retval < 0) {
3723 			warn("error sending CAMIOCOMMAND ioctl");
3724 			if (arglist & CAM_ARG_VERBOSE) {
3725 				cam_error_print(device, ccb, CAM_ESF_ALL,
3726 						CAM_EPF_ALL, stderr);
3727 			}
3728 			error = 1;
3729 			goto scsiformat_bailout;
3730 		}
3731 
3732 		status = ccb->ccb_h.status & CAM_STATUS_MASK;
3733 
3734 		if ((status != CAM_REQ_CMP)
3735 		 && (status == CAM_SCSI_STATUS_ERROR)
3736 		 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3737 			struct scsi_sense_data *sense;
3738 			int error_code, sense_key, asc, ascq;
3739 
3740 			sense = &ccb->csio.sense_data;
3741 			scsi_extract_sense(sense, &error_code, &sense_key,
3742 					   &asc, &ascq);
3743 
3744 			/*
3745 			 * According to the SCSI-2 and SCSI-3 specs, a
3746 			 * drive that is in the middle of a format should
3747 			 * return NOT READY with an ASC of "logical unit
3748 			 * not ready, format in progress".  The sense key
3749 			 * specific bytes will then be a progress indicator.
3750 			 */
3751 			if ((sense_key == SSD_KEY_NOT_READY)
3752 			 && (asc == 0x04) && (ascq == 0x04)) {
3753 				if ((sense->extra_len >= 10)
3754 				 && ((sense->sense_key_spec[0] &
3755 				      SSD_SCS_VALID) != 0)
3756 				 && (quiet == 0)) {
3757 					int val;
3758 					u_int64_t percentage;
3759 
3760 					val = scsi_2btoul(
3761 						&sense->sense_key_spec[1]);
3762 					percentage = 10000 * val;
3763 
3764 					fprintf(stdout,
3765 						"\rFormatting:  %ju.%02u %% "
3766 						"(%d/%d) done",
3767 						(uintmax_t)(percentage /
3768 						(0x10000 * 100)),
3769 						(unsigned)((percentage /
3770 						0x10000) % 100),
3771 						val, 0x10000);
3772 					fflush(stdout);
3773 				} else if ((quiet == 0)
3774 					&& (++num_warnings <= 1)) {
3775 					warnx("Unexpected SCSI Sense Key "
3776 					      "Specific value returned "
3777 					      "during format:");
3778 					scsi_sense_print(device, &ccb->csio,
3779 							 stderr);
3780 					warnx("Unable to print status "
3781 					      "information, but format will "
3782 					      "proceed.");
3783 					warnx("will exit when format is "
3784 					      "complete");
3785 				}
3786 				sleep(1);
3787 			} else {
3788 				warnx("Unexpected SCSI error during format");
3789 				cam_error_print(device, ccb, CAM_ESF_ALL,
3790 						CAM_EPF_ALL, stderr);
3791 				error = 1;
3792 				goto scsiformat_bailout;
3793 			}
3794 
3795 		} else if (status != CAM_REQ_CMP) {
3796 			warnx("Unexpected CAM status %#x", status);
3797 			if (arglist & CAM_ARG_VERBOSE)
3798 				cam_error_print(device, ccb, CAM_ESF_ALL,
3799 						CAM_EPF_ALL, stderr);
3800 			error = 1;
3801 			goto scsiformat_bailout;
3802 		}
3803 
3804 	} while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
3805 
3806 	if (quiet == 0)
3807 		fprintf(stdout, "\nFormat Complete\n");
3808 
3809 scsiformat_bailout:
3810 
3811 	cam_freeccb(ccb);
3812 
3813 	return(error);
3814 }
3815 
3816 static int
3817 scsireportluns(struct cam_device *device, int argc, char **argv,
3818 	       char *combinedopt, int retry_count, int timeout)
3819 {
3820 	union ccb *ccb;
3821 	int c, countonly, lunsonly;
3822 	struct scsi_report_luns_data *lundata;
3823 	int alloc_len;
3824 	uint8_t report_type;
3825 	uint32_t list_len, i, j;
3826 	int retval;
3827 
3828 	retval = 0;
3829 	lundata = NULL;
3830 	report_type = RPL_REPORT_DEFAULT;
3831 	ccb = cam_getccb(device);
3832 
3833 	if (ccb == NULL) {
3834 		warnx("%s: error allocating ccb", __func__);
3835 		return (1);
3836 	}
3837 
3838 	bzero(&(&ccb->ccb_h)[1],
3839 	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3840 
3841 	countonly = 0;
3842 	lunsonly = 0;
3843 
3844 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3845 		switch (c) {
3846 		case 'c':
3847 			countonly++;
3848 			break;
3849 		case 'l':
3850 			lunsonly++;
3851 			break;
3852 		case 'r':
3853 			if (strcasecmp(optarg, "default") == 0)
3854 				report_type = RPL_REPORT_DEFAULT;
3855 			else if (strcasecmp(optarg, "wellknown") == 0)
3856 				report_type = RPL_REPORT_WELLKNOWN;
3857 			else if (strcasecmp(optarg, "all") == 0)
3858 				report_type = RPL_REPORT_ALL;
3859 			else {
3860 				warnx("%s: invalid report type \"%s\"",
3861 				      __func__, optarg);
3862 				retval = 1;
3863 				goto bailout;
3864 			}
3865 			break;
3866 		default:
3867 			break;
3868 		}
3869 	}
3870 
3871 	if ((countonly != 0)
3872 	 && (lunsonly != 0)) {
3873 		warnx("%s: you can only specify one of -c or -l", __func__);
3874 		retval = 1;
3875 		goto bailout;
3876 	}
3877 	/*
3878 	 * According to SPC-4, the allocation length must be at least 16
3879 	 * bytes -- enough for the header and one LUN.
3880 	 */
3881 	alloc_len = sizeof(*lundata) + 8;
3882 
3883 retry:
3884 
3885 	lundata = malloc(alloc_len);
3886 
3887 	if (lundata == NULL) {
3888 		warn("%s: error mallocing %d bytes", __func__, alloc_len);
3889 		retval = 1;
3890 		goto bailout;
3891 	}
3892 
3893 	scsi_report_luns(&ccb->csio,
3894 			 /*retries*/ retry_count,
3895 			 /*cbfcnp*/ NULL,
3896 			 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3897 			 /*select_report*/ report_type,
3898 			 /*rpl_buf*/ lundata,
3899 			 /*alloc_len*/ alloc_len,
3900 			 /*sense_len*/ SSD_FULL_SIZE,
3901 			 /*timeout*/ timeout ? timeout : 5000);
3902 
3903 	/* Disable freezing the device queue */
3904 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3905 
3906 	if (arglist & CAM_ARG_ERR_RECOVER)
3907 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3908 
3909 	if (cam_send_ccb(device, ccb) < 0) {
3910 		warn("error sending REPORT LUNS command");
3911 
3912 		if (arglist & CAM_ARG_VERBOSE)
3913 			cam_error_print(device, ccb, CAM_ESF_ALL,
3914 					CAM_EPF_ALL, stderr);
3915 
3916 		retval = 1;
3917 		goto bailout;
3918 	}
3919 
3920 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3921 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
3922 		retval = 1;
3923 		goto bailout;
3924 	}
3925 
3926 
3927 	list_len = scsi_4btoul(lundata->length);
3928 
3929 	/*
3930 	 * If we need to list the LUNs, and our allocation
3931 	 * length was too short, reallocate and retry.
3932 	 */
3933 	if ((countonly == 0)
3934 	 && (list_len > (alloc_len - sizeof(*lundata)))) {
3935 		alloc_len = list_len + sizeof(*lundata);
3936 		free(lundata);
3937 		goto retry;
3938 	}
3939 
3940 	if (lunsonly == 0)
3941 		fprintf(stdout, "%u LUN%s found\n", list_len / 8,
3942 			((list_len / 8) > 1) ? "s" : "");
3943 
3944 	if (countonly != 0)
3945 		goto bailout;
3946 
3947 	for (i = 0; i < (list_len / 8); i++) {
3948 		int no_more;
3949 
3950 		no_more = 0;
3951 		for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
3952 			if (j != 0)
3953 				fprintf(stdout, ",");
3954 			switch (lundata->luns[i].lundata[j] &
3955 				RPL_LUNDATA_ATYP_MASK) {
3956 			case RPL_LUNDATA_ATYP_PERIPH:
3957 				if ((lundata->luns[i].lundata[j] &
3958 				    RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
3959 					fprintf(stdout, "%d:",
3960 						lundata->luns[i].lundata[j] &
3961 						RPL_LUNDATA_PERIPH_BUS_MASK);
3962 				else if ((j == 0)
3963 				      && ((lundata->luns[i].lundata[j+2] &
3964 					  RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
3965 					no_more = 1;
3966 
3967 				fprintf(stdout, "%d",
3968 					lundata->luns[i].lundata[j+1]);
3969 				break;
3970 			case RPL_LUNDATA_ATYP_FLAT: {
3971 				uint8_t tmplun[2];
3972 				tmplun[0] = lundata->luns[i].lundata[j] &
3973 					RPL_LUNDATA_FLAT_LUN_MASK;
3974 				tmplun[1] = lundata->luns[i].lundata[j+1];
3975 
3976 				fprintf(stdout, "%d", scsi_2btoul(tmplun));
3977 				no_more = 1;
3978 				break;
3979 			}
3980 			case RPL_LUNDATA_ATYP_LUN:
3981 				fprintf(stdout, "%d:%d:%d",
3982 					(lundata->luns[i].lundata[j+1] &
3983 					RPL_LUNDATA_LUN_BUS_MASK) >> 5,
3984 					lundata->luns[i].lundata[j] &
3985 					RPL_LUNDATA_LUN_TARG_MASK,
3986 					lundata->luns[i].lundata[j+1] &
3987 					RPL_LUNDATA_LUN_LUN_MASK);
3988 				break;
3989 			case RPL_LUNDATA_ATYP_EXTLUN: {
3990 				int field_len, field_len_code, eam_code;
3991 
3992 				eam_code = lundata->luns[i].lundata[j] &
3993 					RPL_LUNDATA_EXT_EAM_MASK;
3994 				field_len_code = (lundata->luns[i].lundata[j] &
3995 					RPL_LUNDATA_EXT_LEN_MASK) >> 4;
3996 				field_len = field_len_code * 2;
3997 
3998 				if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
3999 				 && (field_len_code == 0x00)) {
4000 					fprintf(stdout, "%d",
4001 						lundata->luns[i].lundata[j+1]);
4002 				} else if ((eam_code ==
4003 					    RPL_LUNDATA_EXT_EAM_NOT_SPEC)
4004 					&& (field_len_code == 0x03)) {
4005 					uint8_t tmp_lun[8];
4006 
4007 					/*
4008 					 * This format takes up all 8 bytes.
4009 					 * If we aren't starting at offset 0,
4010 					 * that's a bug.
4011 					 */
4012 					if (j != 0) {
4013 						fprintf(stdout, "Invalid "
4014 							"offset %d for "
4015 							"Extended LUN not "
4016 							"specified format", j);
4017 						no_more = 1;
4018 						break;
4019 					}
4020 					bzero(tmp_lun, sizeof(tmp_lun));
4021 					bcopy(&lundata->luns[i].lundata[j+1],
4022 					      &tmp_lun[1], sizeof(tmp_lun) - 1);
4023 					fprintf(stdout, "%#jx",
4024 					       (intmax_t)scsi_8btou64(tmp_lun));
4025 					no_more = 1;
4026 				} else {
4027 					fprintf(stderr, "Unknown Extended LUN"
4028 						"Address method %#x, length "
4029 						"code %#x", eam_code,
4030 						field_len_code);
4031 					no_more = 1;
4032 				}
4033 				break;
4034 			}
4035 			default:
4036 				fprintf(stderr, "Unknown LUN address method "
4037 					"%#x\n", lundata->luns[i].lundata[0] &
4038 					RPL_LUNDATA_ATYP_MASK);
4039 				break;
4040 			}
4041 			/*
4042 			 * For the flat addressing method, there are no
4043 			 * other levels after it.
4044 			 */
4045 			if (no_more != 0)
4046 				break;
4047 		}
4048 		fprintf(stdout, "\n");
4049 	}
4050 
4051 bailout:
4052 
4053 	cam_freeccb(ccb);
4054 
4055 	free(lundata);
4056 
4057 	return (retval);
4058 }
4059 
4060 static int
4061 scsireadcapacity(struct cam_device *device, int argc, char **argv,
4062 		 char *combinedopt, int retry_count, int timeout)
4063 {
4064 	union ccb *ccb;
4065 	int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
4066 	struct scsi_read_capacity_data rcap;
4067 	struct scsi_read_capacity_data_long rcaplong;
4068 	uint64_t maxsector;
4069 	uint32_t block_len;
4070 	int retval;
4071 	int c;
4072 
4073 	blocksizeonly = 0;
4074 	humanize = 0;
4075 	numblocks = 0;
4076 	quiet = 0;
4077 	sizeonly = 0;
4078 	baseten = 0;
4079 	retval = 0;
4080 
4081 	ccb = cam_getccb(device);
4082 
4083 	if (ccb == NULL) {
4084 		warnx("%s: error allocating ccb", __func__);
4085 		return (1);
4086 	}
4087 
4088 	bzero(&(&ccb->ccb_h)[1],
4089 	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4090 
4091 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
4092 		switch (c) {
4093 		case 'b':
4094 			blocksizeonly++;
4095 			break;
4096 		case 'h':
4097 			humanize++;
4098 			baseten = 0;
4099 			break;
4100 		case 'H':
4101 			humanize++;
4102 			baseten++;
4103 			break;
4104 		case 'N':
4105 			numblocks++;
4106 			break;
4107 		case 'q':
4108 			quiet++;
4109 			break;
4110 		case 's':
4111 			sizeonly++;
4112 			break;
4113 		default:
4114 			break;
4115 		}
4116 	}
4117 
4118 	if ((blocksizeonly != 0)
4119 	 && (numblocks != 0)) {
4120 		warnx("%s: you can only specify one of -b or -N", __func__);
4121 		retval = 1;
4122 		goto bailout;
4123 	}
4124 
4125 	if ((blocksizeonly != 0)
4126 	 && (sizeonly != 0)) {
4127 		warnx("%s: you can only specify one of -b or -s", __func__);
4128 		retval = 1;
4129 		goto bailout;
4130 	}
4131 
4132 	if ((humanize != 0)
4133 	 && (quiet != 0)) {
4134 		warnx("%s: you can only specify one of -h/-H or -q", __func__);
4135 		retval = 1;
4136 		goto bailout;
4137 	}
4138 
4139 	if ((humanize != 0)
4140 	 && (blocksizeonly != 0)) {
4141 		warnx("%s: you can only specify one of -h/-H or -b", __func__);
4142 		retval = 1;
4143 		goto bailout;
4144 	}
4145 
4146 	scsi_read_capacity(&ccb->csio,
4147 			   /*retries*/ retry_count,
4148 			   /*cbfcnp*/ NULL,
4149 			   /*tag_action*/ MSG_SIMPLE_Q_TAG,
4150 			   &rcap,
4151 			   SSD_FULL_SIZE,
4152 			   /*timeout*/ timeout ? timeout : 5000);
4153 
4154 	/* Disable freezing the device queue */
4155 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4156 
4157 	if (arglist & CAM_ARG_ERR_RECOVER)
4158 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4159 
4160 	if (cam_send_ccb(device, ccb) < 0) {
4161 		warn("error sending READ CAPACITY command");
4162 
4163 		if (arglist & CAM_ARG_VERBOSE)
4164 			cam_error_print(device, ccb, CAM_ESF_ALL,
4165 					CAM_EPF_ALL, stderr);
4166 
4167 		retval = 1;
4168 		goto bailout;
4169 	}
4170 
4171 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4172 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4173 		retval = 1;
4174 		goto bailout;
4175 	}
4176 
4177 	maxsector = scsi_4btoul(rcap.addr);
4178 	block_len = scsi_4btoul(rcap.length);
4179 
4180 	/*
4181 	 * A last block of 2^32-1 means that the true capacity is over 2TB,
4182 	 * and we need to issue the long READ CAPACITY to get the real
4183 	 * capacity.  Otherwise, we're all set.
4184 	 */
4185 	if (maxsector != 0xffffffff)
4186 		goto do_print;
4187 
4188 	scsi_read_capacity_16(&ccb->csio,
4189 			      /*retries*/ retry_count,
4190 			      /*cbfcnp*/ NULL,
4191 			      /*tag_action*/ MSG_SIMPLE_Q_TAG,
4192 			      /*lba*/ 0,
4193 			      /*reladdr*/ 0,
4194 			      /*pmi*/ 0,
4195 			      &rcaplong,
4196 			      /*sense_len*/ SSD_FULL_SIZE,
4197 			      /*timeout*/ timeout ? timeout : 5000);
4198 
4199 	/* Disable freezing the device queue */
4200 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4201 
4202 	if (arglist & CAM_ARG_ERR_RECOVER)
4203 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4204 
4205 	if (cam_send_ccb(device, ccb) < 0) {
4206 		warn("error sending READ CAPACITY (16) command");
4207 
4208 		if (arglist & CAM_ARG_VERBOSE)
4209 			cam_error_print(device, ccb, CAM_ESF_ALL,
4210 					CAM_EPF_ALL, stderr);
4211 
4212 		retval = 1;
4213 		goto bailout;
4214 	}
4215 
4216 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4217 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4218 		retval = 1;
4219 		goto bailout;
4220 	}
4221 
4222 	maxsector = scsi_8btou64(rcaplong.addr);
4223 	block_len = scsi_4btoul(rcaplong.length);
4224 
4225 do_print:
4226 	if (blocksizeonly == 0) {
4227 		/*
4228 		 * Humanize implies !quiet, and also implies numblocks.
4229 		 */
4230 		if (humanize != 0) {
4231 			char tmpstr[6];
4232 			int64_t tmpbytes;
4233 			int ret;
4234 
4235 			tmpbytes = (maxsector + 1) * block_len;
4236 			ret = humanize_number(tmpstr, sizeof(tmpstr),
4237 					      tmpbytes, "", HN_AUTOSCALE,
4238 					      HN_B | HN_DECIMAL |
4239 					      ((baseten != 0) ?
4240 					      HN_DIVISOR_1000 : 0));
4241 			if (ret == -1) {
4242 				warnx("%s: humanize_number failed!", __func__);
4243 				retval = 1;
4244 				goto bailout;
4245 			}
4246 			fprintf(stdout, "Device Size: %s%s", tmpstr,
4247 				(sizeonly == 0) ?  ", " : "\n");
4248 		} else if (numblocks != 0) {
4249 			fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4250 				"Blocks: " : "", (uintmax_t)maxsector + 1,
4251 				(sizeonly == 0) ? ", " : "\n");
4252 		} else {
4253 			fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4254 				"Last Block: " : "", (uintmax_t)maxsector,
4255 				(sizeonly == 0) ? ", " : "\n");
4256 		}
4257 	}
4258 	if (sizeonly == 0)
4259 		fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
4260 			"Block Length: " : "", block_len, (quiet == 0) ?
4261 			" bytes" : "");
4262 bailout:
4263 	cam_freeccb(ccb);
4264 
4265 	return (retval);
4266 }
4267 
4268 static int
4269 atapm(struct cam_device *device, int argc, char **argv,
4270 		 char *combinedopt, int retry_count, int timeout)
4271 {
4272 	union ccb *ccb;
4273 	int retval = 0;
4274 	int t = -1;
4275 	int c;
4276 	u_char cmd, sc;
4277 
4278 	ccb = cam_getccb(device);
4279 
4280 	if (ccb == NULL) {
4281 		warnx("%s: error allocating ccb", __func__);
4282 		return (1);
4283 	}
4284 
4285 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
4286 		switch (c) {
4287 		case 't':
4288 			t = atoi(optarg);
4289 			break;
4290 		default:
4291 			break;
4292 		}
4293 	}
4294 	if (strcmp(argv[1], "idle") == 0) {
4295 		if (t == -1)
4296 			cmd = ATA_IDLE_IMMEDIATE;
4297 		else
4298 			cmd = ATA_IDLE_CMD;
4299 	} else if (strcmp(argv[1], "standby") == 0) {
4300 		if (t == -1)
4301 			cmd = ATA_STANDBY_IMMEDIATE;
4302 		else
4303 			cmd = ATA_STANDBY_CMD;
4304 	} else {
4305 		cmd = ATA_SLEEP;
4306 		t = -1;
4307 	}
4308 	if (t < 0)
4309 		sc = 0;
4310 	else if (t <= (240 * 5))
4311 		sc = t / 5;
4312 	else if (t <= (11 * 30 * 60))
4313 		sc = t / (30 * 60) + 241;
4314 	else
4315 		sc = 253;
4316 	cam_fill_ataio(&ccb->ataio,
4317 		      retry_count,
4318 		      NULL,
4319 		      /*flags*/CAM_DIR_NONE,
4320 		      MSG_SIMPLE_Q_TAG,
4321 		      /*data_ptr*/NULL,
4322 		      /*dxfer_len*/0,
4323 		      timeout ? timeout : 30 * 1000);
4324 	ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
4325 
4326 	/* Disable freezing the device queue */
4327 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4328 
4329 	if (arglist & CAM_ARG_ERR_RECOVER)
4330 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4331 
4332 	if (cam_send_ccb(device, ccb) < 0) {
4333 		warn("error sending command");
4334 
4335 		if (arglist & CAM_ARG_VERBOSE)
4336 			cam_error_print(device, ccb, CAM_ESF_ALL,
4337 					CAM_EPF_ALL, stderr);
4338 
4339 		retval = 1;
4340 		goto bailout;
4341 	}
4342 
4343 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4344 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4345 		retval = 1;
4346 		goto bailout;
4347 	}
4348 bailout:
4349 	cam_freeccb(ccb);
4350 	return (retval);
4351 }
4352 
4353 #endif /* MINIMALISTIC */
4354 
4355 void
4356 usage(int verbose)
4357 {
4358 	fprintf(verbose ? stdout : stderr,
4359 "usage:  camcontrol <command>  [device id][generic args][command args]\n"
4360 "        camcontrol devlist    [-v]\n"
4361 #ifndef MINIMALISTIC
4362 "        camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
4363 "        camcontrol tur        [dev_id][generic args]\n"
4364 "        camcontrol inquiry    [dev_id][generic args] [-D] [-S] [-R]\n"
4365 "        camcontrol identify   [dev_id][generic args] [-v]\n"
4366 "        camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
4367 "        camcontrol readcap    [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
4368 "                              [-q] [-s]\n"
4369 "        camcontrol start      [dev_id][generic args]\n"
4370 "        camcontrol stop       [dev_id][generic args]\n"
4371 "        camcontrol load       [dev_id][generic args]\n"
4372 "        camcontrol eject      [dev_id][generic args]\n"
4373 #endif /* MINIMALISTIC */
4374 "        camcontrol rescan     <all | bus[:target:lun]>\n"
4375 "        camcontrol reset      <all | bus[:target:lun]>\n"
4376 #ifndef MINIMALISTIC
4377 "        camcontrol defects    [dev_id][generic args] <-f format> [-P][-G]\n"
4378 "        camcontrol modepage   [dev_id][generic args] <-m page | -l>\n"
4379 "                              [-P pagectl][-e | -b][-d]\n"
4380 "        camcontrol cmd        [dev_id][generic args]\n"
4381 "                              <-a cmd [args] | -c cmd [args]>\n"
4382 "                              [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
4383 "        camcontrol debug      [-I][-P][-T][-S][-X][-c]\n"
4384 "                              <all|bus[:target[:lun]]|off>\n"
4385 "        camcontrol tags       [dev_id][generic args] [-N tags] [-q] [-v]\n"
4386 "        camcontrol negotiate  [dev_id][generic args] [-a][-c]\n"
4387 "                              [-D <enable|disable>][-M mode][-O offset]\n"
4388 "                              [-q][-R syncrate][-v][-T <enable|disable>]\n"
4389 "                              [-U][-W bus_width]\n"
4390 "        camcontrol format     [dev_id][generic args][-q][-r][-w][-y]\n"
4391 "        camcontrol idle       [dev_id][generic args][-t time]\n"
4392 "        camcontrol standby    [dev_id][generic args][-t time]\n"
4393 "        camcontrol sleep      [dev_id][generic args]\n"
4394 #endif /* MINIMALISTIC */
4395 "        camcontrol help\n");
4396 	if (!verbose)
4397 		return;
4398 #ifndef MINIMALISTIC
4399 	fprintf(stdout,
4400 "Specify one of the following options:\n"
4401 "devlist     list all CAM devices\n"
4402 "periphlist  list all CAM peripheral drivers attached to a device\n"
4403 "tur         send a test unit ready to the named device\n"
4404 "inquiry     send a SCSI inquiry command to the named device\n"
4405 "identify    send a ATA identify command to the named device\n"
4406 "reportluns  send a SCSI report luns command to the device\n"
4407 "readcap     send a SCSI read capacity command to the device\n"
4408 "start       send a Start Unit command to the device\n"
4409 "stop        send a Stop Unit command to the device\n"
4410 "load        send a Start Unit command to the device with the load bit set\n"
4411 "eject       send a Stop Unit command to the device with the eject bit set\n"
4412 "rescan      rescan all busses, the given bus, or bus:target:lun\n"
4413 "reset       reset all busses, the given bus, or bus:target:lun\n"
4414 "defects     read the defect list of the specified device\n"
4415 "modepage    display or edit (-e) the given mode page\n"
4416 "cmd         send the given scsi command, may need -i or -o as well\n"
4417 "debug       turn debugging on/off for a bus, target, or lun, or all devices\n"
4418 "tags        report or set the number of transaction slots for a device\n"
4419 "negotiate   report or set device negotiation parameters\n"
4420 "format      send the SCSI FORMAT UNIT command to the named device\n"
4421 "idle        send the ATA IDLE command to the named device\n"
4422 "standby     send the ATA STANDBY command to the named device\n"
4423 "sleep       send the ATA SLEEP command to the named device\n"
4424 "help        this message\n"
4425 "Device Identifiers:\n"
4426 "bus:target        specify the bus and target, lun defaults to 0\n"
4427 "bus:target:lun    specify the bus, target and lun\n"
4428 "deviceUNIT        specify the device name, like \"da4\" or \"cd2\"\n"
4429 "Generic arguments:\n"
4430 "-v                be verbose, print out sense information\n"
4431 "-t timeout        command timeout in seconds, overrides default timeout\n"
4432 "-n dev_name       specify device name, e.g. \"da\", \"cd\"\n"
4433 "-u unit           specify unit number, e.g. \"0\", \"5\"\n"
4434 "-E                have the kernel attempt to perform SCSI error recovery\n"
4435 "-C count          specify the SCSI command retry count (needs -E to work)\n"
4436 "modepage arguments:\n"
4437 "-l                list all available mode pages\n"
4438 "-m page           specify the mode page to view or edit\n"
4439 "-e                edit the specified mode page\n"
4440 "-b                force view to binary mode\n"
4441 "-d                disable block descriptors for mode sense\n"
4442 "-P pgctl          page control field 0-3\n"
4443 "defects arguments:\n"
4444 "-f format         specify defect list format (block, bfi or phys)\n"
4445 "-G                get the grown defect list\n"
4446 "-P                get the permanant defect list\n"
4447 "inquiry arguments:\n"
4448 "-D                get the standard inquiry data\n"
4449 "-S                get the serial number\n"
4450 "-R                get the transfer rate, etc.\n"
4451 "reportluns arguments:\n"
4452 "-c                only report a count of available LUNs\n"
4453 "-l                only print out luns, and not a count\n"
4454 "-r <reporttype>   specify \"default\", \"wellknown\" or \"all\"\n"
4455 "readcap arguments\n"
4456 "-b                only report the blocksize\n"
4457 "-h                human readable device size, base 2\n"
4458 "-H                human readable device size, base 10\n"
4459 "-N                print the number of blocks instead of last block\n"
4460 "-q                quiet, print numbers only\n"
4461 "-s                only report the last block/device size\n"
4462 "cmd arguments:\n"
4463 "-c cdb [args]     specify the SCSI CDB\n"
4464 "-i len fmt        specify input data and input data format\n"
4465 "-o len fmt [args] specify output data and output data fmt\n"
4466 "debug arguments:\n"
4467 "-I                CAM_DEBUG_INFO -- scsi commands, errors, data\n"
4468 "-T                CAM_DEBUG_TRACE -- routine flow tracking\n"
4469 "-S                CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
4470 "-c                CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
4471 "tags arguments:\n"
4472 "-N tags           specify the number of tags to use for this device\n"
4473 "-q                be quiet, don't report the number of tags\n"
4474 "-v                report a number of tag-related parameters\n"
4475 "negotiate arguments:\n"
4476 "-a                send a test unit ready after negotiation\n"
4477 "-c                report/set current negotiation settings\n"
4478 "-D <arg>          \"enable\" or \"disable\" disconnection\n"
4479 "-M mode           set ATA mode\n"
4480 "-O offset         set command delay offset\n"
4481 "-q                be quiet, don't report anything\n"
4482 "-R syncrate       synchronization rate in MHz\n"
4483 "-T <arg>          \"enable\" or \"disable\" tagged queueing\n"
4484 "-U                report/set user negotiation settings\n"
4485 "-W bus_width      set the bus width in bits (8, 16 or 32)\n"
4486 "-v                also print a Path Inquiry CCB for the controller\n"
4487 "format arguments:\n"
4488 "-q                be quiet, don't print status messages\n"
4489 "-r                run in report only mode\n"
4490 "-w                don't send immediate format command\n"
4491 "-y                don't ask any questions\n"
4492 "idle/standby arguments:\n"
4493 "-t <arg>          number of seconds before respective state.\n");
4494 #endif /* MINIMALISTIC */
4495 }
4496 
4497 int
4498 main(int argc, char **argv)
4499 {
4500 	int c;
4501 	char *device = NULL;
4502 	int unit = 0;
4503 	struct cam_device *cam_dev = NULL;
4504 	int timeout = 0, retry_count = 1;
4505 	camcontrol_optret optreturn;
4506 	char *tstr;
4507 	const char *mainopt = "C:En:t:u:v";
4508 	const char *subopt = NULL;
4509 	char combinedopt[256];
4510 	int error = 0, optstart = 2;
4511 	int devopen = 1;
4512 #ifndef MINIMALISTIC
4513 	int bus, target, lun;
4514 #endif /* MINIMALISTIC */
4515 
4516 	cmdlist = CAM_CMD_NONE;
4517 	arglist = CAM_ARG_NONE;
4518 
4519 	if (argc < 2) {
4520 		usage(0);
4521 		exit(1);
4522 	}
4523 
4524 	/*
4525 	 * Get the base option.
4526 	 */
4527 	optreturn = getoption(argv[1], &cmdlist, &arglist, &subopt);
4528 
4529 	if (optreturn == CC_OR_AMBIGUOUS) {
4530 		warnx("ambiguous option %s", argv[1]);
4531 		usage(0);
4532 		exit(1);
4533 	} else if (optreturn == CC_OR_NOT_FOUND) {
4534 		warnx("option %s not found", argv[1]);
4535 		usage(0);
4536 		exit(1);
4537 	}
4538 
4539 	/*
4540 	 * Ahh, getopt(3) is a pain.
4541 	 *
4542 	 * This is a gross hack.  There really aren't many other good
4543 	 * options (excuse the pun) for parsing options in a situation like
4544 	 * this.  getopt is kinda braindead, so you end up having to run
4545 	 * through the options twice, and give each invocation of getopt
4546 	 * the option string for the other invocation.
4547 	 *
4548 	 * You would think that you could just have two groups of options.
4549 	 * The first group would get parsed by the first invocation of
4550 	 * getopt, and the second group would get parsed by the second
4551 	 * invocation of getopt.  It doesn't quite work out that way.  When
4552 	 * the first invocation of getopt finishes, it leaves optind pointing
4553 	 * to the argument _after_ the first argument in the second group.
4554 	 * So when the second invocation of getopt comes around, it doesn't
4555 	 * recognize the first argument it gets and then bails out.
4556 	 *
4557 	 * A nice alternative would be to have a flag for getopt that says
4558 	 * "just keep parsing arguments even when you encounter an unknown
4559 	 * argument", but there isn't one.  So there's no real clean way to
4560 	 * easily parse two sets of arguments without having one invocation
4561 	 * of getopt know about the other.
4562 	 *
4563 	 * Without this hack, the first invocation of getopt would work as
4564 	 * long as the generic arguments are first, but the second invocation
4565 	 * (in the subfunction) would fail in one of two ways.  In the case
4566 	 * where you don't set optreset, it would fail because optind may be
4567 	 * pointing to the argument after the one it should be pointing at.
4568 	 * In the case where you do set optreset, and reset optind, it would
4569 	 * fail because getopt would run into the first set of options, which
4570 	 * it doesn't understand.
4571 	 *
4572 	 * All of this would "sort of" work if you could somehow figure out
4573 	 * whether optind had been incremented one option too far.  The
4574 	 * mechanics of that, however, are more daunting than just giving
4575 	 * both invocations all of the expect options for either invocation.
4576 	 *
4577 	 * Needless to say, I wouldn't mind if someone invented a better
4578 	 * (non-GPL!) command line parsing interface than getopt.  I
4579 	 * wouldn't mind if someone added more knobs to getopt to make it
4580 	 * work better.  Who knows, I may talk myself into doing it someday,
4581 	 * if the standards weenies let me.  As it is, it just leads to
4582 	 * hackery like this and causes people to avoid it in some cases.
4583 	 *
4584 	 * KDM, September 8th, 1998
4585 	 */
4586 	if (subopt != NULL)
4587 		sprintf(combinedopt, "%s%s", mainopt, subopt);
4588 	else
4589 		sprintf(combinedopt, "%s", mainopt);
4590 
4591 	/*
4592 	 * For these options we do not parse optional device arguments and
4593 	 * we do not open a passthrough device.
4594 	 */
4595 	if ((cmdlist == CAM_CMD_RESCAN)
4596 	 || (cmdlist == CAM_CMD_RESET)
4597 	 || (cmdlist == CAM_CMD_DEVTREE)
4598 	 || (cmdlist == CAM_CMD_USAGE)
4599 	 || (cmdlist == CAM_CMD_DEBUG))
4600 		devopen = 0;
4601 
4602 #ifndef MINIMALISTIC
4603 	if ((devopen == 1)
4604 	 && (argc > 2 && argv[2][0] != '-')) {
4605 		char name[30];
4606 		int rv;
4607 
4608 		/*
4609 		 * First catch people who try to do things like:
4610 		 * camcontrol tur /dev/da0
4611 		 * camcontrol doesn't take device nodes as arguments.
4612 		 */
4613 		if (argv[2][0] == '/') {
4614 			warnx("%s is not a valid device identifier", argv[2]);
4615 			errx(1, "please read the camcontrol(8) man page");
4616 		} else if (isdigit(argv[2][0])) {
4617 			/* device specified as bus:target[:lun] */
4618 			rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
4619 			if (rv < 2)
4620 				errx(1, "numeric device specification must "
4621 				     "be either bus:target, or "
4622 				     "bus:target:lun");
4623 			/* default to 0 if lun was not specified */
4624 			if ((arglist & CAM_ARG_LUN) == 0) {
4625 				lun = 0;
4626 				arglist |= CAM_ARG_LUN;
4627 			}
4628 			optstart++;
4629 		} else {
4630 			if (cam_get_device(argv[2], name, sizeof name, &unit)
4631 			    == -1)
4632 				errx(1, "%s", cam_errbuf);
4633 			device = strdup(name);
4634 			arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
4635 			optstart++;
4636 		}
4637 	}
4638 #endif /* MINIMALISTIC */
4639 	/*
4640 	 * Start getopt processing at argv[2/3], since we've already
4641 	 * accepted argv[1..2] as the command name, and as a possible
4642 	 * device name.
4643 	 */
4644 	optind = optstart;
4645 
4646 	/*
4647 	 * Now we run through the argument list looking for generic
4648 	 * options, and ignoring options that possibly belong to
4649 	 * subfunctions.
4650 	 */
4651 	while ((c = getopt(argc, argv, combinedopt))!= -1){
4652 		switch(c) {
4653 			case 'C':
4654 				retry_count = strtol(optarg, NULL, 0);
4655 				if (retry_count < 0)
4656 					errx(1, "retry count %d is < 0",
4657 					     retry_count);
4658 				arglist |= CAM_ARG_RETRIES;
4659 				break;
4660 			case 'E':
4661 				arglist |= CAM_ARG_ERR_RECOVER;
4662 				break;
4663 			case 'n':
4664 				arglist |= CAM_ARG_DEVICE;
4665 				tstr = optarg;
4666 				while (isspace(*tstr) && (*tstr != '\0'))
4667 					tstr++;
4668 				device = (char *)strdup(tstr);
4669 				break;
4670 			case 't':
4671 				timeout = strtol(optarg, NULL, 0);
4672 				if (timeout < 0)
4673 					errx(1, "invalid timeout %d", timeout);
4674 				/* Convert the timeout from seconds to ms */
4675 				timeout *= 1000;
4676 				arglist |= CAM_ARG_TIMEOUT;
4677 				break;
4678 			case 'u':
4679 				arglist |= CAM_ARG_UNIT;
4680 				unit = strtol(optarg, NULL, 0);
4681 				break;
4682 			case 'v':
4683 				arglist |= CAM_ARG_VERBOSE;
4684 				break;
4685 			default:
4686 				break;
4687 		}
4688 	}
4689 
4690 #ifndef MINIMALISTIC
4691 	/*
4692 	 * For most commands we'll want to open the passthrough device
4693 	 * associated with the specified device.  In the case of the rescan
4694 	 * commands, we don't use a passthrough device at all, just the
4695 	 * transport layer device.
4696 	 */
4697 	if (devopen == 1) {
4698 		if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
4699 		 && (((arglist & CAM_ARG_DEVICE) == 0)
4700 		  || ((arglist & CAM_ARG_UNIT) == 0))) {
4701 			errx(1, "subcommand \"%s\" requires a valid device "
4702 			     "identifier", argv[1]);
4703 		}
4704 
4705 		if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
4706 				cam_open_btl(bus, target, lun, O_RDWR, NULL) :
4707 				cam_open_spec_device(device,unit,O_RDWR,NULL)))
4708 		     == NULL)
4709 			errx(1,"%s", cam_errbuf);
4710 	}
4711 #endif /* MINIMALISTIC */
4712 
4713 	/*
4714 	 * Reset optind to 2, and reset getopt, so these routines can parse
4715 	 * the arguments again.
4716 	 */
4717 	optind = optstart;
4718 	optreset = 1;
4719 
4720 	switch(cmdlist) {
4721 #ifndef MINIMALISTIC
4722 		case CAM_CMD_DEVLIST:
4723 			error = getdevlist(cam_dev);
4724 			break;
4725 #endif /* MINIMALISTIC */
4726 		case CAM_CMD_DEVTREE:
4727 			error = getdevtree();
4728 			break;
4729 #ifndef MINIMALISTIC
4730 		case CAM_CMD_TUR:
4731 			error = testunitready(cam_dev, retry_count, timeout, 0);
4732 			break;
4733 		case CAM_CMD_INQUIRY:
4734 			error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
4735 					      retry_count, timeout);
4736 			break;
4737 		case CAM_CMD_IDENTIFY:
4738 			error = ataidentify(cam_dev, retry_count, timeout);
4739 			break;
4740 		case CAM_CMD_STARTSTOP:
4741 			error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
4742 					  arglist & CAM_ARG_EJECT, retry_count,
4743 					  timeout);
4744 			break;
4745 #endif /* MINIMALISTIC */
4746 		case CAM_CMD_RESCAN:
4747 			error = dorescan_or_reset(argc, argv, 1);
4748 			break;
4749 		case CAM_CMD_RESET:
4750 			error = dorescan_or_reset(argc, argv, 0);
4751 			break;
4752 #ifndef MINIMALISTIC
4753 		case CAM_CMD_READ_DEFECTS:
4754 			error = readdefects(cam_dev, argc, argv, combinedopt,
4755 					    retry_count, timeout);
4756 			break;
4757 		case CAM_CMD_MODE_PAGE:
4758 			modepage(cam_dev, argc, argv, combinedopt,
4759 				 retry_count, timeout);
4760 			break;
4761 		case CAM_CMD_SCSI_CMD:
4762 			error = scsicmd(cam_dev, argc, argv, combinedopt,
4763 					retry_count, timeout);
4764 			break;
4765 		case CAM_CMD_DEBUG:
4766 			error = camdebug(argc, argv, combinedopt);
4767 			break;
4768 		case CAM_CMD_TAG:
4769 			error = tagcontrol(cam_dev, argc, argv, combinedopt);
4770 			break;
4771 		case CAM_CMD_RATE:
4772 			error = ratecontrol(cam_dev, retry_count, timeout,
4773 					    argc, argv, combinedopt);
4774 			break;
4775 		case CAM_CMD_FORMAT:
4776 			error = scsiformat(cam_dev, argc, argv,
4777 					   combinedopt, retry_count, timeout);
4778 			break;
4779 		case CAM_CMD_REPORTLUNS:
4780 			error = scsireportluns(cam_dev, argc, argv,
4781 					       combinedopt, retry_count,
4782 					       timeout);
4783 			break;
4784 		case CAM_CMD_READCAP:
4785 			error = scsireadcapacity(cam_dev, argc, argv,
4786 						 combinedopt, retry_count,
4787 						 timeout);
4788 			break;
4789 		case CAM_CMD_IDLE:
4790 		case CAM_CMD_STANDBY:
4791 		case CAM_CMD_SLEEP:
4792 			error = atapm(cam_dev, argc, argv,
4793 						 combinedopt, retry_count,
4794 						 timeout);
4795 			break;
4796 #endif /* MINIMALISTIC */
4797 		case CAM_CMD_USAGE:
4798 			usage(1);
4799 			break;
4800 		default:
4801 			usage(0);
4802 			error = 1;
4803 			break;
4804 	}
4805 
4806 	if (cam_dev != NULL)
4807 		cam_close_device(cam_dev);
4808 
4809 	exit(error);
4810 }
4811