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