xref: /openbsd-src/sys/dev/ic/aac.c (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
1 /*	$OpenBSD: aac.c,v 1.91 2020/10/15 00:01:24 krw 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 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 		goto out;
1284 
1285 	scsi_iopool_init(&sc->aac_iopool, sc,
1286 	    aac_alloc_command, aac_release_command);
1287 
1288 	/*
1289 	 * Fill in the init structure.  This tells the adapter about the
1290 	 * physical location of various important shared data structures.
1291 	 */
1292 	ip = &sc->aac_common->ac_init;
1293 	ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1294 	ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1295 
1296 	ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1297 					 offsetof(struct aac_common, ac_fibs);
1298 	ip->AdapterFibsVirtualAddress = 0;
1299 	ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1300 	ip->AdapterFibAlign = sizeof(struct aac_fib);
1301 
1302 	ip->PrintfBufferAddress = sc->aac_common_busaddr +
1303 				  offsetof(struct aac_common, ac_printf);
1304 	ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1305 
1306 	/*
1307 	 * The adapter assumes that pages are 4K in size, except on some
1308 	 * broken firmware versions that do the page->byte conversion twice,
1309 	 * therefore 'assuming' that this value is in 16MB units (2^24).
1310 	 * Round up since the granularity is so high.
1311 	 */
1312 	ip->HostPhysMemPages = ptoa(physmem) / AAC_PAGE_SIZE;
1313 	if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) {
1314 		ip->HostPhysMemPages =
1315 		    (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
1316 	}
1317 	ip->HostElapsedSeconds = getuptime(); /* reset later if invalid */
1318 
1319 	/*
1320 	 * Initialise FIB queues.  Note that it appears that the layout of the
1321 	 * indexes and the segmentation of the entries may be mandated by the
1322 	 * adapter, which is only told about the base of the queue index fields.
1323 	 *
1324 	 * The initial values of the indices are assumed to inform the adapter
1325 	 * of the sizes of the respective queues, and theoretically it could
1326 	 * work out the entire layout of the queue structures from this.  We
1327 	 * take the easy route and just lay this area out like everyone else
1328 	 * does.
1329 	 *
1330 	 * The Linux driver uses a much more complex scheme whereby several
1331 	 * header records are kept for each queue.  We use a couple of generic
1332 	 * list manipulation functions which 'know' the size of each list by
1333 	 * virtue of a table.
1334 	 */
1335 	qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
1336 	qoffset &= ~(AAC_QUEUE_ALIGN - 1);
1337 	sc->aac_queues =
1338 	    (struct aac_queue_table *)((caddr_t)sc->aac_common + qoffset);
1339 	ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset;
1340 
1341 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1342 		AAC_HOST_NORM_CMD_ENTRIES;
1343 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1344 		AAC_HOST_NORM_CMD_ENTRIES;
1345 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1346 		AAC_HOST_HIGH_CMD_ENTRIES;
1347 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1348 		AAC_HOST_HIGH_CMD_ENTRIES;
1349 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1350 		AAC_ADAP_NORM_CMD_ENTRIES;
1351 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1352 		AAC_ADAP_NORM_CMD_ENTRIES;
1353 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1354 		AAC_ADAP_HIGH_CMD_ENTRIES;
1355 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1356 		AAC_ADAP_HIGH_CMD_ENTRIES;
1357 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1358 		AAC_HOST_NORM_RESP_ENTRIES;
1359 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1360 		AAC_HOST_NORM_RESP_ENTRIES;
1361 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1362 		AAC_HOST_HIGH_RESP_ENTRIES;
1363 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1364 		AAC_HOST_HIGH_RESP_ENTRIES;
1365 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1366 		AAC_ADAP_NORM_RESP_ENTRIES;
1367 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1368 		AAC_ADAP_NORM_RESP_ENTRIES;
1369 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1370 		AAC_ADAP_HIGH_RESP_ENTRIES;
1371 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1372 		AAC_ADAP_HIGH_RESP_ENTRIES;
1373 	sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1374 		&sc->aac_queues->qt_HostNormCmdQueue[0];
1375 	sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1376 		&sc->aac_queues->qt_HostHighCmdQueue[0];
1377 	sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1378 		&sc->aac_queues->qt_AdapNormCmdQueue[0];
1379 	sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1380 		&sc->aac_queues->qt_AdapHighCmdQueue[0];
1381 	sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1382 		&sc->aac_queues->qt_HostNormRespQueue[0];
1383 	sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1384 		&sc->aac_queues->qt_HostHighRespQueue[0];
1385 	sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1386 		&sc->aac_queues->qt_AdapNormRespQueue[0];
1387 	sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1388 		&sc->aac_queues->qt_AdapHighRespQueue[0];
1389 
1390 	/*
1391 	 * Do controller-type-specific initialisation
1392 	 */
1393 	switch (sc->aac_hwif) {
1394 	case AAC_HWIF_I960RX:
1395 		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
1396 		break;
1397 	case AAC_HWIF_RKT:
1398 		AAC_SETREG4(sc, AAC_RKT_ODBR, ~0);
1399 		break;
1400 	default:
1401 		break;
1402 	}
1403 
1404 	/*
1405 	 * Give the init structure to the controller.
1406 	 */
1407 	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1408 			     sc->aac_common_busaddr +
1409 			     offsetof(struct aac_common, ac_init), 0, 0, 0,
1410 			     NULL)) {
1411 		printf("%s: error establishing init structure\n",
1412 		    sc->aac_dev.dv_xname);
1413 		error = EIO;
1414 		goto bail_out;
1415 	}
1416 
1417 	aac_describe_controller(sc);
1418 	aac_startup(sc);
1419 
1420 	return (0);
1421 
1422  bail_out:
1423 	if (state > 3)
1424 		bus_dmamap_unload(sc->aac_dmat, sc->aac_common_map);
1425 	if (state > 2)
1426 		bus_dmamap_destroy(sc->aac_dmat, sc->aac_common_map);
1427 	if (state > 1)
1428 		bus_dmamem_unmap(sc->aac_dmat, (caddr_t)sc->aac_common,
1429 		    sizeof *sc->aac_common);
1430 	if (state > 0)
1431 		bus_dmamem_free(sc->aac_dmat, &seg, 1);
1432 
1433  out:
1434 	return (error);
1435 }
1436 
1437 /*
1438  * Send a synchronous command to the controller and wait for a result.
1439  */
1440 int
1441 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1442 		 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp)
1443 {
1444 //	time_t then;
1445 	int i;
1446 	u_int32_t status;
1447 	u_int16_t reason;
1448 
1449 	/* populate the mailbox */
1450 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1451 
1452 	/* ensure the sync command doorbell flag is cleared */
1453 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1454 
1455 	/* then set it to signal the adapter */
1456 	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1457 
1458 	DELAY(AAC_SYNC_DELAY);
1459 
1460 	/* spin waiting for the command to complete */
1461 	for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) {
1462 		reason = AAC_GET_ISTATUS(sc);
1463 		if (reason & AAC_DB_SYNC_COMMAND)
1464 			break;
1465 		reason = AAC_GET_ISTATUS(sc);
1466 		if (reason & AAC_DB_SYNC_COMMAND)
1467 			break;
1468 		reason = AAC_GET_ISTATUS(sc);
1469 		if (reason & AAC_DB_SYNC_COMMAND)
1470 			break;
1471 		DELAY(1000);
1472 	}
1473 	if (i == AAC_IMMEDIATE_TIMEOUT * 1000) {
1474 		printf("aac_sync_command: failed, reason=%#x\n", reason);
1475 		return (EIO);
1476 	}
1477 
1478 	/* clear the completion flag */
1479 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1480 
1481 	/* get the command status */
1482 	status = AAC_GET_MAILBOX(sc, 0);
1483 
1484 	if (sp != NULL)
1485 		*sp = status;
1486 
1487 	return(0);
1488 }
1489 
1490 /*
1491  * Grab the sync fib area.
1492  */
1493 int
1494 aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags)
1495 {
1496 
1497 	/*
1498 	 * If the force flag is set, the system is shutting down, or in
1499 	 * trouble.  Ignore the mutex.
1500 	 */
1501 	if (!(flags & AAC_SYNC_LOCK_FORCE))
1502 		AAC_LOCK_ACQUIRE(&sc->aac_sync_lock);
1503 
1504 	*fib = &sc->aac_common->ac_sync_fib;
1505 
1506 	return (1);
1507 }
1508 
1509 /*
1510  * Release the sync fib area.
1511  */
1512 void
1513 aac_release_sync_fib(struct aac_softc *sc)
1514 {
1515 	AAC_LOCK_RELEASE(&sc->aac_sync_lock);
1516 }
1517 
1518 /*
1519  * Send a synchronous FIB to the controller and wait for a result.
1520  */
1521 int
1522 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1523 	     struct aac_fib *fib, u_int16_t datasize)
1524 {
1525 
1526 	if (datasize > AAC_FIB_DATASIZE) {
1527 		printf("aac_sync_fib 1: datasize=%d AAC_FIB_DATASIZE %lu\n",
1528 		    datasize, AAC_FIB_DATASIZE);
1529 		return(EINVAL);
1530 	}
1531 
1532 	/*
1533 	 * Set up the sync FIB
1534 	 */
1535 	fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
1536 				AAC_FIBSTATE_INITIALISED |
1537 				AAC_FIBSTATE_EMPTY;
1538 	fib->Header.XferState |= xferstate;
1539 	fib->Header.Command = command;
1540 	fib->Header.StructType = AAC_FIBTYPE_TFIB;
1541 	fib->Header.Size = sizeof(struct aac_fib) + datasize;
1542 	fib->Header.SenderSize = sizeof(struct aac_fib);
1543 	fib->Header.SenderFibAddress = 0;	/* Not needed */
1544 	fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
1545 					 offsetof(struct aac_common,
1546 						  ac_sync_fib);
1547 
1548 	/*
1549 	 * Give the FIB to the controller, wait for a response.
1550 	 */
1551 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
1552 			     fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
1553 		AAC_DPRINTF(AAC_D_IO, ("%s: aac_sync_fib: IO error\n",
1554 				       sc->aac_dev.dv_xname));
1555 		printf("aac_sync_fib 2\n");
1556 		return(EIO);
1557 	}
1558 
1559 	return (0);
1560 }
1561 
1562 /*****************************************************************************
1563  * Adapter-space FIB queue manipulation
1564  *
1565  * Note that the queue implementation here is a little funky; neither the PI or
1566  * CI will ever be zero.  This behaviour is a controller feature.
1567  */
1568 static struct {
1569 	int size;
1570 	int notify;
1571 } aac_qinfo[] = {
1572 	{ AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL },
1573 	{ AAC_HOST_HIGH_CMD_ENTRIES, 0 },
1574 	{ AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY },
1575 	{ AAC_ADAP_HIGH_CMD_ENTRIES, 0 },
1576 	{ AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL },
1577 	{ AAC_HOST_HIGH_RESP_ENTRIES, 0 },
1578 	{ AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY },
1579 	{ AAC_ADAP_HIGH_RESP_ENTRIES, 0 }
1580 };
1581 
1582 /*
1583  * Atomically insert an entry into the nominated queue, returns 0 on success
1584  * or EBUSY if the queue is full.
1585  *
1586  * Note: it would be more efficient to defer notifying the controller in
1587  *	 the case where we may be inserting several entries in rapid
1588  *	 succession, but implementing this usefully may be difficult
1589  *	 (it would involve a separate queue/notify interface).
1590  */
1591 int
1592 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
1593 {
1594 	u_int32_t pi, ci;
1595 	int error;
1596 	u_int32_t fib_size;
1597 	u_int32_t fib_addr;
1598 
1599 	fib_size = cm->cm_fib->Header.Size;
1600 	fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
1601 
1602 	/* get the producer/consumer indices */
1603 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1604 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1605 
1606 	/* wrap the queue? */
1607 	if (pi >= aac_qinfo[queue].size)
1608 		pi = 0;
1609 
1610 	/* check for queue full */
1611 	if ((pi + 1) == ci) {
1612 		error = EBUSY;
1613 		goto out;
1614 	}
1615 
1616 	/* populate queue entry */
1617 	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1618 	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1619 
1620 	/* update producer index */
1621 	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1622 
1623 	/*
1624 	 * To avoid a race with its completion interrupt, place this command on
1625 	 * the busy queue prior to advertising it to the controller.
1626 	 */
1627 	aac_enqueue_busy(cm);
1628 
1629 	/* notify the adapter if we know how */
1630 	if (aac_qinfo[queue].notify != 0)
1631 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1632 
1633 	error = 0;
1634 
1635 out:
1636 	return (error);
1637 }
1638 
1639 /*
1640  * Atomically remove one entry from the nominated queue, returns 0 on success
1641  * or ENOENT if the queue is empty.
1642  */
1643 int
1644 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1645 		struct aac_fib **fib_addr)
1646 {
1647 	u_int32_t pi, ci;
1648 	u_int32_t fib_index;
1649 	int notify;
1650 	int error;
1651 
1652 	/* get the producer/consumer indices */
1653 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1654 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1655 
1656 	/* check for queue empty */
1657 	if (ci == pi) {
1658 		error = ENOENT;
1659 		goto out;
1660 	}
1661 
1662 	/* wrap the pi so the following test works */
1663 	if (pi >= aac_qinfo[queue].size)
1664 		pi = 0;
1665 
1666 	notify = 0;
1667 	if (ci == pi + 1)
1668 		notify++;
1669 
1670 	/* wrap the queue? */
1671 	if (ci >= aac_qinfo[queue].size)
1672 		ci = 0;
1673 
1674 	/* fetch the entry */
1675 	*fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1676 
1677 	switch (queue) {
1678 	case AAC_HOST_NORM_CMD_QUEUE:
1679 	case AAC_HOST_HIGH_CMD_QUEUE:
1680 		/*
1681 		 * The aq_fib_addr is only 32 bits wide so it can't be counted
1682 		 * on to hold an address.  For AIF's, the adapter assumes
1683 		 * that it's giving us an address into the array of AIF fibs.
1684 		 * Therefore, we have to convert it to an index.
1685 		 */
1686 		fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr /
1687 			sizeof(struct aac_fib);
1688 		*fib_addr = &sc->aac_common->ac_fibs[fib_index];
1689 		break;
1690 
1691 	case AAC_HOST_NORM_RESP_QUEUE:
1692 	case AAC_HOST_HIGH_RESP_QUEUE:
1693 	{
1694 		struct aac_command *cm;
1695 
1696 		/*
1697 		 * As above, an index is used instead of an actual address.
1698 		 * Gotta shift the index to account for the fast response
1699 		 * bit.  No other correction is needed since this value was
1700 		 * originally provided by the driver via the SenderFibAddress
1701 		 * field.
1702 		 */
1703 		fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr;
1704 		cm = sc->aac_commands + (fib_index >> 1);
1705 		*fib_addr = cm->cm_fib;
1706 
1707 		/*
1708 		 * Is this a fast response? If it is, update the fib fields in
1709 		 * local memory since the whole fib isn't DMA'd back up.
1710 		 */
1711 		if (fib_index & 0x01) {
1712 			(*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP;
1713 			*((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL;
1714 		}
1715 		break;
1716 	}
1717 	default:
1718 		panic("Invalid queue in aac_dequeue_fib()");
1719 		break;
1720 	}
1721 
1722 
1723 	/* update consumer index */
1724 	sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1725 
1726 	/* if we have made the queue un-full, notify the adapter */
1727 	if (notify && (aac_qinfo[queue].notify != 0))
1728 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1729 	error = 0;
1730 
1731 out:
1732 	return (error);
1733 }
1734 
1735 /*
1736  * Put our response to an Adapter Initialed Fib on the response queue
1737  */
1738 int
1739 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
1740 {
1741 	u_int32_t pi, ci;
1742 	int error;
1743 	u_int32_t fib_size;
1744 	u_int32_t fib_addr;
1745 
1746 	/* Tell the adapter where the FIB is */
1747 	fib_size = fib->Header.Size;
1748 	fib_addr = fib->Header.SenderFibAddress;
1749 	fib->Header.ReceiverFibAddress = fib_addr;
1750 
1751 	/* get the producer/consumer indices */
1752 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1753 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1754 
1755 	/* wrap the queue? */
1756 	if (pi >= aac_qinfo[queue].size)
1757 		pi = 0;
1758 
1759 	/* check for queue full */
1760 	if ((pi + 1) == ci) {
1761 		error = EBUSY;
1762 		goto out;
1763 	}
1764 
1765 	/* populate queue entry */
1766 	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1767 	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1768 
1769 	/* update producer index */
1770 	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1771 
1772 	/* notify the adapter if we know how */
1773 	if (aac_qinfo[queue].notify != 0)
1774 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1775 
1776 	error = 0;
1777 
1778 out:
1779 	return(error);
1780 }
1781 
1782 void
1783 aac_command_timeout(struct aac_command *cm)
1784 {
1785 	struct aac_softc *sc = cm->cm_sc;
1786 
1787 	printf("%s: COMMAND %p (flags=%#x) TIMEOUT AFTER %d SECONDS\n",
1788 	       sc->aac_dev.dv_xname, cm, cm->cm_flags,
1789 	       (int)(getuptime() - cm->cm_timestamp));
1790 
1791 	if (cm->cm_flags & AAC_CMD_TIMEDOUT)
1792 		return;
1793 
1794 	cm->cm_flags |= AAC_CMD_TIMEDOUT;
1795 
1796 	AAC_PRINT_FIB(sc, cm->cm_fib);
1797 
1798 	if (cm->cm_flags & AAC_ON_AACQ_BIO) {
1799 		struct scsi_xfer *xs = cm->cm_private;
1800 		int s = splbio();
1801 		xs->error = XS_DRIVER_STUFFUP;
1802 		splx(s);
1803 		scsi_done(xs);
1804 
1805 		aac_remove_bio(cm);
1806 		aac_unmap_command(cm);
1807 	}
1808 }
1809 
1810 void
1811 aac_timeout(struct aac_softc *sc)
1812 {
1813 	struct aac_command *cm;
1814 	time_t deadline;
1815 
1816 	/*
1817 	 * Traverse the busy command list and timeout any commands
1818 	 * that are past their deadline.
1819 	 */
1820 	deadline = getuptime() - AAC_CMD_TIMEOUT;
1821 	TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
1822 		if (cm->cm_timestamp  < deadline)
1823 			aac_command_timeout(cm);
1824 	}
1825 }
1826 
1827 /*
1828  * Interface Function Vectors
1829  */
1830 
1831 /*
1832  * Read the current firmware status word.
1833  */
1834 int
1835 aac_sa_get_fwstatus(struct aac_softc *sc)
1836 {
1837 	return (AAC_GETREG4(sc, AAC_SA_FWSTATUS));
1838 }
1839 
1840 int
1841 aac_rx_get_fwstatus(struct aac_softc *sc)
1842 {
1843 	return (AAC_GETREG4(sc, AAC_RX_FWSTATUS));
1844 }
1845 
1846 int
1847 aac_fa_get_fwstatus(struct aac_softc *sc)
1848 {
1849 	return (AAC_GETREG4(sc, AAC_FA_FWSTATUS));
1850 }
1851 
1852 int
1853 aac_rkt_get_fwstatus(struct aac_softc *sc)
1854 {
1855 	return(AAC_GETREG4(sc, AAC_RKT_FWSTATUS));
1856 }
1857 
1858 /*
1859  * Notify the controller of a change in a given queue
1860  */
1861 
1862 void
1863 aac_sa_qnotify(struct aac_softc *sc, int qbit)
1864 {
1865 	AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
1866 }
1867 
1868 void
1869 aac_rx_qnotify(struct aac_softc *sc, int qbit)
1870 {
1871 	AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
1872 }
1873 
1874 void
1875 aac_fa_qnotify(struct aac_softc *sc, int qbit)
1876 {
1877 	AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
1878 	AAC_FA_HACK(sc);
1879 }
1880 
1881 void
1882 aac_rkt_qnotify(struct aac_softc *sc, int qbit)
1883 {
1884 	AAC_SETREG4(sc, AAC_RKT_IDBR, qbit);
1885 }
1886 
1887 /*
1888  * Get the interrupt reason bits
1889  */
1890 int
1891 aac_sa_get_istatus(struct aac_softc *sc)
1892 {
1893 	return (AAC_GETREG2(sc, AAC_SA_DOORBELL0));
1894 }
1895 
1896 int
1897 aac_rx_get_istatus(struct aac_softc *sc)
1898 {
1899 	return (AAC_GETREG4(sc, AAC_RX_ODBR));
1900 }
1901 
1902 int
1903 aac_fa_get_istatus(struct aac_softc *sc)
1904 {
1905 	return (AAC_GETREG2(sc, AAC_FA_DOORBELL0));
1906 }
1907 
1908 int
1909 aac_rkt_get_istatus(struct aac_softc *sc)
1910 {
1911 	return(AAC_GETREG4(sc, AAC_RKT_ODBR));
1912 }
1913 
1914 /*
1915  * Clear some interrupt reason bits
1916  */
1917 void
1918 aac_sa_clear_istatus(struct aac_softc *sc, int mask)
1919 {
1920 	AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
1921 }
1922 
1923 void
1924 aac_rx_clear_istatus(struct aac_softc *sc, int mask)
1925 {
1926 	AAC_SETREG4(sc, AAC_RX_ODBR, mask);
1927 }
1928 
1929 void
1930 aac_fa_clear_istatus(struct aac_softc *sc, int mask)
1931 {
1932 	AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
1933 	AAC_FA_HACK(sc);
1934 }
1935 
1936 void
1937 aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
1938 {
1939 	AAC_SETREG4(sc, AAC_RKT_ODBR, mask);
1940 }
1941 
1942 /*
1943  * Populate the mailbox and set the command word
1944  */
1945 void
1946 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1947 		   u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1948 {
1949 	AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
1950 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
1951 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
1952 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
1953 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
1954 }
1955 
1956 void
1957 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1958 		   u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1959 {
1960 	AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
1961 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
1962 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
1963 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
1964 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
1965 }
1966 
1967 void
1968 aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1969 		   u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1970 {
1971 	AAC_SETREG4(sc, AAC_FA_MAILBOX, command);
1972 	AAC_FA_HACK(sc);
1973 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
1974 	AAC_FA_HACK(sc);
1975 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
1976 	AAC_FA_HACK(sc);
1977 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
1978 	AAC_FA_HACK(sc);
1979 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
1980 	AAC_FA_HACK(sc);
1981 }
1982 
1983 void
1984 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1985 		    u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1986 {
1987 	AAC_SETREG4(sc, AAC_RKT_MAILBOX, command);
1988 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
1989 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
1990 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
1991 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
1992 }
1993 
1994 /*
1995  * Fetch the immediate command status word
1996  */
1997 int
1998 aac_sa_get_mailbox(struct aac_softc *sc, int mb)
1999 {
2000 	return (AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
2001 }
2002 
2003 int
2004 aac_rx_get_mailbox(struct aac_softc *sc, int mb)
2005 {
2006 	return (AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
2007 }
2008 
2009 int
2010 aac_fa_get_mailbox(struct aac_softc *sc, int mb)
2011 {
2012 	return (AAC_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4)));
2013 }
2014 
2015 int
2016 aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
2017 {
2018 	return(AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
2019 }
2020 
2021 /*
2022  * Set/clear interrupt masks
2023  */
2024 void
2025 aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2026 {
2027 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts\n",
2028 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2029 
2030 	if (enable)
2031 		AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2032 	else
2033 		AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2034 }
2035 
2036 void
2037 aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2038 {
2039 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2040 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2041 
2042 	if (enable)
2043 		AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2044 	else
2045 		AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
2046 }
2047 
2048 void
2049 aac_fa_set_interrupts(struct aac_softc *sc, int enable)
2050 {
2051 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2052 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2053 
2054 	if (enable) {
2055 		AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2056 		AAC_FA_HACK(sc);
2057 	} else {
2058 		AAC_SETREG2((sc), AAC_FA_MASK0, ~0);
2059 		AAC_FA_HACK(sc);
2060 	}
2061 }
2062 
2063 void
2064 aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
2065 {
2066 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2067 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2068 
2069 	if (enable)
2070 		AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
2071 	else
2072 		AAC_SETREG4(sc, AAC_RKT_OIMR, ~0);
2073 }
2074 
2075 void
2076 aac_eval_mapping(size, cyls, heads, secs)
2077 	u_int32_t size;
2078 	int *cyls, *heads, *secs;
2079 {
2080 	*cyls = size / AAC_HEADS / AAC_SECS;
2081 	if (*cyls < AAC_MAXCYLS) {
2082 		*heads = AAC_HEADS;
2083 		*secs = AAC_SECS;
2084 	} else {
2085 		/* Too high for 64 * 32 */
2086 		*cyls = size / AAC_MEDHEADS / AAC_MEDSECS;
2087 		if (*cyls < AAC_MAXCYLS) {
2088 			*heads = AAC_MEDHEADS;
2089 			*secs = AAC_MEDSECS;
2090 		} else {
2091 			/* Too high for 127 * 63 */
2092 			*cyls = size / AAC_BIGHEADS / AAC_BIGSECS;
2093 			*heads = AAC_BIGHEADS;
2094 			*secs = AAC_BIGSECS;
2095 		}
2096 	}
2097 }
2098 
2099 /* Emulated SCSI operation on cache device */
2100 void
2101 aac_internal_cache_cmd(struct scsi_xfer *xs)
2102 {
2103 	struct scsi_link *link = xs->sc_link;
2104 	struct aac_softc *sc = link->bus->sb_adapter_softc;
2105 	struct scsi_inquiry_data inq;
2106 	struct scsi_sense_data sd;
2107 	struct scsi_read_cap_data rcd;
2108 	u_int8_t target = link->target;
2109 
2110 	AAC_DPRINTF(AAC_D_CMD, ("%s: aac_internal_cache_cmd: ",
2111 				sc->aac_dev.dv_xname));
2112 
2113 	switch (xs->cmd.opcode) {
2114 	case TEST_UNIT_READY:
2115 	case START_STOP:
2116 #if 0
2117 	case VERIFY:
2118 #endif
2119 		AAC_DPRINTF(AAC_D_CMD, ("opc %#x tgt %d ", xs->cmd.opcode,
2120 		    target));
2121 		break;
2122 
2123 	case REQUEST_SENSE:
2124 		AAC_DPRINTF(AAC_D_CMD, ("REQUEST SENSE tgt %d ", target));
2125 		bzero(&sd, sizeof sd);
2126 		sd.error_code = SSD_ERRCODE_CURRENT;
2127 		sd.segment = 0;
2128 		sd.flags = SKEY_NO_SENSE;
2129 		aac_enc32(sd.info, 0);
2130 		sd.extra_len = 0;
2131 		scsi_copy_internal_data(xs, &sd, sizeof(sd));
2132 		break;
2133 
2134 	case INQUIRY:
2135 		AAC_DPRINTF(AAC_D_CMD, ("INQUIRY tgt %d devtype %x ", target,
2136 		    sc->aac_hdr[target].hd_devtype));
2137 		bzero(&inq, sizeof inq);
2138 		/* XXX How do we detect removable/CD-ROM devices?  */
2139 		inq.device = T_DIRECT;
2140 		inq.dev_qual2 = 0;
2141 		inq.version = SCSI_REV_2;
2142 		inq.response_format = SID_SCSI2_RESPONSE;
2143 		inq.additional_length = SID_SCSI2_ALEN;
2144 		inq.flags |= SID_CmdQue;
2145 		strlcpy(inq.vendor, "Adaptec", sizeof inq.vendor);
2146 		snprintf(inq.product, sizeof inq.product, "Container #%02d",
2147 		    target);
2148 		strlcpy(inq.revision, "   ", sizeof inq.revision);
2149 		scsi_copy_internal_data(xs, &inq, sizeof(inq));
2150 		break;
2151 
2152 	case READ_CAPACITY:
2153 		AAC_DPRINTF(AAC_D_CMD, ("READ CAPACITY tgt %d ", target));
2154 		bzero(&rcd, sizeof rcd);
2155 		_lto4b(sc->aac_hdr[target].hd_size - 1, rcd.addr);
2156 		_lto4b(AAC_BLOCK_SIZE, rcd.length);
2157 		scsi_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd);
2158 		break;
2159 
2160 	default:
2161 		AAC_DPRINTF(AAC_D_CMD, ("\n"));
2162 		printf("aac_internal_cache_cmd got bad opcode: %#x\n",
2163 		    xs->cmd.opcode);
2164 		xs->error = XS_DRIVER_STUFFUP;
2165 		return;
2166 	}
2167 
2168 	xs->error = XS_NOERROR;
2169 }
2170 
2171 void
2172 aac_scsi_cmd(struct scsi_xfer *xs)
2173 {
2174 	struct scsi_link *link = xs->sc_link;
2175 	struct aac_softc *sc = link->bus->sb_adapter_softc;
2176 	u_int8_t target = link->target;
2177 	struct aac_command *cm;
2178 	u_int32_t blockno, blockcnt;
2179 	struct scsi_rw *rw;
2180 	struct scsi_rw_10 *rw10;
2181 	int s;
2182 
2183 	s = splbio();
2184 
2185 	xs->error = XS_NOERROR;
2186 
2187 	if (target >= AAC_MAX_CONTAINERS || !sc->aac_hdr[target].hd_present ||
2188 	    link->lun != 0) {
2189 		/*
2190 		 * XXX Should be XS_SENSE but that would require setting up a
2191 		 * faked sense too.
2192 		 */
2193 		splx(s);
2194 		xs->error = XS_DRIVER_STUFFUP;
2195 		scsi_done(xs);
2196 		return;
2197 	}
2198 
2199 	AAC_DPRINTF(AAC_D_CMD, ("%s: aac_scsi_cmd: ", sc->aac_dev.dv_xname));
2200 
2201 	xs->error = XS_NOERROR;
2202 	cm = NULL;
2203 	link = xs->sc_link;
2204 	target = link->target;
2205 
2206 	switch (xs->cmd.opcode) {
2207 	case TEST_UNIT_READY:
2208 	case REQUEST_SENSE:
2209 	case INQUIRY:
2210 	case START_STOP:
2211 	case READ_CAPACITY:
2212 #if 0
2213 	case VERIFY:
2214 #endif
2215 		aac_internal_cache_cmd(xs);
2216 		scsi_done(xs);
2217 		goto ready;
2218 
2219 	case PREVENT_ALLOW:
2220 		AAC_DPRINTF(AAC_D_CMD, ("PREVENT/ALLOW "));
2221 		/* XXX Not yet implemented */
2222 		xs->error = XS_NOERROR;
2223 		scsi_done(xs);
2224 		goto ready;
2225 
2226 	case SYNCHRONIZE_CACHE:
2227 		AAC_DPRINTF(AAC_D_CMD, ("SYNCHRONIZE_CACHE "));
2228 		/* XXX Not yet implemented */
2229 		xs->error = XS_NOERROR;
2230 		scsi_done(xs);
2231 		goto ready;
2232 
2233 	default:
2234 		AAC_DPRINTF(AAC_D_CMD, ("unknown opc %#x ", xs->cmd.opcode));
2235 		/* XXX Not yet implemented */
2236 		xs->error = XS_DRIVER_STUFFUP;
2237 		scsi_done(xs);
2238 		goto ready;
2239 
2240 	case READ_COMMAND:
2241 	case READ_10:
2242 	case WRITE_COMMAND:
2243 	case WRITE_10:
2244 		AAC_DPRINTF(AAC_D_CMD, ("rw opc %#x ", xs->cmd.opcode));
2245 
2246 		/* A read or write operation. */
2247 		if (xs->cmdlen == 6) {
2248 			rw = (struct scsi_rw *)&xs->cmd;
2249 			blockno = _3btol(rw->addr) &
2250 				(SRW_TOPADDR << 16 | 0xffff);
2251 			blockcnt = rw->length ? rw->length : 0x100;
2252 		} else {
2253 			rw10 = (struct scsi_rw_10 *)&xs->cmd;
2254 			blockno = _4btol(rw10->addr);
2255 			blockcnt = _2btol(rw10->length);
2256 		}
2257 
2258 		AAC_DPRINTF(AAC_D_CMD, ("opcode=%d blkno=%d bcount=%d ",
2259 					xs->cmd.opcode, blockno, blockcnt));
2260 
2261 		if (blockno >= sc->aac_hdr[target].hd_size ||
2262 		    blockno + blockcnt > sc->aac_hdr[target].hd_size) {
2263 			AAC_DPRINTF(AAC_D_CMD, ("\n"));
2264 			printf("%s: out of bounds %u-%u >= %u\n",
2265 			       sc->aac_dev.dv_xname, blockno,
2266 			       blockcnt, sc->aac_hdr[target].hd_size);
2267 			/*
2268 			 * XXX Should be XS_SENSE but that
2269 			 * would require setting up a faked
2270 			 * sense too.
2271 			 */
2272 			xs->error = XS_DRIVER_STUFFUP;
2273 			scsi_done(xs);
2274 			goto ready;
2275 		}
2276 
2277 		cm = xs->io;
2278 		aac_scrub_command(cm);
2279 
2280 		/* fill out the command */
2281 		cm->cm_data = (void *)xs->data;
2282 		cm->cm_datalen = xs->datalen;
2283 		cm->cm_complete = aac_bio_complete;
2284 		cm->cm_private = xs;
2285 		cm->cm_timestamp = getuptime();
2286 		cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
2287 		cm->cm_blkno = blockno;
2288 		cm->cm_bcount = blockcnt;
2289 
2290 		AAC_DPRINTF(AAC_D_CMD, ("\n"));
2291 		aac_enqueue_bio(cm);
2292 		aac_startio(sc);
2293 
2294 		/* XXX what if enqueue did not start a transfer? */
2295 		if (xs->flags & SCSI_POLL) {
2296 			if (!aac_wait_command(cm, xs->timeout))
2297 			{
2298 				printf("%s: command timed out\n",
2299 				       sc->aac_dev.dv_xname);
2300 				xs->error = XS_DRIVER_STUFFUP;
2301 				scsi_done(xs);
2302 				splx(s);
2303 				return;
2304 			}
2305 			scsi_done(xs);
2306 		}
2307 	}
2308 
2309  ready:
2310 	splx(s);
2311 	AAC_DPRINTF(AAC_D_CMD, ("%s: scsi_cmd complete\n",
2312 				sc->aac_dev.dv_xname));
2313 }
2314 
2315 /*
2316  * Debugging and Diagnostics
2317  */
2318 
2319 /*
2320  * Print some information about the controller.
2321  */
2322 void
2323 aac_describe_controller(struct aac_softc *sc)
2324 {
2325 	struct aac_fib *fib;
2326 	struct aac_adapter_info	*info;
2327 
2328 	aac_alloc_sync_fib(sc, &fib, 0);
2329 
2330 	fib->data[0] = 0;
2331 	if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2332 		printf("%s: RequestAdapterInfo failed 2\n",
2333 		       sc->aac_dev.dv_xname);
2334 		aac_release_sync_fib(sc);
2335 		return;
2336 	}
2337 	info = (struct aac_adapter_info *)&fib->data[0];
2338 
2339 	printf("%s: %s %dMHz, %dMB cache memory, %s\n", sc->aac_dev.dv_xname,
2340 	       aac_describe_code(aac_cpu_variant, info->CpuVariant),
2341 	       info->ClockSpeed, info->BufferMem / (1024 * 1024),
2342 	       aac_describe_code(aac_battery_platform, info->batteryPlatform));
2343 
2344 	/* save the kernel revision structure for later use */
2345 	sc->aac_revision = info->KernelRevision;
2346 	printf("%s: Kernel %d.%d-%d, Build %d, S/N %6X\n",
2347 	       sc->aac_dev.dv_xname,
2348 	       info->KernelRevision.external.comp.major,
2349 	       info->KernelRevision.external.comp.minor,
2350 	       info->KernelRevision.external.comp.dash,
2351 	       info->KernelRevision.buildNumber,
2352 	       (u_int32_t)(info->SerialNumber & 0xffffff));
2353 
2354 	aac_release_sync_fib(sc);
2355 }
2356 
2357 /*
2358  * Look up a text description of a numeric error code and return a pointer to
2359  * same.
2360  */
2361 char *
2362 aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
2363 {
2364 	int i;
2365 
2366 	for (i = 0; table[i].string != NULL; i++)
2367 		if (table[i].code == code)
2368 			return(table[i].string);
2369 	return(table[i + 1].string);
2370 }
2371 
2372 #ifdef AAC_DEBUG
2373 /*
2374  * Print a FIB
2375  */
2376 void
2377 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
2378 {
2379 	printf("%s: FIB @ %p\n", caller, fib);
2380 	printf("  XferState %b\n", fib->Header.XferState, "\20"
2381 	    "\1HOSTOWNED"
2382 	    "\2ADAPTEROWNED"
2383 	    "\3INITIALISED"
2384 	    "\4EMPTY"
2385 	    "\5FROMPOOL"
2386 	    "\6FROMHOST"
2387 	    "\7FROMADAP"
2388 	    "\10REXPECTED"
2389 	    "\11RNOTEXPECTED"
2390 	    "\12DONEADAP"
2391 	    "\13DONEHOST"
2392 	    "\14HIGH"
2393 	    "\15NORM"
2394 	    "\16ASYNC"
2395 	    "\17PAGEFILEIO"
2396 	    "\20SHUTDOWN"
2397 	    "\21LAZYWRITE"
2398 	    "\22ADAPMICROFIB"
2399 	    "\23BIOSFIB"
2400 	    "\24FAST_RESPONSE"
2401 	    "\25APIFIB\n");
2402 	printf("  Command         %d\n", fib->Header.Command);
2403 	printf("  StructType      %d\n", fib->Header.StructType);
2404 	printf("  Flags           0x%x\n", fib->Header.Flags);
2405 	printf("  Size            %d\n", fib->Header.Size);
2406 	printf("  SenderSize      %d\n", fib->Header.SenderSize);
2407 	printf("  SenderAddress   0x%x\n", fib->Header.SenderFibAddress);
2408 	printf("  ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress);
2409 	printf("  SenderData      0x%x\n", fib->Header.SenderData);
2410 	switch(fib->Header.Command) {
2411 	case ContainerCommand: {
2412 		struct aac_blockread *br = (struct aac_blockread *)fib->data;
2413 		struct aac_blockwrite *bw = (struct aac_blockwrite *)fib->data;
2414 		struct aac_sg_table *sg = NULL;
2415 		int i;
2416 
2417 		if (br->Command == VM_CtBlockRead) {
2418 			printf("  BlockRead: container %d  0x%x/%d\n",
2419 			    br->ContainerId, br->BlockNumber, br->ByteCount);
2420 			    sg = &br->SgMap;
2421 		}
2422 		if (bw->Command == VM_CtBlockWrite) {
2423 			printf("  BlockWrite: container %d  0x%x/%d (%s)\n",
2424 			    bw->ContainerId, bw->BlockNumber, bw->ByteCount,
2425 			    bw->Stable == CSTABLE ? "stable" : "unstable");
2426 			sg = &bw->SgMap;
2427 		}
2428 		if (sg != NULL) {
2429 			printf("  %d s/g entries\n", sg->SgCount);
2430 			for (i = 0; i < sg->SgCount; i++)
2431 				printf("  0x%08x/%d\n",
2432 				       sg->SgEntry[i].SgAddress,
2433 				       sg->SgEntry[i].SgByteCount);
2434 		}
2435 		break;
2436 	}
2437 	default:
2438 		printf("   %16D\n", fib->data, " ");
2439 		printf("   %16D\n", fib->data + 16, " ");
2440 	break;
2441 	}
2442 }
2443 
2444 /*
2445  * Describe an AIF we have received.
2446  */
2447 void
2448 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
2449 {
2450 	printf("%s: print_aif: ", sc->aac_dev.dv_xname);
2451 
2452 	switch(aif->command) {
2453 	case AifCmdEventNotify:
2454 		printf("EventNotify(%d)\n", aif->seqNumber);
2455 
2456 		switch(aif->data.EN.type) {
2457 		case AifEnGeneric:
2458 			/* Generic notification */
2459 			printf("\t(Generic) %.*s\n",
2460 			       (int)sizeof(aif->data.EN.data.EG),
2461 			       aif->data.EN.data.EG.text);
2462 			break;
2463 		case AifEnTaskComplete:
2464 			/* Task has completed */
2465 			printf("\t(TaskComplete)\n");
2466 			break;
2467 		case AifEnConfigChange:
2468 			/* Adapter configuration change occurred */
2469 			printf("\t(ConfigChange)\n");
2470 			break;
2471 		case AifEnContainerChange:
2472 			/* Adapter specific container configuration change */
2473 			printf("\t(ContainerChange) container %d,%d\n",
2474 			       aif->data.EN.data.ECC.container[0],
2475 			       aif->data.EN.data.ECC.container[1]);
2476 			break;
2477 		case AifEnDeviceFailure:
2478 			/* SCSI device failed */
2479 			printf("\t(DeviceFailure) handle %d\n",
2480 			       aif->data.EN.data.EDF.deviceHandle);
2481 			break;
2482 		case AifEnMirrorFailover:
2483 			/* Mirror failover started */
2484 			printf("\t(MirrorFailover) container %d failed, "
2485 			       "migrating from slice %d to %d\n",
2486 			       aif->data.EN.data.EMF.container,
2487 			       aif->data.EN.data.EMF.failedSlice,
2488 			       aif->data.EN.data.EMF.creatingSlice);
2489 			break;
2490 		case AifEnContainerEvent:
2491 			/* Significant container event */
2492 			printf("\t(ContainerEvent) container %d event %d\n",
2493 			       aif->data.EN.data.ECE.container,
2494 			       aif->data.EN.data.ECE.eventType);
2495 			break;
2496 		case AifEnFileSystemChange:
2497 			/* File system changed */
2498 			printf("\t(FileSystemChange)\n");
2499 			break;
2500 		case AifEnConfigPause:
2501 			/* Container pause event */
2502 			printf("\t(ConfigPause)\n");
2503 			break;
2504 		case AifEnConfigResume:
2505 			/* Container resume event */
2506 			printf("\t(ConfigResume)\n");
2507 			break;
2508 		case AifEnFailoverChange:
2509 			/* Failover space assignment changed */
2510 			printf("\t(FailoverChange)\n");
2511 			break;
2512 		case AifEnRAID5RebuildDone:
2513 			/* RAID5 rebuild finished */
2514 			printf("\t(RAID5RebuildDone)\n");
2515 			break;
2516 		case AifEnEnclosureManagement:
2517 			/* Enclosure management event */
2518 			printf("\t(EnclosureManagement) EMPID %d unit %d "
2519 			       "event %d\n",
2520 			       aif->data.EN.data.EEE.empID,
2521 			       aif->data.EN.data.EEE.unitID,
2522 			       aif->data.EN.data.EEE.eventType);
2523 			break;
2524 		case AifEnBatteryEvent:
2525 			/* Significant NV battery event */
2526 			printf("\t(BatteryEvent) %d (state was %d, is %d\n",
2527 			       aif->data.EN.data.EBE.transition_type,
2528 			       aif->data.EN.data.EBE.current_state,
2529 			       aif->data.EN.data.EBE.prior_state);
2530 			break;
2531 		case AifEnAddContainer:
2532 			/* A new container was created. */
2533 			printf("\t(AddContainer)\n");
2534 			break;
2535 		case AifEnDeleteContainer:
2536 			/* A container was deleted. */
2537 			printf("\t(DeleteContainer)\n");
2538 			break;
2539 		case AifEnBatteryNeedsRecond:
2540 			/* The battery needs reconditioning */
2541 			printf("\t(BatteryNeedsRecond)\n");
2542 			break;
2543 		case AifEnClusterEvent:
2544 			/* Some cluster event */
2545 			printf("\t(ClusterEvent) event %d\n",
2546 			       aif->data.EN.data.ECLE.eventType);
2547 			break;
2548 		case AifEnDiskSetEvent:
2549 			/* A disk set event occured. */
2550 			printf("(DiskSetEvent) event %d "
2551 			       "diskset %lld creator %lld\n",
2552 			       aif->data.EN.data.EDS.eventType,
2553 			       aif->data.EN.data.EDS.DsNum,
2554 			       aif->data.EN.data.EDS.CreatorId);
2555 			break;
2556 		case AifDenMorphComplete:
2557 			/* A morph operation completed */
2558 			printf("\t(MorphComplete)\n");
2559 			break;
2560 		case AifDenVolumeExtendComplete:
2561 			/* A volume expand operation completed */
2562 			printf("\t(VolumeExtendComplete)\n");
2563 			break;
2564 		default:
2565 			printf("\t(%d)\n", aif->data.EN.type);
2566 			break;
2567 		}
2568 		break;
2569 	case AifCmdJobProgress:
2570 	{
2571 		char	*status;
2572 		switch(aif->data.PR[0].status) {
2573 		case AifJobStsSuccess:
2574 			status = "success"; break;
2575 		case AifJobStsFinished:
2576 			status = "finished"; break;
2577 		case AifJobStsAborted:
2578 			status = "aborted"; break;
2579 		case AifJobStsFailed:
2580 			status = "failed"; break;
2581 		case AifJobStsSuspended:
2582 			status = "suspended"; break;
2583 		case AifJobStsRunning:
2584 			status = "running"; break;
2585 		default:
2586 			status = "unknown status"; break;
2587 		}
2588 
2589 		printf("JobProgress (%d) - %s (%d, %d)\n",
2590 		       aif->seqNumber, status,
2591 		       aif->data.PR[0].currentTick,
2592 		       aif->data.PR[0].finalTick);
2593 
2594 		switch(aif->data.PR[0].jd.type) {
2595 		case AifJobScsiZero:
2596 			/* SCSI dev clear operation */
2597 			printf("\t(ScsiZero) handle %d\n",
2598 				      aif->data.PR[0].jd.client.scsi_dh);
2599 			break;
2600 		case AifJobScsiVerify:
2601 			/* SCSI device Verify operation NO REPAIR */
2602 			printf("\t(ScsiVerify) handle %d\n",
2603 				      aif->data.PR[0].jd.client.scsi_dh);
2604 			break;
2605 		case AifJobScsiExercise:
2606 			/* SCSI device Exercise operation */
2607 			printf("\t(ScsiExercise) handle %d\n",
2608 			       aif->data.PR[0].jd.client.scsi_dh);
2609 			break;
2610 		case AifJobScsiVerifyRepair:
2611 			/* SCSI device Verify operation WITH repair */
2612 			printf("\t(ScsiVerifyRepair) handle %d\n",
2613 			       aif->data.PR[0].jd.client.scsi_dh);
2614 			break;
2615 		case AifJobCtrZero:
2616 			/* Container clear operation */
2617 			printf("\t(ContainerZero) container %d\n",
2618 			       aif->data.PR[0].jd.client.container.src);
2619 			break;
2620 		case AifJobCtrCopy:
2621 			/* Container copy operation */
2622 			printf("\t(ContainerCopy) container %d to %d\n",
2623 			       aif->data.PR[0].jd.client.container.src,
2624 			       aif->data.PR[0].jd.client.container.dst);
2625 			break;
2626 		case AifJobCtrCreateMirror:
2627 			/* Container Create Mirror operation */
2628 			printf("\t(ContainerCreateMirror) container %d\n",
2629 			       aif->data.PR[0].jd.client.container.src);
2630 			/* XXX two containers? */
2631 			break;
2632 		case AifJobCtrMergeMirror:
2633 			/* Container Merge Mirror operation */
2634 			printf("\t(ContainerMergeMirror) container %d\n",
2635 			       aif->data.PR[0].jd.client.container.src);
2636 			/* XXX two containers? */
2637 			break;
2638 		case AifJobCtrScrubMirror:
2639 			/* Container Scrub Mirror operation */
2640 			printf("\t(ContainerScrubMirror) container %d\n",
2641 			       aif->data.PR[0].jd.client.container.src);
2642 			break;
2643 		case AifJobCtrRebuildRaid5:
2644 			/* Container Rebuild Raid5 operation */
2645 			printf("\t(ContainerRebuildRaid5) container %d\n",
2646 			       aif->data.PR[0].jd.client.container.src);
2647 			break;
2648 		case AifJobCtrScrubRaid5:
2649 			/* Container Scrub Raid5 operation */
2650 			printf("\t(ContainerScrubRaid5) container %d\n",
2651 			       aif->data.PR[0].jd.client.container.src);
2652 			break;
2653 		case AifJobCtrMorph:
2654 			/* Container morph operation */
2655 			printf("\t(ContainerMorph) container %d\n",
2656 			       aif->data.PR[0].jd.client.container.src);
2657 			/* XXX two containers? */
2658 			break;
2659 		case AifJobCtrPartCopy:
2660 			/* Container Partition copy operation */
2661 			printf("\t(ContainerPartCopy) container %d to %d\n",
2662 			       aif->data.PR[0].jd.client.container.src,
2663 			       aif->data.PR[0].jd.client.container.dst);
2664 			break;
2665 		case AifJobCtrRebuildMirror:
2666 			/* Container Rebuild Mirror operation */
2667 			printf("\t(ContainerRebuildMirror) container %d\n",
2668 			       aif->data.PR[0].jd.client.container.src);
2669 			break;
2670 		case AifJobCtrCrazyCache:
2671 			/* crazy cache */
2672 			printf("\t(ContainerCrazyCache) container %d\n",
2673 			       aif->data.PR[0].jd.client.container.src);
2674 			/* XXX two containers? */
2675 			break;
2676 		case AifJobFsCreate:
2677 			/* File System Create operation */
2678 			printf("\t(FsCreate)\n");
2679 			break;
2680 		case AifJobFsVerify:
2681 			/* File System Verify operation */
2682 			printf("\t(FsVerivy)\n");
2683 			break;
2684 		case AifJobFsExtend:
2685 			/* File System Extend operation */
2686 			printf("\t(FsExtend)\n");
2687 			break;
2688 		case AifJobApiFormatNTFS:
2689 			/* Format a drive to NTFS */
2690 			printf("\t(FormatNTFS)\n");
2691 			break;
2692 		case AifJobApiFormatFAT:
2693 			/* Format a drive to FAT */
2694 			printf("\t(FormatFAT)\n");
2695 			break;
2696 		case AifJobApiUpdateSnapshot:
2697 			/* update the read/write half of a snapshot */
2698 			printf("\t(UpdateSnapshot)\n");
2699 			break;
2700 		case AifJobApiFormatFAT32:
2701 			/* Format a drive to FAT32 */
2702 			printf("\t(FormatFAT32)\n");
2703 			break;
2704 		case AifJobCtlContinuousCtrVerify:
2705 			/* Adapter operation */
2706 			printf("\t(ContinuousCtrVerify)\n");
2707 			break;
2708 		default:
2709 			printf("\t(%d)\n", aif->data.PR[0].jd.type);
2710 			break;
2711 		}
2712 		break;
2713 	}
2714 	case AifCmdAPIReport:
2715 		printf("APIReport (%d)\n", aif->seqNumber);
2716 		break;
2717 	case AifCmdDriverNotify:
2718 		printf("DriverNotify (%d)\n", aif->seqNumber);
2719 		break;
2720 	default:
2721 		printf("AIF %d (%d)\n", aif->command, aif->seqNumber);
2722 		break;
2723 	}
2724 }
2725 #endif
2726