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