xref: /netbsd-src/sys/dev/ic/aac.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /*	$NetBSD: aac.c,v 1.37 2007/10/21 12:59:33 briggs Exp $	*/
2 
3 /*-
4  * Copyright (c) 2002, 2007 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Andrew Doran.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*-
40  * Copyright (c) 2001 Scott Long
41  * Copyright (c) 2001 Adaptec, Inc.
42  * Copyright (c) 2000 Michael Smith
43  * Copyright (c) 2000 BSDi
44  * Copyright (c) 2000 Niklas Hallqvist
45  * All rights reserved.
46  *
47  * Redistribution and use in source and binary forms, with or without
48  * modification, are permitted provided that the following conditions
49  * are met:
50  * 1. Redistributions of source code must retain the above copyright
51  *    notice, this list of conditions and the following disclaimer.
52  * 2. Redistributions in binary form must reproduce the above copyright
53  *    notice, this list of conditions and the following disclaimer in the
54  *    documentation and/or other materials provided with the distribution.
55  *
56  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
57  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
60  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66  * SUCH DAMAGE.
67  */
68 
69 /*
70  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
71  *
72  * TODO:
73  *
74  * o Management interface.
75  * o Look again at some of the portability issues.
76  * o Handle various AIFs (e.g., notification that a container is going away).
77  */
78 
79 #include <sys/cdefs.h>
80 __KERNEL_RCSID(0, "$NetBSD: aac.c,v 1.37 2007/10/21 12:59:33 briggs Exp $");
81 
82 #include <sys/param.h>
83 #include <sys/systm.h>
84 #include <sys/buf.h>
85 #include <sys/device.h>
86 #include <sys/kernel.h>
87 #include <sys/malloc.h>
88 #include <sys/proc.h>
89 
90 #include <sys/bus.h>
91 
92 #include <uvm/uvm_extern.h>
93 
94 #include <dev/ic/aacreg.h>
95 #include <dev/ic/aacvar.h>
96 #include <dev/ic/aac_tables.h>
97 
98 #include "locators.h"
99 
100 static int	aac_new_intr(void *);
101 static int	aac_alloc_commands(struct aac_softc *);
102 #ifdef notyet
103 static void	aac_free_commands(struct aac_softc *);
104 #endif
105 static int	aac_check_firmware(struct aac_softc *);
106 static void	aac_describe_controller(struct aac_softc *);
107 static int	aac_dequeue_fib(struct aac_softc *, int, u_int32_t *,
108 				struct aac_fib **);
109 static int	aac_enqueue_fib(struct aac_softc *, int, struct aac_ccb *);
110 static int	aac_enqueue_response(struct aac_softc *, int, struct aac_fib *);
111 static void	aac_host_command(struct aac_softc *);
112 static void	aac_host_response(struct aac_softc *);
113 static int	aac_init(struct aac_softc *);
114 static int	aac_print(void *, const char *);
115 static void	aac_shutdown(void *);
116 static void	aac_startup(struct aac_softc *);
117 static int	aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t,
118 				 u_int32_t, u_int32_t, u_int32_t, u_int32_t *);
119 static int	aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t, void *,
120 			     u_int16_t, void *, u_int16_t *);
121 
122 #ifdef AAC_DEBUG
123 static void	aac_print_fib(struct aac_softc *, struct aac_fib *, const char *);
124 #endif
125 
126 /*
127  * Adapter-space FIB queue manipulation.
128  *
129  * Note that the queue implementation here is a little funky; neither the PI or
130  * CI will ever be zero.  This behaviour is a controller feature.
131  */
132 static struct {
133 	int	size;
134 	int	notify;
135 } const aac_qinfo[] = {
136 	{ AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL },
137 	{ AAC_HOST_HIGH_CMD_ENTRIES, 0 },
138 	{ AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY },
139 	{ AAC_ADAP_HIGH_CMD_ENTRIES, 0 },
140 	{ AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL },
141 	{ AAC_HOST_HIGH_RESP_ENTRIES, 0 },
142 	{ AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY },
143 	{ AAC_ADAP_HIGH_RESP_ENTRIES, 0 }
144 };
145 
146 #ifdef AAC_DEBUG
147 int	aac_debug = AAC_DEBUG;
148 #endif
149 
150 MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for aac(4)");
151 
152 static void	*aac_sdh;
153 
154 extern struct	cfdriver aac_cd;
155 
156 int
157 aac_attach(struct aac_softc *sc)
158 {
159 	struct aac_attach_args aaca;
160 	int i, rv;
161 	int locs[AACCF_NLOCS];
162 
163 	SIMPLEQ_INIT(&sc->sc_ccb_free);
164 	SIMPLEQ_INIT(&sc->sc_ccb_queue);
165 	SIMPLEQ_INIT(&sc->sc_ccb_complete);
166 
167 	/*
168 	 * Disable interrupts before we do anything.
169 	 */
170 	AAC_MASK_INTERRUPTS(sc);
171 
172 	/*
173 	 * Initialise the adapter.
174 	 */
175 	if (aac_check_firmware(sc))
176 		return (EINVAL);
177 
178 	if ((rv = aac_init(sc)) != 0)
179 		return (rv);
180 
181 	if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) {
182 		rv = sc->sc_intr_set(sc, aac_new_intr, sc);
183 		if (rv)
184 			return (rv);
185 	}
186 
187 	aac_startup(sc);
188 
189 	/*
190 	 * Print a little information about the controller.
191 	 */
192 	aac_describe_controller(sc);
193 
194 	/*
195 	 * Attach devices.
196 	 */
197 	for (i = 0; i < AAC_MAX_CONTAINERS; i++) {
198 		if (!sc->sc_hdr[i].hd_present)
199 			continue;
200 		aaca.aaca_unit = i;
201 
202 		locs[AACCF_UNIT] = i;
203 
204 		config_found_sm_loc(&sc->sc_dv, "aac", locs, &aaca,
205 				    aac_print, config_stdsubmatch);
206 	}
207 
208 	/*
209 	 * Enable interrupts, and register our shutdown hook.
210 	 */
211 	sc->sc_flags |= AAC_ONLINE;
212 	AAC_UNMASK_INTERRUPTS(sc);
213 	if (aac_sdh != NULL)
214 		shutdownhook_establish(aac_shutdown, NULL);
215 	return (0);
216 }
217 
218 static int
219 aac_alloc_commands(struct aac_softc *sc)
220 {
221 	struct aac_fibmap *fm;
222 	struct aac_ccb *ac;
223 	bus_addr_t fibpa;
224 	int size, nsegs;
225 	int i, error;
226 	int state;
227 
228 	if (sc->sc_total_fibs + sc->sc_max_fibs_alloc > sc->sc_max_fibs)
229 		return ENOMEM;
230 
231 	fm = malloc(sizeof(struct aac_fibmap), M_AACBUF, M_NOWAIT|M_ZERO);
232 	if (fm == NULL)
233 		return ENOMEM;
234 
235 	size = sc->sc_max_fibs_alloc * sc->sc_max_fib_size;
236 
237 	state = 0;
238 	error = bus_dmamap_create(sc->sc_dmat, size, 1, size,
239 	    0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &fm->fm_fibmap);
240 	if (error != 0) {
241 		aprint_error("%s: cannot create fibs dmamap (%d)\n",
242 		    sc->sc_dv.dv_xname, error);
243 		goto bail_out;
244 	}
245 	state++;
246 	error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0,
247 	    &fm->fm_fibseg, 1, &nsegs, BUS_DMA_NOWAIT);
248 	if (error != 0) {
249 		aprint_error("%s: can't allocate fibs structure (%d)\n",
250 		    sc->sc_dv.dv_xname, error);
251 		goto bail_out;
252 	}
253 	state++;
254 	error = bus_dmamem_map(sc->sc_dmat, &fm->fm_fibseg, nsegs, size,
255 	    (void **)&fm->fm_fibs, 0);
256 	if (error != 0) {
257 		aprint_error("%s: can't map fibs structure (%d)\n",
258 		    sc->sc_dv.dv_xname, error);
259 		goto bail_out;
260 	}
261 	state++;
262 	error = bus_dmamap_load(sc->sc_dmat, fm->fm_fibmap, fm->fm_fibs,
263 	    size, NULL, BUS_DMA_NOWAIT);
264 	if (error != 0) {
265 		aprint_error("%s: cannot load fibs dmamap (%d)\n",
266 		    sc->sc_dv.dv_xname, error);
267 		goto bail_out;
268 	}
269 
270 	fm->fm_ccbs = sc->sc_ccbs + sc->sc_total_fibs;
271 	fibpa = fm->fm_fibseg.ds_addr;
272 
273 	memset(fm->fm_fibs, 0, size);
274 	for (i = 0; i < sc->sc_max_fibs_alloc; i++) {
275 		ac = fm->fm_ccbs + i;
276 
277 		error = bus_dmamap_create(sc->sc_dmat, AAC_MAX_XFER(sc),
278 		    sc->sc_max_sgs, AAC_MAX_XFER(sc), 0,
279 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ac->ac_dmamap_xfer);
280 		if (error) {
281 			while (--i >= 0) {
282 				ac = fm->fm_ccbs + i;
283 				bus_dmamap_destroy(sc->sc_dmat,
284 				    ac->ac_dmamap_xfer);
285 				sc->sc_total_fibs--;
286 			}
287 			aprint_error("%s: cannot create ccb dmamap (%d)",
288 			    sc->sc_dv.dv_xname, error);
289 			goto bail_out;
290 		}
291 
292 		ac->ac_fibmap = fm;
293 		ac->ac_fib = (struct aac_fib *)
294 		    ((char *) fm->fm_fibs + i * sc->sc_max_fib_size);
295 		ac->ac_fibphys = fibpa + i * sc->sc_max_fib_size;
296 		aac_ccb_free(sc, ac);
297 		sc->sc_total_fibs++;
298 	}
299 
300 	TAILQ_INSERT_TAIL(&sc->sc_fibmap_tqh, fm, fm_link);
301 
302 	return 0;
303 bail_out:
304 	if (state > 3)
305 		bus_dmamap_unload(sc->sc_dmat, fm->fm_fibmap);
306 	if (state > 2)
307 		bus_dmamem_unmap(sc->sc_dmat, (void *) fm->fm_fibs, size);
308 	if (state > 1)
309 		bus_dmamem_free(sc->sc_dmat, &fm->fm_fibseg, 1);
310 
311 	bus_dmamap_destroy(sc->sc_dmat, fm->fm_fibmap);
312 
313 	free(fm, M_AACBUF);
314 
315 	return error;
316 }
317 
318 #ifdef notyet
319 static void
320 aac_free_commands(struct aac_softc *sc)
321 {
322 }
323 #endif
324 
325 /*
326  * Print autoconfiguration message for a sub-device.
327  */
328 static int
329 aac_print(void *aux, const char *pnp)
330 {
331 	struct aac_attach_args *aaca;
332 
333 	aaca = aux;
334 
335 	if (pnp != NULL)
336 		aprint_normal("block device at %s", pnp);
337 	aprint_normal(" unit %d", aaca->aaca_unit);
338 	return (UNCONF);
339 }
340 
341 /*
342  * Look up a text description of a numeric error code and return a pointer to
343  * same.
344  */
345 const char *
346 aac_describe_code(const struct aac_code_lookup *table, u_int32_t code)
347 {
348 	int i;
349 
350 	for (i = 0; table[i].string != NULL; i++)
351 		if (table[i].code == code)
352 			return (table[i].string);
353 
354 	return (table[i + 1].string);
355 }
356 
357 /*
358  * bitmask_snprintf(9) format string for the adapter options.
359  */
360 static const char *optfmt =
361     "\20\1SNAPSHOT\2CLUSTERS\3WCACHE\4DATA64\5HOSTTIME\6RAID50"
362     "\7WINDOW4GB"
363     "\10SCSIUPGD\11SOFTERR\12NORECOND\13SGMAP64\14ALARM\15NONDASD";
364 
365 static void
366 aac_describe_controller(struct aac_softc *sc)
367 {
368 	u_int8_t fmtbuf[256];
369 	u_int8_t tbuf[AAC_FIB_DATASIZE];
370 	u_int16_t bufsize;
371 	struct aac_adapter_info *info;
372 	u_int8_t arg;
373 
374 	arg = 0;
375 	if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &tbuf,
376 	    &bufsize)) {
377 		aprint_error("%s: RequestAdapterInfo failed\n",
378 		    sc->sc_dv.dv_xname);
379 		return;
380 	}
381 	if (bufsize != sizeof(*info)) {
382 		aprint_error("%s: "
383 		    "RequestAdapterInfo returned wrong data size (%d != %zu)\n",
384 		    sc->sc_dv.dv_xname, bufsize, sizeof(*info));
385 		return;
386 	}
387 	info = (struct aac_adapter_info *)&tbuf[0];
388 
389 	aprint_normal("%s: %s at %dMHz, %dMB mem (%dMB cache), %s\n",
390 	    sc->sc_dv.dv_xname,
391 	    aac_describe_code(aac_cpu_variant, le32toh(info->CpuVariant)),
392 	    le32toh(info->ClockSpeed),
393 	    le32toh(info->TotalMem) / (1024 * 1024),
394 	    le32toh(info->BufferMem) / (1024 * 1024),
395 	    aac_describe_code(aac_battery_platform,
396 			      le32toh(info->batteryPlatform)));
397 
398 	aprint_verbose("%s: Kernel %d.%d-%d [Build %d], ",
399 	    sc->sc_dv.dv_xname,
400 	    info->KernelRevision.external.comp.major,
401 	    info->KernelRevision.external.comp.minor,
402 	    info->KernelRevision.external.comp.dash,
403 	    info->KernelRevision.buildNumber);
404 
405 	aprint_verbose("Monitor %d.%d-%d [Build %d], S/N %6X\n",
406 	    info->MonitorRevision.external.comp.major,
407 	    info->MonitorRevision.external.comp.minor,
408 	    info->MonitorRevision.external.comp.dash,
409 	    info->MonitorRevision.buildNumber,
410 	    ((u_int32_t)info->SerialNumber & 0xffffff));
411 
412 	aprint_verbose("%s: Controller supports: %s\n",
413 	    sc->sc_dv.dv_xname,
414 	    bitmask_snprintf(sc->sc_supported_options, optfmt, fmtbuf,
415 			     sizeof(fmtbuf)));
416 
417 	/* Save the kernel revision structure for later use. */
418 	sc->sc_revision = info->KernelRevision;
419 }
420 
421 /*
422  * Retrieve the firmware version numbers.  Dell PERC2/QC cards with firmware
423  * version 1.x are not compatible with this driver.
424  */
425 static int
426 aac_check_firmware(struct aac_softc *sc)
427 {
428 	u_int32_t major, minor, opts, atusize = 0, status = 0;
429 	u_int32_t calcsgs;
430 
431 	if ((sc->sc_quirks & AAC_QUIRK_PERC2QC) != 0) {
432 		if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
433 		    NULL)) {
434 			aprint_error("%s: error reading firmware version\n",
435 			    sc->sc_dv.dv_xname);
436 			return (1);
437 		}
438 
439 		/* These numbers are stored as ASCII! */
440 		major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
441 		minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
442 		if (major == 1) {
443 			aprint_error(
444 			    "%s: firmware version %d.%d not supported.\n",
445 			    sc->sc_dv.dv_xname, major, minor);
446 			return (1);
447 		}
448 	}
449 
450 	if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, &status)) {
451 		if (status != AAC_SRB_STS_INVALID_REQUEST) {
452 			aprint_error("%s: GETINFO failed, status 0x%08x\n",
453 				     sc->sc_dv.dv_xname, status);
454 			return (1);
455 		}
456 	} else {
457 		opts = AAC_GET_MAILBOX(sc, 1);
458 		atusize = AAC_GET_MAILBOX(sc, 2);
459 		sc->sc_supported_options = opts;
460 
461 		if (((opts & AAC_SUPPORTED_4GB_WINDOW) != 0) &&
462 		    ((sc->sc_quirks & AAC_QUIRK_NO4GB) == 0) )
463 			sc->sc_quirks |= AAC_QUIRK_4GB_WINDOW;
464 
465 		if (((opts & AAC_SUPPORTED_SGMAP_HOST64) != 0) &&
466 		    (sizeof(bus_addr_t) > 4)) {
467 			aprint_normal("%s: Enabling 64-bit address support\n",
468 				      sc->sc_dv.dv_xname);
469 			sc->sc_quirks |= AAC_QUIRK_SG_64BIT;
470 		}
471 		if ((opts & AAC_SUPPORTED_NEW_COMM) &&
472 		    (sc->sc_if.aif_send_command != NULL)) {
473 			sc->sc_quirks |= AAC_QUIRK_NEW_COMM;
474 		}
475 #ifdef notyet
476 		if (opts & AAC_SUPPORTED_64BIT_ARRAYSIZE)
477 			sc->sc_quirks |= AAC_QUIRK_ARRAY_64BIT;
478 #endif
479 	}
480 
481 	sc->sc_max_fibs = (sc->sc_quirks & AAC_QUIRK_256FIBS) ? 256 : 512;
482 
483 	if (   (sc->sc_quirks & AAC_QUIRK_NEW_COMM)
484 	    && (sc->sc_regsize < atusize)) {
485 		aprint_error("%s: Not enabling new comm i/f -- "
486 			     "atusize 0x%08x, regsize 0x%08x\n",
487 			     sc->sc_dv.dv_xname, atusize,
488 			     (u_int32_t) sc->sc_regsize);
489 		sc->sc_quirks &= ~AAC_QUIRK_NEW_COMM;
490 	}
491 #if 0
492 	if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) {
493 		aprint_error("%s: Not enabling new comm i/f -- "
494 			     "driver not ready yet\n",
495 			     sc->sc_dv.dv_xname);
496 		sc->sc_quirks &= ~AAC_QUIRK_NEW_COMM;
497 	}
498 #endif
499 
500 	sc->sc_max_fib_size = sizeof(struct aac_fib);
501 	sc->sc_max_sectors = 128;	/* 64KB */
502 	if (sc->sc_quirks & AAC_QUIRK_SG_64BIT)
503 		sc->sc_max_sgs = (sc->sc_max_fib_size
504 					- sizeof(struct aac_blockwrite64)
505 					+ sizeof(struct aac_sg_table64))
506 				      / sizeof(struct aac_sg_table64);
507 	else
508 		sc->sc_max_sgs = (sc->sc_max_fib_size
509 					- sizeof(struct aac_blockwrite)
510 					+ sizeof(struct aac_sg_table))
511 				      / sizeof(struct aac_sg_table);
512 
513 	if (!aac_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL)) {
514 		u_int32_t	opt1, opt2, opt3;
515 		u_int32_t	tmpval;
516 
517 		opt1 = AAC_GET_MAILBOX(sc, 1);
518 		opt2 = AAC_GET_MAILBOX(sc, 2);
519 		opt3 = AAC_GET_MAILBOX(sc, 3);
520 		if (!opt1 || !opt2 || !opt3) {
521 			aprint_verbose("%s: GETCOMMPREF appears untrustworthy."
522 			    "  Ignoring.\n", sc->sc_dv.dv_xname);
523 		} else {
524 			sc->sc_max_fib_size = le32toh(opt1) & 0xffff;
525 			sc->sc_max_sectors = (le32toh(opt1) >> 16) << 1;
526 			tmpval = (le32toh(opt2) >> 16);
527 			if (tmpval < sc->sc_max_sgs) {
528 				sc->sc_max_sgs = tmpval;
529 			}
530 			tmpval = (le32toh(opt3) & 0xffff);
531 			if (tmpval < sc->sc_max_fibs) {
532 				sc->sc_max_fibs = tmpval;
533 			}
534 		}
535 	}
536 	if (sc->sc_max_fib_size > PAGE_SIZE)
537 		sc->sc_max_fib_size = PAGE_SIZE;
538 
539 	if (sc->sc_quirks & AAC_QUIRK_SG_64BIT)
540 		calcsgs = (sc->sc_max_fib_size
541 			   - sizeof(struct aac_blockwrite64)
542 			   + sizeof(struct aac_sg_table64))
543 			      / sizeof(struct aac_sg_table64);
544 	else
545 		calcsgs = (sc->sc_max_fib_size
546 			   - sizeof(struct aac_blockwrite)
547 			   + sizeof(struct aac_sg_table))
548 			      / sizeof(struct aac_sg_table);
549 
550 	if (calcsgs < sc->sc_max_sgs) {
551 		sc->sc_max_sgs = calcsgs;
552 	}
553 
554 	sc->sc_max_fibs_alloc = PAGE_SIZE / sc->sc_max_fib_size;
555 
556 	return (0);
557 }
558 
559 static int
560 aac_init(struct aac_softc *sc)
561 {
562 	int nsegs, i, rv, state, norm, high;
563 	struct aac_adapter_init	*ip;
564 	u_int32_t code, qoff;
565 
566 	state = 0;
567 
568 	/*
569 	 * First wait for the adapter to come ready.
570 	 */
571 	for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) {
572 		code = AAC_GET_FWSTATUS(sc);
573 		if ((code & AAC_SELF_TEST_FAILED) != 0) {
574 			aprint_error("%s: FATAL: selftest failed\n",
575 			    sc->sc_dv.dv_xname);
576 			return (ENXIO);
577 		}
578 		if ((code & AAC_KERNEL_PANIC) != 0) {
579 			aprint_error("%s: FATAL: controller kernel panic\n",
580 			    sc->sc_dv.dv_xname);
581 			return (ENXIO);
582 		}
583 		if ((code & AAC_UP_AND_RUNNING) != 0)
584 			break;
585 		DELAY(1000);
586 	}
587 	if (i == AAC_BOOT_TIMEOUT * 1000) {
588 		aprint_error(
589 		    "%s: FATAL: controller not coming ready, status %x\n",
590 		    sc->sc_dv.dv_xname, code);
591 		return (ENXIO);
592 	}
593 
594 	sc->sc_aif_fib = malloc(sizeof(struct aac_fib), M_AACBUF,
595 	    M_NOWAIT | M_ZERO);
596 	if (sc->sc_aif_fib == NULL) {
597 		aprint_error("%s: cannot alloc fib structure\n",
598 		    sc->sc_dv.dv_xname);
599 		return (ENOMEM);
600 	}
601 	if ((rv = bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_common), 1,
602 	    sizeof(*sc->sc_common), 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
603 	    &sc->sc_common_dmamap)) != 0) {
604 		aprint_error("%s: cannot create common dmamap\n",
605 		    sc->sc_dv.dv_xname);
606 		goto bail_out;
607 	}
608 	state++;
609 	if ((rv = bus_dmamem_alloc(sc->sc_dmat, sizeof(*sc->sc_common),
610 	    PAGE_SIZE, 0, &sc->sc_common_seg, 1, &nsegs,
611 	    BUS_DMA_NOWAIT)) != 0) {
612 		aprint_error("%s: can't allocate common structure\n",
613 		    sc->sc_dv.dv_xname);
614 		goto bail_out;
615 	}
616 	state++;
617 	if ((rv = bus_dmamem_map(sc->sc_dmat, &sc->sc_common_seg, nsegs,
618 	    sizeof(*sc->sc_common), (void **)&sc->sc_common, 0)) != 0) {
619 		aprint_error("%s: can't map common structure\n",
620 		    sc->sc_dv.dv_xname);
621 		goto bail_out;
622 	}
623 	state++;
624 	if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_common_dmamap,
625 	    sc->sc_common, sizeof(*sc->sc_common), NULL,
626 	    BUS_DMA_NOWAIT)) != 0) {
627 		aprint_error("%s: cannot load common dmamap\n",
628 		    sc->sc_dv.dv_xname);
629 		goto bail_out;
630 	}
631 	state++;
632 
633 	memset(sc->sc_common, 0, sizeof(*sc->sc_common));
634 
635 	TAILQ_INIT(&sc->sc_fibmap_tqh);
636 	sc->sc_ccbs = malloc(sizeof(struct aac_ccb) * sc->sc_max_fibs, M_AACBUF,
637 	    M_NOWAIT | M_ZERO);
638 	if (sc->sc_ccbs == NULL) {
639 		aprint_error("%s: memory allocation failure getting ccbs\n",
640 		    sc->sc_dv.dv_xname);
641 		rv = ENOMEM;
642 		goto bail_out;
643 	}
644 	state++;
645 	while (sc->sc_total_fibs < AAC_PREALLOCATE_FIBS(sc)) {
646 		if (aac_alloc_commands(sc) != 0)
647 			break;
648 	}
649 	if (sc->sc_total_fibs == 0)
650 		goto bail_out;
651 
652 	/*
653 	 * Fill in the init structure.  This tells the adapter about the
654 	 * physical location of various important shared data structures.
655 	 */
656 	ip = &sc->sc_common->ac_init;
657 	ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION);
658 	if (sc->sc_max_fib_size > sizeof(struct aac_fib)) {
659 		ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION_4);
660 		sc->sc_quirks |= AAC_QUIRK_RAW_IO;
661 	}
662 	ip->MiniPortRevision = htole32(AAC_INIT_STRUCT_MINIPORT_REVISION);
663 
664 	ip->AdapterFibsPhysicalAddress = htole32(sc->sc_common_seg.ds_addr +
665 	    offsetof(struct aac_common, ac_fibs));
666 	ip->AdapterFibsVirtualAddress = 0;
667 	ip->AdapterFibsSize =
668 	    htole32(AAC_ADAPTER_FIBS * sizeof(struct aac_fib));
669 	ip->AdapterFibAlign = htole32(sizeof(struct aac_fib));
670 
671 	ip->PrintfBufferAddress = htole32(sc->sc_common_seg.ds_addr +
672 	    offsetof(struct aac_common, ac_printf));
673 	ip->PrintfBufferSize = htole32(AAC_PRINTF_BUFSIZE);
674 
675 	/*
676 	 * The adapter assumes that pages are 4K in size, except on some
677 	 * broken firmware versions that do the page->byte conversion twice,
678 	 * therefore 'assuming' that this value is in 16MB units (2^24).
679 	 * Round up since the granularity is so high.
680 	 */
681 	ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
682 	if (sc->sc_quirks & AAC_QUIRK_BROKEN_MMAP) {
683 		ip->HostPhysMemPages =
684 		    (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
685 	}
686 	ip->HostElapsedSeconds = 0;	/* reset later if invalid */
687 
688 	ip->InitFlags = 0;
689 	if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) {
690 		ip->InitFlags = htole32(AAC_INITFLAGS_NEW_COMM_SUPPORTED);
691 		aprint_normal("%s: New comm. interface enabled\n",
692 				sc->sc_dv.dv_xname);
693 	}
694 
695 	ip->MaxIoCommands = htole32(sc->sc_max_fibs);
696 	ip->MaxIoSize = htole32(sc->sc_max_sectors << 9);
697 	ip->MaxFibSize = htole32(sc->sc_max_fib_size);
698 
699 	/*
700 	 * Initialise FIB queues.  Note that it appears that the layout of
701 	 * the indexes and the segmentation of the entries is mandated by
702 	 * the adapter, which is only told about the base of the queue index
703 	 * fields.
704 	 *
705 	 * The initial values of the indices are assumed to inform the
706 	 * adapter of the sizes of the respective queues.
707 	 *
708 	 * The Linux driver uses a much more complex scheme whereby several
709 	 * header records are kept for each queue.  We use a couple of
710 	 * generic list manipulation functions which 'know' the size of each
711 	 * list by virtue of a table.
712 	 */
713 	qoff = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
714 	qoff &= ~(AAC_QUEUE_ALIGN - 1);
715 	sc->sc_queues = (struct aac_queue_table *)((uintptr_t)sc->sc_common + qoff);
716 	ip->CommHeaderAddress = htole32(sc->sc_common_seg.ds_addr +
717 	    ((char *)sc->sc_queues - (char *)sc->sc_common));
718 	memset(sc->sc_queues, 0, sizeof(struct aac_queue_table));
719 
720 	norm = htole32(AAC_HOST_NORM_CMD_ENTRIES);
721 	high = htole32(AAC_HOST_HIGH_CMD_ENTRIES);
722 
723 	sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
724 	    norm;
725 	sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
726 	    norm;
727 	sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
728 	    high;
729 	sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
730 	    high;
731 
732 	norm = htole32(AAC_ADAP_NORM_CMD_ENTRIES);
733 	high = htole32(AAC_ADAP_HIGH_CMD_ENTRIES);
734 
735 	sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
736 	    norm;
737 	sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
738 	    norm;
739 	sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
740 	    high;
741 	sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
742 	    high;
743 
744 	norm = htole32(AAC_HOST_NORM_RESP_ENTRIES);
745 	high = htole32(AAC_HOST_HIGH_RESP_ENTRIES);
746 
747 	sc->sc_queues->
748 	    qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm;
749 	sc->sc_queues->
750 	    qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm;
751 	sc->sc_queues->
752 	    qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high;
753 	sc->sc_queues->
754 	    qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high;
755 
756 	norm = htole32(AAC_ADAP_NORM_RESP_ENTRIES);
757 	high = htole32(AAC_ADAP_HIGH_RESP_ENTRIES);
758 
759 	sc->sc_queues->
760 	    qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm;
761 	sc->sc_queues->
762 	    qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm;
763 	sc->sc_queues->
764 	    qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high;
765 	sc->sc_queues->
766 	    qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high;
767 
768 	sc->sc_qentries[AAC_HOST_NORM_CMD_QUEUE] =
769 	    &sc->sc_queues->qt_HostNormCmdQueue[0];
770 	sc->sc_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
771 	    &sc->sc_queues->qt_HostHighCmdQueue[0];
772 	sc->sc_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
773 	    &sc->sc_queues->qt_AdapNormCmdQueue[0];
774 	sc->sc_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
775 	    &sc->sc_queues->qt_AdapHighCmdQueue[0];
776 	sc->sc_qentries[AAC_HOST_NORM_RESP_QUEUE] =
777 	    &sc->sc_queues->qt_HostNormRespQueue[0];
778 	sc->sc_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
779 	    &sc->sc_queues->qt_HostHighRespQueue[0];
780 	sc->sc_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
781 	    &sc->sc_queues->qt_AdapNormRespQueue[0];
782 	sc->sc_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
783 	    &sc->sc_queues->qt_AdapHighRespQueue[0];
784 
785 	/*
786 	 * Do controller-type-specific initialisation
787 	 */
788 	switch (sc->sc_hwif) {
789 	case AAC_HWIF_I960RX:
790 		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
791 		break;
792 	}
793 
794 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 0,
795 	    sizeof(*sc->sc_common),
796 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
797 
798 	/*
799 	 * Give the init structure to the controller.
800 	 */
801 	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
802 	    sc->sc_common_seg.ds_addr + offsetof(struct aac_common, ac_init),
803 	    0, 0, 0, NULL)) {
804 		aprint_error("%s: error establishing init structure\n",
805 		    sc->sc_dv.dv_xname);
806 		rv = EIO;
807 		goto bail_out;
808 	}
809 
810 	return (0);
811 
812  bail_out:
813  	if (state > 4)
814  		free(sc->sc_ccbs, M_AACBUF);
815  	if (state > 3)
816  		bus_dmamap_unload(sc->sc_dmat, sc->sc_common_dmamap);
817 	if (state > 2)
818 		bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_common,
819 		    sizeof(*sc->sc_common));
820 	if (state > 1)
821 		bus_dmamem_free(sc->sc_dmat, &sc->sc_common_seg, 1);
822 	if (state > 0)
823 		bus_dmamap_destroy(sc->sc_dmat, sc->sc_common_dmamap);
824 
825 	free(sc->sc_aif_fib, M_AACBUF);
826 
827 	return (rv);
828 }
829 
830 /*
831  * Probe for containers, create disks.
832  */
833 static void
834 aac_startup(struct aac_softc *sc)
835 {
836 	struct aac_mntinfo mi;
837 	struct aac_mntinforesponse mir;
838 	struct aac_drive *hd;
839 	u_int16_t rsize;
840 	int i;
841 
842 	/*
843 	 * Loop over possible containers.
844 	 */
845 	hd = sc->sc_hdr;
846 
847 	for (i = 0; i < AAC_MAX_CONTAINERS; i++, hd++) {
848 		/*
849 		 * Request information on this container.
850 		 */
851 		memset(&mi, 0, sizeof(mi));
852 		mi.Command = htole32(VM_NameServe);
853 		mi.MntType = htole32(FT_FILESYS);
854 		mi.MntCount = htole32(i);
855 		if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(mi), &mir,
856 		    &rsize)) {
857 			aprint_error("%s: error probing container %d\n",
858 			    sc->sc_dv.dv_xname, i);
859 			continue;
860 		}
861 		if (rsize != sizeof(mir)) {
862 			aprint_error("%s: container info response wrong size "
863 			    "(%d should be %zu)\n",
864 			    sc->sc_dv.dv_xname, rsize, sizeof(mir));
865 			continue;
866 		}
867 
868 		/*
869 		 * Check container volume type for validity.  Note that many
870 		 * of the possible types may never show up.
871 		 */
872 		if (le32toh(mir.Status) != ST_OK ||
873 		    le32toh(mir.MntTable[0].VolType) == CT_NONE)
874 			continue;
875 
876 		hd->hd_present = 1;
877 		hd->hd_size = le32toh(mir.MntTable[0].Capacity);
878 		hd->hd_devtype = le32toh(mir.MntTable[0].VolType);
879 		hd->hd_size &= ~0x1f;
880 		sc->sc_nunits++;
881 	}
882 }
883 
884 static void
885 aac_shutdown(void *cookie)
886 {
887 	struct aac_softc *sc;
888 	struct aac_close_command cc;
889 	u_int32_t i;
890 
891 	for (i = 0; i < aac_cd.cd_ndevs; i++) {
892 		if ((sc = device_lookup(&aac_cd, i)) == NULL)
893 			continue;
894 		if ((sc->sc_flags & AAC_ONLINE) == 0)
895 			continue;
896 
897 		AAC_MASK_INTERRUPTS(sc);
898 
899 		/*
900 		 * Send a Container shutdown followed by a HostShutdown FIB
901 		 * to the controller to convince it that we don't want to
902 		 * talk to it anymore.  We've been closed and all I/O
903 		 * completed already
904 		 */
905 		memset(&cc, 0, sizeof(cc));
906 		cc.Command = htole32(VM_CloseAll);
907 		cc.ContainerId = 0xffffffff;
908 		if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc),
909 		    NULL, NULL)) {
910 			printf("%s: unable to halt controller\n",
911 			    sc->sc_dv.dv_xname);
912 			continue;
913 		}
914 
915 		/*
916 		 * Note that issuing this command to the controller makes it
917 		 * shut down but also keeps it from coming back up without a
918 		 * reset of the PCI bus.
919 		 */
920 		if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
921 		    &i, sizeof(i), NULL, NULL))
922 			printf("%s: unable to halt controller\n",
923 			    sc->sc_dv.dv_xname);
924 
925 		sc->sc_flags &= ~AAC_ONLINE;
926 	}
927 }
928 
929 static int
930 aac_new_intr(void *cookie)
931 {
932 	struct aac_softc *sc;
933 	u_int32_t index, fast;
934 	struct aac_ccb *ac;
935 	struct aac_fib *fib;
936 	struct aac_fibmap *fm;
937 	int i;
938 
939 	sc = (struct aac_softc *) cookie;
940 
941 	for (;;) {
942 		index = AAC_GET_OUTB_QUEUE(sc);
943 		if (index == 0xffffffff)
944 			index = AAC_GET_OUTB_QUEUE(sc);
945 		if (index == 0xffffffff)
946 			break;
947 		if (index & 2) {
948 			if (index == 0xfffffffe) {
949 				/* XXX This means that the controller wants
950 				 * more work.  Ignore it for now.
951 				 */
952 				continue;
953 			}
954 			/* AIF */
955 			index &= ~2;
956 			fib = sc->sc_aif_fib;
957 			for (i = 0; i < sizeof(struct aac_fib)/4; i++) {
958 				((u_int32_t*)fib)[i] =
959 				    AAC_GETREG4(sc, index + i*4);
960 			}
961 #ifdef notyet
962 			aac_handle_aif(sc, &fib);
963 #endif
964 
965 			AAC_SET_OUTB_QUEUE(sc, index);
966 			AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
967 		} else {
968 			fast = index & 1;
969 			ac = sc->sc_ccbs + (index >> 2);
970 			fib = ac->ac_fib;
971 			fm = ac->ac_fibmap;
972 			if (fast) {
973 				bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap,
974 				    (char *)fib - (char *)fm->fm_fibs,
975 				    sc->sc_max_fib_size,
976 				    BUS_DMASYNC_POSTWRITE |
977 				    BUS_DMASYNC_POSTREAD);
978 				fib->Header.XferState |=
979 				    htole32(AAC_FIBSTATE_DONEADAP);
980 				*((u_int32_t *)(fib->data)) =
981 				    htole32(AAC_ERROR_NORMAL);
982 			}
983 			ac->ac_flags |= AAC_CCB_COMPLETED;
984 
985 			if (ac->ac_intr != NULL)
986 				(*ac->ac_intr)(ac);
987 			else
988 				wakeup(ac);
989 		}
990 	}
991 
992 	/*
993 	 * Try to submit more commands.
994 	 */
995 	if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue))
996 		aac_ccb_enqueue(sc, NULL);
997 
998 	return 1;
999 }
1000 
1001 /*
1002  * Take an interrupt.
1003  */
1004 int
1005 aac_intr(void *cookie)
1006 {
1007 	struct aac_softc *sc;
1008 	u_int16_t reason;
1009 	int claimed;
1010 
1011 	sc = cookie;
1012 	claimed = 0;
1013 
1014 	AAC_DPRINTF(AAC_D_INTR, ("aac_intr(%p) ", sc));
1015 
1016 	reason = AAC_GET_ISTATUS(sc);
1017 	AAC_CLEAR_ISTATUS(sc, reason);
1018 
1019 	AAC_DPRINTF(AAC_D_INTR, ("istatus 0x%04x ", reason));
1020 
1021 	/*
1022 	 * Controller wants to talk to the log.  XXX Should we defer this?
1023 	 */
1024 	if ((reason & AAC_DB_PRINTF) != 0) {
1025 		if (sc->sc_common->ac_printf[0] == '\0')
1026 			sc->sc_common->ac_printf[0] = ' ';
1027 		printf("%s: WARNING: adapter logged message:\n",
1028 			sc->sc_dv.dv_xname);
1029 		printf("%s:     %.*s", sc->sc_dv.dv_xname,
1030 			AAC_PRINTF_BUFSIZE, sc->sc_common->ac_printf);
1031 		sc->sc_common->ac_printf[0] = '\0';
1032 		AAC_QNOTIFY(sc, AAC_DB_PRINTF);
1033 		claimed = 1;
1034 	}
1035 
1036 	/*
1037 	 * Controller has a message for us?
1038 	 */
1039 	if ((reason & AAC_DB_COMMAND_READY) != 0) {
1040 		aac_host_command(sc);
1041 		claimed = 1;
1042 	}
1043 
1044 	/*
1045 	 * Controller has a response for us?
1046 	 */
1047 	if ((reason & AAC_DB_RESPONSE_READY) != 0) {
1048 		aac_host_response(sc);
1049 		claimed = 1;
1050 	}
1051 
1052 	/*
1053 	 * Spurious interrupts that we don't use - reset the mask and clear
1054 	 * the interrupts.
1055 	 */
1056 	if ((reason & (AAC_DB_SYNC_COMMAND | AAC_DB_COMMAND_NOT_FULL |
1057             AAC_DB_RESPONSE_NOT_FULL)) != 0) {
1058 		AAC_UNMASK_INTERRUPTS(sc);
1059 		AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND |
1060 		    AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL);
1061 		claimed = 1;
1062 	}
1063 
1064 	return (claimed);
1065 }
1066 
1067 /*
1068  * Handle notification of one or more FIBs coming from the controller.
1069  */
1070 static void
1071 aac_host_command(struct aac_softc *sc)
1072 {
1073 	struct aac_fib *fib;
1074 	u_int32_t fib_size;
1075 
1076 	for (;;) {
1077 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size,
1078 		    &fib))
1079 			break;	/* nothing to do */
1080 
1081 		bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1082 		    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
1083 		    BUS_DMASYNC_POSTREAD);
1084 
1085 		switch (le16toh(fib->Header.Command)) {
1086 		case AifRequest:
1087 #ifdef notyet
1088 			aac_handle_aif(sc,
1089 			    (struct aac_aif_command *)&fib->data[0]);
1090 #endif
1091 			AAC_PRINT_FIB(sc, fib);
1092 			break;
1093 		default:
1094 			printf("%s: unknown command from controller\n",
1095 			    sc->sc_dv.dv_xname);
1096 			AAC_PRINT_FIB(sc, fib);
1097 			break;
1098 		}
1099 
1100 		bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1101 		    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
1102 		    BUS_DMASYNC_PREREAD);
1103 
1104 		if ((fib->Header.XferState == 0) ||
1105 		    (fib->Header.StructType != AAC_FIBTYPE_TFIB)) {
1106 			break; // continue; ???
1107 		}
1108 
1109 		/* XXX reply to FIBs requesting responses ?? */
1110 
1111 		/* Return the AIF/FIB to the controller */
1112 		if (le32toh(fib->Header.XferState) & AAC_FIBSTATE_FROMADAP) {
1113 			u_int16_t	size;
1114 
1115 			fib->Header.XferState |=
1116 				htole32(AAC_FIBSTATE_DONEHOST);
1117 			*(u_int32_t*)fib->data = htole32(ST_OK);
1118 
1119 			/* XXX Compute the Size field? */
1120 			size = le16toh(fib->Header.Size);
1121 			if (size > sizeof(struct aac_fib)) {
1122 				size = sizeof(struct aac_fib);
1123 				fib->Header.Size = htole16(size);
1124 			}
1125 
1126 			/*
1127 			 * Since we didn't generate this command, it can't
1128 			 * go through the normal process.
1129 			 */
1130 			aac_enqueue_response(sc,
1131 					AAC_ADAP_NORM_RESP_QUEUE, fib);
1132 		}
1133 	}
1134 }
1135 
1136 /*
1137  * Handle notification of one or more FIBs completed by the controller
1138  */
1139 static void
1140 aac_host_response(struct aac_softc *sc)
1141 {
1142 	struct aac_ccb *ac;
1143 	struct aac_fib *fib;
1144 	u_int32_t fib_size;
1145 
1146 	/*
1147 	 * Look for completed FIBs on our queue.
1148 	 */
1149 	for (;;) {
1150 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
1151 		    &fib))
1152 			break;	/* nothing to do */
1153 
1154 		if ((fib->Header.SenderData & 0x80000000) == 0) {
1155 			/* Not valid; not sent by us. */
1156 			AAC_PRINT_FIB(sc, fib);
1157 		} else {
1158 			ac = (struct aac_ccb *)(sc->sc_ccbs +
1159 			    (fib->Header.SenderData & 0x7fffffff));
1160 			fib->Header.SenderData = 0;
1161 			SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_complete, ac, ac_chain);
1162 		}
1163 	}
1164 
1165 	/*
1166 	 * Deal with any completed commands.
1167 	 */
1168 	while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_complete)) != NULL) {
1169 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_complete, ac_chain);
1170 		ac->ac_flags |= AAC_CCB_COMPLETED;
1171 
1172 		if (ac->ac_intr != NULL)
1173 			(*ac->ac_intr)(ac);
1174 		else
1175 			wakeup(ac);
1176 	}
1177 
1178 	/*
1179 	 * Try to submit more commands.
1180 	 */
1181 	if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue))
1182 		aac_ccb_enqueue(sc, NULL);
1183 }
1184 
1185 /*
1186  * Send a synchronous command to the controller and wait for a result.
1187  */
1188 static int
1189 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1190 		 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp)
1191 {
1192 	int i;
1193 	u_int32_t status;
1194 	int s;
1195 
1196 	s = splbio();
1197 
1198 	/* Populate the mailbox. */
1199 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1200 
1201 	/* Ensure the sync command doorbell flag is cleared. */
1202 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1203 
1204 	/* ... then set it to signal the adapter. */
1205 	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1206 	DELAY(AAC_SYNC_DELAY);
1207 
1208 	/* Spin waiting for the command to complete. */
1209 	for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) {
1210 		if (AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND)
1211 			break;
1212 		DELAY(1000);
1213 	}
1214 	if (i == AAC_IMMEDIATE_TIMEOUT * 1000) {
1215 		splx(s);
1216 		return (EIO);
1217 	}
1218 
1219 	/* Clear the completion flag. */
1220 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1221 
1222 	/* Get the command status. */
1223 	status = AAC_GET_MAILBOXSTATUS(sc);
1224 	splx(s);
1225 	if (sp != NULL)
1226 		*sp = status;
1227 
1228 	return (0);	/* XXX Check command return status? */
1229 }
1230 
1231 /*
1232  * Send a synchronous FIB to the controller and wait for a result.
1233  */
1234 static int
1235 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1236 	     void *data, u_int16_t datasize, void *result,
1237 	     u_int16_t *resultsize)
1238 {
1239 	struct aac_fib *fib;
1240 	u_int32_t fibpa, status;
1241 
1242 	fib = &sc->sc_common->ac_sync_fib;
1243 	fibpa = sc->sc_common_seg.ds_addr +
1244 	    offsetof(struct aac_common, ac_sync_fib);
1245 
1246 	if (datasize > AAC_FIB_DATASIZE)
1247 		return (EINVAL);
1248 
1249 	/*
1250 	 * Set up the sync FIB.
1251 	 */
1252 	fib->Header.XferState = htole32(AAC_FIBSTATE_HOSTOWNED |
1253 	    AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY | xferstate);
1254 	fib->Header.Command = htole16(command);
1255 	fib->Header.StructType = AAC_FIBTYPE_TFIB;
1256 	fib->Header.Size = htole16(sizeof(*fib) + datasize);
1257 	fib->Header.SenderSize = htole16(sizeof(*fib));
1258 	fib->Header.SenderFibAddress = 0; /* not needed */
1259 	fib->Header.ReceiverFibAddress = htole32(fibpa);
1260 
1261 	/*
1262 	 * Copy in data.
1263 	 */
1264 	if (data != NULL) {
1265 		memcpy(fib->data, data, datasize);
1266 		fib->Header.XferState |=
1267 		    htole32(AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM);
1268 	}
1269 
1270 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1271 	    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
1272 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1273 
1274 	/*
1275 	 * Give the FIB to the controller, wait for a response.
1276 	 */
1277 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fibpa, 0, 0, 0, &status))
1278 		return (EIO);
1279 	if (status != 1) {
1280 		printf("%s: syncfib command %04x status %08x\n",
1281 			sc->sc_dv.dv_xname, command, status);
1282 	}
1283 
1284 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1285 	    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
1286 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1287 
1288 	/*
1289 	 * Copy out the result
1290 	 */
1291 	if (result != NULL) {
1292 		*resultsize = le16toh(fib->Header.Size) - sizeof(fib->Header);
1293 		memcpy(result, fib->data, *resultsize);
1294 	}
1295 
1296 	return (0);
1297 }
1298 
1299 struct aac_ccb *
1300 aac_ccb_alloc(struct aac_softc *sc, int flags)
1301 {
1302 	struct aac_ccb *ac;
1303 	int s;
1304 
1305 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_alloc(%p, 0x%x) ", sc, flags));
1306 
1307 	s = splbio();
1308 	ac = SIMPLEQ_FIRST(&sc->sc_ccb_free);
1309 	if (ac == NULL) {
1310 		if (aac_alloc_commands(sc)) {
1311 			splx(s);
1312 			return NULL;
1313 		}
1314 		ac = SIMPLEQ_FIRST(&sc->sc_ccb_free);
1315 	}
1316 #ifdef DIAGNOSTIC
1317 	if (ac == NULL)
1318 		panic("aac_ccb_get: no free CCBS");
1319 #endif
1320 	SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ac_chain);
1321 	splx(s);
1322 
1323 	ac->ac_flags = flags;
1324 	return (ac);
1325 }
1326 
1327 void
1328 aac_ccb_free(struct aac_softc *sc, struct aac_ccb *ac)
1329 {
1330 	int s;
1331 
1332 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_free(%p, %p) ", sc, ac));
1333 
1334 	ac->ac_flags = 0;
1335 	ac->ac_intr = NULL;
1336 	ac->ac_fib->Header.XferState = htole32(AAC_FIBSTATE_EMPTY);
1337 	ac->ac_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1338 	ac->ac_fib->Header.Flags = 0;
1339 	ac->ac_fib->Header.SenderSize = htole16(sc->sc_max_fib_size);
1340 
1341 #ifdef AAC_DEBUG
1342 	/*
1343 	 * These are duplicated in aac_ccb_submit() to cover the case where
1344 	 * an intermediate stage may have destroyed them.  They're left
1345 	 * initialised here for debugging purposes only.
1346 	 */
1347 	ac->ac_fib->Header.SenderFibAddress =
1348 	    htole32(((u_int32_t) (ac - sc->sc_ccbs)) << 2);
1349 	ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
1350 #endif
1351 
1352 	s = splbio();
1353 	SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ac, ac_chain);
1354 	splx(s);
1355 }
1356 
1357 int
1358 aac_ccb_map(struct aac_softc *sc, struct aac_ccb *ac)
1359 {
1360 	int error;
1361 
1362 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_map(%p, %p) ", sc, ac));
1363 
1364 #ifdef DIAGNOSTIC
1365 	if ((ac->ac_flags & AAC_CCB_MAPPED) != 0)
1366 		panic("aac_ccb_map: already mapped");
1367 #endif
1368 
1369 	error = bus_dmamap_load(sc->sc_dmat, ac->ac_dmamap_xfer, ac->ac_data,
1370 	    ac->ac_datalen, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
1371 	    ((ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE));
1372 	if (error) {
1373 		printf("%s: aac_ccb_map: ", sc->sc_dv.dv_xname);
1374 		if (error == EFBIG)
1375 			printf("more than %d DMA segs\n", sc->sc_max_sgs);
1376 		else
1377 			printf("error %d loading DMA map\n", error);
1378 		return (error);
1379 	}
1380 
1381 	bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
1382 	    (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_PREREAD :
1383 	    BUS_DMASYNC_PREWRITE);
1384 
1385 #ifdef DIAGNOSTIC
1386 	ac->ac_flags |= AAC_CCB_MAPPED;
1387 #endif
1388 	return (0);
1389 }
1390 
1391 void
1392 aac_ccb_unmap(struct aac_softc *sc, struct aac_ccb *ac)
1393 {
1394 
1395 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_unmap(%p, %p) ", sc, ac));
1396 
1397 #ifdef DIAGNOSTIC
1398 	if ((ac->ac_flags & AAC_CCB_MAPPED) == 0)
1399 		panic("aac_ccb_unmap: not mapped");
1400 #endif
1401 
1402 	bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
1403 	    (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_POSTREAD :
1404 	    BUS_DMASYNC_POSTWRITE);
1405 	bus_dmamap_unload(sc->sc_dmat, ac->ac_dmamap_xfer);
1406 
1407 #ifdef DIAGNOSTIC
1408 	ac->ac_flags &= ~AAC_CCB_MAPPED;
1409 #endif
1410 }
1411 
1412 void
1413 aac_ccb_enqueue(struct aac_softc *sc, struct aac_ccb *ac)
1414 {
1415 	int s;
1416 
1417 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_enqueue(%p, %p) ", sc, ac));
1418 
1419 	s = splbio();
1420 
1421 	if (ac != NULL)
1422 		SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ac, ac_chain);
1423 
1424 	while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) {
1425 		if (aac_ccb_submit(sc, ac))
1426 			break;
1427 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ac_chain);
1428 	}
1429 
1430 	splx(s);
1431 }
1432 
1433 int
1434 aac_ccb_submit(struct aac_softc *sc, struct aac_ccb *ac)
1435 {
1436 	struct aac_fibmap *fm;
1437 	u_int32_t acidx;
1438 
1439 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_submit(%p, %p) ", sc, ac));
1440 
1441 	acidx = (u_int32_t) (ac - sc->sc_ccbs);
1442 	/* Fix up the address values. */
1443 	ac->ac_fib->Header.SenderFibAddress = htole32(acidx << 2);
1444 	ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
1445 
1446 	/* Save a pointer to the command for speedy reverse-lookup. */
1447 	ac->ac_fib->Header.SenderData = acidx | 0x80000000;
1448 
1449 	fm = ac->ac_fibmap;
1450 	bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap,
1451 	    (char *)ac->ac_fib - (char *)fm->fm_fibs, sc->sc_max_fib_size,
1452 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1453 
1454 	/* Put the FIB on the outbound queue. */
1455 	if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) {
1456 		int count = 10000000L;
1457 		while (AAC_SEND_COMMAND(sc, ac) != 0) {
1458 			if (--count == 0) {
1459 				panic("aac: fixme!");
1460 				return EAGAIN;
1461 			}
1462 			DELAY(5);
1463 		}
1464 		return 0;
1465 	} else {
1466 		return (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, ac));
1467 	}
1468 }
1469 
1470 int
1471 aac_ccb_poll(struct aac_softc *sc, struct aac_ccb *ac, int timo)
1472 {
1473 	int rv, s;
1474 
1475 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_poll(%p, %p, %d) ", sc, ac, timo));
1476 
1477 	s = splbio();
1478 
1479 	if ((rv = aac_ccb_submit(sc, ac)) != 0) {
1480 		splx(s);
1481 		return (rv);
1482 	}
1483 
1484 	for (timo *= 1000; timo != 0; timo--) {
1485 		if (sc->sc_quirks & AAC_QUIRK_NEW_COMM)
1486 			aac_new_intr(sc);
1487 		else
1488 			aac_intr(sc);
1489 		if ((ac->ac_flags & AAC_CCB_COMPLETED) != 0)
1490 			break;
1491 		DELAY(100);
1492 	}
1493 
1494 	splx(s);
1495 	return (timo == 0);
1496 }
1497 
1498 /*
1499  * Atomically insert an entry into the nominated queue, returns 0 on success
1500  * or EBUSY if the queue is full.
1501  *
1502  * XXX Note that it would be more efficient to defer notifying the
1503  * controller in the case where we may be inserting several entries in rapid
1504  * succession, but implementing this usefully is difficult.
1505  */
1506 static int
1507 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_ccb *ac)
1508 {
1509 	u_int32_t fib_size, fib_addr, pi, ci;
1510 
1511 	fib_size = le16toh(ac->ac_fib->Header.Size);
1512 	fib_addr = le32toh(ac->ac_fib->Header.ReceiverFibAddress);
1513 
1514 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1515 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1516 	    sizeof(sc->sc_common->ac_qbuf),
1517 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1518 
1519 	/* Get the producer/consumer indices.  */
1520 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
1521 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
1522 
1523 	/* Wrap the queue? */
1524 	if (pi >= aac_qinfo[queue].size)
1525 		pi = 0;
1526 
1527 	/* Check for queue full. */
1528 	if ((pi + 1) == ci)
1529 		return (EAGAIN);
1530 
1531 	/* Populate queue entry. */
1532 	(sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size);
1533 	(sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr);
1534 
1535 	/* Update producer index. */
1536 	sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1);
1537 
1538 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1539 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1540 	    sizeof(sc->sc_common->ac_qbuf),
1541 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1542 
1543 	/* Notify the adapter if we know how. */
1544 	if (aac_qinfo[queue].notify != 0)
1545 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1546 
1547 	return (0);
1548 }
1549 
1550 /*
1551  * Atomically remove one entry from the nominated queue, returns 0 on success
1552  * or ENOENT if the queue is empty.
1553  */
1554 static int
1555 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1556 		struct aac_fib **fib_addr)
1557 {
1558 	struct aac_fibmap *fm;
1559 	struct aac_ccb *ac;
1560 	u_int32_t pi, ci, idx;
1561 	int notify;
1562 
1563 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1564 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1565 	    sizeof(sc->sc_common->ac_qbuf),
1566 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1567 
1568 	/* Get the producer/consumer indices. */
1569 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
1570 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
1571 
1572 	/* Check for queue empty. */
1573 	if (ci == pi)
1574 		return (ENOENT);
1575 
1576 	notify = 0;
1577 	if (ci == pi + 1)
1578 		notify = 1;
1579 
1580 	/* Wrap the queue? */
1581 	if (ci >= aac_qinfo[queue].size)
1582 		ci = 0;
1583 
1584 	/* Fetch the entry. */
1585 	*fib_size = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_size);
1586 
1587 	switch (queue) {
1588 	case AAC_HOST_NORM_CMD_QUEUE:
1589 	case AAC_HOST_HIGH_CMD_QUEUE:
1590 		idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr);
1591 		idx /= sizeof(struct aac_fib);
1592 		*fib_addr = &sc->sc_common->ac_fibs[idx];
1593 		break;
1594 	case AAC_HOST_NORM_RESP_QUEUE:
1595 	case AAC_HOST_HIGH_RESP_QUEUE:
1596 		idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr);
1597 		ac = sc->sc_ccbs + (idx >> 2);
1598 		*fib_addr = ac->ac_fib;
1599 		if (idx & 0x01) {
1600 			fm = ac->ac_fibmap;
1601 			bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap,
1602 			    (char *)ac->ac_fib - (char *)fm->fm_fibs,
1603 			    sc->sc_max_fib_size,
1604 			    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1605 			ac->ac_fib->Header.XferState |=
1606 				htole32(AAC_FIBSTATE_DONEADAP);
1607 			*((u_int32_t*)(ac->ac_fib->data)) =
1608 				htole32(AAC_ERROR_NORMAL);
1609 		}
1610 		break;
1611 	default:
1612 		panic("Invalid queue in aac_dequeue_fib()");
1613 		break;
1614 	}
1615 
1616 	/* Update consumer index. */
1617 	sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1618 
1619 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1620 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1621 	    sizeof(sc->sc_common->ac_qbuf),
1622 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1623 
1624 	/* If we have made the queue un-full, notify the adapter. */
1625 	if (notify && (aac_qinfo[queue].notify != 0))
1626 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1627 
1628 	return (0);
1629 }
1630 
1631 /*
1632  * Put our response to an adapter-initiated fib (AIF) on the response queue.
1633  */
1634 static int
1635 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
1636 {
1637 	u_int32_t fib_size, fib_addr, pi, ci;
1638 
1639 	fib_size = le16toh(fib->Header.Size);
1640 	fib_addr = fib->Header.SenderFibAddress;
1641 	fib->Header.ReceiverFibAddress = fib_addr;
1642 
1643 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1644 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1645 	    sizeof(sc->sc_common->ac_qbuf),
1646 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1647 
1648 	/* Get the producer/consumer indices.  */
1649 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
1650 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
1651 
1652 	/* Wrap the queue? */
1653 	if (pi >= aac_qinfo[queue].size)
1654 		pi = 0;
1655 
1656 	/* Check for queue full. */
1657 	if ((pi + 1) == ci)
1658 		return (EAGAIN);
1659 
1660 	/* Populate queue entry. */
1661 	(sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size);
1662 	(sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr);
1663 
1664 	/* Update producer index. */
1665 	sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1);
1666 
1667 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1668 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1669 	    sizeof(sc->sc_common->ac_qbuf),
1670 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1671 
1672 	/* Notify the adapter if we know how. */
1673 	if (aac_qinfo[queue].notify != 0)
1674 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1675 
1676 	return (0);
1677 }
1678 
1679 #ifdef AAC_DEBUG
1680 /*
1681  * Print a FIB
1682  */
1683 static void
1684 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib,
1685     const char *caller)
1686 {
1687 	struct aac_blockread *br;
1688 	struct aac_blockwrite *bw;
1689 	struct aac_sg_table *sg;
1690 	char tbuf[512];
1691 	int i;
1692 
1693 	printf("%s: FIB @ %p\n", caller, fib);
1694 	bitmask_snprintf(le32toh(fib->Header.XferState),
1695 	    "\20"
1696 	    "\1HOSTOWNED"
1697 	    "\2ADAPTEROWNED"
1698 	    "\3INITIALISED"
1699 	    "\4EMPTY"
1700 	    "\5FROMPOOL"
1701 	    "\6FROMHOST"
1702 	    "\7FROMADAP"
1703 	    "\10REXPECTED"
1704 	    "\11RNOTEXPECTED"
1705 	    "\12DONEADAP"
1706 	    "\13DONEHOST"
1707 	    "\14HIGH"
1708 	    "\15NORM"
1709 	    "\16ASYNC"
1710 	    "\17PAGEFILEIO"
1711 	    "\20SHUTDOWN"
1712 	    "\21LAZYWRITE"
1713 	    "\22ADAPMICROFIB"
1714 	    "\23BIOSFIB"
1715 	    "\24FAST_RESPONSE"
1716 	    "\25APIFIB\n",
1717 	    tbuf,
1718 	    sizeof(tbuf));
1719 
1720 	printf("  XferState       %s\n", tbuf);
1721 	printf("  Command         %d\n", le16toh(fib->Header.Command));
1722 	printf("  StructType      %d\n", fib->Header.StructType);
1723 	printf("  Flags           0x%x\n", fib->Header.Flags);
1724 	printf("  Size            %d\n", le16toh(fib->Header.Size));
1725 	printf("  SenderSize      %d\n", le16toh(fib->Header.SenderSize));
1726 	printf("  SenderAddress   0x%x\n",
1727 	    le32toh(fib->Header.SenderFibAddress));
1728 	printf("  ReceiverAddress 0x%x\n",
1729 	    le32toh(fib->Header.ReceiverFibAddress));
1730 	printf("  SenderData      0x%x\n", fib->Header.SenderData);
1731 
1732 	switch (fib->Header.Command) {
1733 	case ContainerCommand: {
1734 		br = (struct aac_blockread *)fib->data;
1735 		bw = (struct aac_blockwrite *)fib->data;
1736 		sg = NULL;
1737 
1738 		if (le32toh(br->Command) == VM_CtBlockRead) {
1739 			printf("  BlockRead: container %d  0x%x/%d\n",
1740 			    le32toh(br->ContainerId), le32toh(br->BlockNumber),
1741 			    le32toh(br->ByteCount));
1742 			sg = &br->SgMap;
1743 		}
1744 		if (le32toh(bw->Command) == VM_CtBlockWrite) {
1745 			printf("  BlockWrite: container %d  0x%x/%d (%s)\n",
1746 			    le32toh(bw->ContainerId), le32toh(bw->BlockNumber),
1747 			    le32toh(bw->ByteCount),
1748 			    le32toh(bw->Stable) == CSTABLE ?
1749 			    "stable" : "unstable");
1750 			sg = &bw->SgMap;
1751 		}
1752 		if (sg != NULL) {
1753 			printf("  %d s/g entries\n", le32toh(sg->SgCount));
1754 			for (i = 0; i < le32toh(sg->SgCount); i++)
1755 				printf("  0x%08x/%d\n",
1756 				    le32toh(sg->SgEntry[i].SgAddress),
1757 				    le32toh(sg->SgEntry[i].SgByteCount));
1758 		}
1759 		break;
1760 	}
1761 	default:
1762 		// dump first 32 bytes of fib->data
1763 		printf("  Raw data:");
1764 		for (i = 0; i < 32; i++)
1765 			printf(" %02x", fib->data[i]);
1766 		printf("\n");
1767 		break;
1768 	}
1769 }
1770 #endif /* AAC_DEBUG */
1771