xref: /openbsd-src/sys/dev/ic/aac.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: aac.c,v 1.67 2016/03/27 11:06:19 mpi Exp $	*/
2 
3 /*-
4  * Copyright (c) 2000 Michael Smith
5  * Copyright (c) 2001 Scott Long
6  * Copyright (c) 2000 BSDi
7  * Copyright (c) 2001 Adaptec, Inc.
8  * Copyright (c) 2000 Niklas Hallqvist
9  * Copyright (c) 2004 Nathan Binkert
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	$FreeBSD: /c/ncvs/src/sys/dev/aac/aac.c,v 1.1 2000/09/13 03:20:34 msmith Exp $
34  */
35 
36 /*
37  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
38  */
39 
40 /*
41  * This driver would not have rewritten for OpenBSD if it was not for the
42  * hardware donation from Nocom.  I want to thank them for their support.
43  * Of course, credit should go to Mike Smith for the original work he did
44  * in the FreeBSD driver where I found lots of reusable code and inspiration.
45  * - Niklas Hallqvist
46  */
47 
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/buf.h>
51 #include <sys/device.h>
52 #include <sys/kernel.h>
53 #include <sys/kthread.h>
54 #include <sys/malloc.h>
55 #include <sys/rwlock.h>
56 #include <sys/time.h>
57 
58 #include <machine/bus.h>
59 
60 #include <uvm/uvm_extern.h>
61 
62 #include <scsi/scsi_all.h>
63 #include <scsi/scsi_disk.h>
64 #include <scsi/scsiconf.h>
65 
66 #include <dev/ic/aacreg.h>
67 #include <dev/ic/aacvar.h>
68 #include <dev/ic/aac_tables.h>
69 
70 /* Geometry constants. */
71 #define AAC_MAXCYLS		1024
72 #define AAC_HEADS		64
73 #define AAC_SECS		32	/* mapping 64*32 */
74 #define AAC_MEDHEADS		127
75 #define AAC_MEDSECS		63	/* mapping 127*63 */
76 #define AAC_BIGHEADS		255
77 #define AAC_BIGSECS		63	/* mapping 255*63 */
78 #define AAC_SECS32		0x1f	/* round capacity */
79 
80 struct scsi_xfer;
81 
82 void	aac_copy_internal_data(struct scsi_xfer *, u_int8_t *, size_t);
83 char   *aac_describe_code(struct aac_code_lookup *, u_int32_t);
84 void	aac_describe_controller(struct aac_softc *);
85 int	aac_enqueue_fib(struct aac_softc *, int, struct aac_command *);
86 int	aac_dequeue_fib(struct aac_softc *, int, u_int32_t *,
87 			struct aac_fib **);
88 int	aac_enqueue_response(struct aac_softc *sc, int queue,
89 			     struct aac_fib *fib);
90 
91 void	aac_eval_mapping(u_int32_t, int *, int *, int *);
92 void	aac_print_printf(struct aac_softc *);
93 int	aac_init(struct aac_softc *);
94 int	aac_check_firmware(struct aac_softc *);
95 void	aac_internal_cache_cmd(struct scsi_xfer *);
96 
97 /* Command Processing */
98 void	aac_timeout(struct aac_softc *);
99 void	aac_command_timeout(struct aac_command *);
100 int	aac_map_command(struct aac_command *);
101 void	aac_complete(void *);
102 int	aac_bio_command(struct aac_softc *, struct aac_command **);
103 void	aac_bio_complete(struct aac_command *);
104 int	aac_wait_command(struct aac_command *, int);
105 void	aac_create_thread(void *);
106 void	aac_command_thread(void *);
107 
108 /* Command Buffer Management */
109 void	aac_map_command_sg(void *, bus_dma_segment_t *, int, int);
110 int	aac_alloc_commands(struct aac_softc *);
111 void	aac_free_commands(struct aac_softc *);
112 void	aac_unmap_command(struct aac_command *);
113 int	aac_wait_command(struct aac_command *, int);
114 void *	aac_alloc_command(void *);
115 void	aac_scrub_command(struct aac_command *);
116 void	aac_release_command(void *, void *);
117 int	aac_alloc_sync_fib(struct aac_softc *, struct aac_fib **, int);
118 void	aac_release_sync_fib(struct aac_softc *);
119 int	aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t,
120 	    struct aac_fib *, u_int16_t);
121 
122 void	aac_scsi_cmd(struct scsi_xfer *);
123 void	aac_startio(struct aac_softc *);
124 void	aac_startup(struct aac_softc *);
125 int	aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t,
126     u_int32_t, u_int32_t, u_int32_t, u_int32_t *);
127 
128 struct cfdriver aac_cd = {
129 	NULL, "aac", DV_DULL
130 };
131 
132 struct scsi_adapter aac_switch = {
133 	aac_scsi_cmd,
134 	scsi_minphys,
135 	NULL,		/* probe */
136 	NULL,		/* free */
137 	NULL		/* ioctl */
138 };
139 
140 /* Falcon/PPC interface */
141 int	aac_fa_get_fwstatus(struct aac_softc *);
142 void	aac_fa_qnotify(struct aac_softc *, int);
143 int	aac_fa_get_istatus(struct aac_softc *);
144 void	aac_fa_clear_istatus(struct aac_softc *, int);
145 void	aac_fa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, u_int32_t,
146 			   u_int32_t, u_int32_t);
147 int	aac_fa_get_mailbox(struct aac_softc *, int);
148 void	aac_fa_set_interrupts(struct aac_softc *, int);
149 
150 struct aac_interface aac_fa_interface = {
151 	aac_fa_get_fwstatus,
152 	aac_fa_qnotify,
153 	aac_fa_get_istatus,
154 	aac_fa_clear_istatus,
155 	aac_fa_set_mailbox,
156 	aac_fa_get_mailbox,
157 	aac_fa_set_interrupts
158 };
159 
160 /* StrongARM interface */
161 int	aac_sa_get_fwstatus(struct aac_softc *);
162 void	aac_sa_qnotify(struct aac_softc *, int);
163 int	aac_sa_get_istatus(struct aac_softc *);
164 void	aac_sa_clear_istatus(struct aac_softc *, int);
165 void	aac_sa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t,
166     u_int32_t, u_int32_t, u_int32_t);
167 int	aac_sa_get_mailbox(struct aac_softc *, int);
168 void	aac_sa_set_interrupts(struct aac_softc *, int);
169 
170 struct aac_interface aac_sa_interface = {
171 	aac_sa_get_fwstatus,
172 	aac_sa_qnotify,
173 	aac_sa_get_istatus,
174 	aac_sa_clear_istatus,
175 	aac_sa_set_mailbox,
176 	aac_sa_get_mailbox,
177 	aac_sa_set_interrupts
178 };
179 
180 /* i960Rx interface */
181 int	aac_rx_get_fwstatus(struct aac_softc *);
182 void	aac_rx_qnotify(struct aac_softc *, int);
183 int	aac_rx_get_istatus(struct aac_softc *);
184 void	aac_rx_clear_istatus(struct aac_softc *, int);
185 void	aac_rx_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t,
186     u_int32_t, u_int32_t, u_int32_t);
187 int	aac_rx_get_mailbox(struct aac_softc *, int);
188 void	aac_rx_set_interrupts(struct aac_softc *, int);
189 
190 struct aac_interface aac_rx_interface = {
191 	aac_rx_get_fwstatus,
192 	aac_rx_qnotify,
193 	aac_rx_get_istatus,
194 	aac_rx_clear_istatus,
195 	aac_rx_set_mailbox,
196 	aac_rx_get_mailbox,
197 	aac_rx_set_interrupts
198 };
199 
200 /* Rocket/MIPS interface */
201 int	aac_rkt_get_fwstatus(struct aac_softc *);
202 void	aac_rkt_qnotify(struct aac_softc *, int);
203 int	aac_rkt_get_istatus(struct aac_softc *);
204 void	aac_rkt_clear_istatus(struct aac_softc *, int);
205 void	aac_rkt_set_mailbox(struct aac_softc *, u_int32_t,
206 				    u_int32_t, u_int32_t,
207 				    u_int32_t, u_int32_t);
208 int	aac_rkt_get_mailbox(struct aac_softc *, int);
209 void	aac_rkt_set_interrupts(struct aac_softc *, int);
210 
211 struct aac_interface aac_rkt_interface = {
212 	aac_rkt_get_fwstatus,
213 	aac_rkt_qnotify,
214 	aac_rkt_get_istatus,
215 	aac_rkt_clear_istatus,
216 	aac_rkt_set_mailbox,
217 	aac_rkt_get_mailbox,
218 	aac_rkt_set_interrupts
219 };
220 
221 #ifdef AAC_DEBUG
222 int	aac_debug = AAC_DEBUG;
223 #endif
224 
225 int
226 aac_attach(struct aac_softc *sc)
227 {
228 	struct scsibus_attach_args saa;
229 	int error;
230 
231 	/*
232 	 * Initialise per-controller queues.
233 	 */
234 	mtx_init(&sc->aac_free_mtx, IPL_BIO);
235 	aac_initq_free(sc);
236 	aac_initq_ready(sc);
237 	aac_initq_busy(sc);
238 	aac_initq_bio(sc);
239 
240 	/* disable interrupts before we enable anything */
241 	AAC_MASK_INTERRUPTS(sc);
242 
243 	/* mark controller as suspended until we get ourselves organised */
244 	sc->aac_state |= AAC_STATE_SUSPEND;
245 
246 	/*
247 	 * Check that the firmware on the card is supported.
248 	 */
249 	error = aac_check_firmware(sc);
250 	if (error)
251 		return (error);
252 
253 	/*
254 	 * Initialize locks
255 	 */
256 	AAC_LOCK_INIT(&sc->aac_sync_lock, "AAC sync FIB lock");
257 	AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock");
258 	AAC_LOCK_INIT(&sc->aac_io_lock, "AAC I/O lock");
259 	AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock");
260 	TAILQ_INIT(&sc->aac_container_tqh);
261 
262 	/* Initialize the local AIF queue pointers */
263 	sc->aac_aifq_head = sc->aac_aifq_tail = AAC_AIFQ_LENGTH;
264 
265 	/*
266 	 * Initialise the adapter.
267 	 */
268 	error = aac_init(sc);
269 	if (error)
270 		return (error);
271 
272 	/* Fill in the prototype scsi_link. */
273 	sc->aac_link.adapter_softc = sc;
274 	sc->aac_link.adapter = &aac_switch;
275 	sc->aac_link.openings = (sc->total_fibs - 8) /
276 	    (sc->aac_container_count ? sc->aac_container_count : 1);
277 	sc->aac_link.adapter_buswidth = AAC_MAX_CONTAINERS;
278 	sc->aac_link.adapter_target = AAC_MAX_CONTAINERS;
279 	sc->aac_link.pool = &sc->aac_iopool;
280 
281 	bzero(&saa, sizeof(saa));
282 	saa.saa_sc_link = &sc->aac_link;
283 
284 	config_found(&sc->aac_dev, &saa, scsiprint);
285 
286 	/* Create the AIF thread */
287 	sc->aifthread = 0;
288 	sc->aifflags = 0;
289 	kthread_create_deferred(aac_create_thread, sc);
290 
291 	return (0);
292 }
293 
294 void
295 aac_create_thread(void *arg)
296 {
297 	struct aac_softc *sc = arg;
298 
299 	if (kthread_create(aac_command_thread, sc, &sc->aifthread,
300 	    sc->aac_dev.dv_xname)) {
301 		/* TODO disable aac */
302 		printf("%s: failed to create kernel thread, disabled",
303 		sc->aac_dev.dv_xname);
304 	}
305 	AAC_DPRINTF(AAC_D_MISC, ("%s: aac_create_thread\n",
306 	    sc->aac_dev.dv_xname));
307 
308 }
309 
310 /*
311  * Probe for containers, create disks.
312  */
313 void
314 aac_startup(struct aac_softc *sc)
315 {
316 	struct aac_fib *fib;
317 	struct aac_mntinfo *mi;
318 	struct aac_mntinforesp *mir = NULL;
319 	int count = 0, i = 0;
320 
321 
322 	aac_alloc_sync_fib(sc, &fib, 0);
323 	mi = (struct aac_mntinfo *)&fib->data[0];
324 
325 	AAC_DPRINTF(AAC_D_MISC, ("%s: aac startup\n", sc->aac_dev.dv_xname));
326 
327 	sc->aac_container_count = 0;
328 	/* loop over possible containers */
329 	do {
330 		/* request information on this container */
331 		bzero(mi, sizeof(struct aac_mntinfo));
332 		mi->Command = VM_NameServe;
333 		mi->MntType = FT_FILESYS;
334 		mi->MntCount = i;
335 		if (aac_sync_fib(sc, ContainerCommand, 0, fib,
336 				 sizeof(struct aac_mntinfo))) {
337 			printf("%s: error probing container %d\n",
338 			       sc->aac_dev.dv_xname, i);
339 			continue;
340 		}
341 
342 		mir = (struct aac_mntinforesp *)&fib->data[0];
343 		/* XXX Need to check if count changed */
344 		count = mir->MntRespCount;
345 
346 		/*
347 		 * Check container volume type for validity.  Note
348 		 * that many of the possible types may never show up.
349 		 */
350 		if (mir->Status == ST_OK &&
351 		    mir->MntTable[0].VolType != CT_NONE) {
352 			int drv_cyls, drv_hds, drv_secs;
353 
354 			AAC_DPRINTF(AAC_D_MISC,
355 			    ("%s: %d: id %x  name '%.16s'  size %u  type %d\n",
356 			     sc->aac_dev.dv_xname, i,
357 			     mir->MntTable[0].ObjectId,
358 			     mir->MntTable[0].FileSystemName,
359 			     mir->MntTable[0].Capacity,
360 			     mir->MntTable[0].VolType));
361 
362 			sc->aac_container_count++;
363 			sc->aac_hdr[i].hd_present = 1;
364 			sc->aac_hdr[i].hd_size = mir->MntTable[0].Capacity;
365 
366 			/*
367 			 * Evaluate mapping (sectors per head, heads per cyl)
368 			 */
369 			sc->aac_hdr[i].hd_size &= ~AAC_SECS32;
370 			aac_eval_mapping(sc->aac_hdr[i].hd_size, &drv_cyls,
371 					 &drv_hds, &drv_secs);
372 			sc->aac_hdr[i].hd_heads = drv_hds;
373 			sc->aac_hdr[i].hd_secs = drv_secs;
374 			/* Round the size */
375 			sc->aac_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs;
376 
377 			sc->aac_hdr[i].hd_devtype = mir->MntTable[0].VolType;
378 
379 			/* XXX Save the name too for use in IDENTIFY later */
380 		}
381 
382 		i++;
383 	} while ((i < count) && (i < AAC_MAX_CONTAINERS));
384 
385 	aac_release_sync_fib(sc);
386 
387 	/* mark the controller up */
388 	sc->aac_state &= ~AAC_STATE_SUSPEND;
389 
390 	/* enable interrupts now */
391 	AAC_UNMASK_INTERRUPTS(sc);
392 }
393 
394 /*
395  * Take an interrupt.
396  */
397 int
398 aac_intr(void *arg)
399 {
400 	struct aac_softc *sc = arg;
401 	u_int16_t reason;
402 
403 
404 	/*
405 	 * Read the status register directly.  This is faster than taking the
406 	 * driver lock and reading the queues directly.  It also saves having
407 	 * to turn parts of the driver lock into a spin mutex, which would be
408 	 * ugly.
409 	 */
410 	reason = AAC_GET_ISTATUS(sc);
411 	AAC_CLEAR_ISTATUS(sc, reason);
412 	(void)AAC_GET_ISTATUS(sc);
413 
414 	if (reason == 0)
415 		return (0);
416 
417 	AAC_DPRINTF(AAC_D_INTR, ("%s: intr: sc=%p: reason=%#x\n",
418 				 sc->aac_dev.dv_xname, sc, reason));
419 
420 	/* controller wants to talk to us */
421 	if (reason & (AAC_DB_PRINTF | AAC_DB_COMMAND_READY |
422 		      AAC_DB_RESPONSE_READY)) {
423 
424 		if (reason & AAC_DB_RESPONSE_READY) {
425 			/* handle completion processing */
426 			if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
427 				sc->aifflags |= AAC_AIFFLAGS_COMPLETE;
428 			} else {
429 				AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
430 				aac_complete(sc);
431 				AAC_LOCK_RELEASE(&sc->aac_io_lock);
432 			}
433 		}
434 
435 
436 		/*
437 		 * XXX Make sure that we don't get fooled by strange messages
438 		 * that start with a NULL.
439 		 */
440 		if (reason & AAC_DB_PRINTF)
441 			if (sc->aac_common->ac_printf[0] == 0)
442 				sc->aac_common->ac_printf[0] = 32;
443 
444 		/*
445 		 * This might miss doing the actual wakeup.  However, the
446 		 * msleep that this is waking up has a timeout, so it will
447 		 * wake up eventually.  AIFs and printfs are low enough
448 		 * priority that they can handle hanging out for a few seconds
449 		 * if needed.
450 		 */
451 		if (sc->aifthread)
452 			wakeup(sc->aifthread);
453 
454 	}
455 
456 	return (1);
457 }
458 
459 /*
460  * Command Processing
461  */
462 
463 /*
464  * Start as much queued I/O as possible on the controller
465  */
466 void
467 aac_startio(struct aac_softc *sc)
468 {
469 	struct aac_command *cm;
470 
471 	AAC_DPRINTF(AAC_D_CMD, ("%s: start command", sc->aac_dev.dv_xname));
472 
473 	if (sc->flags & AAC_QUEUE_FRZN) {
474 		AAC_DPRINTF(AAC_D_CMD, (": queue frozen"));
475 		return;
476 	}
477 
478 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
479 
480 	for (;;) {
481 		/*
482 		 * Try to get a command that's been put off for lack of
483 		 * resources
484 		 */
485 		cm = aac_dequeue_ready(sc);
486 
487 		/*
488 		 * Try to build a command off the bio queue (ignore error
489 		 * return)
490 		 */
491 		if (cm == NULL) {
492 			AAC_DPRINTF(AAC_D_CMD, ("\n"));
493 			aac_bio_command(sc, &cm);
494 			AAC_DPRINTF(AAC_D_CMD, ("%s: start done bio",
495 						sc->aac_dev.dv_xname));
496 		}
497 
498 		/* nothing to do? */
499 		if (cm == NULL)
500 			break;
501 
502 		/*
503 		 * Try to give the command to the controller.  Any error is
504 		 * catastrophic since it means that bus_dmamap_load() failed.
505 		 */
506 		if (aac_map_command(cm) != 0)
507 			panic("aac: error mapping command %p", cm);
508 
509 		AAC_DPRINTF(AAC_D_CMD, ("\n%s: another command",
510 					sc->aac_dev.dv_xname));
511 	}
512 
513 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
514 }
515 
516 /*
517  * Deliver a command to the controller; allocate controller resources at the
518  * last moment when possible.
519  */
520 int
521 aac_map_command(struct aac_command *cm)
522 {
523 	struct aac_softc *sc = cm->cm_sc;
524 	int error = 0;
525 
526 	AAC_DPRINTF(AAC_D_CMD, (": map command"));
527 
528 	/* don't map more than once */
529 	if (cm->cm_flags & AAC_CMD_MAPPED)
530 		panic("aac: command %p already mapped", cm);
531 
532 	if (cm->cm_datalen != 0) {
533 		error = bus_dmamap_load(sc->aac_dmat, cm->cm_datamap,
534 					cm->cm_data, cm->cm_datalen, NULL,
535 					BUS_DMA_NOWAIT);
536 		if (error)
537 			return (error);
538 
539 		aac_map_command_sg(cm, cm->cm_datamap->dm_segs,
540 				   cm->cm_datamap->dm_nsegs, 0);
541 	} else {
542 		aac_map_command_sg(cm, NULL, 0, 0);
543 	}
544 
545 	return (error);
546 }
547 
548 /*
549  * Handle notification of one or more FIBs coming from the controller.
550  */
551 void
552 aac_command_thread(void *arg)
553 {
554 	struct aac_softc *sc = arg;
555 	struct aac_fib *fib;
556 	u_int32_t fib_size;
557 	int size, retval;
558 
559 	AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: starting\n",
560 	    sc->aac_dev.dv_xname));
561 	AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
562 	sc->aifflags = AAC_AIFFLAGS_RUNNING;
563 
564 	while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
565 
566 		AAC_DPRINTF(AAC_D_THREAD,
567 		    ("%s: aac_command_thread: aifflags=%#x\n",
568 		    sc->aac_dev.dv_xname, sc->aifflags));
569 		retval = 0;
570 
571 		if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0) {
572 			AAC_DPRINTF(AAC_D_THREAD,
573 				    ("%s: command thread sleeping\n",
574 				     sc->aac_dev.dv_xname));
575 			AAC_LOCK_RELEASE(&sc->aac_io_lock);
576 			retval = tsleep(sc->aifthread, PRIBIO, "aifthd",
577 					AAC_PERIODIC_INTERVAL * hz);
578 			AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
579 		}
580 
581 		if ((sc->aifflags & AAC_AIFFLAGS_COMPLETE) != 0) {
582 			aac_complete(sc);
583 			sc->aifflags &= ~AAC_AIFFLAGS_COMPLETE;
584 		}
585 
586 		/*
587 		 * While we're here, check to see if any commands are stuck.
588 		 * This is pretty low-priority, so it's ok if it doesn't
589 		 * always fire.
590 		 */
591 		if (retval == EWOULDBLOCK)
592 			aac_timeout(sc);
593 
594 		/* Check the hardware printf message buffer */
595 		if (sc->aac_common->ac_printf[0] != 0)
596 			aac_print_printf(sc);
597 
598 		/* Also check to see if the adapter has a command for us. */
599 		while (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
600 				       &fib_size, &fib) == 0) {
601 
602 			AAC_PRINT_FIB(sc, fib);
603 
604 			switch (fib->Header.Command) {
605 			case AifRequest:
606 				//aac_handle_aif(sc, fib);
607 				break;
608 			default:
609 				printf("%s: unknown command from controller\n",
610 				       sc->aac_dev.dv_xname);
611 				break;
612 			}
613 
614 			if ((fib->Header.XferState == 0) ||
615 			    (fib->Header.StructType != AAC_FIBTYPE_TFIB))
616 				break;
617 
618 			/* Return the AIF to the controller. */
619 			if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
620 				fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
621 				*(AAC_FSAStatus*)fib->data = ST_OK;
622 
623 				/* XXX Compute the Size field? */
624 				size = fib->Header.Size;
625 				if (size > sizeof(struct aac_fib)) {
626 					size = sizeof(struct aac_fib);
627 					fib->Header.Size = size;
628 				}
629 
630 				/*
631 				 * Since we did not generate this command, it
632 				 * cannot go through the normal
633 				 * enqueue->startio chain.
634 				 */
635 				aac_enqueue_response(sc,
636 						     AAC_ADAP_NORM_RESP_QUEUE,
637 						     fib);
638 			}
639 		}
640 	}
641 	sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
642 	AAC_LOCK_RELEASE(&sc->aac_io_lock);
643 
644 	AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: exiting\n",
645 	    sc->aac_dev.dv_xname));
646 	kthread_exit(0);
647 }
648 
649 /*
650  * Process completed commands.
651  */
652 void
653 aac_complete(void *context)
654 {
655 	struct aac_softc *sc = (struct aac_softc *)context;
656 	struct aac_command *cm;
657 	struct aac_fib *fib;
658 	u_int32_t fib_size;
659 
660 	AAC_DPRINTF(AAC_D_CMD, ("%s: complete", sc->aac_dev.dv_xname));
661 
662 	/* pull completed commands off the queue */
663 	for (;;) {
664 		/* look for completed FIBs on our queue */
665 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
666 				    &fib))
667 			break;	/* nothing to do */
668 
669 		/* get the command, unmap and hand off for processing */
670 		cm = sc->aac_commands + fib->Header.SenderData;
671 		if (cm == NULL) {
672 			AAC_PRINT_FIB(sc, fib);
673 			break;
674 		}
675 
676 		aac_remove_busy(cm);
677 		aac_unmap_command(cm);
678 		cm->cm_flags |= AAC_CMD_COMPLETED;
679 
680 		/* is there a completion handler? */
681 		if (cm->cm_complete != NULL) {
682 			cm->cm_complete(cm);
683 		} else {
684 			/* assume that someone is sleeping on this command */
685 			wakeup(cm);
686 		}
687 	}
688 
689 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
690 	/* see if we can start some more I/O */
691 	sc->flags &= ~AAC_QUEUE_FRZN;
692 	aac_startio(sc);
693 }
694 
695 /*
696  * Get a bio and build a command to go with it.
697  */
698 int
699 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
700 {
701 	struct aac_command *cm;
702 	struct aac_fib *fib;
703 	struct scsi_xfer *xs;
704 	u_int8_t opcode = 0;
705 
706 	AAC_DPRINTF(AAC_D_CMD, ("%s: bio command", sc->aac_dev.dv_xname));
707 
708 	/* get the resources we will need */
709 	if ((cm = aac_dequeue_bio(sc)) == NULL)
710 		goto fail;
711 	xs = cm->cm_private;
712 
713 	/* build the FIB */
714 	fib = cm->cm_fib;
715 	fib->Header.Size = sizeof(struct aac_fib_header);
716 	fib->Header.XferState =
717 		AAC_FIBSTATE_HOSTOWNED   |
718 		AAC_FIBSTATE_INITIALISED |
719 		AAC_FIBSTATE_EMPTY	 |
720 		AAC_FIBSTATE_FROMHOST	 |
721 		AAC_FIBSTATE_REXPECTED   |
722 		AAC_FIBSTATE_NORM	 |
723 		AAC_FIBSTATE_ASYNC	 |
724 		AAC_FIBSTATE_FAST_RESPONSE;
725 
726 	switch(xs->cmd->opcode) {
727 	case READ_COMMAND:
728 	case READ_BIG:
729 		opcode = READ_COMMAND;
730 		break;
731 	case WRITE_COMMAND:
732 	case WRITE_BIG:
733 		opcode = WRITE_COMMAND;
734 		break;
735 	default:
736 		panic("%s: invalid opcode %#x", sc->aac_dev.dv_xname,
737 		      xs->cmd->opcode);
738 	}
739 
740 	/* build the read/write request */
741 	if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
742 		fib->Header.Command = ContainerCommand;
743 		if (opcode == READ_COMMAND) {
744 			struct aac_blockread *br;
745 			br = (struct aac_blockread *)&fib->data[0];
746 			br->Command = VM_CtBlockRead;
747 			br->ContainerId = xs->sc_link->target;
748 			br->BlockNumber = cm->cm_blkno;
749 			br->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE;
750 			fib->Header.Size += sizeof(struct aac_blockread);
751 			cm->cm_sgtable = &br->SgMap;
752 			cm->cm_flags |= AAC_CMD_DATAIN;
753 		} else {
754 			struct aac_blockwrite *bw;
755 			bw = (struct aac_blockwrite *)&fib->data[0];
756 			bw->Command = VM_CtBlockWrite;
757 			bw->ContainerId = xs->sc_link->target;
758 			bw->BlockNumber = cm->cm_blkno;
759 			bw->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE;
760 			bw->Stable = CUNSTABLE;
761 			fib->Header.Size += sizeof(struct aac_blockwrite);
762 			cm->cm_flags |= AAC_CMD_DATAOUT;
763 			cm->cm_sgtable = &bw->SgMap;
764 		}
765 	} else {
766 		fib->Header.Command = ContainerCommand64;
767 		if (opcode == READ_COMMAND) {
768 			struct aac_blockread64 *br;
769 			br = (struct aac_blockread64 *)&fib->data[0];
770 			br->Command = VM_CtHostRead64;
771 			br->ContainerId = xs->sc_link->target;
772 			br->BlockNumber = cm->cm_blkno;
773 			br->SectorCount = cm->cm_bcount;
774 			br->Pad = 0;
775 			br->Flags = 0;
776 			fib->Header.Size += sizeof(struct aac_blockread64);
777 			cm->cm_flags |= AAC_CMD_DATAOUT;
778 			cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64;
779 		} else {
780 			struct aac_blockwrite64 *bw;
781 			bw = (struct aac_blockwrite64 *)&fib->data[0];
782 			bw->Command = VM_CtHostWrite64;
783 			bw->ContainerId = xs->sc_link->target;
784 			bw->BlockNumber = cm->cm_blkno;
785 			bw->SectorCount = cm->cm_bcount;
786 			bw->Pad = 0;
787 			bw->Flags = 0;
788 			fib->Header.Size += sizeof(struct aac_blockwrite64);
789 			cm->cm_flags |= AAC_CMD_DATAIN;
790 			cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64;
791 		}
792 	}
793 
794 	*cmp = cm;
795 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
796 	return(0);
797 
798 fail:
799 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
800 	return(ENOMEM);
801 }
802 
803 /*
804  * Handle a bio-instigated command that has been completed.
805  */
806 void
807 aac_bio_complete(struct aac_command *cm)
808 {
809 	struct aac_blockread_response *brr;
810 	struct aac_blockwrite_response *bwr;
811 	struct scsi_xfer *xs = (struct scsi_xfer *)cm->cm_private;
812 	AAC_FSAStatus status;
813 	int s;
814 
815 	AAC_DPRINTF(AAC_D_CMD,
816 		    ("%s: bio complete\n", cm->cm_sc->aac_dev.dv_xname));
817 
818 	/* fetch relevant status and then release the command */
819 	if (xs->flags & SCSI_DATA_IN) {
820 		brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
821 		status = brr->Status;
822 	} else {
823 		bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
824 		status = bwr->Status;
825 	}
826 
827 	xs->error = status == ST_OK? XS_NOERROR : XS_DRIVER_STUFFUP;
828 	xs->resid = 0;
829 	s = splbio();
830 	scsi_done(xs);
831 	splx(s);
832 }
833 
834 /*
835  * Submit a command to the controller, return when it completes.
836  * XXX This is very dangerous!  If the card has gone out to lunch, we could
837  *     be stuck here forever.  At the same time, signals are not caught
838  *     because there is a risk that a signal could wakeup the tsleep before
839  *     the card has a chance to complete the command.  The passed in timeout
840  *     is ignored for the same reason.  Since there is no way to cancel a
841  *     command in progress, we should probably create a 'dead' queue where
842  *     commands go that have been interrupted/timed-out/etc, that keeps them
843  *     out of the free pool.  That way, if the card is just slow, it won't
844  *     spam the memory of a command that has been recycled.
845  */
846 int
847 aac_wait_command(struct aac_command *cm, int timeout)
848 {
849 	struct aac_softc *sc = cm->cm_sc;
850 	int error = 0;
851 
852 	AAC_DPRINTF(AAC_D_CMD, (": wait for command"));
853 
854 	/* Put the command on the ready queue and get things going */
855 	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
856 	aac_enqueue_ready(cm);
857 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
858 	aac_startio(sc);
859 	while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) {
860 		AAC_DPRINTF(AAC_D_MISC, ("%s: sleeping until command done\n",
861 					 sc->aac_dev.dv_xname));
862 		AAC_LOCK_RELEASE(&sc->aac_io_lock);
863 		error = tsleep(cm, PRIBIO, "aacwait", timeout);
864 		AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
865 	}
866 	return (error);
867 }
868 
869 /*
870  *Command Buffer Management
871  */
872 
873 /*
874  * Allocate a command.
875  */
876 void *
877 aac_alloc_command(void *xsc)
878 {
879 	struct aac_softc *sc = xsc;
880 	struct aac_command *cm;
881 
882 	AAC_DPRINTF(AAC_D_CMD, (": allocate command"));
883 	mtx_enter(&sc->aac_free_mtx);
884 	cm = aac_dequeue_free(sc);
885 	mtx_leave(&sc->aac_free_mtx);
886 
887 	return (cm);
888 }
889 
890 void
891 aac_scrub_command(struct aac_command *cm)
892 {
893 	cm->cm_sgtable = NULL;
894 	cm->cm_flags = 0;
895 	cm->cm_complete = NULL;
896 	cm->cm_private = NULL;
897 	cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
898 	cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
899 	cm->cm_fib->Header.Flags = 0;
900 	cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
901 }
902 
903 /*
904  * Release a command back to the freelist.
905  */
906 void
907 aac_release_command(void *xsc, void *xcm)
908 {
909 	struct aac_softc *sc = xsc;
910 	struct aac_command *cm = xcm;
911 	AAC_DPRINTF(AAC_D_CMD, (": release command"));
912 
913 	mtx_enter(&sc->aac_free_mtx);
914 	aac_enqueue_free(cm);
915 	mtx_leave(&sc->aac_free_mtx);
916 }
917 
918 /*
919  * Allocate and initialise commands/FIBs for this adapter.
920  */
921 int
922 aac_alloc_commands(struct aac_softc *sc)
923 {
924 	struct aac_command *cm;
925 	struct aac_fibmap *fm;
926 	int i, error = ENOMEM;
927 
928 	if (sc->total_fibs + AAC_FIB_COUNT > sc->aac_max_fibs)
929 		return (ENOMEM);
930 
931 	fm = malloc(sizeof(*fm), M_DEVBUF, M_NOWAIT | M_ZERO);
932 	if (fm == NULL)
933 		goto exit;
934 
935 	/* allocate the FIBs in DMAable memory and load them */
936 	if (bus_dmamem_alloc(sc->aac_dmat, AAC_FIBMAP_SIZE, PAGE_SIZE, 0,
937 	    &fm->aac_seg, 1, &fm->aac_nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) {
938 		printf("%s: can't alloc FIBs\n", sc->aac_dev.dv_xname);
939 		error = ENOBUFS;
940 		goto exit_alloc;
941 	}
942 
943 	if (bus_dmamem_map(sc->aac_dmat, &fm->aac_seg, 1,
944 	    AAC_FIBMAP_SIZE, (caddr_t *)&fm->aac_fibs, BUS_DMA_NOWAIT)) {
945 		printf("%s: can't map FIB structure\n", sc->aac_dev.dv_xname);
946 		error = ENOBUFS;
947 		goto exit_map;
948 	}
949 
950 	if (bus_dmamap_create(sc->aac_dmat, AAC_FIBMAP_SIZE, 1,
951 	    AAC_FIBMAP_SIZE, 0, BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
952 		printf("%s: can't create dma map\n", sc->aac_dev.dv_xname);
953 		error = ENOBUFS;
954 		goto exit_create;
955 	}
956 
957 	if (bus_dmamap_load(sc->aac_dmat, fm->aac_fibmap, fm->aac_fibs,
958 	    AAC_FIBMAP_SIZE, NULL, BUS_DMA_NOWAIT)) {
959 		printf("%s: can't load dma map\n", sc->aac_dev.dv_xname);
960 		error = ENOBUFS;
961 		goto exit_load;
962 	}
963 
964 	/* initialise constant fields in the command structure */
965 	AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
966 	for (i = 0; i < AAC_FIB_COUNT; i++) {
967 		cm = sc->aac_commands + sc->total_fibs;
968 		fm->aac_commands = cm;
969 		cm->cm_sc = sc;
970 		cm->cm_fib = fm->aac_fibs + i;
971 		cm->cm_fibphys = fm->aac_fibmap->dm_segs[0].ds_addr +
972 			(i * sizeof(struct aac_fib));
973 		cm->cm_index = sc->total_fibs;
974 
975 		if (bus_dmamap_create(sc->aac_dmat, MAXBSIZE, AAC_MAXSGENTRIES,
976 		    MAXBSIZE, 0, BUS_DMA_NOWAIT, &cm->cm_datamap)) {
977 			break;
978 		}
979 		aac_release_command(sc, cm);
980 		sc->total_fibs++;
981 	}
982 
983 	if (i > 0) {
984 		TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
985 		AAC_DPRINTF(AAC_D_MISC, ("%s: total_fibs= %d\n",
986 					 sc->aac_dev.dv_xname,
987 					 sc->total_fibs));
988 		AAC_LOCK_RELEASE(&sc->aac_io_lock);
989 		return (0);
990 	}
991 
992  exit_load:
993 	bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap);
994  exit_create:
995 	bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs, AAC_FIBMAP_SIZE);
996  exit_map:
997 	bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs);
998  exit_alloc:
999 	free(fm, M_DEVBUF, 0);
1000  exit:
1001 	AAC_LOCK_RELEASE(&sc->aac_io_lock);
1002 	return (error);
1003 }
1004 
1005 /*
1006  * Free FIBs owned by this adapter.
1007  */
1008 void
1009 aac_free_commands(struct aac_softc *sc)
1010 {
1011 	struct aac_fibmap *fm;
1012 	struct aac_command *cm;
1013 	int i;
1014 
1015 	while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1016 
1017 		TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link);
1018 
1019 		/*
1020 		 * We check against total_fibs to handle partially
1021 		 * allocated blocks.
1022 		 */
1023 		for (i = 0; i < AAC_FIB_COUNT && sc->total_fibs--; i++) {
1024 			cm = fm->aac_commands + i;
1025 			bus_dmamap_destroy(sc->aac_dmat, cm->cm_datamap);
1026 		}
1027 
1028 		bus_dmamap_unload(sc->aac_dmat, fm->aac_fibmap);
1029 		bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap);
1030 		bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs,
1031 				 AAC_FIBMAP_SIZE);
1032 		bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs);
1033 		free(fm, M_DEVBUF, 0);
1034 	}
1035 }
1036 
1037 
1038 /*
1039  * Command-mapping helper function - populate this command's s/g table.
1040  */
1041 void
1042 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1043 {
1044 	struct aac_command *cm = arg;
1045 	struct aac_softc *sc = cm->cm_sc;
1046 	struct aac_fib *fib = cm->cm_fib;
1047 	int i;
1048 
1049 	/* copy into the FIB */
1050 	if (cm->cm_sgtable != NULL) {
1051 		if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1052 			struct aac_sg_table *sg = cm->cm_sgtable;
1053 			sg->SgCount = nseg;
1054 			for (i = 0; i < nseg; i++) {
1055 				sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1056 				sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1057 			}
1058 			/* update the FIB size for the s/g count */
1059 			fib->Header.Size += nseg * sizeof(struct aac_sg_entry);
1060 		} else {
1061 			struct aac_sg_table64 *sg;
1062 			sg = (struct aac_sg_table64 *)cm->cm_sgtable;
1063 			sg->SgCount = nseg;
1064 			for (i = 0; i < nseg; i++) {
1065 				sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
1066 				sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
1067 			}
1068 			/* update the FIB size for the s/g count */
1069 			fib->Header.Size += nseg*sizeof(struct aac_sg_entry64);
1070 		}
1071 	}
1072 
1073 	/* Fix up the address values in the FIB.  Use the command array index
1074 	 * instead of a pointer since these fields are only 32 bits.  Shift
1075 	 * the SenderFibAddress over to make room for the fast response bit.
1076 	 */
1077 	cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 1);
1078 	cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
1079 
1080 	/* save a pointer to the command for speedy reverse-lookup */
1081 	cm->cm_fib->Header.SenderData = cm->cm_index;
1082 
1083 	if (cm->cm_flags & AAC_CMD_DATAIN)
1084 		bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1085 				cm->cm_datamap->dm_mapsize,
1086 				BUS_DMASYNC_PREREAD);
1087 	if (cm->cm_flags & AAC_CMD_DATAOUT)
1088 		bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1089 				cm->cm_datamap->dm_mapsize,
1090 				BUS_DMASYNC_PREWRITE);
1091 	cm->cm_flags |= AAC_CMD_MAPPED;
1092 
1093 	/* put the FIB on the outbound queue */
1094 	if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) {
1095 		aac_remove_busy(cm);
1096 		aac_unmap_command(cm);
1097 		aac_requeue_ready(cm);
1098 	}
1099 }
1100 
1101 /*
1102  * Unmap a command from controller-visible space.
1103  */
1104 void
1105 aac_unmap_command(struct aac_command *cm)
1106 {
1107 	struct aac_softc *sc = cm->cm_sc;
1108 
1109 	if (!(cm->cm_flags & AAC_CMD_MAPPED))
1110 		return;
1111 
1112 	if (cm->cm_datalen != 0) {
1113 		if (cm->cm_flags & AAC_CMD_DATAIN)
1114 			bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1115 					cm->cm_datamap->dm_mapsize,
1116 					BUS_DMASYNC_POSTREAD);
1117 		if (cm->cm_flags & AAC_CMD_DATAOUT)
1118 			bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1119 					cm->cm_datamap->dm_mapsize,
1120 					BUS_DMASYNC_POSTWRITE);
1121 
1122 		bus_dmamap_unload(sc->aac_dmat, cm->cm_datamap);
1123 	}
1124 	cm->cm_flags &= ~AAC_CMD_MAPPED;
1125 }
1126 
1127 /*
1128  * Hardware Interface
1129  */
1130 
1131 /*
1132  * Initialise the adapter.
1133  */
1134 int
1135 aac_check_firmware(struct aac_softc *sc)
1136 {
1137 	u_int32_t major, minor, options;
1138 
1139 	/*
1140 	 * Retrieve the firmware version numbers.  Dell PERC2/QC cards with
1141 	 * firmware version 1.x are not compatible with this driver.
1142 	 */
1143 	if (sc->flags & AAC_FLAGS_PERC2QC) {
1144 		if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
1145 				     NULL)) {
1146 			printf("%s: Error reading firmware version\n",
1147 			       sc->aac_dev.dv_xname);
1148 			return (EIO);
1149 		}
1150 
1151 		/* These numbers are stored as ASCII! */
1152 		major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
1153 		minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
1154 		if (major == 1) {
1155 			printf("%s: Firmware version %d.%d is not supported\n",
1156 			       sc->aac_dev.dv_xname, major, minor);
1157 			return (EINVAL);
1158 		}
1159 	}
1160 
1161 	/*
1162 	 * Retrieve the capabilities/supported options word so we know what
1163 	 * work-arounds to enable.
1164 	 */
1165 	if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, NULL)) {
1166 		printf("%s: RequestAdapterInfo failed\n",
1167 		       sc->aac_dev.dv_xname);
1168 		return (EIO);
1169 	}
1170 	options = AAC_GET_MAILBOX(sc, 1);
1171 	sc->supported_options = options;
1172 
1173 	if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
1174 	    (sc->flags & AAC_FLAGS_NO4GB) == 0)
1175 		sc->flags |= AAC_FLAGS_4GB_WINDOW;
1176 	if (options & AAC_SUPPORTED_NONDASD)
1177 		sc->flags |= AAC_FLAGS_ENABLE_CAM;
1178 	if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0
1179 	     && (sizeof(bus_addr_t) > 4)) {
1180 		printf("%s: Enabling 64-bit address support\n",
1181 		       sc->aac_dev.dv_xname);
1182 		sc->flags |= AAC_FLAGS_SG_64BIT;
1183 	}
1184 
1185 	/* Check for broken hardware that does a lower number of commands */
1186 	if ((sc->flags & AAC_FLAGS_256FIBS) == 0)
1187 		sc->aac_max_fibs = AAC_MAX_FIBS;
1188 	else
1189 		sc->aac_max_fibs = 256;
1190 
1191 	return (0);
1192 }
1193 
1194 int
1195 aac_init(struct aac_softc *sc)
1196 {
1197 	bus_dma_segment_t seg;
1198 	int nsegs;
1199 	int i, error;
1200 	int state = 0;
1201 	struct aac_adapter_init	*ip;
1202 	time_t then;
1203 	u_int32_t code, qoffset;
1204 
1205 	/*
1206 	 * First wait for the adapter to come ready.
1207 	 */
1208 	then = time_uptime;
1209 	for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) {
1210 		code = AAC_GET_FWSTATUS(sc);
1211 		if (code & AAC_SELF_TEST_FAILED) {
1212 			printf("%s: FATAL: selftest failed\n",
1213 			    sc->aac_dev.dv_xname);
1214 			return (ENXIO);
1215 		}
1216 		if (code & AAC_KERNEL_PANIC) {
1217 			printf("%s: FATAL: controller kernel panic\n",
1218 			    sc->aac_dev.dv_xname);
1219 			return (ENXIO);
1220 		}
1221 		if (code & AAC_UP_AND_RUNNING)
1222 			break;
1223 		DELAY(1000);
1224 	}
1225 	if (i == AAC_BOOT_TIMEOUT * 1000) {
1226 		printf("%s: FATAL: controller not coming ready, status %x\n",
1227 		    sc->aac_dev.dv_xname, code);
1228 		return (ENXIO);
1229 	}
1230 
1231 	/*
1232 	 * Work around a bug in the 2120 and 2200 that cannot DMA commands
1233 	 * below address 8192 in physical memory.
1234 	 * XXX If the padding is not needed, can it be put to use instead
1235 	 * of ignored?
1236 	 */
1237 	if (bus_dmamem_alloc(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, PAGE_SIZE, 0,
1238 			     &seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) {
1239 		printf("%s: can't allocate common structure\n",
1240 		    sc->aac_dev.dv_xname);
1241 		return (ENOMEM);
1242 	}
1243 	state++;
1244 
1245 	if (bus_dmamem_map(sc->aac_dmat, &seg, nsegs, AAC_COMMON_ALLOCSIZE,
1246 			   (caddr_t *)&sc->aac_common, BUS_DMA_NOWAIT)) {
1247 		printf("%s: can't map common structure\n",
1248 		    sc->aac_dev.dv_xname);
1249 		error = ENOMEM;
1250 		goto bail_out;
1251 	}
1252 	state++;
1253 
1254 	if (bus_dmamap_create(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, 1,
1255 	    AAC_COMMON_ALLOCSIZE, 0, BUS_DMA_NOWAIT, &sc->aac_common_map)) {
1256 		printf("%s: can't create dma map\n", sc->aac_dev.dv_xname);
1257 		error = ENOBUFS;
1258 		goto bail_out;
1259 	}
1260 	state++;
1261 
1262 	if (bus_dmamap_load(sc->aac_dmat, sc->aac_common_map, sc->aac_common,
1263 	    AAC_COMMON_ALLOCSIZE, NULL, BUS_DMA_NOWAIT)) {
1264 		printf("%s: can't load dma map\n", sc->aac_dev.dv_xname);
1265 		error = ENOBUFS;
1266 		goto bail_out;
1267 	}
1268 	state++;
1269 
1270 	sc->aac_common_busaddr = sc->aac_common_map->dm_segs[0].ds_addr;
1271 
1272 	if (sc->aac_common_busaddr < 8192) {
1273 		sc->aac_common = (struct aac_common *)
1274 		    ((uint8_t *)sc->aac_common + 8192);
1275 		sc->aac_common_busaddr += 8192;
1276 	}
1277 
1278 	/* Allocate some FIBs and associated command structs */
1279 	TAILQ_INIT(&sc->aac_fibmap_tqh);
1280 	sc->aac_commands = malloc(AAC_MAX_FIBS * sizeof(struct aac_command),
1281 	    M_DEVBUF, M_WAITOK | M_ZERO);
1282 	while (sc->total_fibs < AAC_MAX_FIBS) {
1283 		if (aac_alloc_commands(sc) != 0)
1284 			break;
1285 	}
1286 	if (sc->total_fibs == 0)
1287 		goto out;
1288 
1289 	scsi_iopool_init(&sc->aac_iopool, sc,
1290 	    aac_alloc_command, aac_release_command);
1291 
1292 	/*
1293 	 * Fill in the init structure.  This tells the adapter about the
1294 	 * physical location of various important shared data structures.
1295 	 */
1296 	ip = &sc->aac_common->ac_init;
1297 	ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1298 	ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1299 
1300 	ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1301 					 offsetof(struct aac_common, ac_fibs);
1302 	ip->AdapterFibsVirtualAddress = 0;
1303 	ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1304 	ip->AdapterFibAlign = sizeof(struct aac_fib);
1305 
1306 	ip->PrintfBufferAddress = sc->aac_common_busaddr +
1307 				  offsetof(struct aac_common, ac_printf);
1308 	ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1309 
1310 	/*
1311 	 * The adapter assumes that pages are 4K in size, except on some
1312 	 * broken firmware versions that do the page->byte conversion twice,
1313 	 * therefore 'assuming' that this value is in 16MB units (2^24).
1314 	 * Round up since the granularity is so high.
1315 	 */
1316 	ip->HostPhysMemPages = ptoa(physmem) / AAC_PAGE_SIZE;
1317 	if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) {
1318 		ip->HostPhysMemPages =
1319 		    (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
1320 	}
1321 	ip->HostElapsedSeconds = time_uptime; /* reset later if invalid */
1322 
1323 	/*
1324 	 * Initialise FIB queues.  Note that it appears that the layout of the
1325 	 * indexes and the segmentation of the entries may be mandated by the
1326 	 * adapter, which is only told about the base of the queue index fields.
1327 	 *
1328 	 * The initial values of the indices are assumed to inform the adapter
1329 	 * of the sizes of the respective queues, and theoretically it could
1330 	 * work out the entire layout of the queue structures from this.  We
1331 	 * take the easy route and just lay this area out like everyone else
1332 	 * does.
1333 	 *
1334 	 * The Linux driver uses a much more complex scheme whereby several
1335 	 * header records are kept for each queue.  We use a couple of generic
1336 	 * list manipulation functions which 'know' the size of each list by
1337 	 * virtue of a table.
1338 	 */
1339 	qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
1340 	qoffset &= ~(AAC_QUEUE_ALIGN - 1);
1341 	sc->aac_queues =
1342 	    (struct aac_queue_table *)((caddr_t)sc->aac_common + qoffset);
1343 	ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset;
1344 
1345 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1346 		AAC_HOST_NORM_CMD_ENTRIES;
1347 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1348 		AAC_HOST_NORM_CMD_ENTRIES;
1349 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1350 		AAC_HOST_HIGH_CMD_ENTRIES;
1351 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1352 		AAC_HOST_HIGH_CMD_ENTRIES;
1353 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1354 		AAC_ADAP_NORM_CMD_ENTRIES;
1355 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1356 		AAC_ADAP_NORM_CMD_ENTRIES;
1357 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1358 		AAC_ADAP_HIGH_CMD_ENTRIES;
1359 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1360 		AAC_ADAP_HIGH_CMD_ENTRIES;
1361 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1362 		AAC_HOST_NORM_RESP_ENTRIES;
1363 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1364 		AAC_HOST_NORM_RESP_ENTRIES;
1365 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1366 		AAC_HOST_HIGH_RESP_ENTRIES;
1367 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1368 		AAC_HOST_HIGH_RESP_ENTRIES;
1369 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1370 		AAC_ADAP_NORM_RESP_ENTRIES;
1371 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1372 		AAC_ADAP_NORM_RESP_ENTRIES;
1373 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1374 		AAC_ADAP_HIGH_RESP_ENTRIES;
1375 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1376 		AAC_ADAP_HIGH_RESP_ENTRIES;
1377 	sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1378 		&sc->aac_queues->qt_HostNormCmdQueue[0];
1379 	sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1380 		&sc->aac_queues->qt_HostHighCmdQueue[0];
1381 	sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1382 		&sc->aac_queues->qt_AdapNormCmdQueue[0];
1383 	sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1384 		&sc->aac_queues->qt_AdapHighCmdQueue[0];
1385 	sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1386 		&sc->aac_queues->qt_HostNormRespQueue[0];
1387 	sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1388 		&sc->aac_queues->qt_HostHighRespQueue[0];
1389 	sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1390 		&sc->aac_queues->qt_AdapNormRespQueue[0];
1391 	sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1392 		&sc->aac_queues->qt_AdapHighRespQueue[0];
1393 
1394 	/*
1395 	 * Do controller-type-specific initialisation
1396 	 */
1397 	switch (sc->aac_hwif) {
1398 	case AAC_HWIF_I960RX:
1399 		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
1400 		break;
1401 	case AAC_HWIF_RKT:
1402 		AAC_SETREG4(sc, AAC_RKT_ODBR, ~0);
1403 		break;
1404 	default:
1405 		break;
1406 	}
1407 
1408 	/*
1409 	 * Give the init structure to the controller.
1410 	 */
1411 	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1412 			     sc->aac_common_busaddr +
1413 			     offsetof(struct aac_common, ac_init), 0, 0, 0,
1414 			     NULL)) {
1415 		printf("%s: error establishing init structure\n",
1416 		    sc->aac_dev.dv_xname);
1417 		error = EIO;
1418 		goto bail_out;
1419 	}
1420 
1421 	aac_describe_controller(sc);
1422 	aac_startup(sc);
1423 
1424 	return (0);
1425 
1426  bail_out:
1427 	if (state > 3)
1428 		bus_dmamap_unload(sc->aac_dmat, sc->aac_common_map);
1429 	if (state > 2)
1430 		bus_dmamap_destroy(sc->aac_dmat, sc->aac_common_map);
1431 	if (state > 1)
1432 		bus_dmamem_unmap(sc->aac_dmat, (caddr_t)sc->aac_common,
1433 		    sizeof *sc->aac_common);
1434 	if (state > 0)
1435 		bus_dmamem_free(sc->aac_dmat, &seg, 1);
1436 
1437  out:
1438 	return (error);
1439 }
1440 
1441 /*
1442  * Send a synchronous command to the controller and wait for a result.
1443  */
1444 int
1445 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1446 		 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp)
1447 {
1448 //	time_t then;
1449 	int i;
1450 	u_int32_t status;
1451 	u_int16_t reason;
1452 
1453 	/* populate the mailbox */
1454 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1455 
1456 	/* ensure the sync command doorbell flag is cleared */
1457 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1458 
1459 	/* then set it to signal the adapter */
1460 	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1461 
1462 	DELAY(AAC_SYNC_DELAY);
1463 
1464 	/* spin waiting for the command to complete */
1465 	for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) {
1466 		reason = AAC_GET_ISTATUS(sc);
1467 		if (reason & AAC_DB_SYNC_COMMAND)
1468 			break;
1469 		reason = AAC_GET_ISTATUS(sc);
1470 		if (reason & AAC_DB_SYNC_COMMAND)
1471 			break;
1472 		reason = AAC_GET_ISTATUS(sc);
1473 		if (reason & AAC_DB_SYNC_COMMAND)
1474 			break;
1475 		DELAY(1000);
1476 	}
1477 	if (i == AAC_IMMEDIATE_TIMEOUT * 1000) {
1478 		printf("aac_sync_command: failed, reason=%#x\n", reason);
1479 		return (EIO);
1480 	}
1481 
1482 	/* clear the completion flag */
1483 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1484 
1485 	/* get the command status */
1486 	status = AAC_GET_MAILBOX(sc, 0);
1487 
1488 	if (sp != NULL)
1489 		*sp = status;
1490 
1491 	return(0);
1492 }
1493 
1494 /*
1495  * Grab the sync fib area.
1496  */
1497 int
1498 aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags)
1499 {
1500 
1501 	/*
1502 	 * If the force flag is set, the system is shutting down, or in
1503 	 * trouble.  Ignore the mutex.
1504 	 */
1505 	if (!(flags & AAC_SYNC_LOCK_FORCE))
1506 		AAC_LOCK_ACQUIRE(&sc->aac_sync_lock);
1507 
1508 	*fib = &sc->aac_common->ac_sync_fib;
1509 
1510 	return (1);
1511 }
1512 
1513 /*
1514  * Release the sync fib area.
1515  */
1516 void
1517 aac_release_sync_fib(struct aac_softc *sc)
1518 {
1519 	AAC_LOCK_RELEASE(&sc->aac_sync_lock);
1520 }
1521 
1522 /*
1523  * Send a synchronous FIB to the controller and wait for a result.
1524  */
1525 int
1526 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1527 	     struct aac_fib *fib, u_int16_t datasize)
1528 {
1529 
1530 	if (datasize > AAC_FIB_DATASIZE) {
1531 		printf("aac_sync_fib 1: datasize=%d AAC_FIB_DATASIZE %lu\n",
1532 		    datasize, AAC_FIB_DATASIZE);
1533 		return(EINVAL);
1534 	}
1535 
1536 	/*
1537 	 * Set up the sync FIB
1538 	 */
1539 	fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
1540 				AAC_FIBSTATE_INITIALISED |
1541 				AAC_FIBSTATE_EMPTY;
1542 	fib->Header.XferState |= xferstate;
1543 	fib->Header.Command = command;
1544 	fib->Header.StructType = AAC_FIBTYPE_TFIB;
1545 	fib->Header.Size = sizeof(struct aac_fib) + datasize;
1546 	fib->Header.SenderSize = sizeof(struct aac_fib);
1547 	fib->Header.SenderFibAddress = 0;	/* Not needed */
1548 	fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
1549 					 offsetof(struct aac_common,
1550 						  ac_sync_fib);
1551 
1552 	/*
1553 	 * Give the FIB to the controller, wait for a response.
1554 	 */
1555 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
1556 			     fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
1557 		AAC_DPRINTF(AAC_D_IO, ("%s: aac_sync_fib: IO error\n",
1558 				       sc->aac_dev.dv_xname));
1559 		printf("aac_sync_fib 2\n");
1560 		return(EIO);
1561 	}
1562 
1563 	return (0);
1564 }
1565 
1566 /*****************************************************************************
1567  * Adapter-space FIB queue manipulation
1568  *
1569  * Note that the queue implementation here is a little funky; neither the PI or
1570  * CI will ever be zero.  This behaviour is a controller feature.
1571  */
1572 static struct {
1573 	int size;
1574 	int notify;
1575 } aac_qinfo[] = {
1576 	{ AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL },
1577 	{ AAC_HOST_HIGH_CMD_ENTRIES, 0 },
1578 	{ AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY },
1579 	{ AAC_ADAP_HIGH_CMD_ENTRIES, 0 },
1580 	{ AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL },
1581 	{ AAC_HOST_HIGH_RESP_ENTRIES, 0 },
1582 	{ AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY },
1583 	{ AAC_ADAP_HIGH_RESP_ENTRIES, 0 }
1584 };
1585 
1586 /*
1587  * Atomically insert an entry into the nominated queue, returns 0 on success
1588  * or EBUSY if the queue is full.
1589  *
1590  * Note: it would be more efficient to defer notifying the controller in
1591  *	 the case where we may be inserting several entries in rapid
1592  *	 succession, but implementing this usefully may be difficult
1593  *	 (it would involve a separate queue/notify interface).
1594  */
1595 int
1596 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
1597 {
1598 	u_int32_t pi, ci;
1599 	int error;
1600 	u_int32_t fib_size;
1601 	u_int32_t fib_addr;
1602 
1603 	fib_size = cm->cm_fib->Header.Size;
1604 	fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
1605 
1606 	/* get the producer/consumer indices */
1607 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1608 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1609 
1610 	/* wrap the queue? */
1611 	if (pi >= aac_qinfo[queue].size)
1612 		pi = 0;
1613 
1614 	/* check for queue full */
1615 	if ((pi + 1) == ci) {
1616 		error = EBUSY;
1617 		goto out;
1618 	}
1619 
1620 	/* populate queue entry */
1621 	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1622 	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1623 
1624 	/* update producer index */
1625 	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1626 
1627 	/*
1628 	 * To avoid a race with its completion interrupt, place this command on
1629 	 * the busy queue prior to advertising it to the controller.
1630 	 */
1631 	aac_enqueue_busy(cm);
1632 
1633 	/* notify the adapter if we know how */
1634 	if (aac_qinfo[queue].notify != 0)
1635 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1636 
1637 	error = 0;
1638 
1639 out:
1640 	return (error);
1641 }
1642 
1643 /*
1644  * Atomically remove one entry from the nominated queue, returns 0 on success
1645  * or ENOENT if the queue is empty.
1646  */
1647 int
1648 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1649 		struct aac_fib **fib_addr)
1650 {
1651 	u_int32_t pi, ci;
1652 	u_int32_t fib_index;
1653 	int notify;
1654 	int error;
1655 
1656 	/* get the producer/consumer indices */
1657 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1658 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1659 
1660 	/* check for queue empty */
1661 	if (ci == pi) {
1662 		error = ENOENT;
1663 		goto out;
1664 	}
1665 
1666 	/* wrap the pi so the following test works */
1667 	if (pi >= aac_qinfo[queue].size)
1668 		pi = 0;
1669 
1670 	notify = 0;
1671 	if (ci == pi + 1)
1672 		notify++;
1673 
1674 	/* wrap the queue? */
1675 	if (ci >= aac_qinfo[queue].size)
1676 		ci = 0;
1677 
1678 	/* fetch the entry */
1679 	*fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1680 
1681 	switch (queue) {
1682 	case AAC_HOST_NORM_CMD_QUEUE:
1683 	case AAC_HOST_HIGH_CMD_QUEUE:
1684 		/*
1685 		 * The aq_fib_addr is only 32 bits wide so it can't be counted
1686 		 * on to hold an address.  For AIF's, the adapter assumes
1687 		 * that it's giving us an address into the array of AIF fibs.
1688 		 * Therefore, we have to convert it to an index.
1689 		 */
1690 		fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr /
1691 			sizeof(struct aac_fib);
1692 		*fib_addr = &sc->aac_common->ac_fibs[fib_index];
1693 		break;
1694 
1695 	case AAC_HOST_NORM_RESP_QUEUE:
1696 	case AAC_HOST_HIGH_RESP_QUEUE:
1697 	{
1698 		struct aac_command *cm;
1699 
1700 		/*
1701 		 * As above, an index is used instead of an actual address.
1702 		 * Gotta shift the index to account for the fast response
1703 		 * bit.  No other correction is needed since this value was
1704 		 * originally provided by the driver via the SenderFibAddress
1705 		 * field.
1706 		 */
1707 		fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr;
1708 		cm = sc->aac_commands + (fib_index >> 1);
1709 		*fib_addr = cm->cm_fib;
1710 
1711 		/*
1712 		 * Is this a fast response? If it is, update the fib fields in
1713 		 * local memory since the whole fib isn't DMA'd back up.
1714 		 */
1715 		if (fib_index & 0x01) {
1716 			(*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP;
1717 			*((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL;
1718 		}
1719 		break;
1720 	}
1721 	default:
1722 		panic("Invalid queue in aac_dequeue_fib()");
1723 		break;
1724 	}
1725 
1726 
1727 	/* update consumer index */
1728 	sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1729 
1730 	/* if we have made the queue un-full, notify the adapter */
1731 	if (notify && (aac_qinfo[queue].notify != 0))
1732 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1733 	error = 0;
1734 
1735 out:
1736 	return (error);
1737 }
1738 
1739 /*
1740  * Put our response to an Adapter Initialed Fib on the response queue
1741  */
1742 int
1743 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
1744 {
1745 	u_int32_t pi, ci;
1746 	int error;
1747 	u_int32_t fib_size;
1748 	u_int32_t fib_addr;
1749 
1750 	/* Tell the adapter where the FIB is */
1751 	fib_size = fib->Header.Size;
1752 	fib_addr = fib->Header.SenderFibAddress;
1753 	fib->Header.ReceiverFibAddress = fib_addr;
1754 
1755 	/* get the producer/consumer indices */
1756 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1757 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1758 
1759 	/* wrap the queue? */
1760 	if (pi >= aac_qinfo[queue].size)
1761 		pi = 0;
1762 
1763 	/* check for queue full */
1764 	if ((pi + 1) == ci) {
1765 		error = EBUSY;
1766 		goto out;
1767 	}
1768 
1769 	/* populate queue entry */
1770 	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1771 	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1772 
1773 	/* update producer index */
1774 	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1775 
1776 	/* notify the adapter if we know how */
1777 	if (aac_qinfo[queue].notify != 0)
1778 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1779 
1780 	error = 0;
1781 
1782 out:
1783 	return(error);
1784 }
1785 
1786 void
1787 aac_command_timeout(struct aac_command *cm)
1788 {
1789 	struct aac_softc *sc = cm->cm_sc;
1790 
1791 	printf("%s: COMMAND %p (flags=%#x) TIMEOUT AFTER %d SECONDS\n",
1792 	       sc->aac_dev.dv_xname, cm, cm->cm_flags,
1793 	       (int)(time_uptime - cm->cm_timestamp));
1794 
1795 	if (cm->cm_flags & AAC_CMD_TIMEDOUT)
1796 		return;
1797 
1798 	cm->cm_flags |= AAC_CMD_TIMEDOUT;
1799 
1800 	AAC_PRINT_FIB(sc, cm->cm_fib);
1801 
1802 	if (cm->cm_flags & AAC_ON_AACQ_BIO) {
1803 		struct scsi_xfer *xs = cm->cm_private;
1804 		int s = splbio();
1805 		xs->error = XS_DRIVER_STUFFUP;
1806 		splx(s);
1807 		scsi_done(xs);
1808 
1809 		aac_remove_bio(cm);
1810 		aac_unmap_command(cm);
1811 	}
1812 }
1813 
1814 void
1815 aac_timeout(struct aac_softc *sc)
1816 {
1817 	struct aac_command *cm;
1818 	time_t deadline;
1819 
1820 	/*
1821 	 * Traverse the busy command list and timeout any commands
1822 	 * that are past their deadline.
1823 	 */
1824 	deadline = time_uptime - AAC_CMD_TIMEOUT;
1825 	TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
1826 		if (cm->cm_timestamp  < deadline)
1827 			aac_command_timeout(cm);
1828 	}
1829 }
1830 
1831 /*
1832  * Interface Function Vectors
1833  */
1834 
1835 /*
1836  * Read the current firmware status word.
1837  */
1838 int
1839 aac_sa_get_fwstatus(struct aac_softc *sc)
1840 {
1841 	return (AAC_GETREG4(sc, AAC_SA_FWSTATUS));
1842 }
1843 
1844 int
1845 aac_rx_get_fwstatus(struct aac_softc *sc)
1846 {
1847 	return (AAC_GETREG4(sc, AAC_RX_FWSTATUS));
1848 }
1849 
1850 int
1851 aac_fa_get_fwstatus(struct aac_softc *sc)
1852 {
1853 	return (AAC_GETREG4(sc, AAC_FA_FWSTATUS));
1854 }
1855 
1856 int
1857 aac_rkt_get_fwstatus(struct aac_softc *sc)
1858 {
1859 	return(AAC_GETREG4(sc, AAC_RKT_FWSTATUS));
1860 }
1861 
1862 /*
1863  * Notify the controller of a change in a given queue
1864  */
1865 
1866 void
1867 aac_sa_qnotify(struct aac_softc *sc, int qbit)
1868 {
1869 	AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
1870 }
1871 
1872 void
1873 aac_rx_qnotify(struct aac_softc *sc, int qbit)
1874 {
1875 	AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
1876 }
1877 
1878 void
1879 aac_fa_qnotify(struct aac_softc *sc, int qbit)
1880 {
1881 	AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
1882 	AAC_FA_HACK(sc);
1883 }
1884 
1885 void
1886 aac_rkt_qnotify(struct aac_softc *sc, int qbit)
1887 {
1888 	AAC_SETREG4(sc, AAC_RKT_IDBR, qbit);
1889 }
1890 
1891 /*
1892  * Get the interrupt reason bits
1893  */
1894 int
1895 aac_sa_get_istatus(struct aac_softc *sc)
1896 {
1897 	return (AAC_GETREG2(sc, AAC_SA_DOORBELL0));
1898 }
1899 
1900 int
1901 aac_rx_get_istatus(struct aac_softc *sc)
1902 {
1903 	return (AAC_GETREG4(sc, AAC_RX_ODBR));
1904 }
1905 
1906 int
1907 aac_fa_get_istatus(struct aac_softc *sc)
1908 {
1909 	return (AAC_GETREG2(sc, AAC_FA_DOORBELL0));
1910 }
1911 
1912 int
1913 aac_rkt_get_istatus(struct aac_softc *sc)
1914 {
1915 	return(AAC_GETREG4(sc, AAC_RKT_ODBR));
1916 }
1917 
1918 /*
1919  * Clear some interrupt reason bits
1920  */
1921 void
1922 aac_sa_clear_istatus(struct aac_softc *sc, int mask)
1923 {
1924 	AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
1925 }
1926 
1927 void
1928 aac_rx_clear_istatus(struct aac_softc *sc, int mask)
1929 {
1930 	AAC_SETREG4(sc, AAC_RX_ODBR, mask);
1931 }
1932 
1933 void
1934 aac_fa_clear_istatus(struct aac_softc *sc, int mask)
1935 {
1936 	AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
1937 	AAC_FA_HACK(sc);
1938 }
1939 
1940 void
1941 aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
1942 {
1943 	AAC_SETREG4(sc, AAC_RKT_ODBR, mask);
1944 }
1945 
1946 /*
1947  * Populate the mailbox and set the command word
1948  */
1949 void
1950 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1951 		   u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1952 {
1953 	AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
1954 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
1955 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
1956 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
1957 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
1958 }
1959 
1960 void
1961 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1962 		   u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1963 {
1964 	AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
1965 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
1966 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
1967 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
1968 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
1969 }
1970 
1971 void
1972 aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1973 		   u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1974 {
1975 	AAC_SETREG4(sc, AAC_FA_MAILBOX, command);
1976 	AAC_FA_HACK(sc);
1977 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
1978 	AAC_FA_HACK(sc);
1979 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
1980 	AAC_FA_HACK(sc);
1981 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
1982 	AAC_FA_HACK(sc);
1983 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
1984 	AAC_FA_HACK(sc);
1985 }
1986 
1987 void
1988 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1989 		    u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1990 {
1991 	AAC_SETREG4(sc, AAC_RKT_MAILBOX, command);
1992 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
1993 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
1994 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
1995 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
1996 }
1997 
1998 /*
1999  * Fetch the immediate command status word
2000  */
2001 int
2002 aac_sa_get_mailbox(struct aac_softc *sc, int mb)
2003 {
2004 	return (AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
2005 }
2006 
2007 int
2008 aac_rx_get_mailbox(struct aac_softc *sc, int mb)
2009 {
2010 	return (AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
2011 }
2012 
2013 int
2014 aac_fa_get_mailbox(struct aac_softc *sc, int mb)
2015 {
2016 	return (AAC_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4)));
2017 }
2018 
2019 int
2020 aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
2021 {
2022 	return(AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
2023 }
2024 
2025 /*
2026  * Set/clear interrupt masks
2027  */
2028 void
2029 aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2030 {
2031 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts\n",
2032 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2033 
2034 	if (enable)
2035 		AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2036 	else
2037 		AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2038 }
2039 
2040 void
2041 aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2042 {
2043 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2044 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2045 
2046 	if (enable)
2047 		AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2048 	else
2049 		AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
2050 }
2051 
2052 void
2053 aac_fa_set_interrupts(struct aac_softc *sc, int enable)
2054 {
2055 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2056 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2057 
2058 	if (enable) {
2059 		AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2060 		AAC_FA_HACK(sc);
2061 	} else {
2062 		AAC_SETREG2((sc), AAC_FA_MASK0, ~0);
2063 		AAC_FA_HACK(sc);
2064 	}
2065 }
2066 
2067 void
2068 aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
2069 {
2070 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2071 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2072 
2073 	if (enable)
2074 		AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
2075 	else
2076 		AAC_SETREG4(sc, AAC_RKT_OIMR, ~0);
2077 }
2078 
2079 void
2080 aac_eval_mapping(size, cyls, heads, secs)
2081 	u_int32_t size;
2082 	int *cyls, *heads, *secs;
2083 {
2084 	*cyls = size / AAC_HEADS / AAC_SECS;
2085 	if (*cyls < AAC_MAXCYLS) {
2086 		*heads = AAC_HEADS;
2087 		*secs = AAC_SECS;
2088 	} else {
2089 		/* Too high for 64 * 32 */
2090 		*cyls = size / AAC_MEDHEADS / AAC_MEDSECS;
2091 		if (*cyls < AAC_MAXCYLS) {
2092 			*heads = AAC_MEDHEADS;
2093 			*secs = AAC_MEDSECS;
2094 		} else {
2095 			/* Too high for 127 * 63 */
2096 			*cyls = size / AAC_BIGHEADS / AAC_BIGSECS;
2097 			*heads = AAC_BIGHEADS;
2098 			*secs = AAC_BIGSECS;
2099 		}
2100 	}
2101 }
2102 
2103 void
2104 aac_copy_internal_data(struct scsi_xfer *xs, u_int8_t *data, size_t size)
2105 {
2106 	struct aac_softc *sc = xs->sc_link->adapter_softc;
2107 	size_t copy_cnt;
2108 
2109 	AAC_DPRINTF(AAC_D_MISC, ("%s: aac_copy_internal_data\n",
2110 				 sc->aac_dev.dv_xname));
2111 
2112 	if (!xs->datalen)
2113 		printf("%s: uio move not yet supported\n",
2114 		       sc->aac_dev.dv_xname);
2115 	else {
2116 		copy_cnt = MIN(size, xs->datalen);
2117 		bcopy(data, xs->data, copy_cnt);
2118 	}
2119 }
2120 
2121 /* Emulated SCSI operation on cache device */
2122 void
2123 aac_internal_cache_cmd(struct scsi_xfer *xs)
2124 {
2125 	struct scsi_link *link = xs->sc_link;
2126 	struct aac_softc *sc = link->adapter_softc;
2127 	struct scsi_inquiry_data inq;
2128 	struct scsi_sense_data sd;
2129 	struct scsi_read_cap_data rcd;
2130 	u_int8_t target = link->target;
2131 
2132 	AAC_DPRINTF(AAC_D_CMD, ("aac_internal_cache_cmd: ",
2133 				sc->aac_dev.dv_xname));
2134 
2135 	switch (xs->cmd->opcode) {
2136 	case TEST_UNIT_READY:
2137 	case START_STOP:
2138 #if 0
2139 	case VERIFY:
2140 #endif
2141 		AAC_DPRINTF(AAC_D_CMD, ("opc %#x tgt %d ", xs->cmd->opcode,
2142 		    target));
2143 		break;
2144 
2145 	case REQUEST_SENSE:
2146 		AAC_DPRINTF(AAC_D_CMD, ("REQUEST SENSE tgt %d ", target));
2147 		bzero(&sd, sizeof sd);
2148 		sd.error_code = SSD_ERRCODE_CURRENT;
2149 		sd.segment = 0;
2150 		sd.flags = SKEY_NO_SENSE;
2151 		aac_enc32(sd.info, 0);
2152 		sd.extra_len = 0;
2153 		aac_copy_internal_data(xs, (u_int8_t *)&sd, sizeof sd);
2154 		break;
2155 
2156 	case INQUIRY:
2157 		AAC_DPRINTF(AAC_D_CMD, ("INQUIRY tgt %d devtype %x ", target,
2158 		    sc->aac_hdr[target].hd_devtype));
2159 		bzero(&inq, sizeof inq);
2160 		/* XXX How do we detect removable/CD-ROM devices?  */
2161 		inq.device = T_DIRECT;
2162 		inq.dev_qual2 = 0;
2163 		inq.version = 2;
2164 		inq.response_format = 2;
2165 		inq.additional_length = 32;
2166 		inq.flags |= SID_CmdQue;
2167 		strlcpy(inq.vendor, "Adaptec", sizeof inq.vendor);
2168 		snprintf(inq.product, sizeof inq.product, "Container #%02d",
2169 		    target);
2170 		strlcpy(inq.revision, "   ", sizeof inq.revision);
2171 		aac_copy_internal_data(xs, (u_int8_t *)&inq, sizeof inq);
2172 		break;
2173 
2174 	case READ_CAPACITY:
2175 		AAC_DPRINTF(AAC_D_CMD, ("READ CAPACITY tgt %d ", target));
2176 		bzero(&rcd, sizeof rcd);
2177 		_lto4b(sc->aac_hdr[target].hd_size - 1, rcd.addr);
2178 		_lto4b(AAC_BLOCK_SIZE, rcd.length);
2179 		aac_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd);
2180 		break;
2181 
2182 	default:
2183 		AAC_DPRINTF(AAC_D_CMD, ("\n"));
2184 		printf("aac_internal_cache_cmd got bad opcode: %#x\n",
2185 		    xs->cmd->opcode);
2186 		xs->error = XS_DRIVER_STUFFUP;
2187 		return;
2188 	}
2189 
2190 	xs->error = XS_NOERROR;
2191 }
2192 
2193 void
2194 aac_scsi_cmd(struct scsi_xfer *xs)
2195 {
2196 	struct scsi_link *link = xs->sc_link;
2197 	struct aac_softc *sc = link->adapter_softc;
2198 	u_int8_t target = link->target;
2199 	struct aac_command *cm;
2200 	u_int32_t blockno, blockcnt;
2201 	struct scsi_rw *rw;
2202 	struct scsi_rw_big *rwb;
2203 	int s;
2204 
2205 	s = splbio();
2206 
2207 	xs->error = XS_NOERROR;
2208 
2209 	if (target >= AAC_MAX_CONTAINERS || !sc->aac_hdr[target].hd_present ||
2210 	    link->lun != 0) {
2211 		/*
2212 		 * XXX Should be XS_SENSE but that would require setting up a
2213 		 * faked sense too.
2214 		 */
2215 		splx(s);
2216 		xs->error = XS_DRIVER_STUFFUP;
2217 		scsi_done(xs);
2218 		return;
2219 	}
2220 
2221 	AAC_DPRINTF(AAC_D_CMD, ("%s: aac_scsi_cmd: ", sc->aac_dev.dv_xname));
2222 
2223 	xs->error = XS_NOERROR;
2224 	cm = NULL;
2225 	link = xs->sc_link;
2226 	target = link->target;
2227 
2228 	switch (xs->cmd->opcode) {
2229 	case TEST_UNIT_READY:
2230 	case REQUEST_SENSE:
2231 	case INQUIRY:
2232 	case START_STOP:
2233 	case READ_CAPACITY:
2234 #if 0
2235 	case VERIFY:
2236 #endif
2237 		aac_internal_cache_cmd(xs);
2238 		scsi_done(xs);
2239 		goto ready;
2240 
2241 	case PREVENT_ALLOW:
2242 		AAC_DPRINTF(AAC_D_CMD, ("PREVENT/ALLOW "));
2243 		/* XXX Not yet implemented */
2244 		xs->error = XS_NOERROR;
2245 		scsi_done(xs);
2246 		goto ready;
2247 
2248 	case SYNCHRONIZE_CACHE:
2249 		AAC_DPRINTF(AAC_D_CMD, ("SYNCHRONIZE_CACHE "));
2250 		/* XXX Not yet implemented */
2251 		xs->error = XS_NOERROR;
2252 		scsi_done(xs);
2253 		goto ready;
2254 
2255 	default:
2256 		AAC_DPRINTF(AAC_D_CMD, ("unknown opc %#x ", xs->cmd->opcode));
2257 		/* XXX Not yet implemented */
2258 		xs->error = XS_DRIVER_STUFFUP;
2259 		scsi_done(xs);
2260 		goto ready;
2261 
2262 	case READ_COMMAND:
2263 	case READ_BIG:
2264 	case WRITE_COMMAND:
2265 	case WRITE_BIG:
2266 		AAC_DPRINTF(AAC_D_CMD, ("rw opc %#x ", xs->cmd->opcode));
2267 
2268 		/* A read or write operation. */
2269 		if (xs->cmdlen == 6) {
2270 			rw = (struct scsi_rw *)xs->cmd;
2271 			blockno = _3btol(rw->addr) &
2272 				(SRW_TOPADDR << 16 | 0xffff);
2273 			blockcnt = rw->length ? rw->length : 0x100;
2274 		} else {
2275 			rwb = (struct scsi_rw_big *)xs->cmd;
2276 			blockno = _4btol(rwb->addr);
2277 			blockcnt = _2btol(rwb->length);
2278 		}
2279 
2280 		AAC_DPRINTF(AAC_D_CMD, ("blkno=%d bcount=%d ",
2281 					xs->cmd->opcode, blockno, blockcnt));
2282 
2283 		if (blockno >= sc->aac_hdr[target].hd_size ||
2284 		    blockno + blockcnt > sc->aac_hdr[target].hd_size) {
2285 			AAC_DPRINTF(AAC_D_CMD, ("\n"));
2286 			printf("%s: out of bounds %u-%u >= %u\n",
2287 			       sc->aac_dev.dv_xname, blockno,
2288 			       blockcnt, sc->aac_hdr[target].hd_size);
2289 			/*
2290 			 * XXX Should be XS_SENSE but that
2291 			 * would require setting up a faked
2292 			 * sense too.
2293 			 */
2294 			xs->error = XS_DRIVER_STUFFUP;
2295 			scsi_done(xs);
2296 			goto ready;
2297 		}
2298 
2299 		cm = xs->io;
2300 		aac_scrub_command(cm);
2301 
2302 		/* fill out the command */
2303 		cm->cm_data = (void *)xs->data;
2304 		cm->cm_datalen = xs->datalen;
2305 		cm->cm_complete = aac_bio_complete;
2306 		cm->cm_private = xs;
2307 		cm->cm_timestamp = time_uptime;
2308 		cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
2309 		cm->cm_blkno = blockno;
2310 		cm->cm_bcount = blockcnt;
2311 
2312 		AAC_DPRINTF(AAC_D_CMD, ("\n"));
2313 		aac_enqueue_bio(cm);
2314 		aac_startio(sc);
2315 
2316 		/* XXX what if enqueue did not start a transfer? */
2317 		if (xs->flags & SCSI_POLL) {
2318 			if (!aac_wait_command(cm, xs->timeout))
2319 			{
2320 				printf("%s: command timed out\n",
2321 				       sc->aac_dev.dv_xname);
2322 				xs->error = XS_DRIVER_STUFFUP;
2323 				scsi_done(xs);
2324 				splx(s);
2325 				return;
2326 			}
2327 			scsi_done(xs);
2328 		}
2329 	}
2330 
2331  ready:
2332 	splx(s);
2333 	AAC_DPRINTF(AAC_D_CMD, ("%s: scsi_cmd complete\n",
2334 				sc->aac_dev.dv_xname));
2335 }
2336 
2337 /*
2338  * Debugging and Diagnostics
2339  */
2340 
2341 /*
2342  * Print some information about the controller.
2343  */
2344 void
2345 aac_describe_controller(struct aac_softc *sc)
2346 {
2347 	struct aac_fib *fib;
2348 	struct aac_adapter_info	*info;
2349 
2350 	aac_alloc_sync_fib(sc, &fib, 0);
2351 
2352 	fib->data[0] = 0;
2353 	if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2354 		printf("%s: RequestAdapterInfo failed 2\n",
2355 		       sc->aac_dev.dv_xname);
2356 		aac_release_sync_fib(sc);
2357 		return;
2358 	}
2359 	info = (struct aac_adapter_info *)&fib->data[0];
2360 
2361 	printf("%s: %s %dMHz, %dMB cache memory, %s\n", sc->aac_dev.dv_xname,
2362 	       aac_describe_code(aac_cpu_variant, info->CpuVariant),
2363 	       info->ClockSpeed, info->BufferMem / (1024 * 1024),
2364 	       aac_describe_code(aac_battery_platform, info->batteryPlatform));
2365 
2366 	/* save the kernel revision structure for later use */
2367 	sc->aac_revision = info->KernelRevision;
2368 	printf("%s: Kernel %d.%d-%d, Build %d, S/N %6X\n",
2369 	       sc->aac_dev.dv_xname,
2370 	       info->KernelRevision.external.comp.major,
2371 	       info->KernelRevision.external.comp.minor,
2372 	       info->KernelRevision.external.comp.dash,
2373 	       info->KernelRevision.buildNumber,
2374 	       (u_int32_t)(info->SerialNumber & 0xffffff));
2375 
2376 	aac_release_sync_fib(sc);
2377 }
2378 
2379 /*
2380  * Look up a text description of a numeric error code and return a pointer to
2381  * same.
2382  */
2383 char *
2384 aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
2385 {
2386 	int i;
2387 
2388 	for (i = 0; table[i].string != NULL; i++)
2389 		if (table[i].code == code)
2390 			return(table[i].string);
2391 	return(table[i + 1].string);
2392 }
2393 
2394 #ifdef AAC_DEBUG
2395 /*
2396  * Print a FIB
2397  */
2398 void
2399 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
2400 {
2401 	printf("%s: FIB @ %p\n", caller, fib);
2402 	printf("  XferState %b\n", fib->Header.XferState, "\20"
2403 	    "\1HOSTOWNED"
2404 	    "\2ADAPTEROWNED"
2405 	    "\3INITIALISED"
2406 	    "\4EMPTY"
2407 	    "\5FROMPOOL"
2408 	    "\6FROMHOST"
2409 	    "\7FROMADAP"
2410 	    "\10REXPECTED"
2411 	    "\11RNOTEXPECTED"
2412 	    "\12DONEADAP"
2413 	    "\13DONEHOST"
2414 	    "\14HIGH"
2415 	    "\15NORM"
2416 	    "\16ASYNC"
2417 	    "\17PAGEFILEIO"
2418 	    "\20SHUTDOWN"
2419 	    "\21LAZYWRITE"
2420 	    "\22ADAPMICROFIB"
2421 	    "\23BIOSFIB"
2422 	    "\24FAST_RESPONSE"
2423 	    "\25APIFIB\n");
2424 	printf("  Command         %d\n", fib->Header.Command);
2425 	printf("  StructType      %d\n", fib->Header.StructType);
2426 	printf("  Flags           0x%x\n", fib->Header.Flags);
2427 	printf("  Size            %d\n", fib->Header.Size);
2428 	printf("  SenderSize      %d\n", fib->Header.SenderSize);
2429 	printf("  SenderAddress   0x%x\n", fib->Header.SenderFibAddress);
2430 	printf("  ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress);
2431 	printf("  SenderData      0x%x\n", fib->Header.SenderData);
2432 	switch(fib->Header.Command) {
2433 	case ContainerCommand: {
2434 		struct aac_blockread *br = (struct aac_blockread *)fib->data;
2435 		struct aac_blockwrite *bw = (struct aac_blockwrite *)fib->data;
2436 		struct aac_sg_table *sg = NULL;
2437 		int i;
2438 
2439 		if (br->Command == VM_CtBlockRead) {
2440 			printf("  BlockRead: container %d  0x%x/%d\n",
2441 			    br->ContainerId, br->BlockNumber, br->ByteCount);
2442 			    sg = &br->SgMap;
2443 		}
2444 		if (bw->Command == VM_CtBlockWrite) {
2445 			printf("  BlockWrite: container %d  0x%x/%d (%s)\n",
2446 			    bw->ContainerId, bw->BlockNumber, bw->ByteCount,
2447 			    bw->Stable == CSTABLE ? "stable" : "unstable");
2448 			sg = &bw->SgMap;
2449 		}
2450 		if (sg != NULL) {
2451 			printf("  %d s/g entries\n", sg->SgCount);
2452 			for (i = 0; i < sg->SgCount; i++)
2453 				printf("  0x%08x/%d\n",
2454 				       sg->SgEntry[i].SgAddress,
2455 				       sg->SgEntry[i].SgByteCount);
2456 		}
2457 		break;
2458 	}
2459 	default:
2460 		printf("   %16D\n", fib->data, " ");
2461 		printf("   %16D\n", fib->data + 16, " ");
2462 	break;
2463 	}
2464 }
2465 
2466 /*
2467  * Describe an AIF we have received.
2468  */
2469 void
2470 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
2471 {
2472 	printf("%s: print_aif: ", sc->aac_dev.dv_xname);
2473 
2474 	switch(aif->command) {
2475 	case AifCmdEventNotify:
2476 		printf("EventNotify(%d)\n", aif->seqNumber);
2477 
2478 		switch(aif->data.EN.type) {
2479 		case AifEnGeneric:
2480 			/* Generic notification */
2481 			printf("\t(Generic) %.*s\n",
2482 			       (int)sizeof(aif->data.EN.data.EG),
2483 			       aif->data.EN.data.EG.text);
2484 			break;
2485 		case AifEnTaskComplete:
2486 			/* Task has completed */
2487 			printf("\t(TaskComplete)\n");
2488 			break;
2489 		case AifEnConfigChange:
2490 			/* Adapter configuration change occurred */
2491 			printf("\t(ConfigChange)\n");
2492 			break;
2493 		case AifEnContainerChange:
2494 			/* Adapter specific container configuration change */
2495 			printf("\t(ContainerChange) container %d,%d\n",
2496 			       aif->data.EN.data.ECC.container[0],
2497 			       aif->data.EN.data.ECC.container[1]);
2498 			break;
2499 		case AifEnDeviceFailure:
2500 			/* SCSI device failed */
2501 			printf("\t(DeviceFailure) handle %d\n",
2502 			       aif->data.EN.data.EDF.deviceHandle);
2503 			break;
2504 		case AifEnMirrorFailover:
2505 			/* Mirror failover started */
2506 			printf("\t(MirrorFailover) container %d failed, "
2507 			       "migrating from slice %d to %d\n",
2508 			       aif->data.EN.data.EMF.container,
2509 			       aif->data.EN.data.EMF.failedSlice,
2510 			       aif->data.EN.data.EMF.creatingSlice);
2511 			break;
2512 		case AifEnContainerEvent:
2513 			/* Significant container event */
2514 			printf("\t(ContainerEvent) container %d event %d\n",
2515 			       aif->data.EN.data.ECE.container,
2516 			       aif->data.EN.data.ECE.eventType);
2517 			break;
2518 		case AifEnFileSystemChange:
2519 			/* File system changed */
2520 			printf("\t(FileSystemChange)\n");
2521 			break;
2522 		case AifEnConfigPause:
2523 			/* Container pause event */
2524 			printf("\t(ConfigPause)\n");
2525 			break;
2526 		case AifEnConfigResume:
2527 			/* Container resume event */
2528 			printf("\t(ConfigResume)\n");
2529 			break;
2530 		case AifEnFailoverChange:
2531 			/* Failover space assignment changed */
2532 			printf("\t(FailoverChange)\n");
2533 			break;
2534 		case AifEnRAID5RebuildDone:
2535 			/* RAID5 rebuild finished */
2536 			printf("\t(RAID5RebuildDone)\n");
2537 			break;
2538 		case AifEnEnclosureManagement:
2539 			/* Enclosure management event */
2540 			printf("\t(EnclosureManagement) EMPID %d unit %d "
2541 			       "event %d\n",
2542 			       aif->data.EN.data.EEE.empID,
2543 			       aif->data.EN.data.EEE.unitID,
2544 			       aif->data.EN.data.EEE.eventType);
2545 			break;
2546 		case AifEnBatteryEvent:
2547 			/* Significant NV battery event */
2548 			printf("\t(BatteryEvent) %d (state was %d, is %d\n",
2549 			       aif->data.EN.data.EBE.transition_type,
2550 			       aif->data.EN.data.EBE.current_state,
2551 			       aif->data.EN.data.EBE.prior_state);
2552 			break;
2553 		case AifEnAddContainer:
2554 			/* A new container was created. */
2555 			printf("\t(AddContainer)\n");
2556 			break;
2557 		case AifEnDeleteContainer:
2558 			/* A container was deleted. */
2559 			printf("\t(DeleteContainer)\n");
2560 			break;
2561 		case AifEnBatteryNeedsRecond:
2562 			/* The battery needs reconditioning */
2563 			printf("\t(BatteryNeedsRecond)\n");
2564 			break;
2565 		case AifEnClusterEvent:
2566 			/* Some cluster event */
2567 			printf("\t(ClusterEvent) event %d\n",
2568 			       aif->data.EN.data.ECLE.eventType);
2569 			break;
2570 		case AifEnDiskSetEvent:
2571 			/* A disk set event occured. */
2572 			printf("(DiskSetEvent) event %d "
2573 			       "diskset %lld creator %lld\n",
2574 			       aif->data.EN.data.EDS.eventType,
2575 			       aif->data.EN.data.EDS.DsNum,
2576 			       aif->data.EN.data.EDS.CreatorId);
2577 			break;
2578 		case AifDenMorphComplete:
2579 			/* A morph operation completed */
2580 			printf("\t(MorphComplete)\n");
2581 			break;
2582 		case AifDenVolumeExtendComplete:
2583 			/* A volume expand operation completed */
2584 			printf("\t(VolumeExtendComplete)\n");
2585 			break;
2586 		default:
2587 			printf("\t(%d)\n", aif->data.EN.type);
2588 			break;
2589 		}
2590 		break;
2591 	case AifCmdJobProgress:
2592 	{
2593 		char	*status;
2594 		switch(aif->data.PR[0].status) {
2595 		case AifJobStsSuccess:
2596 			status = "success"; break;
2597 		case AifJobStsFinished:
2598 			status = "finished"; break;
2599 		case AifJobStsAborted:
2600 			status = "aborted"; break;
2601 		case AifJobStsFailed:
2602 			status = "failed"; break;
2603 		case AifJobStsSuspended:
2604 			status = "suspended"; break;
2605 		case AifJobStsRunning:
2606 			status = "running"; break;
2607 		default:
2608 			status = "unknown status"; break;
2609 		}
2610 
2611 		printf("JobProgress (%d) - %s (%d, %d)\n",
2612 		       aif->seqNumber, status,
2613 		       aif->data.PR[0].currentTick,
2614 		       aif->data.PR[0].finalTick);
2615 
2616 		switch(aif->data.PR[0].jd.type) {
2617 		case AifJobScsiZero:
2618 			/* SCSI dev clear operation */
2619 			printf("\t(ScsiZero) handle %d\n",
2620 				      aif->data.PR[0].jd.client.scsi_dh);
2621 			break;
2622 		case AifJobScsiVerify:
2623 			/* SCSI device Verify operation NO REPAIR */
2624 			printf("\t(ScsiVerify) handle %d\n",
2625 				      aif->data.PR[0].jd.client.scsi_dh);
2626 			break;
2627 		case AifJobScsiExercise:
2628 			/* SCSI device Exercise operation */
2629 			printf("\t(ScsiExercise) handle %d\n",
2630 			       aif->data.PR[0].jd.client.scsi_dh);
2631 			break;
2632 		case AifJobScsiVerifyRepair:
2633 			/* SCSI device Verify operation WITH repair */
2634 			printf("\t(ScsiVerifyRepair) handle %d\n",
2635 			       aif->data.PR[0].jd.client.scsi_dh);
2636 			break;
2637 		case AifJobCtrZero:
2638 			/* Container clear operation */
2639 			printf("\t(ContainerZero) container %d\n",
2640 			       aif->data.PR[0].jd.client.container.src);
2641 			break;
2642 		case AifJobCtrCopy:
2643 			/* Container copy operation */
2644 			printf("\t(ContainerCopy) container %d to %d\n",
2645 			       aif->data.PR[0].jd.client.container.src,
2646 			       aif->data.PR[0].jd.client.container.dst);
2647 			break;
2648 		case AifJobCtrCreateMirror:
2649 			/* Container Create Mirror operation */
2650 			printf("\t(ContainerCreateMirror) container %d\n",
2651 			       aif->data.PR[0].jd.client.container.src);
2652 			/* XXX two containers? */
2653 			break;
2654 		case AifJobCtrMergeMirror:
2655 			/* Container Merge Mirror operation */
2656 			printf("\t(ContainerMergeMirror) container %d\n",
2657 			       aif->data.PR[0].jd.client.container.src);
2658 			/* XXX two containers? */
2659 			break;
2660 		case AifJobCtrScrubMirror:
2661 			/* Container Scrub Mirror operation */
2662 			printf("\t(ContainerScrubMirror) container %d\n",
2663 			       aif->data.PR[0].jd.client.container.src);
2664 			break;
2665 		case AifJobCtrRebuildRaid5:
2666 			/* Container Rebuild Raid5 operation */
2667 			printf("\t(ContainerRebuildRaid5) container %d\n",
2668 			       aif->data.PR[0].jd.client.container.src);
2669 			break;
2670 		case AifJobCtrScrubRaid5:
2671 			/* Container Scrub Raid5 operation */
2672 			printf("\t(ContainerScrubRaid5) container %d\n",
2673 			       aif->data.PR[0].jd.client.container.src);
2674 			break;
2675 		case AifJobCtrMorph:
2676 			/* Container morph operation */
2677 			printf("\t(ContainerMorph) container %d\n",
2678 			       aif->data.PR[0].jd.client.container.src);
2679 			/* XXX two containers? */
2680 			break;
2681 		case AifJobCtrPartCopy:
2682 			/* Container Partition copy operation */
2683 			printf("\t(ContainerPartCopy) container %d to %d\n",
2684 			       aif->data.PR[0].jd.client.container.src,
2685 			       aif->data.PR[0].jd.client.container.dst);
2686 			break;
2687 		case AifJobCtrRebuildMirror:
2688 			/* Container Rebuild Mirror operation */
2689 			printf("\t(ContainerRebuildMirror) container %d\n",
2690 			       aif->data.PR[0].jd.client.container.src);
2691 			break;
2692 		case AifJobCtrCrazyCache:
2693 			/* crazy cache */
2694 			printf("\t(ContainerCrazyCache) container %d\n",
2695 			       aif->data.PR[0].jd.client.container.src);
2696 			/* XXX two containers? */
2697 			break;
2698 		case AifJobFsCreate:
2699 			/* File System Create operation */
2700 			printf("\t(FsCreate)\n");
2701 			break;
2702 		case AifJobFsVerify:
2703 			/* File System Verify operation */
2704 			printf("\t(FsVerivy)\n");
2705 			break;
2706 		case AifJobFsExtend:
2707 			/* File System Extend operation */
2708 			printf("\t(FsExtend)\n");
2709 			break;
2710 		case AifJobApiFormatNTFS:
2711 			/* Format a drive to NTFS */
2712 			printf("\t(FormatNTFS)\n");
2713 			break;
2714 		case AifJobApiFormatFAT:
2715 			/* Format a drive to FAT */
2716 			printf("\t(FormatFAT)\n");
2717 			break;
2718 		case AifJobApiUpdateSnapshot:
2719 			/* update the read/write half of a snapshot */
2720 			printf("\t(UpdateSnapshot)\n");
2721 			break;
2722 		case AifJobApiFormatFAT32:
2723 			/* Format a drive to FAT32 */
2724 			printf("\t(FormatFAT32)\n");
2725 			break;
2726 		case AifJobCtlContinuousCtrVerify:
2727 			/* Adapter operation */
2728 			printf("\t(ContinuousCtrVerify)\n");
2729 			break;
2730 		default:
2731 			printf("\t(%d)\n", aif->data.PR[0].jd.type);
2732 			break;
2733 		}
2734 		break;
2735 	}
2736 	case AifCmdAPIReport:
2737 		printf("APIReport (%d)\n", aif->seqNumber);
2738 		break;
2739 	case AifCmdDriverNotify:
2740 		printf("DriverNotify (%d)\n", aif->seqNumber);
2741 		break;
2742 	default:
2743 		printf("AIF %d (%d)\n", aif->command, aif->seqNumber);
2744 		break;
2745 	}
2746 }
2747 #endif
2748