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