xref: /freebsd/sbin/camcontrol/camcontrol.c (revision 31f957034a5f23eafcb47aa7a2d54e3a03de1b4d)
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:i: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 need_res = 0;
2188 	char *datastr = NULL, *tstr, *resstr = NULL;
2189 	int error = 0;
2190 	int fd_data = 0, fd_res = 0;
2191 	int retval;
2192 
2193 	ccb = cam_getccb(device);
2194 
2195 	if (ccb == NULL) {
2196 		warnx("scsicmd: error allocating ccb");
2197 		return(1);
2198 	}
2199 
2200 	bzero(&(&ccb->ccb_h)[1],
2201 	      sizeof(union ccb) - sizeof(struct ccb_hdr));
2202 
2203 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
2204 		switch(c) {
2205 		case 'a':
2206 			tstr = optarg;
2207 			while (isspace(*tstr) && (*tstr != '\0'))
2208 				tstr++;
2209 			hook.argc = argc - optind;
2210 			hook.argv = argv + optind;
2211 			hook.got = 0;
2212 			atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
2213 						    iget, &hook);
2214 			/*
2215 			 * Increment optind by the number of arguments the
2216 			 * encoding routine processed.  After each call to
2217 			 * getopt(3), optind points to the argument that
2218 			 * getopt should process _next_.  In this case,
2219 			 * that means it points to the first command string
2220 			 * argument, if there is one.  Once we increment
2221 			 * this, it should point to either the next command
2222 			 * line argument, or it should be past the end of
2223 			 * the list.
2224 			 */
2225 			optind += hook.got;
2226 			break;
2227 		case 'c':
2228 			tstr = optarg;
2229 			while (isspace(*tstr) && (*tstr != '\0'))
2230 				tstr++;
2231 			hook.argc = argc - optind;
2232 			hook.argv = argv + optind;
2233 			hook.got = 0;
2234 			cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
2235 						    iget, &hook);
2236 			/*
2237 			 * Increment optind by the number of arguments the
2238 			 * encoding routine processed.  After each call to
2239 			 * getopt(3), optind points to the argument that
2240 			 * getopt should process _next_.  In this case,
2241 			 * that means it points to the first command string
2242 			 * argument, if there is one.  Once we increment
2243 			 * this, it should point to either the next command
2244 			 * line argument, or it should be past the end of
2245 			 * the list.
2246 			 */
2247 			optind += hook.got;
2248 			break;
2249 		case 'i':
2250 			if (arglist & CAM_ARG_CMD_OUT) {
2251 				warnx("command must either be "
2252 				      "read or write, not both");
2253 				error = 1;
2254 				goto scsicmd_bailout;
2255 			}
2256 			arglist |= CAM_ARG_CMD_IN;
2257 			flags = CAM_DIR_IN;
2258 			data_bytes = strtol(optarg, NULL, 0);
2259 			if (data_bytes <= 0) {
2260 				warnx("invalid number of input bytes %d",
2261 				      data_bytes);
2262 				error = 1;
2263 				goto scsicmd_bailout;
2264 			}
2265 			hook.argc = argc - optind;
2266 			hook.argv = argv + optind;
2267 			hook.got = 0;
2268 			optind++;
2269 			datastr = cget(&hook, NULL);
2270 			/*
2271 			 * If the user supplied "-" instead of a format, he
2272 			 * wants the data to be written to stdout.
2273 			 */
2274 			if ((datastr != NULL)
2275 			 && (datastr[0] == '-'))
2276 				fd_data = 1;
2277 
2278 			data_ptr = (u_int8_t *)malloc(data_bytes);
2279 			if (data_ptr == NULL) {
2280 				warnx("can't malloc memory for data_ptr");
2281 				error = 1;
2282 				goto scsicmd_bailout;
2283 			}
2284 			break;
2285 		case 'o':
2286 			if (arglist & CAM_ARG_CMD_IN) {
2287 				warnx("command must either be "
2288 				      "read or write, not both");
2289 				error = 1;
2290 				goto scsicmd_bailout;
2291 			}
2292 			arglist |= CAM_ARG_CMD_OUT;
2293 			flags = CAM_DIR_OUT;
2294 			data_bytes = strtol(optarg, NULL, 0);
2295 			if (data_bytes <= 0) {
2296 				warnx("invalid number of output bytes %d",
2297 				      data_bytes);
2298 				error = 1;
2299 				goto scsicmd_bailout;
2300 			}
2301 			hook.argc = argc - optind;
2302 			hook.argv = argv + optind;
2303 			hook.got = 0;
2304 			datastr = cget(&hook, NULL);
2305 			data_ptr = (u_int8_t *)malloc(data_bytes);
2306 			if (data_ptr == NULL) {
2307 				warnx("can't malloc memory for data_ptr");
2308 				error = 1;
2309 				goto scsicmd_bailout;
2310 			}
2311 			bzero(data_ptr, data_bytes);
2312 			/*
2313 			 * If the user supplied "-" instead of a format, he
2314 			 * wants the data to be read from stdin.
2315 			 */
2316 			if ((datastr != NULL)
2317 			 && (datastr[0] == '-'))
2318 				fd_data = 1;
2319 			else
2320 				buff_encode_visit(data_ptr, data_bytes, datastr,
2321 						  iget, &hook);
2322 			optind += hook.got;
2323 			break;
2324 		case 'r':
2325 			need_res = 1;
2326 			hook.argc = argc - optind;
2327 			hook.argv = argv + optind;
2328 			hook.got = 0;
2329 			resstr = cget(&hook, NULL);
2330 			if ((resstr != NULL) && (resstr[0] == '-'))
2331 				fd_res = 1;
2332 			optind += hook.got;
2333 			break;
2334 		default:
2335 			break;
2336 		}
2337 	}
2338 
2339 	/*
2340 	 * If fd_data is set, and we're writing to the device, we need to
2341 	 * read the data the user wants written from stdin.
2342 	 */
2343 	if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
2344 		ssize_t amt_read;
2345 		int amt_to_read = data_bytes;
2346 		u_int8_t *buf_ptr = data_ptr;
2347 
2348 		for (amt_read = 0; amt_to_read > 0;
2349 		     amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
2350 			if (amt_read == -1) {
2351 				warn("error reading data from stdin");
2352 				error = 1;
2353 				goto scsicmd_bailout;
2354 			}
2355 			amt_to_read -= amt_read;
2356 			buf_ptr += amt_read;
2357 		}
2358 	}
2359 
2360 	if (arglist & CAM_ARG_ERR_RECOVER)
2361 		flags |= CAM_PASS_ERR_RECOVER;
2362 
2363 	/* Disable freezing the device queue */
2364 	flags |= CAM_DEV_QFRZDIS;
2365 
2366 	if (cdb_len) {
2367 		/*
2368 		 * This is taken from the SCSI-3 draft spec.
2369 		 * (T10/1157D revision 0.3)
2370 		 * The top 3 bits of an opcode are the group code.
2371 		 * The next 5 bits are the command code.
2372 		 * Group 0:  six byte commands
2373 		 * Group 1:  ten byte commands
2374 		 * Group 2:  ten byte commands
2375 		 * Group 3:  reserved
2376 		 * Group 4:  sixteen byte commands
2377 		 * Group 5:  twelve byte commands
2378 		 * Group 6:  vendor specific
2379 		 * Group 7:  vendor specific
2380 		 */
2381 		switch((cdb[0] >> 5) & 0x7) {
2382 			case 0:
2383 				cdb_len = 6;
2384 				break;
2385 			case 1:
2386 			case 2:
2387 				cdb_len = 10;
2388 				break;
2389 			case 3:
2390 			case 6:
2391 			case 7:
2392 			        /* computed by buff_encode_visit */
2393 				break;
2394 			case 4:
2395 				cdb_len = 16;
2396 				break;
2397 			case 5:
2398 				cdb_len = 12;
2399 				break;
2400 		}
2401 
2402 		/*
2403 		 * We should probably use csio_build_visit or something like that
2404 		 * here, but it's easier to encode arguments as you go.  The
2405 		 * alternative would be skipping the CDB argument and then encoding
2406 		 * it here, since we've got the data buffer argument by now.
2407 		 */
2408 		bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
2409 
2410 		cam_fill_csio(&ccb->csio,
2411 		      /*retries*/ retry_count,
2412 		      /*cbfcnp*/ NULL,
2413 		      /*flags*/ flags,
2414 		      /*tag_action*/ MSG_SIMPLE_Q_TAG,
2415 		      /*data_ptr*/ data_ptr,
2416 		      /*dxfer_len*/ data_bytes,
2417 		      /*sense_len*/ SSD_FULL_SIZE,
2418 		      /*cdb_len*/ cdb_len,
2419 		      /*timeout*/ timeout ? timeout : 5000);
2420 	} else {
2421 		atacmd_len = 12;
2422 		bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
2423 		if (need_res)
2424 			ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
2425 
2426 		cam_fill_ataio(&ccb->ataio,
2427 		      /*retries*/ retry_count,
2428 		      /*cbfcnp*/ NULL,
2429 		      /*flags*/ flags,
2430 		      /*tag_action*/ 0,
2431 		      /*data_ptr*/ data_ptr,
2432 		      /*dxfer_len*/ data_bytes,
2433 		      /*timeout*/ timeout ? timeout : 5000);
2434 	}
2435 
2436 	if (((retval = cam_send_ccb(device, ccb)) < 0)
2437 	 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2438 		if (retval < 0)
2439 			warn("error sending command");
2440 		else
2441 			warnx("error sending command");
2442 
2443 		if (arglist & CAM_ARG_VERBOSE) {
2444 			cam_error_print(device, ccb, CAM_ESF_ALL,
2445 					CAM_EPF_ALL, stderr);
2446 		}
2447 
2448 		error = 1;
2449 		goto scsicmd_bailout;
2450 	}
2451 
2452 	if (atacmd_len && need_res) {
2453 		if (fd_res == 0) {
2454 			buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
2455 					  arg_put, NULL);
2456 			fprintf(stdout, "\n");
2457 		} else {
2458 			fprintf(stdout,
2459 			    "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
2460 			    ccb->ataio.res.status,
2461 			    ccb->ataio.res.error,
2462 			    ccb->ataio.res.lba_low,
2463 			    ccb->ataio.res.lba_mid,
2464 			    ccb->ataio.res.lba_high,
2465 			    ccb->ataio.res.device,
2466 			    ccb->ataio.res.lba_low_exp,
2467 			    ccb->ataio.res.lba_mid_exp,
2468 			    ccb->ataio.res.lba_high_exp,
2469 			    ccb->ataio.res.sector_count,
2470 			    ccb->ataio.res.sector_count_exp);
2471 			fflush(stdout);
2472 		}
2473 	}
2474 
2475 	if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
2476 	 && (arglist & CAM_ARG_CMD_IN)
2477 	 && (data_bytes > 0)) {
2478 		if (fd_data == 0) {
2479 			buff_decode_visit(data_ptr, data_bytes, datastr,
2480 					  arg_put, NULL);
2481 			fprintf(stdout, "\n");
2482 		} else {
2483 			ssize_t amt_written;
2484 			int amt_to_write = data_bytes;
2485 			u_int8_t *buf_ptr = data_ptr;
2486 
2487 			for (amt_written = 0; (amt_to_write > 0) &&
2488 			     (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
2489 				amt_to_write -= amt_written;
2490 				buf_ptr += amt_written;
2491 			}
2492 			if (amt_written == -1) {
2493 				warn("error writing data to stdout");
2494 				error = 1;
2495 				goto scsicmd_bailout;
2496 			} else if ((amt_written == 0)
2497 				&& (amt_to_write > 0)) {
2498 				warnx("only wrote %u bytes out of %u",
2499 				      data_bytes - amt_to_write, data_bytes);
2500 			}
2501 		}
2502 	}
2503 
2504 scsicmd_bailout:
2505 
2506 	if ((data_bytes > 0) && (data_ptr != NULL))
2507 		free(data_ptr);
2508 
2509 	cam_freeccb(ccb);
2510 
2511 	return(error);
2512 }
2513 
2514 static int
2515 camdebug(int argc, char **argv, char *combinedopt)
2516 {
2517 	int c, fd;
2518 	int bus = -1, target = -1, lun = -1;
2519 	char *tstr, *tmpstr = NULL;
2520 	union ccb ccb;
2521 	int error = 0;
2522 
2523 	bzero(&ccb, sizeof(union ccb));
2524 
2525 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
2526 		switch(c) {
2527 		case 'I':
2528 			arglist |= CAM_ARG_DEBUG_INFO;
2529 			ccb.cdbg.flags |= CAM_DEBUG_INFO;
2530 			break;
2531 		case 'P':
2532 			arglist |= CAM_ARG_DEBUG_PERIPH;
2533 			ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
2534 			break;
2535 		case 'S':
2536 			arglist |= CAM_ARG_DEBUG_SUBTRACE;
2537 			ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
2538 			break;
2539 		case 'T':
2540 			arglist |= CAM_ARG_DEBUG_TRACE;
2541 			ccb.cdbg.flags |= CAM_DEBUG_TRACE;
2542 			break;
2543 		case 'X':
2544 			arglist |= CAM_ARG_DEBUG_XPT;
2545 			ccb.cdbg.flags |= CAM_DEBUG_XPT;
2546 			break;
2547 		case 'c':
2548 			arglist |= CAM_ARG_DEBUG_CDB;
2549 			ccb.cdbg.flags |= CAM_DEBUG_CDB;
2550 			break;
2551 		default:
2552 			break;
2553 		}
2554 	}
2555 
2556 	if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
2557 		warnx("error opening transport layer device %s", XPT_DEVICE);
2558 		warn("%s", XPT_DEVICE);
2559 		return(1);
2560 	}
2561 	argc -= optind;
2562 	argv += optind;
2563 
2564 	if (argc <= 0) {
2565 		warnx("you must specify \"off\", \"all\" or a bus,");
2566 		warnx("bus:target, or bus:target:lun");
2567 		close(fd);
2568 		return(1);
2569 	}
2570 
2571 	tstr = *argv;
2572 
2573 	while (isspace(*tstr) && (*tstr != '\0'))
2574 		tstr++;
2575 
2576 	if (strncmp(tstr, "off", 3) == 0) {
2577 		ccb.cdbg.flags = CAM_DEBUG_NONE;
2578 		arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
2579 			     CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
2580 			     CAM_ARG_DEBUG_XPT);
2581 	} else if (strncmp(tstr, "all", 3) != 0) {
2582 		tmpstr = (char *)strtok(tstr, ":");
2583 		if ((tmpstr != NULL) && (*tmpstr != '\0')){
2584 			bus = strtol(tmpstr, NULL, 0);
2585 			arglist |= CAM_ARG_BUS;
2586 			tmpstr = (char *)strtok(NULL, ":");
2587 			if ((tmpstr != NULL) && (*tmpstr != '\0')){
2588 				target = strtol(tmpstr, NULL, 0);
2589 				arglist |= CAM_ARG_TARGET;
2590 				tmpstr = (char *)strtok(NULL, ":");
2591 				if ((tmpstr != NULL) && (*tmpstr != '\0')){
2592 					lun = strtol(tmpstr, NULL, 0);
2593 					arglist |= CAM_ARG_LUN;
2594 				}
2595 			}
2596 		} else {
2597 			error = 1;
2598 			warnx("you must specify \"all\", \"off\", or a bus,");
2599 			warnx("bus:target, or bus:target:lun to debug");
2600 		}
2601 	}
2602 
2603 	if (error == 0) {
2604 
2605 		ccb.ccb_h.func_code = XPT_DEBUG;
2606 		ccb.ccb_h.path_id = bus;
2607 		ccb.ccb_h.target_id = target;
2608 		ccb.ccb_h.target_lun = lun;
2609 
2610 		if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
2611 			warn("CAMIOCOMMAND ioctl failed");
2612 			error = 1;
2613 		}
2614 
2615 		if (error == 0) {
2616 			if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
2617 			     CAM_FUNC_NOTAVAIL) {
2618 				warnx("CAM debugging not available");
2619 				warnx("you need to put options CAMDEBUG in"
2620 				      " your kernel config file!");
2621 				error = 1;
2622 			} else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
2623 				    CAM_REQ_CMP) {
2624 				warnx("XPT_DEBUG CCB failed with status %#x",
2625 				      ccb.ccb_h.status);
2626 				error = 1;
2627 			} else {
2628 				if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
2629 					fprintf(stderr,
2630 						"Debugging turned off\n");
2631 				} else {
2632 					fprintf(stderr,
2633 						"Debugging enabled for "
2634 						"%d:%d:%d\n",
2635 						bus, target, lun);
2636 				}
2637 			}
2638 		}
2639 		close(fd);
2640 	}
2641 
2642 	return(error);
2643 }
2644 
2645 static int
2646 tagcontrol(struct cam_device *device, int argc, char **argv,
2647 	   char *combinedopt)
2648 {
2649 	int c;
2650 	union ccb *ccb;
2651 	int numtags = -1;
2652 	int retval = 0;
2653 	int quiet = 0;
2654 	char pathstr[1024];
2655 
2656 	ccb = cam_getccb(device);
2657 
2658 	if (ccb == NULL) {
2659 		warnx("tagcontrol: error allocating ccb");
2660 		return(1);
2661 	}
2662 
2663 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
2664 		switch(c) {
2665 		case 'N':
2666 			numtags = strtol(optarg, NULL, 0);
2667 			if (numtags < 0) {
2668 				warnx("tag count %d is < 0", numtags);
2669 				retval = 1;
2670 				goto tagcontrol_bailout;
2671 			}
2672 			break;
2673 		case 'q':
2674 			quiet++;
2675 			break;
2676 		default:
2677 			break;
2678 		}
2679 	}
2680 
2681 	cam_path_string(device, pathstr, sizeof(pathstr));
2682 
2683 	if (numtags >= 0) {
2684 		bzero(&(&ccb->ccb_h)[1],
2685 		      sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
2686 		ccb->ccb_h.func_code = XPT_REL_SIMQ;
2687 		ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
2688 		ccb->crs.openings = numtags;
2689 
2690 
2691 		if (cam_send_ccb(device, ccb) < 0) {
2692 			perror("error sending XPT_REL_SIMQ CCB");
2693 			retval = 1;
2694 			goto tagcontrol_bailout;
2695 		}
2696 
2697 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2698 			warnx("XPT_REL_SIMQ CCB failed");
2699 			cam_error_print(device, ccb, CAM_ESF_ALL,
2700 					CAM_EPF_ALL, stderr);
2701 			retval = 1;
2702 			goto tagcontrol_bailout;
2703 		}
2704 
2705 
2706 		if (quiet == 0)
2707 			fprintf(stdout, "%stagged openings now %d\n",
2708 				pathstr, ccb->crs.openings);
2709 	}
2710 
2711 	bzero(&(&ccb->ccb_h)[1],
2712 	      sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
2713 
2714 	ccb->ccb_h.func_code = XPT_GDEV_STATS;
2715 
2716 	if (cam_send_ccb(device, ccb) < 0) {
2717 		perror("error sending XPT_GDEV_STATS CCB");
2718 		retval = 1;
2719 		goto tagcontrol_bailout;
2720 	}
2721 
2722 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2723 		warnx("XPT_GDEV_STATS CCB failed");
2724 		cam_error_print(device, ccb, CAM_ESF_ALL,
2725 				CAM_EPF_ALL, stderr);
2726 		retval = 1;
2727 		goto tagcontrol_bailout;
2728 	}
2729 
2730 	if (arglist & CAM_ARG_VERBOSE) {
2731 		fprintf(stdout, "%s", pathstr);
2732 		fprintf(stdout, "dev_openings  %d\n", ccb->cgds.dev_openings);
2733 		fprintf(stdout, "%s", pathstr);
2734 		fprintf(stdout, "dev_active    %d\n", ccb->cgds.dev_active);
2735 		fprintf(stdout, "%s", pathstr);
2736 		fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
2737 		fprintf(stdout, "%s", pathstr);
2738 		fprintf(stdout, "devq_queued   %d\n", ccb->cgds.devq_queued);
2739 		fprintf(stdout, "%s", pathstr);
2740 		fprintf(stdout, "held          %d\n", ccb->cgds.held);
2741 		fprintf(stdout, "%s", pathstr);
2742 		fprintf(stdout, "mintags       %d\n", ccb->cgds.mintags);
2743 		fprintf(stdout, "%s", pathstr);
2744 		fprintf(stdout, "maxtags       %d\n", ccb->cgds.maxtags);
2745 	} else {
2746 		if (quiet == 0) {
2747 			fprintf(stdout, "%s", pathstr);
2748 			fprintf(stdout, "device openings: ");
2749 		}
2750 		fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
2751 			ccb->cgds.dev_active);
2752 	}
2753 
2754 tagcontrol_bailout:
2755 
2756 	cam_freeccb(ccb);
2757 	return(retval);
2758 }
2759 
2760 static void
2761 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
2762 {
2763 	char pathstr[1024];
2764 
2765 	cam_path_string(device, pathstr, sizeof(pathstr));
2766 
2767 	if (cts->transport == XPORT_SPI) {
2768 		struct ccb_trans_settings_spi *spi =
2769 		    &cts->xport_specific.spi;
2770 
2771 		if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
2772 
2773 			fprintf(stdout, "%ssync parameter: %d\n", pathstr,
2774 				spi->sync_period);
2775 
2776 			if (spi->sync_offset != 0) {
2777 				u_int freq;
2778 
2779 				freq = scsi_calc_syncsrate(spi->sync_period);
2780 				fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
2781 					pathstr, freq / 1000, freq % 1000);
2782 			}
2783 		}
2784 
2785 		if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
2786 			fprintf(stdout, "%soffset: %d\n", pathstr,
2787 			    spi->sync_offset);
2788 		}
2789 
2790 		if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
2791 			fprintf(stdout, "%sbus width: %d bits\n", pathstr,
2792 				(0x01 << spi->bus_width) * 8);
2793 		}
2794 
2795 		if (spi->valid & CTS_SPI_VALID_DISC) {
2796 			fprintf(stdout, "%sdisconnection is %s\n", pathstr,
2797 				(spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
2798 				"enabled" : "disabled");
2799 		}
2800 	}
2801 	if (cts->transport == XPORT_ATA) {
2802 		struct ccb_trans_settings_ata *ata =
2803 		    &cts->xport_specific.ata;
2804 
2805 		if ((ata->valid & CTS_ATA_VALID_MODE) != 0) {
2806 			fprintf(stdout, "%sATA mode: %s\n", pathstr,
2807 				ata_mode2string(ata->mode));
2808 		}
2809 		if ((ata->valid & CTS_ATA_VALID_ATAPI) != 0) {
2810 			fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2811 				ata->atapi);
2812 		}
2813 		if ((ata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
2814 			fprintf(stdout, "%sPIO transaction length: %d\n",
2815 				pathstr, ata->bytecount);
2816 		}
2817 	}
2818 	if (cts->transport == XPORT_SATA) {
2819 		struct ccb_trans_settings_sata *sata =
2820 		    &cts->xport_specific.sata;
2821 
2822 		if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
2823 			fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
2824 				sata->revision);
2825 		}
2826 		if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
2827 			fprintf(stdout, "%sATA mode: %s\n", pathstr,
2828 				ata_mode2string(sata->mode));
2829 		}
2830 		if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
2831 			fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2832 				sata->atapi);
2833 		}
2834 		if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
2835 			fprintf(stdout, "%sPIO transaction length: %d\n",
2836 				pathstr, sata->bytecount);
2837 		}
2838 		if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
2839 			fprintf(stdout, "%sPMP presence: %d\n", pathstr,
2840 				sata->pm_present);
2841 		}
2842 		if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
2843 			fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
2844 				sata->tags);
2845 		}
2846 	}
2847 	if (cts->protocol == PROTO_SCSI) {
2848 		struct ccb_trans_settings_scsi *scsi=
2849 		    &cts->proto_specific.scsi;
2850 
2851 		if (scsi->valid & CTS_SCSI_VALID_TQ) {
2852 			fprintf(stdout, "%stagged queueing is %s\n", pathstr,
2853 				(scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
2854 				"enabled" : "disabled");
2855 		}
2856 	}
2857 
2858 }
2859 
2860 /*
2861  * Get a path inquiry CCB for the specified device.
2862  */
2863 static int
2864 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
2865 {
2866 	union ccb *ccb;
2867 	int retval = 0;
2868 
2869 	ccb = cam_getccb(device);
2870 	if (ccb == NULL) {
2871 		warnx("get_cpi: couldn't allocate CCB");
2872 		return(1);
2873 	}
2874 	bzero(&(&ccb->ccb_h)[1],
2875 	      sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2876 	ccb->ccb_h.func_code = XPT_PATH_INQ;
2877 	if (cam_send_ccb(device, ccb) < 0) {
2878 		warn("get_cpi: error sending Path Inquiry CCB");
2879 		if (arglist & CAM_ARG_VERBOSE)
2880 			cam_error_print(device, ccb, CAM_ESF_ALL,
2881 					CAM_EPF_ALL, stderr);
2882 		retval = 1;
2883 		goto get_cpi_bailout;
2884 	}
2885 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2886 		if (arglist & CAM_ARG_VERBOSE)
2887 			cam_error_print(device, ccb, CAM_ESF_ALL,
2888 					CAM_EPF_ALL, stderr);
2889 		retval = 1;
2890 		goto get_cpi_bailout;
2891 	}
2892 	bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
2893 
2894 get_cpi_bailout:
2895 	cam_freeccb(ccb);
2896 	return(retval);
2897 }
2898 
2899 /*
2900  * Get a get device CCB for the specified device.
2901  */
2902 static int
2903 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
2904 {
2905 	union ccb *ccb;
2906 	int retval = 0;
2907 
2908 	ccb = cam_getccb(device);
2909 	if (ccb == NULL) {
2910 		warnx("get_cgd: couldn't allocate CCB");
2911 		return(1);
2912 	}
2913 	bzero(&(&ccb->ccb_h)[1],
2914 	      sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2915 	ccb->ccb_h.func_code = XPT_GDEV_TYPE;
2916 	if (cam_send_ccb(device, ccb) < 0) {
2917 		warn("get_cgd: error sending Path Inquiry CCB");
2918 		if (arglist & CAM_ARG_VERBOSE)
2919 			cam_error_print(device, ccb, CAM_ESF_ALL,
2920 					CAM_EPF_ALL, stderr);
2921 		retval = 1;
2922 		goto get_cgd_bailout;
2923 	}
2924 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2925 		if (arglist & CAM_ARG_VERBOSE)
2926 			cam_error_print(device, ccb, CAM_ESF_ALL,
2927 					CAM_EPF_ALL, stderr);
2928 		retval = 1;
2929 		goto get_cgd_bailout;
2930 	}
2931 	bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
2932 
2933 get_cgd_bailout:
2934 	cam_freeccb(ccb);
2935 	return(retval);
2936 }
2937 
2938 static void
2939 cpi_print(struct ccb_pathinq *cpi)
2940 {
2941 	char adapter_str[1024];
2942 	int i;
2943 
2944 	snprintf(adapter_str, sizeof(adapter_str),
2945 		 "%s%d:", cpi->dev_name, cpi->unit_number);
2946 
2947 	fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
2948 		cpi->version_num);
2949 
2950 	for (i = 1; i < 0xff; i = i << 1) {
2951 		const char *str;
2952 
2953 		if ((i & cpi->hba_inquiry) == 0)
2954 			continue;
2955 
2956 		fprintf(stdout, "%s supports ", adapter_str);
2957 
2958 		switch(i) {
2959 		case PI_MDP_ABLE:
2960 			str = "MDP message";
2961 			break;
2962 		case PI_WIDE_32:
2963 			str = "32 bit wide SCSI";
2964 			break;
2965 		case PI_WIDE_16:
2966 			str = "16 bit wide SCSI";
2967 			break;
2968 		case PI_SDTR_ABLE:
2969 			str = "SDTR message";
2970 			break;
2971 		case PI_LINKED_CDB:
2972 			str = "linked CDBs";
2973 			break;
2974 		case PI_TAG_ABLE:
2975 			str = "tag queue messages";
2976 			break;
2977 		case PI_SOFT_RST:
2978 			str = "soft reset alternative";
2979 			break;
2980 		case PI_SATAPM:
2981 			str = "SATA Port Multiplier";
2982 			break;
2983 		default:
2984 			str = "unknown PI bit set";
2985 			break;
2986 		}
2987 		fprintf(stdout, "%s\n", str);
2988 	}
2989 
2990 	for (i = 1; i < 0xff; i = i << 1) {
2991 		const char *str;
2992 
2993 		if ((i & cpi->hba_misc) == 0)
2994 			continue;
2995 
2996 		fprintf(stdout, "%s ", adapter_str);
2997 
2998 		switch(i) {
2999 		case PIM_SCANHILO:
3000 			str = "bus scans from high ID to low ID";
3001 			break;
3002 		case PIM_NOREMOVE:
3003 			str = "removable devices not included in scan";
3004 			break;
3005 		case PIM_NOINITIATOR:
3006 			str = "initiator role not supported";
3007 			break;
3008 		case PIM_NOBUSRESET:
3009 			str = "user has disabled initial BUS RESET or"
3010 			      " controller is in target/mixed mode";
3011 			break;
3012 		case PIM_NO_6_BYTE:
3013 			str = "do not send 6-byte commands";
3014 			break;
3015 		case PIM_SEQSCAN:
3016 			str = "scan bus sequentially";
3017 			break;
3018 		default:
3019 			str = "unknown PIM bit set";
3020 			break;
3021 		}
3022 		fprintf(stdout, "%s\n", str);
3023 	}
3024 
3025 	for (i = 1; i < 0xff; i = i << 1) {
3026 		const char *str;
3027 
3028 		if ((i & cpi->target_sprt) == 0)
3029 			continue;
3030 
3031 		fprintf(stdout, "%s supports ", adapter_str);
3032 		switch(i) {
3033 		case PIT_PROCESSOR:
3034 			str = "target mode processor mode";
3035 			break;
3036 		case PIT_PHASE:
3037 			str = "target mode phase cog. mode";
3038 			break;
3039 		case PIT_DISCONNECT:
3040 			str = "disconnects in target mode";
3041 			break;
3042 		case PIT_TERM_IO:
3043 			str = "terminate I/O message in target mode";
3044 			break;
3045 		case PIT_GRP_6:
3046 			str = "group 6 commands in target mode";
3047 			break;
3048 		case PIT_GRP_7:
3049 			str = "group 7 commands in target mode";
3050 			break;
3051 		default:
3052 			str = "unknown PIT bit set";
3053 			break;
3054 		}
3055 
3056 		fprintf(stdout, "%s\n", str);
3057 	}
3058 	fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
3059 		cpi->hba_eng_cnt);
3060 	fprintf(stdout, "%s maximum target: %d\n", adapter_str,
3061 		cpi->max_target);
3062 	fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
3063 		cpi->max_lun);
3064 	fprintf(stdout, "%s highest path ID in subsystem: %d\n",
3065 		adapter_str, cpi->hpath_id);
3066 	fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
3067 		cpi->initiator_id);
3068 	fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
3069 	fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
3070 	fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
3071 	fprintf(stdout, "%s base transfer speed: ", adapter_str);
3072 	if (cpi->base_transfer_speed > 1000)
3073 		fprintf(stdout, "%d.%03dMB/sec\n",
3074 			cpi->base_transfer_speed / 1000,
3075 			cpi->base_transfer_speed % 1000);
3076 	else
3077 		fprintf(stdout, "%dKB/sec\n",
3078 			(cpi->base_transfer_speed % 1000) * 1000);
3079 }
3080 
3081 static int
3082 get_print_cts(struct cam_device *device, int user_settings, int quiet,
3083 	      struct ccb_trans_settings *cts)
3084 {
3085 	int retval;
3086 	union ccb *ccb;
3087 
3088 	retval = 0;
3089 	ccb = cam_getccb(device);
3090 
3091 	if (ccb == NULL) {
3092 		warnx("get_print_cts: error allocating ccb");
3093 		return(1);
3094 	}
3095 
3096 	bzero(&(&ccb->ccb_h)[1],
3097 	      sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3098 
3099 	ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
3100 
3101 	if (user_settings == 0)
3102 		ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
3103 	else
3104 		ccb->cts.type = CTS_TYPE_USER_SETTINGS;
3105 
3106 	if (cam_send_ccb(device, ccb) < 0) {
3107 		perror("error sending XPT_GET_TRAN_SETTINGS CCB");
3108 		if (arglist & CAM_ARG_VERBOSE)
3109 			cam_error_print(device, ccb, CAM_ESF_ALL,
3110 					CAM_EPF_ALL, stderr);
3111 		retval = 1;
3112 		goto get_print_cts_bailout;
3113 	}
3114 
3115 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3116 		warnx("XPT_GET_TRANS_SETTINGS CCB failed");
3117 		if (arglist & CAM_ARG_VERBOSE)
3118 			cam_error_print(device, ccb, CAM_ESF_ALL,
3119 					CAM_EPF_ALL, stderr);
3120 		retval = 1;
3121 		goto get_print_cts_bailout;
3122 	}
3123 
3124 	if (quiet == 0)
3125 		cts_print(device, &ccb->cts);
3126 
3127 	if (cts != NULL)
3128 		bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
3129 
3130 get_print_cts_bailout:
3131 
3132 	cam_freeccb(ccb);
3133 
3134 	return(retval);
3135 }
3136 
3137 static int
3138 ratecontrol(struct cam_device *device, int retry_count, int timeout,
3139 	    int argc, char **argv, char *combinedopt)
3140 {
3141 	int c;
3142 	union ccb *ccb;
3143 	int user_settings = 0;
3144 	int retval = 0;
3145 	int disc_enable = -1, tag_enable = -1;
3146 	int mode = -1;
3147 	int offset = -1;
3148 	double syncrate = -1;
3149 	int bus_width = -1;
3150 	int quiet = 0;
3151 	int change_settings = 0, send_tur = 0;
3152 	struct ccb_pathinq cpi;
3153 
3154 	ccb = cam_getccb(device);
3155 	if (ccb == NULL) {
3156 		warnx("ratecontrol: error allocating ccb");
3157 		return(1);
3158 	}
3159 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3160 		switch(c){
3161 		case 'a':
3162 			send_tur = 1;
3163 			break;
3164 		case 'c':
3165 			user_settings = 0;
3166 			break;
3167 		case 'D':
3168 			if (strncasecmp(optarg, "enable", 6) == 0)
3169 				disc_enable = 1;
3170 			else if (strncasecmp(optarg, "disable", 7) == 0)
3171 				disc_enable = 0;
3172 			else {
3173 				warnx("-D argument \"%s\" is unknown", optarg);
3174 				retval = 1;
3175 				goto ratecontrol_bailout;
3176 			}
3177 			change_settings = 1;
3178 			break;
3179 		case 'M':
3180 			mode = ata_string2mode(optarg);
3181 			if (mode < 0) {
3182 				warnx("unknown mode '%s'", optarg);
3183 				retval = 1;
3184 				goto ratecontrol_bailout;
3185 			}
3186 			change_settings = 1;
3187 			break;
3188 		case 'O':
3189 			offset = strtol(optarg, NULL, 0);
3190 			if (offset < 0) {
3191 				warnx("offset value %d is < 0", offset);
3192 				retval = 1;
3193 				goto ratecontrol_bailout;
3194 			}
3195 			change_settings = 1;
3196 			break;
3197 		case 'q':
3198 			quiet++;
3199 			break;
3200 		case 'R':
3201 			syncrate = atof(optarg);
3202 			if (syncrate < 0) {
3203 				warnx("sync rate %f is < 0", syncrate);
3204 				retval = 1;
3205 				goto ratecontrol_bailout;
3206 			}
3207 			change_settings = 1;
3208 			break;
3209 		case 'T':
3210 			if (strncasecmp(optarg, "enable", 6) == 0)
3211 				tag_enable = 1;
3212 			else if (strncasecmp(optarg, "disable", 7) == 0)
3213 				tag_enable = 0;
3214 			else {
3215 				warnx("-T argument \"%s\" is unknown", optarg);
3216 				retval = 1;
3217 				goto ratecontrol_bailout;
3218 			}
3219 			change_settings = 1;
3220 			break;
3221 		case 'U':
3222 			user_settings = 1;
3223 			break;
3224 		case 'W':
3225 			bus_width = strtol(optarg, NULL, 0);
3226 			if (bus_width < 0) {
3227 				warnx("bus width %d is < 0", bus_width);
3228 				retval = 1;
3229 				goto ratecontrol_bailout;
3230 			}
3231 			change_settings = 1;
3232 			break;
3233 		default:
3234 			break;
3235 		}
3236 	}
3237 	bzero(&(&ccb->ccb_h)[1],
3238 	      sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
3239 	/*
3240 	 * Grab path inquiry information, so we can determine whether
3241 	 * or not the initiator is capable of the things that the user
3242 	 * requests.
3243 	 */
3244 	ccb->ccb_h.func_code = XPT_PATH_INQ;
3245 	if (cam_send_ccb(device, ccb) < 0) {
3246 		perror("error sending XPT_PATH_INQ CCB");
3247 		if (arglist & CAM_ARG_VERBOSE) {
3248 			cam_error_print(device, ccb, CAM_ESF_ALL,
3249 					CAM_EPF_ALL, stderr);
3250 		}
3251 		retval = 1;
3252 		goto ratecontrol_bailout;
3253 	}
3254 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3255 		warnx("XPT_PATH_INQ CCB failed");
3256 		if (arglist & CAM_ARG_VERBOSE) {
3257 			cam_error_print(device, ccb, CAM_ESF_ALL,
3258 					CAM_EPF_ALL, stderr);
3259 		}
3260 		retval = 1;
3261 		goto ratecontrol_bailout;
3262 	}
3263 	bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
3264 	bzero(&(&ccb->ccb_h)[1],
3265 	      sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3266 	if (quiet == 0) {
3267 		fprintf(stdout, "%s parameters:\n",
3268 		    user_settings ? "User" : "Current");
3269 	}
3270 	retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
3271 	if (retval != 0)
3272 		goto ratecontrol_bailout;
3273 
3274 	if (arglist & CAM_ARG_VERBOSE)
3275 		cpi_print(&cpi);
3276 
3277 	if (change_settings) {
3278 		int didsettings = 0;
3279 		struct ccb_trans_settings_spi *spi = NULL;
3280 		struct ccb_trans_settings_ata *ata = NULL;
3281 		struct ccb_trans_settings_sata *sata = NULL;
3282 		struct ccb_trans_settings_scsi *scsi = NULL;
3283 
3284 		if (ccb->cts.transport == XPORT_SPI)
3285 			spi = &ccb->cts.xport_specific.spi;
3286 		if (ccb->cts.transport == XPORT_ATA)
3287 			ata = &ccb->cts.xport_specific.ata;
3288 		if (ccb->cts.transport == XPORT_SATA)
3289 			sata = &ccb->cts.xport_specific.sata;
3290 		if (ccb->cts.protocol == PROTO_SCSI)
3291 			scsi = &ccb->cts.proto_specific.scsi;
3292 		ccb->cts.xport_specific.valid = 0;
3293 		ccb->cts.proto_specific.valid = 0;
3294 		if (spi && disc_enable != -1) {
3295 			spi->valid |= CTS_SPI_VALID_DISC;
3296 			if (disc_enable == 0)
3297 				spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
3298 			else
3299 				spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3300 		}
3301 		if (scsi && tag_enable != -1) {
3302 			if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
3303 				warnx("HBA does not support tagged queueing, "
3304 				      "so you cannot modify tag settings");
3305 				retval = 1;
3306 				goto ratecontrol_bailout;
3307 			}
3308 			scsi->valid |= CTS_SCSI_VALID_TQ;
3309 			if (tag_enable == 0)
3310 				scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
3311 			else
3312 				scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3313 			didsettings++;
3314 		}
3315 		if (spi && offset != -1) {
3316 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3317 				warnx("HBA is not capable of changing offset");
3318 				retval = 1;
3319 				goto ratecontrol_bailout;
3320 			}
3321 			spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3322 			spi->sync_offset = offset;
3323 			didsettings++;
3324 		}
3325 		if (spi && syncrate != -1) {
3326 			int prelim_sync_period;
3327 			u_int freq;
3328 
3329 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3330 				warnx("HBA is not capable of changing "
3331 				      "transfer rates");
3332 				retval = 1;
3333 				goto ratecontrol_bailout;
3334 			}
3335 			spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3336 			/*
3337 			 * The sync rate the user gives us is in MHz.
3338 			 * We need to translate it into KHz for this
3339 			 * calculation.
3340 			 */
3341 			syncrate *= 1000;
3342 			/*
3343 			 * Next, we calculate a "preliminary" sync period
3344 			 * in tenths of a nanosecond.
3345 			 */
3346 			if (syncrate == 0)
3347 				prelim_sync_period = 0;
3348 			else
3349 				prelim_sync_period = 10000000 / syncrate;
3350 			spi->sync_period =
3351 				scsi_calc_syncparam(prelim_sync_period);
3352 			freq = scsi_calc_syncsrate(spi->sync_period);
3353 			didsettings++;
3354 		}
3355 		if (sata && syncrate != -1) {
3356 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3357 				warnx("HBA is not capable of changing "
3358 				      "transfer rates");
3359 				retval = 1;
3360 				goto ratecontrol_bailout;
3361 			}
3362 			sata->revision = ata_speed2revision(syncrate * 100);
3363 			if (sata->revision < 0) {
3364 				warnx("Invalid rate %f", syncrate);
3365 				retval = 1;
3366 				goto ratecontrol_bailout;
3367 			}
3368 			sata->valid |= CTS_SATA_VALID_REVISION;
3369 			didsettings++;
3370 		}
3371 		if ((ata || sata) && mode != -1) {
3372 			if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3373 				warnx("HBA is not capable of changing "
3374 				      "transfer rates");
3375 				retval = 1;
3376 				goto ratecontrol_bailout;
3377 			}
3378 			if (ata) {
3379 				ata->mode = mode;
3380 				ata->valid |= CTS_ATA_VALID_MODE;
3381 			} else {
3382 				sata->mode = mode;
3383 				sata->valid |= CTS_SATA_VALID_MODE;
3384 			}
3385 			didsettings++;
3386 		}
3387 		/*
3388 		 * The bus_width argument goes like this:
3389 		 * 0 == 8 bit
3390 		 * 1 == 16 bit
3391 		 * 2 == 32 bit
3392 		 * Therefore, if you shift the number of bits given on the
3393 		 * command line right by 4, you should get the correct
3394 		 * number.
3395 		 */
3396 		if (spi && bus_width != -1) {
3397 			/*
3398 			 * We might as well validate things here with a
3399 			 * decipherable error message, rather than what
3400 			 * will probably be an indecipherable error message
3401 			 * by the time it gets back to us.
3402 			 */
3403 			if ((bus_width == 16)
3404 			 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
3405 				warnx("HBA does not support 16 bit bus width");
3406 				retval = 1;
3407 				goto ratecontrol_bailout;
3408 			} else if ((bus_width == 32)
3409 				&& ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
3410 				warnx("HBA does not support 32 bit bus width");
3411 				retval = 1;
3412 				goto ratecontrol_bailout;
3413 			} else if ((bus_width != 8)
3414 				&& (bus_width != 16)
3415 				&& (bus_width != 32)) {
3416 				warnx("Invalid bus width %d", bus_width);
3417 				retval = 1;
3418 				goto ratecontrol_bailout;
3419 			}
3420 			spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
3421 			spi->bus_width = bus_width >> 4;
3422 			didsettings++;
3423 		}
3424 		if  (didsettings == 0) {
3425 			goto ratecontrol_bailout;
3426 		}
3427 		if  (!user_settings && (ata || sata)) {
3428 			warnx("You can modify only user settings for ATA/SATA");
3429 			retval = 1;
3430 			goto ratecontrol_bailout;
3431 		}
3432 		ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
3433 		if (cam_send_ccb(device, ccb) < 0) {
3434 			perror("error sending XPT_SET_TRAN_SETTINGS CCB");
3435 			if (arglist & CAM_ARG_VERBOSE) {
3436 				cam_error_print(device, ccb, CAM_ESF_ALL,
3437 						CAM_EPF_ALL, stderr);
3438 			}
3439 			retval = 1;
3440 			goto ratecontrol_bailout;
3441 		}
3442 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3443 			warnx("XPT_SET_TRANS_SETTINGS CCB failed");
3444 			if (arglist & CAM_ARG_VERBOSE) {
3445 				cam_error_print(device, ccb, CAM_ESF_ALL,
3446 						CAM_EPF_ALL, stderr);
3447 			}
3448 			retval = 1;
3449 			goto ratecontrol_bailout;
3450 		}
3451 	}
3452 	if (send_tur) {
3453 		retval = testunitready(device, retry_count, timeout,
3454 				       (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
3455 		/*
3456 		 * If the TUR didn't succeed, just bail.
3457 		 */
3458 		if (retval != 0) {
3459 			if (quiet == 0)
3460 				fprintf(stderr, "Test Unit Ready failed\n");
3461 			goto ratecontrol_bailout;
3462 		}
3463 		/*
3464 		 * If the user wants things quiet, there's no sense in
3465 		 * getting the transfer settings, if we're not going
3466 		 * to print them.
3467 		 */
3468 		if (quiet != 0)
3469 			goto ratecontrol_bailout;
3470 		fprintf(stdout, "New parameters:\n");
3471 		retval = get_print_cts(device, user_settings, 0, NULL);
3472 	}
3473 
3474 ratecontrol_bailout:
3475 	cam_freeccb(ccb);
3476 	return(retval);
3477 }
3478 
3479 static int
3480 scsiformat(struct cam_device *device, int argc, char **argv,
3481 	   char *combinedopt, int retry_count, int timeout)
3482 {
3483 	union ccb *ccb;
3484 	int c;
3485 	int ycount = 0, quiet = 0;
3486 	int error = 0, response = 0, retval = 0;
3487 	int use_timeout = 10800 * 1000;
3488 	int immediate = 1;
3489 	struct format_defect_list_header fh;
3490 	u_int8_t *data_ptr = NULL;
3491 	u_int32_t dxfer_len = 0;
3492 	u_int8_t byte2 = 0;
3493 	int num_warnings = 0;
3494 	int reportonly = 0;
3495 
3496 	ccb = cam_getccb(device);
3497 
3498 	if (ccb == NULL) {
3499 		warnx("scsiformat: error allocating ccb");
3500 		return(1);
3501 	}
3502 
3503 	bzero(&(&ccb->ccb_h)[1],
3504 	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3505 
3506 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3507 		switch(c) {
3508 		case 'q':
3509 			quiet++;
3510 			break;
3511 		case 'r':
3512 			reportonly = 1;
3513 			break;
3514 		case 'w':
3515 			immediate = 0;
3516 			break;
3517 		case 'y':
3518 			ycount++;
3519 			break;
3520 		}
3521 	}
3522 
3523 	if (reportonly)
3524 		goto doreport;
3525 
3526 	if (quiet == 0) {
3527 		fprintf(stdout, "You are about to REMOVE ALL DATA from the "
3528 			"following device:\n");
3529 
3530 		error = scsidoinquiry(device, argc, argv, combinedopt,
3531 				      retry_count, timeout);
3532 
3533 		if (error != 0) {
3534 			warnx("scsiformat: error sending inquiry");
3535 			goto scsiformat_bailout;
3536 		}
3537 	}
3538 
3539 	if (ycount == 0) {
3540 
3541 		do {
3542 			char str[1024];
3543 
3544 			fprintf(stdout, "Are you SURE you want to do "
3545 				"this? (yes/no) ");
3546 
3547 			if (fgets(str, sizeof(str), stdin) != NULL) {
3548 
3549 				if (strncasecmp(str, "yes", 3) == 0)
3550 					response = 1;
3551 				else if (strncasecmp(str, "no", 2) == 0)
3552 					response = -1;
3553 				else {
3554 					fprintf(stdout, "Please answer"
3555 						" \"yes\" or \"no\"\n");
3556 				}
3557 			}
3558 		} while (response == 0);
3559 
3560 		if (response == -1) {
3561 			error = 1;
3562 			goto scsiformat_bailout;
3563 		}
3564 	}
3565 
3566 	if (timeout != 0)
3567 		use_timeout = timeout;
3568 
3569 	if (quiet == 0) {
3570 		fprintf(stdout, "Current format timeout is %d seconds\n",
3571 			use_timeout / 1000);
3572 	}
3573 
3574 	/*
3575 	 * If the user hasn't disabled questions and didn't specify a
3576 	 * timeout on the command line, ask them if they want the current
3577 	 * timeout.
3578 	 */
3579 	if ((ycount == 0)
3580 	 && (timeout == 0)) {
3581 		char str[1024];
3582 		int new_timeout = 0;
3583 
3584 		fprintf(stdout, "Enter new timeout in seconds or press\n"
3585 			"return to keep the current timeout [%d] ",
3586 			use_timeout / 1000);
3587 
3588 		if (fgets(str, sizeof(str), stdin) != NULL) {
3589 			if (str[0] != '\0')
3590 				new_timeout = atoi(str);
3591 		}
3592 
3593 		if (new_timeout != 0) {
3594 			use_timeout = new_timeout * 1000;
3595 			fprintf(stdout, "Using new timeout value %d\n",
3596 				use_timeout / 1000);
3597 		}
3598 	}
3599 
3600 	/*
3601 	 * Keep this outside the if block below to silence any unused
3602 	 * variable warnings.
3603 	 */
3604 	bzero(&fh, sizeof(fh));
3605 
3606 	/*
3607 	 * If we're in immediate mode, we've got to include the format
3608 	 * header
3609 	 */
3610 	if (immediate != 0) {
3611 		fh.byte2 = FU_DLH_IMMED;
3612 		data_ptr = (u_int8_t *)&fh;
3613 		dxfer_len = sizeof(fh);
3614 		byte2 = FU_FMT_DATA;
3615 	} else if (quiet == 0) {
3616 		fprintf(stdout, "Formatting...");
3617 		fflush(stdout);
3618 	}
3619 
3620 	scsi_format_unit(&ccb->csio,
3621 			 /* retries */ retry_count,
3622 			 /* cbfcnp */ NULL,
3623 			 /* tag_action */ MSG_SIMPLE_Q_TAG,
3624 			 /* byte2 */ byte2,
3625 			 /* ileave */ 0,
3626 			 /* data_ptr */ data_ptr,
3627 			 /* dxfer_len */ dxfer_len,
3628 			 /* sense_len */ SSD_FULL_SIZE,
3629 			 /* timeout */ use_timeout);
3630 
3631 	/* Disable freezing the device queue */
3632 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3633 
3634 	if (arglist & CAM_ARG_ERR_RECOVER)
3635 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3636 
3637 	if (((retval = cam_send_ccb(device, ccb)) < 0)
3638 	 || ((immediate == 0)
3639 	   && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
3640 		const char errstr[] = "error sending format command";
3641 
3642 		if (retval < 0)
3643 			warn(errstr);
3644 		else
3645 			warnx(errstr);
3646 
3647 		if (arglist & CAM_ARG_VERBOSE) {
3648 			cam_error_print(device, ccb, CAM_ESF_ALL,
3649 					CAM_EPF_ALL, stderr);
3650 		}
3651 		error = 1;
3652 		goto scsiformat_bailout;
3653 	}
3654 
3655 	/*
3656 	 * If we ran in non-immediate mode, we already checked for errors
3657 	 * above and printed out any necessary information.  If we're in
3658 	 * immediate mode, we need to loop through and get status
3659 	 * information periodically.
3660 	 */
3661 	if (immediate == 0) {
3662 		if (quiet == 0) {
3663 			fprintf(stdout, "Format Complete\n");
3664 		}
3665 		goto scsiformat_bailout;
3666 	}
3667 
3668 doreport:
3669 	do {
3670 		cam_status status;
3671 
3672 		bzero(&(&ccb->ccb_h)[1],
3673 		      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3674 
3675 		/*
3676 		 * There's really no need to do error recovery or
3677 		 * retries here, since we're just going to sit in a
3678 		 * loop and wait for the device to finish formatting.
3679 		 */
3680 		scsi_test_unit_ready(&ccb->csio,
3681 				     /* retries */ 0,
3682 				     /* cbfcnp */ NULL,
3683 				     /* tag_action */ MSG_SIMPLE_Q_TAG,
3684 				     /* sense_len */ SSD_FULL_SIZE,
3685 				     /* timeout */ 5000);
3686 
3687 		/* Disable freezing the device queue */
3688 		ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3689 
3690 		retval = cam_send_ccb(device, ccb);
3691 
3692 		/*
3693 		 * If we get an error from the ioctl, bail out.  SCSI
3694 		 * errors are expected.
3695 		 */
3696 		if (retval < 0) {
3697 			warn("error sending CAMIOCOMMAND ioctl");
3698 			if (arglist & CAM_ARG_VERBOSE) {
3699 				cam_error_print(device, ccb, CAM_ESF_ALL,
3700 						CAM_EPF_ALL, stderr);
3701 			}
3702 			error = 1;
3703 			goto scsiformat_bailout;
3704 		}
3705 
3706 		status = ccb->ccb_h.status & CAM_STATUS_MASK;
3707 
3708 		if ((status != CAM_REQ_CMP)
3709 		 && (status == CAM_SCSI_STATUS_ERROR)
3710 		 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3711 			struct scsi_sense_data *sense;
3712 			int error_code, sense_key, asc, ascq;
3713 
3714 			sense = &ccb->csio.sense_data;
3715 			scsi_extract_sense(sense, &error_code, &sense_key,
3716 					   &asc, &ascq);
3717 
3718 			/*
3719 			 * According to the SCSI-2 and SCSI-3 specs, a
3720 			 * drive that is in the middle of a format should
3721 			 * return NOT READY with an ASC of "logical unit
3722 			 * not ready, format in progress".  The sense key
3723 			 * specific bytes will then be a progress indicator.
3724 			 */
3725 			if ((sense_key == SSD_KEY_NOT_READY)
3726 			 && (asc == 0x04) && (ascq == 0x04)) {
3727 				if ((sense->extra_len >= 10)
3728 				 && ((sense->sense_key_spec[0] &
3729 				      SSD_SCS_VALID) != 0)
3730 				 && (quiet == 0)) {
3731 					int val;
3732 					u_int64_t percentage;
3733 
3734 					val = scsi_2btoul(
3735 						&sense->sense_key_spec[1]);
3736 					percentage = 10000 * val;
3737 
3738 					fprintf(stdout,
3739 						"\rFormatting:  %ju.%02u %% "
3740 						"(%d/%d) done",
3741 						(uintmax_t)(percentage /
3742 						(0x10000 * 100)),
3743 						(unsigned)((percentage /
3744 						0x10000) % 100),
3745 						val, 0x10000);
3746 					fflush(stdout);
3747 				} else if ((quiet == 0)
3748 					&& (++num_warnings <= 1)) {
3749 					warnx("Unexpected SCSI Sense Key "
3750 					      "Specific value returned "
3751 					      "during format:");
3752 					scsi_sense_print(device, &ccb->csio,
3753 							 stderr);
3754 					warnx("Unable to print status "
3755 					      "information, but format will "
3756 					      "proceed.");
3757 					warnx("will exit when format is "
3758 					      "complete");
3759 				}
3760 				sleep(1);
3761 			} else {
3762 				warnx("Unexpected SCSI error during format");
3763 				cam_error_print(device, ccb, CAM_ESF_ALL,
3764 						CAM_EPF_ALL, stderr);
3765 				error = 1;
3766 				goto scsiformat_bailout;
3767 			}
3768 
3769 		} else if (status != CAM_REQ_CMP) {
3770 			warnx("Unexpected CAM status %#x", status);
3771 			if (arglist & CAM_ARG_VERBOSE)
3772 				cam_error_print(device, ccb, CAM_ESF_ALL,
3773 						CAM_EPF_ALL, stderr);
3774 			error = 1;
3775 			goto scsiformat_bailout;
3776 		}
3777 
3778 	} while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
3779 
3780 	if (quiet == 0)
3781 		fprintf(stdout, "\nFormat Complete\n");
3782 
3783 scsiformat_bailout:
3784 
3785 	cam_freeccb(ccb);
3786 
3787 	return(error);
3788 }
3789 
3790 static int
3791 scsireportluns(struct cam_device *device, int argc, char **argv,
3792 	       char *combinedopt, int retry_count, int timeout)
3793 {
3794 	union ccb *ccb;
3795 	int c, countonly, lunsonly;
3796 	struct scsi_report_luns_data *lundata;
3797 	int alloc_len;
3798 	uint8_t report_type;
3799 	uint32_t list_len, i, j;
3800 	int retval;
3801 
3802 	retval = 0;
3803 	lundata = NULL;
3804 	report_type = RPL_REPORT_DEFAULT;
3805 	ccb = cam_getccb(device);
3806 
3807 	if (ccb == NULL) {
3808 		warnx("%s: error allocating ccb", __func__);
3809 		return (1);
3810 	}
3811 
3812 	bzero(&(&ccb->ccb_h)[1],
3813 	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3814 
3815 	countonly = 0;
3816 	lunsonly = 0;
3817 
3818 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
3819 		switch (c) {
3820 		case 'c':
3821 			countonly++;
3822 			break;
3823 		case 'l':
3824 			lunsonly++;
3825 			break;
3826 		case 'r':
3827 			if (strcasecmp(optarg, "default") == 0)
3828 				report_type = RPL_REPORT_DEFAULT;
3829 			else if (strcasecmp(optarg, "wellknown") == 0)
3830 				report_type = RPL_REPORT_WELLKNOWN;
3831 			else if (strcasecmp(optarg, "all") == 0)
3832 				report_type = RPL_REPORT_ALL;
3833 			else {
3834 				warnx("%s: invalid report type \"%s\"",
3835 				      __func__, optarg);
3836 				retval = 1;
3837 				goto bailout;
3838 			}
3839 			break;
3840 		default:
3841 			break;
3842 		}
3843 	}
3844 
3845 	if ((countonly != 0)
3846 	 && (lunsonly != 0)) {
3847 		warnx("%s: you can only specify one of -c or -l", __func__);
3848 		retval = 1;
3849 		goto bailout;
3850 	}
3851 	/*
3852 	 * According to SPC-4, the allocation length must be at least 16
3853 	 * bytes -- enough for the header and one LUN.
3854 	 */
3855 	alloc_len = sizeof(*lundata) + 8;
3856 
3857 retry:
3858 
3859 	lundata = malloc(alloc_len);
3860 
3861 	if (lundata == NULL) {
3862 		warn("%s: error mallocing %d bytes", __func__, alloc_len);
3863 		retval = 1;
3864 		goto bailout;
3865 	}
3866 
3867 	scsi_report_luns(&ccb->csio,
3868 			 /*retries*/ retry_count,
3869 			 /*cbfcnp*/ NULL,
3870 			 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3871 			 /*select_report*/ report_type,
3872 			 /*rpl_buf*/ lundata,
3873 			 /*alloc_len*/ alloc_len,
3874 			 /*sense_len*/ SSD_FULL_SIZE,
3875 			 /*timeout*/ timeout ? timeout : 5000);
3876 
3877 	/* Disable freezing the device queue */
3878 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3879 
3880 	if (arglist & CAM_ARG_ERR_RECOVER)
3881 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3882 
3883 	if (cam_send_ccb(device, ccb) < 0) {
3884 		warn("error sending REPORT LUNS command");
3885 
3886 		if (arglist & CAM_ARG_VERBOSE)
3887 			cam_error_print(device, ccb, CAM_ESF_ALL,
3888 					CAM_EPF_ALL, stderr);
3889 
3890 		retval = 1;
3891 		goto bailout;
3892 	}
3893 
3894 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3895 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
3896 		retval = 1;
3897 		goto bailout;
3898 	}
3899 
3900 
3901 	list_len = scsi_4btoul(lundata->length);
3902 
3903 	/*
3904 	 * If we need to list the LUNs, and our allocation
3905 	 * length was too short, reallocate and retry.
3906 	 */
3907 	if ((countonly == 0)
3908 	 && (list_len > (alloc_len - sizeof(*lundata)))) {
3909 		alloc_len = list_len + sizeof(*lundata);
3910 		free(lundata);
3911 		goto retry;
3912 	}
3913 
3914 	if (lunsonly == 0)
3915 		fprintf(stdout, "%u LUN%s found\n", list_len / 8,
3916 			((list_len / 8) > 1) ? "s" : "");
3917 
3918 	if (countonly != 0)
3919 		goto bailout;
3920 
3921 	for (i = 0; i < (list_len / 8); i++) {
3922 		int no_more;
3923 
3924 		no_more = 0;
3925 		for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
3926 			if (j != 0)
3927 				fprintf(stdout, ",");
3928 			switch (lundata->luns[i].lundata[j] &
3929 				RPL_LUNDATA_ATYP_MASK) {
3930 			case RPL_LUNDATA_ATYP_PERIPH:
3931 				if ((lundata->luns[i].lundata[j] &
3932 				    RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
3933 					fprintf(stdout, "%d:",
3934 						lundata->luns[i].lundata[j] &
3935 						RPL_LUNDATA_PERIPH_BUS_MASK);
3936 				else if ((j == 0)
3937 				      && ((lundata->luns[i].lundata[j+2] &
3938 					  RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
3939 					no_more = 1;
3940 
3941 				fprintf(stdout, "%d",
3942 					lundata->luns[i].lundata[j+1]);
3943 				break;
3944 			case RPL_LUNDATA_ATYP_FLAT: {
3945 				uint8_t tmplun[2];
3946 				tmplun[0] = lundata->luns[i].lundata[j] &
3947 					RPL_LUNDATA_FLAT_LUN_MASK;
3948 				tmplun[1] = lundata->luns[i].lundata[j+1];
3949 
3950 				fprintf(stdout, "%d", scsi_2btoul(tmplun));
3951 				no_more = 1;
3952 				break;
3953 			}
3954 			case RPL_LUNDATA_ATYP_LUN:
3955 				fprintf(stdout, "%d:%d:%d",
3956 					(lundata->luns[i].lundata[j+1] &
3957 					RPL_LUNDATA_LUN_BUS_MASK) >> 5,
3958 					lundata->luns[i].lundata[j] &
3959 					RPL_LUNDATA_LUN_TARG_MASK,
3960 					lundata->luns[i].lundata[j+1] &
3961 					RPL_LUNDATA_LUN_LUN_MASK);
3962 				break;
3963 			case RPL_LUNDATA_ATYP_EXTLUN: {
3964 				int field_len, field_len_code, eam_code;
3965 
3966 				eam_code = lundata->luns[i].lundata[j] &
3967 					RPL_LUNDATA_EXT_EAM_MASK;
3968 				field_len_code = (lundata->luns[i].lundata[j] &
3969 					RPL_LUNDATA_EXT_LEN_MASK) >> 4;
3970 				field_len = field_len_code * 2;
3971 
3972 				if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
3973 				 && (field_len_code == 0x00)) {
3974 					fprintf(stdout, "%d",
3975 						lundata->luns[i].lundata[j+1]);
3976 				} else if ((eam_code ==
3977 					    RPL_LUNDATA_EXT_EAM_NOT_SPEC)
3978 					&& (field_len_code == 0x03)) {
3979 					uint8_t tmp_lun[8];
3980 
3981 					/*
3982 					 * This format takes up all 8 bytes.
3983 					 * If we aren't starting at offset 0,
3984 					 * that's a bug.
3985 					 */
3986 					if (j != 0) {
3987 						fprintf(stdout, "Invalid "
3988 							"offset %d for "
3989 							"Extended LUN not "
3990 							"specified format", j);
3991 						no_more = 1;
3992 						break;
3993 					}
3994 					bzero(tmp_lun, sizeof(tmp_lun));
3995 					bcopy(&lundata->luns[i].lundata[j+1],
3996 					      &tmp_lun[1], sizeof(tmp_lun) - 1);
3997 					fprintf(stdout, "%#jx",
3998 					       (intmax_t)scsi_8btou64(tmp_lun));
3999 					no_more = 1;
4000 				} else {
4001 					fprintf(stderr, "Unknown Extended LUN"
4002 						"Address method %#x, length "
4003 						"code %#x", eam_code,
4004 						field_len_code);
4005 					no_more = 1;
4006 				}
4007 				break;
4008 			}
4009 			default:
4010 				fprintf(stderr, "Unknown LUN address method "
4011 					"%#x\n", lundata->luns[i].lundata[0] &
4012 					RPL_LUNDATA_ATYP_MASK);
4013 				break;
4014 			}
4015 			/*
4016 			 * For the flat addressing method, there are no
4017 			 * other levels after it.
4018 			 */
4019 			if (no_more != 0)
4020 				break;
4021 		}
4022 		fprintf(stdout, "\n");
4023 	}
4024 
4025 bailout:
4026 
4027 	cam_freeccb(ccb);
4028 
4029 	free(lundata);
4030 
4031 	return (retval);
4032 }
4033 
4034 static int
4035 scsireadcapacity(struct cam_device *device, int argc, char **argv,
4036 		 char *combinedopt, int retry_count, int timeout)
4037 {
4038 	union ccb *ccb;
4039 	int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
4040 	struct scsi_read_capacity_data rcap;
4041 	struct scsi_read_capacity_data_long rcaplong;
4042 	uint64_t maxsector;
4043 	uint32_t block_len;
4044 	int retval;
4045 	int c;
4046 
4047 	blocksizeonly = 0;
4048 	humanize = 0;
4049 	numblocks = 0;
4050 	quiet = 0;
4051 	sizeonly = 0;
4052 	baseten = 0;
4053 	retval = 0;
4054 
4055 	ccb = cam_getccb(device);
4056 
4057 	if (ccb == NULL) {
4058 		warnx("%s: error allocating ccb", __func__);
4059 		return (1);
4060 	}
4061 
4062 	bzero(&(&ccb->ccb_h)[1],
4063 	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4064 
4065 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
4066 		switch (c) {
4067 		case 'b':
4068 			blocksizeonly++;
4069 			break;
4070 		case 'h':
4071 			humanize++;
4072 			baseten = 0;
4073 			break;
4074 		case 'H':
4075 			humanize++;
4076 			baseten++;
4077 			break;
4078 		case 'N':
4079 			numblocks++;
4080 			break;
4081 		case 'q':
4082 			quiet++;
4083 			break;
4084 		case 's':
4085 			sizeonly++;
4086 			break;
4087 		default:
4088 			break;
4089 		}
4090 	}
4091 
4092 	if ((blocksizeonly != 0)
4093 	 && (numblocks != 0)) {
4094 		warnx("%s: you can only specify one of -b or -N", __func__);
4095 		retval = 1;
4096 		goto bailout;
4097 	}
4098 
4099 	if ((blocksizeonly != 0)
4100 	 && (sizeonly != 0)) {
4101 		warnx("%s: you can only specify one of -b or -s", __func__);
4102 		retval = 1;
4103 		goto bailout;
4104 	}
4105 
4106 	if ((humanize != 0)
4107 	 && (quiet != 0)) {
4108 		warnx("%s: you can only specify one of -h/-H or -q", __func__);
4109 		retval = 1;
4110 		goto bailout;
4111 	}
4112 
4113 	if ((humanize != 0)
4114 	 && (blocksizeonly != 0)) {
4115 		warnx("%s: you can only specify one of -h/-H or -b", __func__);
4116 		retval = 1;
4117 		goto bailout;
4118 	}
4119 
4120 	scsi_read_capacity(&ccb->csio,
4121 			   /*retries*/ retry_count,
4122 			   /*cbfcnp*/ NULL,
4123 			   /*tag_action*/ MSG_SIMPLE_Q_TAG,
4124 			   &rcap,
4125 			   SSD_FULL_SIZE,
4126 			   /*timeout*/ timeout ? timeout : 5000);
4127 
4128 	/* Disable freezing the device queue */
4129 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4130 
4131 	if (arglist & CAM_ARG_ERR_RECOVER)
4132 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4133 
4134 	if (cam_send_ccb(device, ccb) < 0) {
4135 		warn("error sending READ CAPACITY command");
4136 
4137 		if (arglist & CAM_ARG_VERBOSE)
4138 			cam_error_print(device, ccb, CAM_ESF_ALL,
4139 					CAM_EPF_ALL, stderr);
4140 
4141 		retval = 1;
4142 		goto bailout;
4143 	}
4144 
4145 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4146 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4147 		retval = 1;
4148 		goto bailout;
4149 	}
4150 
4151 	maxsector = scsi_4btoul(rcap.addr);
4152 	block_len = scsi_4btoul(rcap.length);
4153 
4154 	/*
4155 	 * A last block of 2^32-1 means that the true capacity is over 2TB,
4156 	 * and we need to issue the long READ CAPACITY to get the real
4157 	 * capacity.  Otherwise, we're all set.
4158 	 */
4159 	if (maxsector != 0xffffffff)
4160 		goto do_print;
4161 
4162 	scsi_read_capacity_16(&ccb->csio,
4163 			      /*retries*/ retry_count,
4164 			      /*cbfcnp*/ NULL,
4165 			      /*tag_action*/ MSG_SIMPLE_Q_TAG,
4166 			      /*lba*/ 0,
4167 			      /*reladdr*/ 0,
4168 			      /*pmi*/ 0,
4169 			      &rcaplong,
4170 			      /*sense_len*/ SSD_FULL_SIZE,
4171 			      /*timeout*/ timeout ? timeout : 5000);
4172 
4173 	/* Disable freezing the device queue */
4174 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4175 
4176 	if (arglist & CAM_ARG_ERR_RECOVER)
4177 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4178 
4179 	if (cam_send_ccb(device, ccb) < 0) {
4180 		warn("error sending READ CAPACITY (16) command");
4181 
4182 		if (arglist & CAM_ARG_VERBOSE)
4183 			cam_error_print(device, ccb, CAM_ESF_ALL,
4184 					CAM_EPF_ALL, stderr);
4185 
4186 		retval = 1;
4187 		goto bailout;
4188 	}
4189 
4190 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4191 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4192 		retval = 1;
4193 		goto bailout;
4194 	}
4195 
4196 	maxsector = scsi_8btou64(rcaplong.addr);
4197 	block_len = scsi_4btoul(rcaplong.length);
4198 
4199 do_print:
4200 	if (blocksizeonly == 0) {
4201 		/*
4202 		 * Humanize implies !quiet, and also implies numblocks.
4203 		 */
4204 		if (humanize != 0) {
4205 			char tmpstr[6];
4206 			int64_t tmpbytes;
4207 			int ret;
4208 
4209 			tmpbytes = (maxsector + 1) * block_len;
4210 			ret = humanize_number(tmpstr, sizeof(tmpstr),
4211 					      tmpbytes, "", HN_AUTOSCALE,
4212 					      HN_B | HN_DECIMAL |
4213 					      ((baseten != 0) ?
4214 					      HN_DIVISOR_1000 : 0));
4215 			if (ret == -1) {
4216 				warnx("%s: humanize_number failed!", __func__);
4217 				retval = 1;
4218 				goto bailout;
4219 			}
4220 			fprintf(stdout, "Device Size: %s%s", tmpstr,
4221 				(sizeonly == 0) ?  ", " : "\n");
4222 		} else if (numblocks != 0) {
4223 			fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4224 				"Blocks: " : "", (uintmax_t)maxsector + 1,
4225 				(sizeonly == 0) ? ", " : "\n");
4226 		} else {
4227 			fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4228 				"Last Block: " : "", (uintmax_t)maxsector,
4229 				(sizeonly == 0) ? ", " : "\n");
4230 		}
4231 	}
4232 	if (sizeonly == 0)
4233 		fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
4234 			"Block Length: " : "", block_len, (quiet == 0) ?
4235 			" bytes" : "");
4236 bailout:
4237 	cam_freeccb(ccb);
4238 
4239 	return (retval);
4240 }
4241 
4242 static int
4243 atapm(struct cam_device *device, int argc, char **argv,
4244 		 char *combinedopt, int retry_count, int timeout)
4245 {
4246 	union ccb *ccb;
4247 	int retval = 0;
4248 	int t = -1;
4249 	int c;
4250 	u_char cmd, sc;
4251 
4252 	ccb = cam_getccb(device);
4253 
4254 	if (ccb == NULL) {
4255 		warnx("%s: error allocating ccb", __func__);
4256 		return (1);
4257 	}
4258 
4259 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
4260 		switch (c) {
4261 		case 't':
4262 			t = atoi(optarg);
4263 			break;
4264 		default:
4265 			break;
4266 		}
4267 	}
4268 	if (strcmp(argv[1], "idle") == 0) {
4269 		if (t == -1)
4270 			cmd = ATA_IDLE_IMMEDIATE;
4271 		else
4272 			cmd = ATA_IDLE_CMD;
4273 	} else if (strcmp(argv[1], "standby") == 0) {
4274 		if (t == -1)
4275 			cmd = ATA_STANDBY_IMMEDIATE;
4276 		else
4277 			cmd = ATA_STANDBY_CMD;
4278 	} else {
4279 		cmd = ATA_SLEEP;
4280 		t = -1;
4281 	}
4282 	if (t < 0)
4283 		sc = 0;
4284 	else if (t <= (240 * 5))
4285 		sc = t / 5;
4286 	else if (t <= (11 * 30 * 60))
4287 		sc = t / (30 * 60) + 241;
4288 	else
4289 		sc = 253;
4290 	cam_fill_ataio(&ccb->ataio,
4291 		      retry_count,
4292 		      NULL,
4293 		      /*flags*/CAM_DIR_NONE,
4294 		      MSG_SIMPLE_Q_TAG,
4295 		      /*data_ptr*/NULL,
4296 		      /*dxfer_len*/0,
4297 		      timeout ? timeout : 30 * 1000);
4298 	ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
4299 
4300 	/* Disable freezing the device queue */
4301 	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4302 
4303 	if (arglist & CAM_ARG_ERR_RECOVER)
4304 		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4305 
4306 	if (cam_send_ccb(device, ccb) < 0) {
4307 		warn("error sending command");
4308 
4309 		if (arglist & CAM_ARG_VERBOSE)
4310 			cam_error_print(device, ccb, CAM_ESF_ALL,
4311 					CAM_EPF_ALL, stderr);
4312 
4313 		retval = 1;
4314 		goto bailout;
4315 	}
4316 
4317 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4318 		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4319 		retval = 1;
4320 		goto bailout;
4321 	}
4322 bailout:
4323 	cam_freeccb(ccb);
4324 	return (retval);
4325 }
4326 
4327 #endif /* MINIMALISTIC */
4328 
4329 void
4330 usage(int verbose)
4331 {
4332 	fprintf(verbose ? stdout : stderr,
4333 "usage:  camcontrol <command>  [device id][generic args][command args]\n"
4334 "        camcontrol devlist    [-v]\n"
4335 #ifndef MINIMALISTIC
4336 "        camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
4337 "        camcontrol tur        [dev_id][generic args]\n"
4338 "        camcontrol inquiry    [dev_id][generic args] [-D] [-S] [-R]\n"
4339 "        camcontrol identify   [dev_id][generic args] [-v]\n"
4340 "        camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
4341 "        camcontrol readcap    [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
4342 "                              [-q] [-s]\n"
4343 "        camcontrol start      [dev_id][generic args]\n"
4344 "        camcontrol stop       [dev_id][generic args]\n"
4345 "        camcontrol load       [dev_id][generic args]\n"
4346 "        camcontrol eject      [dev_id][generic args]\n"
4347 #endif /* MINIMALISTIC */
4348 "        camcontrol rescan     <all | bus[:target:lun]>\n"
4349 "        camcontrol reset      <all | bus[:target:lun]>\n"
4350 #ifndef MINIMALISTIC
4351 "        camcontrol defects    [dev_id][generic args] <-f format> [-P][-G]\n"
4352 "        camcontrol modepage   [dev_id][generic args] <-m page | -l>\n"
4353 "                              [-P pagectl][-e | -b][-d]\n"
4354 "        camcontrol cmd        [dev_id][generic args]\n"
4355 "                              <-a cmd [args] | -c cmd [args]>\n"
4356 "                              [-i len fmt|-o len fmt [args]] [-r fmt]\n"
4357 "        camcontrol debug      [-I][-P][-T][-S][-X][-c]\n"
4358 "                              <all|bus[:target[:lun]]|off>\n"
4359 "        camcontrol tags       [dev_id][generic args] [-N tags] [-q] [-v]\n"
4360 "        camcontrol negotiate  [dev_id][generic args] [-a][-c]\n"
4361 "                              [-D <enable|disable>][-M mode][-O offset]\n"
4362 "                              [-q][-R syncrate][-v][-T <enable|disable>]\n"
4363 "                              [-U][-W bus_width]\n"
4364 "        camcontrol format     [dev_id][generic args][-q][-r][-w][-y]\n"
4365 "        camcontrol idle       [dev_id][generic args][-t time]\n"
4366 "        camcontrol standby    [dev_id][generic args][-t time]\n"
4367 "        camcontrol sleep      [dev_id][generic args]\n"
4368 #endif /* MINIMALISTIC */
4369 "        camcontrol help\n");
4370 	if (!verbose)
4371 		return;
4372 #ifndef MINIMALISTIC
4373 	fprintf(stdout,
4374 "Specify one of the following options:\n"
4375 "devlist     list all CAM devices\n"
4376 "periphlist  list all CAM peripheral drivers attached to a device\n"
4377 "tur         send a test unit ready to the named device\n"
4378 "inquiry     send a SCSI inquiry command to the named device\n"
4379 "identify    send a ATA identify command to the named device\n"
4380 "reportluns  send a SCSI report luns command to the device\n"
4381 "readcap     send a SCSI read capacity command to the device\n"
4382 "start       send a Start Unit command to the device\n"
4383 "stop        send a Stop Unit command to the device\n"
4384 "load        send a Start Unit command to the device with the load bit set\n"
4385 "eject       send a Stop Unit command to the device with the eject bit set\n"
4386 "rescan      rescan all busses, the given bus, or bus:target:lun\n"
4387 "reset       reset all busses, the given bus, or bus:target:lun\n"
4388 "defects     read the defect list of the specified device\n"
4389 "modepage    display or edit (-e) the given mode page\n"
4390 "cmd         send the given scsi command, may need -i or -o as well\n"
4391 "debug       turn debugging on/off for a bus, target, or lun, or all devices\n"
4392 "tags        report or set the number of transaction slots for a device\n"
4393 "negotiate   report or set device negotiation parameters\n"
4394 "format      send the SCSI FORMAT UNIT command to the named device\n"
4395 "idle        send the ATA IDLE command to the named device\n"
4396 "standby     send the ATA STANDBY command to the named device\n"
4397 "sleep       send the ATA SLEEP command to the named device\n"
4398 "help        this message\n"
4399 "Device Identifiers:\n"
4400 "bus:target        specify the bus and target, lun defaults to 0\n"
4401 "bus:target:lun    specify the bus, target and lun\n"
4402 "deviceUNIT        specify the device name, like \"da4\" or \"cd2\"\n"
4403 "Generic arguments:\n"
4404 "-v                be verbose, print out sense information\n"
4405 "-t timeout        command timeout in seconds, overrides default timeout\n"
4406 "-n dev_name       specify device name, e.g. \"da\", \"cd\"\n"
4407 "-u unit           specify unit number, e.g. \"0\", \"5\"\n"
4408 "-E                have the kernel attempt to perform SCSI error recovery\n"
4409 "-C count          specify the SCSI command retry count (needs -E to work)\n"
4410 "modepage arguments:\n"
4411 "-l                list all available mode pages\n"
4412 "-m page           specify the mode page to view or edit\n"
4413 "-e                edit the specified mode page\n"
4414 "-b                force view to binary mode\n"
4415 "-d                disable block descriptors for mode sense\n"
4416 "-P pgctl          page control field 0-3\n"
4417 "defects arguments:\n"
4418 "-f format         specify defect list format (block, bfi or phys)\n"
4419 "-G                get the grown defect list\n"
4420 "-P                get the permanant defect list\n"
4421 "inquiry arguments:\n"
4422 "-D                get the standard inquiry data\n"
4423 "-S                get the serial number\n"
4424 "-R                get the transfer rate, etc.\n"
4425 "reportluns arguments:\n"
4426 "-c                only report a count of available LUNs\n"
4427 "-l                only print out luns, and not a count\n"
4428 "-r <reporttype>   specify \"default\", \"wellknown\" or \"all\"\n"
4429 "readcap arguments\n"
4430 "-b                only report the blocksize\n"
4431 "-h                human readable device size, base 2\n"
4432 "-H                human readable device size, base 10\n"
4433 "-N                print the number of blocks instead of last block\n"
4434 "-q                quiet, print numbers only\n"
4435 "-s                only report the last block/device size\n"
4436 "cmd arguments:\n"
4437 "-c cdb [args]     specify the SCSI CDB\n"
4438 "-i len fmt        specify input data and input data format\n"
4439 "-o len fmt [args] specify output data and output data fmt\n"
4440 "debug arguments:\n"
4441 "-I                CAM_DEBUG_INFO -- scsi commands, errors, data\n"
4442 "-T                CAM_DEBUG_TRACE -- routine flow tracking\n"
4443 "-S                CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
4444 "-c                CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
4445 "tags arguments:\n"
4446 "-N tags           specify the number of tags to use for this device\n"
4447 "-q                be quiet, don't report the number of tags\n"
4448 "-v                report a number of tag-related parameters\n"
4449 "negotiate arguments:\n"
4450 "-a                send a test unit ready after negotiation\n"
4451 "-c                report/set current negotiation settings\n"
4452 "-D <arg>          \"enable\" or \"disable\" disconnection\n"
4453 "-M mode           set ATA mode\n"
4454 "-O offset         set command delay offset\n"
4455 "-q                be quiet, don't report anything\n"
4456 "-R syncrate       synchronization rate in MHz\n"
4457 "-T <arg>          \"enable\" or \"disable\" tagged queueing\n"
4458 "-U                report/set user negotiation settings\n"
4459 "-W bus_width      set the bus width in bits (8, 16 or 32)\n"
4460 "-v                also print a Path Inquiry CCB for the controller\n"
4461 "format arguments:\n"
4462 "-q                be quiet, don't print status messages\n"
4463 "-r                run in report only mode\n"
4464 "-w                don't send immediate format command\n"
4465 "-y                don't ask any questions\n"
4466 "idle/standby arguments:\n"
4467 "-t <arg>          number of seconds before respective state.\n");
4468 #endif /* MINIMALISTIC */
4469 }
4470 
4471 int
4472 main(int argc, char **argv)
4473 {
4474 	int c;
4475 	char *device = NULL;
4476 	int unit = 0;
4477 	struct cam_device *cam_dev = NULL;
4478 	int timeout = 0, retry_count = 1;
4479 	camcontrol_optret optreturn;
4480 	char *tstr;
4481 	const char *mainopt = "C:En:t:u:v";
4482 	const char *subopt = NULL;
4483 	char combinedopt[256];
4484 	int error = 0, optstart = 2;
4485 	int devopen = 1;
4486 #ifndef MINIMALISTIC
4487 	int bus, target, lun;
4488 #endif /* MINIMALISTIC */
4489 
4490 	cmdlist = CAM_CMD_NONE;
4491 	arglist = CAM_ARG_NONE;
4492 
4493 	if (argc < 2) {
4494 		usage(0);
4495 		exit(1);
4496 	}
4497 
4498 	/*
4499 	 * Get the base option.
4500 	 */
4501 	optreturn = getoption(argv[1], &cmdlist, &arglist, &subopt);
4502 
4503 	if (optreturn == CC_OR_AMBIGUOUS) {
4504 		warnx("ambiguous option %s", argv[1]);
4505 		usage(0);
4506 		exit(1);
4507 	} else if (optreturn == CC_OR_NOT_FOUND) {
4508 		warnx("option %s not found", argv[1]);
4509 		usage(0);
4510 		exit(1);
4511 	}
4512 
4513 	/*
4514 	 * Ahh, getopt(3) is a pain.
4515 	 *
4516 	 * This is a gross hack.  There really aren't many other good
4517 	 * options (excuse the pun) for parsing options in a situation like
4518 	 * this.  getopt is kinda braindead, so you end up having to run
4519 	 * through the options twice, and give each invocation of getopt
4520 	 * the option string for the other invocation.
4521 	 *
4522 	 * You would think that you could just have two groups of options.
4523 	 * The first group would get parsed by the first invocation of
4524 	 * getopt, and the second group would get parsed by the second
4525 	 * invocation of getopt.  It doesn't quite work out that way.  When
4526 	 * the first invocation of getopt finishes, it leaves optind pointing
4527 	 * to the argument _after_ the first argument in the second group.
4528 	 * So when the second invocation of getopt comes around, it doesn't
4529 	 * recognize the first argument it gets and then bails out.
4530 	 *
4531 	 * A nice alternative would be to have a flag for getopt that says
4532 	 * "just keep parsing arguments even when you encounter an unknown
4533 	 * argument", but there isn't one.  So there's no real clean way to
4534 	 * easily parse two sets of arguments without having one invocation
4535 	 * of getopt know about the other.
4536 	 *
4537 	 * Without this hack, the first invocation of getopt would work as
4538 	 * long as the generic arguments are first, but the second invocation
4539 	 * (in the subfunction) would fail in one of two ways.  In the case
4540 	 * where you don't set optreset, it would fail because optind may be
4541 	 * pointing to the argument after the one it should be pointing at.
4542 	 * In the case where you do set optreset, and reset optind, it would
4543 	 * fail because getopt would run into the first set of options, which
4544 	 * it doesn't understand.
4545 	 *
4546 	 * All of this would "sort of" work if you could somehow figure out
4547 	 * whether optind had been incremented one option too far.  The
4548 	 * mechanics of that, however, are more daunting than just giving
4549 	 * both invocations all of the expect options for either invocation.
4550 	 *
4551 	 * Needless to say, I wouldn't mind if someone invented a better
4552 	 * (non-GPL!) command line parsing interface than getopt.  I
4553 	 * wouldn't mind if someone added more knobs to getopt to make it
4554 	 * work better.  Who knows, I may talk myself into doing it someday,
4555 	 * if the standards weenies let me.  As it is, it just leads to
4556 	 * hackery like this and causes people to avoid it in some cases.
4557 	 *
4558 	 * KDM, September 8th, 1998
4559 	 */
4560 	if (subopt != NULL)
4561 		sprintf(combinedopt, "%s%s", mainopt, subopt);
4562 	else
4563 		sprintf(combinedopt, "%s", mainopt);
4564 
4565 	/*
4566 	 * For these options we do not parse optional device arguments and
4567 	 * we do not open a passthrough device.
4568 	 */
4569 	if ((cmdlist == CAM_CMD_RESCAN)
4570 	 || (cmdlist == CAM_CMD_RESET)
4571 	 || (cmdlist == CAM_CMD_DEVTREE)
4572 	 || (cmdlist == CAM_CMD_USAGE)
4573 	 || (cmdlist == CAM_CMD_DEBUG))
4574 		devopen = 0;
4575 
4576 #ifndef MINIMALISTIC
4577 	if ((devopen == 1)
4578 	 && (argc > 2 && argv[2][0] != '-')) {
4579 		char name[30];
4580 		int rv;
4581 
4582 		/*
4583 		 * First catch people who try to do things like:
4584 		 * camcontrol tur /dev/da0
4585 		 * camcontrol doesn't take device nodes as arguments.
4586 		 */
4587 		if (argv[2][0] == '/') {
4588 			warnx("%s is not a valid device identifier", argv[2]);
4589 			errx(1, "please read the camcontrol(8) man page");
4590 		} else if (isdigit(argv[2][0])) {
4591 			/* device specified as bus:target[:lun] */
4592 			rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
4593 			if (rv < 2)
4594 				errx(1, "numeric device specification must "
4595 				     "be either bus:target, or "
4596 				     "bus:target:lun");
4597 			/* default to 0 if lun was not specified */
4598 			if ((arglist & CAM_ARG_LUN) == 0) {
4599 				lun = 0;
4600 				arglist |= CAM_ARG_LUN;
4601 			}
4602 			optstart++;
4603 		} else {
4604 			if (cam_get_device(argv[2], name, sizeof name, &unit)
4605 			    == -1)
4606 				errx(1, "%s", cam_errbuf);
4607 			device = strdup(name);
4608 			arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
4609 			optstart++;
4610 		}
4611 	}
4612 #endif /* MINIMALISTIC */
4613 	/*
4614 	 * Start getopt processing at argv[2/3], since we've already
4615 	 * accepted argv[1..2] as the command name, and as a possible
4616 	 * device name.
4617 	 */
4618 	optind = optstart;
4619 
4620 	/*
4621 	 * Now we run through the argument list looking for generic
4622 	 * options, and ignoring options that possibly belong to
4623 	 * subfunctions.
4624 	 */
4625 	while ((c = getopt(argc, argv, combinedopt))!= -1){
4626 		switch(c) {
4627 			case 'C':
4628 				retry_count = strtol(optarg, NULL, 0);
4629 				if (retry_count < 0)
4630 					errx(1, "retry count %d is < 0",
4631 					     retry_count);
4632 				arglist |= CAM_ARG_RETRIES;
4633 				break;
4634 			case 'E':
4635 				arglist |= CAM_ARG_ERR_RECOVER;
4636 				break;
4637 			case 'n':
4638 				arglist |= CAM_ARG_DEVICE;
4639 				tstr = optarg;
4640 				while (isspace(*tstr) && (*tstr != '\0'))
4641 					tstr++;
4642 				device = (char *)strdup(tstr);
4643 				break;
4644 			case 't':
4645 				timeout = strtol(optarg, NULL, 0);
4646 				if (timeout < 0)
4647 					errx(1, "invalid timeout %d", timeout);
4648 				/* Convert the timeout from seconds to ms */
4649 				timeout *= 1000;
4650 				arglist |= CAM_ARG_TIMEOUT;
4651 				break;
4652 			case 'u':
4653 				arglist |= CAM_ARG_UNIT;
4654 				unit = strtol(optarg, NULL, 0);
4655 				break;
4656 			case 'v':
4657 				arglist |= CAM_ARG_VERBOSE;
4658 				break;
4659 			default:
4660 				break;
4661 		}
4662 	}
4663 
4664 #ifndef MINIMALISTIC
4665 	/*
4666 	 * For most commands we'll want to open the passthrough device
4667 	 * associated with the specified device.  In the case of the rescan
4668 	 * commands, we don't use a passthrough device at all, just the
4669 	 * transport layer device.
4670 	 */
4671 	if (devopen == 1) {
4672 		if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
4673 		 && (((arglist & CAM_ARG_DEVICE) == 0)
4674 		  || ((arglist & CAM_ARG_UNIT) == 0))) {
4675 			errx(1, "subcommand \"%s\" requires a valid device "
4676 			     "identifier", argv[1]);
4677 		}
4678 
4679 		if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
4680 				cam_open_btl(bus, target, lun, O_RDWR, NULL) :
4681 				cam_open_spec_device(device,unit,O_RDWR,NULL)))
4682 		     == NULL)
4683 			errx(1,"%s", cam_errbuf);
4684 	}
4685 #endif /* MINIMALISTIC */
4686 
4687 	/*
4688 	 * Reset optind to 2, and reset getopt, so these routines can parse
4689 	 * the arguments again.
4690 	 */
4691 	optind = optstart;
4692 	optreset = 1;
4693 
4694 	switch(cmdlist) {
4695 #ifndef MINIMALISTIC
4696 		case CAM_CMD_DEVLIST:
4697 			error = getdevlist(cam_dev);
4698 			break;
4699 #endif /* MINIMALISTIC */
4700 		case CAM_CMD_DEVTREE:
4701 			error = getdevtree();
4702 			break;
4703 #ifndef MINIMALISTIC
4704 		case CAM_CMD_TUR:
4705 			error = testunitready(cam_dev, retry_count, timeout, 0);
4706 			break;
4707 		case CAM_CMD_INQUIRY:
4708 			error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
4709 					      retry_count, timeout);
4710 			break;
4711 		case CAM_CMD_IDENTIFY:
4712 			error = ataidentify(cam_dev, retry_count, timeout);
4713 			break;
4714 		case CAM_CMD_STARTSTOP:
4715 			error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
4716 					  arglist & CAM_ARG_EJECT, retry_count,
4717 					  timeout);
4718 			break;
4719 #endif /* MINIMALISTIC */
4720 		case CAM_CMD_RESCAN:
4721 			error = dorescan_or_reset(argc, argv, 1);
4722 			break;
4723 		case CAM_CMD_RESET:
4724 			error = dorescan_or_reset(argc, argv, 0);
4725 			break;
4726 #ifndef MINIMALISTIC
4727 		case CAM_CMD_READ_DEFECTS:
4728 			error = readdefects(cam_dev, argc, argv, combinedopt,
4729 					    retry_count, timeout);
4730 			break;
4731 		case CAM_CMD_MODE_PAGE:
4732 			modepage(cam_dev, argc, argv, combinedopt,
4733 				 retry_count, timeout);
4734 			break;
4735 		case CAM_CMD_SCSI_CMD:
4736 			error = scsicmd(cam_dev, argc, argv, combinedopt,
4737 					retry_count, timeout);
4738 			break;
4739 		case CAM_CMD_DEBUG:
4740 			error = camdebug(argc, argv, combinedopt);
4741 			break;
4742 		case CAM_CMD_TAG:
4743 			error = tagcontrol(cam_dev, argc, argv, combinedopt);
4744 			break;
4745 		case CAM_CMD_RATE:
4746 			error = ratecontrol(cam_dev, retry_count, timeout,
4747 					    argc, argv, combinedopt);
4748 			break;
4749 		case CAM_CMD_FORMAT:
4750 			error = scsiformat(cam_dev, argc, argv,
4751 					   combinedopt, retry_count, timeout);
4752 			break;
4753 		case CAM_CMD_REPORTLUNS:
4754 			error = scsireportluns(cam_dev, argc, argv,
4755 					       combinedopt, retry_count,
4756 					       timeout);
4757 			break;
4758 		case CAM_CMD_READCAP:
4759 			error = scsireadcapacity(cam_dev, argc, argv,
4760 						 combinedopt, retry_count,
4761 						 timeout);
4762 			break;
4763 		case CAM_CMD_IDLE:
4764 		case CAM_CMD_STANDBY:
4765 		case CAM_CMD_SLEEP:
4766 			error = atapm(cam_dev, argc, argv,
4767 						 combinedopt, retry_count,
4768 						 timeout);
4769 			break;
4770 #endif /* MINIMALISTIC */
4771 		case CAM_CMD_USAGE:
4772 			usage(1);
4773 			break;
4774 		default:
4775 			usage(0);
4776 			error = 1;
4777 			break;
4778 	}
4779 
4780 	if (cam_dev != NULL)
4781 		cam_close_device(cam_dev);
4782 
4783 	exit(error);
4784 }
4785