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