xref: /netbsd-src/sys/dev/ic/aac.c (revision 8ac07aec990b9d2e483062509d0a9fa5b4f57cf2)
1 /*	$NetBSD: aac.c,v 1.38 2008/04/08 12:07:25 cegger 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.38 2008/04/08 12:07:25 cegger 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_dev(&sc->sc_dv, "cannot create fibs dmamap (%d)\n",
242 		    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_dev(&sc->sc_dv, "can't allocate fibs structure (%d)\n",
250 		    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_dev(&sc->sc_dv, "can't map fibs structure (%d)\n",
258 		    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_dev(&sc->sc_dv, "cannot load fibs dmamap (%d)\n",
266 		    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_dev(&sc->sc_dv, "cannot create ccb dmamap (%d)",
288 			    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_dev(&sc->sc_dv, "RequestAdapterInfo failed\n");
378 		return;
379 	}
380 	if (bufsize != sizeof(*info)) {
381 		aprint_error_dev(&sc->sc_dv,
382 		    "RequestAdapterInfo returned wrong data size (%d != %zu)\n",
383 		    bufsize, sizeof(*info));
384 		return;
385 	}
386 	info = (struct aac_adapter_info *)&tbuf[0];
387 
388 	aprint_normal_dev(&sc->sc_dv, "%s at %dMHz, %dMB mem (%dMB cache), %s\n",
389 	    aac_describe_code(aac_cpu_variant, le32toh(info->CpuVariant)),
390 	    le32toh(info->ClockSpeed),
391 	    le32toh(info->TotalMem) / (1024 * 1024),
392 	    le32toh(info->BufferMem) / (1024 * 1024),
393 	    aac_describe_code(aac_battery_platform,
394 			      le32toh(info->batteryPlatform)));
395 
396 	aprint_verbose_dev(&sc->sc_dv, "Kernel %d.%d-%d [Build %d], ",
397 	    info->KernelRevision.external.comp.major,
398 	    info->KernelRevision.external.comp.minor,
399 	    info->KernelRevision.external.comp.dash,
400 	    info->KernelRevision.buildNumber);
401 
402 	aprint_verbose("Monitor %d.%d-%d [Build %d], S/N %6X\n",
403 	    info->MonitorRevision.external.comp.major,
404 	    info->MonitorRevision.external.comp.minor,
405 	    info->MonitorRevision.external.comp.dash,
406 	    info->MonitorRevision.buildNumber,
407 	    ((u_int32_t)info->SerialNumber & 0xffffff));
408 
409 	aprint_verbose_dev(&sc->sc_dv, "Controller supports: %s\n",
410 	    bitmask_snprintf(sc->sc_supported_options, optfmt, fmtbuf,
411 			     sizeof(fmtbuf)));
412 
413 	/* Save the kernel revision structure for later use. */
414 	sc->sc_revision = info->KernelRevision;
415 }
416 
417 /*
418  * Retrieve the firmware version numbers.  Dell PERC2/QC cards with firmware
419  * version 1.x are not compatible with this driver.
420  */
421 static int
422 aac_check_firmware(struct aac_softc *sc)
423 {
424 	u_int32_t major, minor, opts, atusize = 0, status = 0;
425 	u_int32_t calcsgs;
426 
427 	if ((sc->sc_quirks & AAC_QUIRK_PERC2QC) != 0) {
428 		if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
429 		    NULL)) {
430 			aprint_error_dev(&sc->sc_dv, "error reading firmware version\n");
431 			return (1);
432 		}
433 
434 		/* These numbers are stored as ASCII! */
435 		major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
436 		minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
437 		if (major == 1) {
438 			aprint_error_dev(&sc->sc_dv,
439 			    "firmware version %d.%d not supported.\n",
440 			    major, minor);
441 			return (1);
442 		}
443 	}
444 
445 	if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, &status)) {
446 		if (status != AAC_SRB_STS_INVALID_REQUEST) {
447 			aprint_error_dev(&sc->sc_dv, "GETINFO failed, status 0x%08x\n", status);
448 			return (1);
449 		}
450 	} else {
451 		opts = AAC_GET_MAILBOX(sc, 1);
452 		atusize = AAC_GET_MAILBOX(sc, 2);
453 		sc->sc_supported_options = opts;
454 
455 		if (((opts & AAC_SUPPORTED_4GB_WINDOW) != 0) &&
456 		    ((sc->sc_quirks & AAC_QUIRK_NO4GB) == 0) )
457 			sc->sc_quirks |= AAC_QUIRK_4GB_WINDOW;
458 
459 		if (((opts & AAC_SUPPORTED_SGMAP_HOST64) != 0) &&
460 		    (sizeof(bus_addr_t) > 4)) {
461 			aprint_normal_dev(&sc->sc_dv, "Enabling 64-bit address support\n");
462 			sc->sc_quirks |= AAC_QUIRK_SG_64BIT;
463 		}
464 		if ((opts & AAC_SUPPORTED_NEW_COMM) &&
465 		    (sc->sc_if.aif_send_command != NULL)) {
466 			sc->sc_quirks |= AAC_QUIRK_NEW_COMM;
467 		}
468 #ifdef notyet
469 		if (opts & AAC_SUPPORTED_64BIT_ARRAYSIZE)
470 			sc->sc_quirks |= AAC_QUIRK_ARRAY_64BIT;
471 #endif
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 	return (0);
549 }
550 
551 static int
552 aac_init(struct aac_softc *sc)
553 {
554 	int nsegs, i, rv, state, norm, high;
555 	struct aac_adapter_init	*ip;
556 	u_int32_t code, qoff;
557 
558 	state = 0;
559 
560 	/*
561 	 * First wait for the adapter to come ready.
562 	 */
563 	for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) {
564 		code = AAC_GET_FWSTATUS(sc);
565 		if ((code & AAC_SELF_TEST_FAILED) != 0) {
566 			aprint_error_dev(&sc->sc_dv, "FATAL: selftest failed\n");
567 			return (ENXIO);
568 		}
569 		if ((code & AAC_KERNEL_PANIC) != 0) {
570 			aprint_error_dev(&sc->sc_dv, "FATAL: controller kernel panic\n");
571 			return (ENXIO);
572 		}
573 		if ((code & AAC_UP_AND_RUNNING) != 0)
574 			break;
575 		DELAY(1000);
576 	}
577 	if (i == AAC_BOOT_TIMEOUT * 1000) {
578 		aprint_error_dev(&sc->sc_dv,
579 		    "FATAL: controller not coming ready, status %x\n",
580 		    code);
581 		return (ENXIO);
582 	}
583 
584 	sc->sc_aif_fib = malloc(sizeof(struct aac_fib), M_AACBUF,
585 	    M_NOWAIT | M_ZERO);
586 	if (sc->sc_aif_fib == NULL) {
587 		aprint_error_dev(&sc->sc_dv, "cannot alloc fib structure\n");
588 		return (ENOMEM);
589 	}
590 	if ((rv = bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_common), 1,
591 	    sizeof(*sc->sc_common), 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
592 	    &sc->sc_common_dmamap)) != 0) {
593 		aprint_error_dev(&sc->sc_dv, "cannot create common dmamap\n");
594 		goto bail_out;
595 	}
596 	state++;
597 	if ((rv = bus_dmamem_alloc(sc->sc_dmat, sizeof(*sc->sc_common),
598 	    PAGE_SIZE, 0, &sc->sc_common_seg, 1, &nsegs,
599 	    BUS_DMA_NOWAIT)) != 0) {
600 		aprint_error_dev(&sc->sc_dv, "can't allocate common structure\n");
601 		goto bail_out;
602 	}
603 	state++;
604 	if ((rv = bus_dmamem_map(sc->sc_dmat, &sc->sc_common_seg, nsegs,
605 	    sizeof(*sc->sc_common), (void **)&sc->sc_common, 0)) != 0) {
606 		aprint_error_dev(&sc->sc_dv, "can't map common structure\n");
607 		goto bail_out;
608 	}
609 	state++;
610 	if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_common_dmamap,
611 	    sc->sc_common, sizeof(*sc->sc_common), NULL,
612 	    BUS_DMA_NOWAIT)) != 0) {
613 		aprint_error_dev(&sc->sc_dv, "cannot load common dmamap\n");
614 		goto bail_out;
615 	}
616 	state++;
617 
618 	memset(sc->sc_common, 0, sizeof(*sc->sc_common));
619 
620 	TAILQ_INIT(&sc->sc_fibmap_tqh);
621 	sc->sc_ccbs = malloc(sizeof(struct aac_ccb) * sc->sc_max_fibs, M_AACBUF,
622 	    M_NOWAIT | M_ZERO);
623 	if (sc->sc_ccbs == NULL) {
624 		aprint_error_dev(&sc->sc_dv, "memory allocation failure getting ccbs\n");
625 		rv = ENOMEM;
626 		goto bail_out;
627 	}
628 	state++;
629 	while (sc->sc_total_fibs < AAC_PREALLOCATE_FIBS(sc)) {
630 		if (aac_alloc_commands(sc) != 0)
631 			break;
632 	}
633 	if (sc->sc_total_fibs == 0)
634 		goto bail_out;
635 
636 	/*
637 	 * Fill in the init structure.  This tells the adapter about the
638 	 * physical location of various important shared data structures.
639 	 */
640 	ip = &sc->sc_common->ac_init;
641 	ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION);
642 	if (sc->sc_max_fib_size > sizeof(struct aac_fib)) {
643 		ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION_4);
644 		sc->sc_quirks |= AAC_QUIRK_RAW_IO;
645 	}
646 	ip->MiniPortRevision = htole32(AAC_INIT_STRUCT_MINIPORT_REVISION);
647 
648 	ip->AdapterFibsPhysicalAddress = htole32(sc->sc_common_seg.ds_addr +
649 	    offsetof(struct aac_common, ac_fibs));
650 	ip->AdapterFibsVirtualAddress = 0;
651 	ip->AdapterFibsSize =
652 	    htole32(AAC_ADAPTER_FIBS * sizeof(struct aac_fib));
653 	ip->AdapterFibAlign = htole32(sizeof(struct aac_fib));
654 
655 	ip->PrintfBufferAddress = htole32(sc->sc_common_seg.ds_addr +
656 	    offsetof(struct aac_common, ac_printf));
657 	ip->PrintfBufferSize = htole32(AAC_PRINTF_BUFSIZE);
658 
659 	/*
660 	 * The adapter assumes that pages are 4K in size, except on some
661 	 * broken firmware versions that do the page->byte conversion twice,
662 	 * therefore 'assuming' that this value is in 16MB units (2^24).
663 	 * Round up since the granularity is so high.
664 	 */
665 	ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
666 	if (sc->sc_quirks & AAC_QUIRK_BROKEN_MMAP) {
667 		ip->HostPhysMemPages =
668 		    (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
669 	}
670 	ip->HostElapsedSeconds = 0;	/* reset later if invalid */
671 
672 	ip->InitFlags = 0;
673 	if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) {
674 		ip->InitFlags = htole32(AAC_INITFLAGS_NEW_COMM_SUPPORTED);
675 		aprint_normal_dev(&sc->sc_dv, "New comm. interface enabled\n");
676 	}
677 
678 	ip->MaxIoCommands = htole32(sc->sc_max_fibs);
679 	ip->MaxIoSize = htole32(sc->sc_max_sectors << 9);
680 	ip->MaxFibSize = htole32(sc->sc_max_fib_size);
681 
682 	/*
683 	 * Initialise FIB queues.  Note that it appears that the layout of
684 	 * the indexes and the segmentation of the entries is mandated by
685 	 * the adapter, which is only told about the base of the queue index
686 	 * fields.
687 	 *
688 	 * The initial values of the indices are assumed to inform the
689 	 * adapter of the sizes of the respective queues.
690 	 *
691 	 * The Linux driver uses a much more complex scheme whereby several
692 	 * header records are kept for each queue.  We use a couple of
693 	 * generic list manipulation functions which 'know' the size of each
694 	 * list by virtue of a table.
695 	 */
696 	qoff = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
697 	qoff &= ~(AAC_QUEUE_ALIGN - 1);
698 	sc->sc_queues = (struct aac_queue_table *)((uintptr_t)sc->sc_common + qoff);
699 	ip->CommHeaderAddress = htole32(sc->sc_common_seg.ds_addr +
700 	    ((char *)sc->sc_queues - (char *)sc->sc_common));
701 	memset(sc->sc_queues, 0, sizeof(struct aac_queue_table));
702 
703 	norm = htole32(AAC_HOST_NORM_CMD_ENTRIES);
704 	high = htole32(AAC_HOST_HIGH_CMD_ENTRIES);
705 
706 	sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
707 	    norm;
708 	sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
709 	    norm;
710 	sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
711 	    high;
712 	sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
713 	    high;
714 
715 	norm = htole32(AAC_ADAP_NORM_CMD_ENTRIES);
716 	high = htole32(AAC_ADAP_HIGH_CMD_ENTRIES);
717 
718 	sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
719 	    norm;
720 	sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
721 	    norm;
722 	sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
723 	    high;
724 	sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
725 	    high;
726 
727 	norm = htole32(AAC_HOST_NORM_RESP_ENTRIES);
728 	high = htole32(AAC_HOST_HIGH_RESP_ENTRIES);
729 
730 	sc->sc_queues->
731 	    qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm;
732 	sc->sc_queues->
733 	    qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm;
734 	sc->sc_queues->
735 	    qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high;
736 	sc->sc_queues->
737 	    qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high;
738 
739 	norm = htole32(AAC_ADAP_NORM_RESP_ENTRIES);
740 	high = htole32(AAC_ADAP_HIGH_RESP_ENTRIES);
741 
742 	sc->sc_queues->
743 	    qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm;
744 	sc->sc_queues->
745 	    qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm;
746 	sc->sc_queues->
747 	    qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high;
748 	sc->sc_queues->
749 	    qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high;
750 
751 	sc->sc_qentries[AAC_HOST_NORM_CMD_QUEUE] =
752 	    &sc->sc_queues->qt_HostNormCmdQueue[0];
753 	sc->sc_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
754 	    &sc->sc_queues->qt_HostHighCmdQueue[0];
755 	sc->sc_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
756 	    &sc->sc_queues->qt_AdapNormCmdQueue[0];
757 	sc->sc_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
758 	    &sc->sc_queues->qt_AdapHighCmdQueue[0];
759 	sc->sc_qentries[AAC_HOST_NORM_RESP_QUEUE] =
760 	    &sc->sc_queues->qt_HostNormRespQueue[0];
761 	sc->sc_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
762 	    &sc->sc_queues->qt_HostHighRespQueue[0];
763 	sc->sc_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
764 	    &sc->sc_queues->qt_AdapNormRespQueue[0];
765 	sc->sc_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
766 	    &sc->sc_queues->qt_AdapHighRespQueue[0];
767 
768 	/*
769 	 * Do controller-type-specific initialisation
770 	 */
771 	switch (sc->sc_hwif) {
772 	case AAC_HWIF_I960RX:
773 		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
774 		break;
775 	}
776 
777 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 0,
778 	    sizeof(*sc->sc_common),
779 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
780 
781 	/*
782 	 * Give the init structure to the controller.
783 	 */
784 	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
785 	    sc->sc_common_seg.ds_addr + offsetof(struct aac_common, ac_init),
786 	    0, 0, 0, NULL)) {
787 		aprint_error_dev(&sc->sc_dv, "error establishing init structure\n");
788 		rv = EIO;
789 		goto bail_out;
790 	}
791 
792 	return (0);
793 
794  bail_out:
795  	if (state > 4)
796  		free(sc->sc_ccbs, M_AACBUF);
797  	if (state > 3)
798  		bus_dmamap_unload(sc->sc_dmat, sc->sc_common_dmamap);
799 	if (state > 2)
800 		bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_common,
801 		    sizeof(*sc->sc_common));
802 	if (state > 1)
803 		bus_dmamem_free(sc->sc_dmat, &sc->sc_common_seg, 1);
804 	if (state > 0)
805 		bus_dmamap_destroy(sc->sc_dmat, sc->sc_common_dmamap);
806 
807 	free(sc->sc_aif_fib, M_AACBUF);
808 
809 	return (rv);
810 }
811 
812 /*
813  * Probe for containers, create disks.
814  */
815 static void
816 aac_startup(struct aac_softc *sc)
817 {
818 	struct aac_mntinfo mi;
819 	struct aac_mntinforesponse mir;
820 	struct aac_drive *hd;
821 	u_int16_t rsize;
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 		mi.Command = htole32(VM_NameServe);
835 		mi.MntType = htole32(FT_FILESYS);
836 		mi.MntCount = htole32(i);
837 		if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(mi), &mir,
838 		    &rsize)) {
839 			aprint_error_dev(&sc->sc_dv, "error probing container %d\n", i);
840 			continue;
841 		}
842 		if (rsize != sizeof(mir)) {
843 			aprint_error_dev(&sc->sc_dv, "container info response wrong size "
844 			    "(%d should be %zu)\n", rsize, sizeof(mir));
845 			continue;
846 		}
847 
848 		/*
849 		 * Check container volume type for validity.  Note that many
850 		 * of the possible types may never show up.
851 		 */
852 		if (le32toh(mir.Status) != ST_OK ||
853 		    le32toh(mir.MntTable[0].VolType) == CT_NONE)
854 			continue;
855 
856 		hd->hd_present = 1;
857 		hd->hd_size = le32toh(mir.MntTable[0].Capacity);
858 		hd->hd_devtype = le32toh(mir.MntTable[0].VolType);
859 		hd->hd_size &= ~0x1f;
860 		sc->sc_nunits++;
861 	}
862 }
863 
864 static void
865 aac_shutdown(void *cookie)
866 {
867 	struct aac_softc *sc;
868 	struct aac_close_command cc;
869 	u_int32_t i;
870 
871 	for (i = 0; i < aac_cd.cd_ndevs; i++) {
872 		if ((sc = device_lookup(&aac_cd, i)) == NULL)
873 			continue;
874 		if ((sc->sc_flags & AAC_ONLINE) == 0)
875 			continue;
876 
877 		AAC_MASK_INTERRUPTS(sc);
878 
879 		/*
880 		 * Send a Container shutdown followed by a HostShutdown FIB
881 		 * to the controller to convince it that we don't want to
882 		 * talk to it anymore.  We've been closed and all I/O
883 		 * completed already
884 		 */
885 		memset(&cc, 0, sizeof(cc));
886 		cc.Command = htole32(VM_CloseAll);
887 		cc.ContainerId = 0xffffffff;
888 		if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc),
889 		    NULL, NULL)) {
890 			aprint_error_dev(&sc->sc_dv, "unable to halt controller\n");
891 			continue;
892 		}
893 
894 		/*
895 		 * Note that issuing this command to the controller makes it
896 		 * shut down but also keeps it from coming back up without a
897 		 * reset of the PCI bus.
898 		 */
899 		if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
900 		    &i, sizeof(i), NULL, NULL))
901 			aprint_error_dev(&sc->sc_dv, "unable to halt controller\n");
902 
903 		sc->sc_flags &= ~AAC_ONLINE;
904 	}
905 }
906 
907 static int
908 aac_new_intr(void *cookie)
909 {
910 	struct aac_softc *sc;
911 	u_int32_t index, fast;
912 	struct aac_ccb *ac;
913 	struct aac_fib *fib;
914 	struct aac_fibmap *fm;
915 	int i;
916 
917 	sc = (struct aac_softc *) cookie;
918 
919 	for (;;) {
920 		index = AAC_GET_OUTB_QUEUE(sc);
921 		if (index == 0xffffffff)
922 			index = AAC_GET_OUTB_QUEUE(sc);
923 		if (index == 0xffffffff)
924 			break;
925 		if (index & 2) {
926 			if (index == 0xfffffffe) {
927 				/* XXX This means that the controller wants
928 				 * more work.  Ignore it for now.
929 				 */
930 				continue;
931 			}
932 			/* AIF */
933 			index &= ~2;
934 			fib = sc->sc_aif_fib;
935 			for (i = 0; i < sizeof(struct aac_fib)/4; i++) {
936 				((u_int32_t*)fib)[i] =
937 				    AAC_GETREG4(sc, index + i*4);
938 			}
939 #ifdef notyet
940 			aac_handle_aif(sc, &fib);
941 #endif
942 
943 			AAC_SET_OUTB_QUEUE(sc, index);
944 			AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
945 		} else {
946 			fast = index & 1;
947 			ac = sc->sc_ccbs + (index >> 2);
948 			fib = ac->ac_fib;
949 			fm = ac->ac_fibmap;
950 			if (fast) {
951 				bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap,
952 				    (char *)fib - (char *)fm->fm_fibs,
953 				    sc->sc_max_fib_size,
954 				    BUS_DMASYNC_POSTWRITE |
955 				    BUS_DMASYNC_POSTREAD);
956 				fib->Header.XferState |=
957 				    htole32(AAC_FIBSTATE_DONEADAP);
958 				*((u_int32_t *)(fib->data)) =
959 				    htole32(AAC_ERROR_NORMAL);
960 			}
961 			ac->ac_flags |= AAC_CCB_COMPLETED;
962 
963 			if (ac->ac_intr != NULL)
964 				(*ac->ac_intr)(ac);
965 			else
966 				wakeup(ac);
967 		}
968 	}
969 
970 	/*
971 	 * Try to submit more commands.
972 	 */
973 	if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue))
974 		aac_ccb_enqueue(sc, NULL);
975 
976 	return 1;
977 }
978 
979 /*
980  * Take an interrupt.
981  */
982 int
983 aac_intr(void *cookie)
984 {
985 	struct aac_softc *sc;
986 	u_int16_t reason;
987 	int claimed;
988 
989 	sc = cookie;
990 	claimed = 0;
991 
992 	AAC_DPRINTF(AAC_D_INTR, ("aac_intr(%p) ", sc));
993 
994 	reason = AAC_GET_ISTATUS(sc);
995 	AAC_CLEAR_ISTATUS(sc, reason);
996 
997 	AAC_DPRINTF(AAC_D_INTR, ("istatus 0x%04x ", reason));
998 
999 	/*
1000 	 * Controller wants to talk to the log.  XXX Should we defer this?
1001 	 */
1002 	if ((reason & AAC_DB_PRINTF) != 0) {
1003 		if (sc->sc_common->ac_printf[0] == '\0')
1004 			sc->sc_common->ac_printf[0] = ' ';
1005 		printf("%s: WARNING: adapter logged message:\n",
1006 			device_xname(&sc->sc_dv));
1007 		printf("%s:     %.*s", device_xname(&sc->sc_dv),
1008 			AAC_PRINTF_BUFSIZE, sc->sc_common->ac_printf);
1009 		sc->sc_common->ac_printf[0] = '\0';
1010 		AAC_QNOTIFY(sc, AAC_DB_PRINTF);
1011 		claimed = 1;
1012 	}
1013 
1014 	/*
1015 	 * Controller has a message for us?
1016 	 */
1017 	if ((reason & AAC_DB_COMMAND_READY) != 0) {
1018 		aac_host_command(sc);
1019 		claimed = 1;
1020 	}
1021 
1022 	/*
1023 	 * Controller has a response for us?
1024 	 */
1025 	if ((reason & AAC_DB_RESPONSE_READY) != 0) {
1026 		aac_host_response(sc);
1027 		claimed = 1;
1028 	}
1029 
1030 	/*
1031 	 * Spurious interrupts that we don't use - reset the mask and clear
1032 	 * the interrupts.
1033 	 */
1034 	if ((reason & (AAC_DB_SYNC_COMMAND | AAC_DB_COMMAND_NOT_FULL |
1035             AAC_DB_RESPONSE_NOT_FULL)) != 0) {
1036 		AAC_UNMASK_INTERRUPTS(sc);
1037 		AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND |
1038 		    AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL);
1039 		claimed = 1;
1040 	}
1041 
1042 	return (claimed);
1043 }
1044 
1045 /*
1046  * Handle notification of one or more FIBs coming from the controller.
1047  */
1048 static void
1049 aac_host_command(struct aac_softc *sc)
1050 {
1051 	struct aac_fib *fib;
1052 	u_int32_t fib_size;
1053 
1054 	for (;;) {
1055 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size,
1056 		    &fib))
1057 			break;	/* nothing to do */
1058 
1059 		bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1060 		    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
1061 		    BUS_DMASYNC_POSTREAD);
1062 
1063 		switch (le16toh(fib->Header.Command)) {
1064 		case AifRequest:
1065 #ifdef notyet
1066 			aac_handle_aif(sc,
1067 			    (struct aac_aif_command *)&fib->data[0]);
1068 #endif
1069 			AAC_PRINT_FIB(sc, fib);
1070 			break;
1071 		default:
1072 			aprint_error_dev(&sc->sc_dv, "unknown command from controller\n");
1073 			AAC_PRINT_FIB(sc, fib);
1074 			break;
1075 		}
1076 
1077 		bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1078 		    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
1079 		    BUS_DMASYNC_PREREAD);
1080 
1081 		if ((fib->Header.XferState == 0) ||
1082 		    (fib->Header.StructType != AAC_FIBTYPE_TFIB)) {
1083 			break; // continue; ???
1084 		}
1085 
1086 		/* XXX reply to FIBs requesting responses ?? */
1087 
1088 		/* Return the AIF/FIB to the controller */
1089 		if (le32toh(fib->Header.XferState) & AAC_FIBSTATE_FROMADAP) {
1090 			u_int16_t	size;
1091 
1092 			fib->Header.XferState |=
1093 				htole32(AAC_FIBSTATE_DONEHOST);
1094 			*(u_int32_t*)fib->data = htole32(ST_OK);
1095 
1096 			/* XXX Compute the Size field? */
1097 			size = le16toh(fib->Header.Size);
1098 			if (size > sizeof(struct aac_fib)) {
1099 				size = sizeof(struct aac_fib);
1100 				fib->Header.Size = htole16(size);
1101 			}
1102 
1103 			/*
1104 			 * Since we didn't generate this command, it can't
1105 			 * go through the normal process.
1106 			 */
1107 			aac_enqueue_response(sc,
1108 					AAC_ADAP_NORM_RESP_QUEUE, fib);
1109 		}
1110 	}
1111 }
1112 
1113 /*
1114  * Handle notification of one or more FIBs completed by the controller
1115  */
1116 static void
1117 aac_host_response(struct aac_softc *sc)
1118 {
1119 	struct aac_ccb *ac;
1120 	struct aac_fib *fib;
1121 	u_int32_t fib_size;
1122 
1123 	/*
1124 	 * Look for completed FIBs on our queue.
1125 	 */
1126 	for (;;) {
1127 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
1128 		    &fib))
1129 			break;	/* nothing to do */
1130 
1131 		if ((fib->Header.SenderData & 0x80000000) == 0) {
1132 			/* Not valid; not sent by us. */
1133 			AAC_PRINT_FIB(sc, fib);
1134 		} else {
1135 			ac = (struct aac_ccb *)(sc->sc_ccbs +
1136 			    (fib->Header.SenderData & 0x7fffffff));
1137 			fib->Header.SenderData = 0;
1138 			SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_complete, ac, ac_chain);
1139 		}
1140 	}
1141 
1142 	/*
1143 	 * Deal with any completed commands.
1144 	 */
1145 	while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_complete)) != NULL) {
1146 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_complete, ac_chain);
1147 		ac->ac_flags |= AAC_CCB_COMPLETED;
1148 
1149 		if (ac->ac_intr != NULL)
1150 			(*ac->ac_intr)(ac);
1151 		else
1152 			wakeup(ac);
1153 	}
1154 
1155 	/*
1156 	 * Try to submit more commands.
1157 	 */
1158 	if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue))
1159 		aac_ccb_enqueue(sc, NULL);
1160 }
1161 
1162 /*
1163  * Send a synchronous command to the controller and wait for a result.
1164  */
1165 static int
1166 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1167 		 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp)
1168 {
1169 	int i;
1170 	u_int32_t status;
1171 	int s;
1172 
1173 	s = splbio();
1174 
1175 	/* Populate the mailbox. */
1176 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1177 
1178 	/* Ensure the sync command doorbell flag is cleared. */
1179 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1180 
1181 	/* ... then set it to signal the adapter. */
1182 	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1183 	DELAY(AAC_SYNC_DELAY);
1184 
1185 	/* Spin waiting for the command to complete. */
1186 	for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) {
1187 		if (AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND)
1188 			break;
1189 		DELAY(1000);
1190 	}
1191 	if (i == AAC_IMMEDIATE_TIMEOUT * 1000) {
1192 		splx(s);
1193 		return (EIO);
1194 	}
1195 
1196 	/* Clear the completion flag. */
1197 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1198 
1199 	/* Get the command status. */
1200 	status = AAC_GET_MAILBOXSTATUS(sc);
1201 	splx(s);
1202 	if (sp != NULL)
1203 		*sp = status;
1204 
1205 	return (0);	/* XXX Check command return status? */
1206 }
1207 
1208 /*
1209  * Send a synchronous FIB to the controller and wait for a result.
1210  */
1211 static int
1212 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1213 	     void *data, u_int16_t datasize, void *result,
1214 	     u_int16_t *resultsize)
1215 {
1216 	struct aac_fib *fib;
1217 	u_int32_t fibpa, status;
1218 
1219 	fib = &sc->sc_common->ac_sync_fib;
1220 	fibpa = sc->sc_common_seg.ds_addr +
1221 	    offsetof(struct aac_common, ac_sync_fib);
1222 
1223 	if (datasize > AAC_FIB_DATASIZE)
1224 		return (EINVAL);
1225 
1226 	/*
1227 	 * Set up the sync FIB.
1228 	 */
1229 	fib->Header.XferState = htole32(AAC_FIBSTATE_HOSTOWNED |
1230 	    AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY | xferstate);
1231 	fib->Header.Command = htole16(command);
1232 	fib->Header.StructType = AAC_FIBTYPE_TFIB;
1233 	fib->Header.Size = htole16(sizeof(*fib) + datasize);
1234 	fib->Header.SenderSize = htole16(sizeof(*fib));
1235 	fib->Header.SenderFibAddress = 0; /* not needed */
1236 	fib->Header.ReceiverFibAddress = htole32(fibpa);
1237 
1238 	/*
1239 	 * Copy in data.
1240 	 */
1241 	if (data != NULL) {
1242 		memcpy(fib->data, data, datasize);
1243 		fib->Header.XferState |=
1244 		    htole32(AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM);
1245 	}
1246 
1247 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1248 	    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
1249 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1250 
1251 	/*
1252 	 * Give the FIB to the controller, wait for a response.
1253 	 */
1254 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fibpa, 0, 0, 0, &status))
1255 		return (EIO);
1256 	if (status != 1) {
1257 		printf("%s: syncfib command %04x status %08x\n",
1258 			device_xname(&sc->sc_dv), command, status);
1259 	}
1260 
1261 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1262 	    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
1263 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1264 
1265 	/*
1266 	 * Copy out the result
1267 	 */
1268 	if (result != NULL) {
1269 		*resultsize = le16toh(fib->Header.Size) - sizeof(fib->Header);
1270 		memcpy(result, fib->data, *resultsize);
1271 	}
1272 
1273 	return (0);
1274 }
1275 
1276 struct aac_ccb *
1277 aac_ccb_alloc(struct aac_softc *sc, int flags)
1278 {
1279 	struct aac_ccb *ac;
1280 	int s;
1281 
1282 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_alloc(%p, 0x%x) ", sc, flags));
1283 
1284 	s = splbio();
1285 	ac = SIMPLEQ_FIRST(&sc->sc_ccb_free);
1286 	if (ac == NULL) {
1287 		if (aac_alloc_commands(sc)) {
1288 			splx(s);
1289 			return NULL;
1290 		}
1291 		ac = SIMPLEQ_FIRST(&sc->sc_ccb_free);
1292 	}
1293 #ifdef DIAGNOSTIC
1294 	if (ac == NULL)
1295 		panic("aac_ccb_get: no free CCBS");
1296 #endif
1297 	SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ac_chain);
1298 	splx(s);
1299 
1300 	ac->ac_flags = flags;
1301 	return (ac);
1302 }
1303 
1304 void
1305 aac_ccb_free(struct aac_softc *sc, struct aac_ccb *ac)
1306 {
1307 	int s;
1308 
1309 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_free(%p, %p) ", sc, ac));
1310 
1311 	ac->ac_flags = 0;
1312 	ac->ac_intr = NULL;
1313 	ac->ac_fib->Header.XferState = htole32(AAC_FIBSTATE_EMPTY);
1314 	ac->ac_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1315 	ac->ac_fib->Header.Flags = 0;
1316 	ac->ac_fib->Header.SenderSize = htole16(sc->sc_max_fib_size);
1317 
1318 #ifdef AAC_DEBUG
1319 	/*
1320 	 * These are duplicated in aac_ccb_submit() to cover the case where
1321 	 * an intermediate stage may have destroyed them.  They're left
1322 	 * initialised here for debugging purposes only.
1323 	 */
1324 	ac->ac_fib->Header.SenderFibAddress =
1325 	    htole32(((u_int32_t) (ac - sc->sc_ccbs)) << 2);
1326 	ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
1327 #endif
1328 
1329 	s = splbio();
1330 	SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ac, ac_chain);
1331 	splx(s);
1332 }
1333 
1334 int
1335 aac_ccb_map(struct aac_softc *sc, struct aac_ccb *ac)
1336 {
1337 	int error;
1338 
1339 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_map(%p, %p) ", sc, ac));
1340 
1341 #ifdef DIAGNOSTIC
1342 	if ((ac->ac_flags & AAC_CCB_MAPPED) != 0)
1343 		panic("aac_ccb_map: already mapped");
1344 #endif
1345 
1346 	error = bus_dmamap_load(sc->sc_dmat, ac->ac_dmamap_xfer, ac->ac_data,
1347 	    ac->ac_datalen, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
1348 	    ((ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE));
1349 	if (error) {
1350 		printf("%s: aac_ccb_map: ", device_xname(&sc->sc_dv));
1351 		if (error == EFBIG)
1352 			printf("more than %d DMA segs\n", sc->sc_max_sgs);
1353 		else
1354 			printf("error %d loading DMA map\n", error);
1355 		return (error);
1356 	}
1357 
1358 	bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
1359 	    (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_PREREAD :
1360 	    BUS_DMASYNC_PREWRITE);
1361 
1362 #ifdef DIAGNOSTIC
1363 	ac->ac_flags |= AAC_CCB_MAPPED;
1364 #endif
1365 	return (0);
1366 }
1367 
1368 void
1369 aac_ccb_unmap(struct aac_softc *sc, struct aac_ccb *ac)
1370 {
1371 
1372 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_unmap(%p, %p) ", sc, ac));
1373 
1374 #ifdef DIAGNOSTIC
1375 	if ((ac->ac_flags & AAC_CCB_MAPPED) == 0)
1376 		panic("aac_ccb_unmap: not mapped");
1377 #endif
1378 
1379 	bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
1380 	    (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_POSTREAD :
1381 	    BUS_DMASYNC_POSTWRITE);
1382 	bus_dmamap_unload(sc->sc_dmat, ac->ac_dmamap_xfer);
1383 
1384 #ifdef DIAGNOSTIC
1385 	ac->ac_flags &= ~AAC_CCB_MAPPED;
1386 #endif
1387 }
1388 
1389 void
1390 aac_ccb_enqueue(struct aac_softc *sc, struct aac_ccb *ac)
1391 {
1392 	int s;
1393 
1394 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_enqueue(%p, %p) ", sc, ac));
1395 
1396 	s = splbio();
1397 
1398 	if (ac != NULL)
1399 		SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ac, ac_chain);
1400 
1401 	while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) {
1402 		if (aac_ccb_submit(sc, ac))
1403 			break;
1404 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ac_chain);
1405 	}
1406 
1407 	splx(s);
1408 }
1409 
1410 int
1411 aac_ccb_submit(struct aac_softc *sc, struct aac_ccb *ac)
1412 {
1413 	struct aac_fibmap *fm;
1414 	u_int32_t acidx;
1415 
1416 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_submit(%p, %p) ", sc, ac));
1417 
1418 	acidx = (u_int32_t) (ac - sc->sc_ccbs);
1419 	/* Fix up the address values. */
1420 	ac->ac_fib->Header.SenderFibAddress = htole32(acidx << 2);
1421 	ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
1422 
1423 	/* Save a pointer to the command for speedy reverse-lookup. */
1424 	ac->ac_fib->Header.SenderData = acidx | 0x80000000;
1425 
1426 	fm = ac->ac_fibmap;
1427 	bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap,
1428 	    (char *)ac->ac_fib - (char *)fm->fm_fibs, sc->sc_max_fib_size,
1429 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1430 
1431 	/* Put the FIB on the outbound queue. */
1432 	if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) {
1433 		int count = 10000000L;
1434 		while (AAC_SEND_COMMAND(sc, ac) != 0) {
1435 			if (--count == 0) {
1436 				panic("aac: fixme!");
1437 				return EAGAIN;
1438 			}
1439 			DELAY(5);
1440 		}
1441 		return 0;
1442 	} else {
1443 		return (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, ac));
1444 	}
1445 }
1446 
1447 int
1448 aac_ccb_poll(struct aac_softc *sc, struct aac_ccb *ac, int timo)
1449 {
1450 	int rv, s;
1451 
1452 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_poll(%p, %p, %d) ", sc, ac, timo));
1453 
1454 	s = splbio();
1455 
1456 	if ((rv = aac_ccb_submit(sc, ac)) != 0) {
1457 		splx(s);
1458 		return (rv);
1459 	}
1460 
1461 	for (timo *= 1000; timo != 0; timo--) {
1462 		if (sc->sc_quirks & AAC_QUIRK_NEW_COMM)
1463 			aac_new_intr(sc);
1464 		else
1465 			aac_intr(sc);
1466 		if ((ac->ac_flags & AAC_CCB_COMPLETED) != 0)
1467 			break;
1468 		DELAY(100);
1469 	}
1470 
1471 	splx(s);
1472 	return (timo == 0);
1473 }
1474 
1475 /*
1476  * Atomically insert an entry into the nominated queue, returns 0 on success
1477  * or EBUSY if the queue is full.
1478  *
1479  * XXX Note that it would be more efficient to defer notifying the
1480  * controller in the case where we may be inserting several entries in rapid
1481  * succession, but implementing this usefully is difficult.
1482  */
1483 static int
1484 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_ccb *ac)
1485 {
1486 	u_int32_t fib_size, fib_addr, pi, ci;
1487 
1488 	fib_size = le16toh(ac->ac_fib->Header.Size);
1489 	fib_addr = le32toh(ac->ac_fib->Header.ReceiverFibAddress);
1490 
1491 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1492 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1493 	    sizeof(sc->sc_common->ac_qbuf),
1494 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1495 
1496 	/* Get the producer/consumer indices.  */
1497 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
1498 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
1499 
1500 	/* Wrap the queue? */
1501 	if (pi >= aac_qinfo[queue].size)
1502 		pi = 0;
1503 
1504 	/* Check for queue full. */
1505 	if ((pi + 1) == ci)
1506 		return (EAGAIN);
1507 
1508 	/* Populate queue entry. */
1509 	(sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size);
1510 	(sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr);
1511 
1512 	/* Update producer index. */
1513 	sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1);
1514 
1515 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1516 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1517 	    sizeof(sc->sc_common->ac_qbuf),
1518 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1519 
1520 	/* Notify the adapter if we know how. */
1521 	if (aac_qinfo[queue].notify != 0)
1522 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1523 
1524 	return (0);
1525 }
1526 
1527 /*
1528  * Atomically remove one entry from the nominated queue, returns 0 on success
1529  * or ENOENT if the queue is empty.
1530  */
1531 static int
1532 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1533 		struct aac_fib **fib_addr)
1534 {
1535 	struct aac_fibmap *fm;
1536 	struct aac_ccb *ac;
1537 	u_int32_t pi, ci, idx;
1538 	int notify;
1539 
1540 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1541 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1542 	    sizeof(sc->sc_common->ac_qbuf),
1543 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1544 
1545 	/* Get the producer/consumer indices. */
1546 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
1547 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
1548 
1549 	/* Check for queue empty. */
1550 	if (ci == pi)
1551 		return (ENOENT);
1552 
1553 	notify = 0;
1554 	if (ci == pi + 1)
1555 		notify = 1;
1556 
1557 	/* Wrap the queue? */
1558 	if (ci >= aac_qinfo[queue].size)
1559 		ci = 0;
1560 
1561 	/* Fetch the entry. */
1562 	*fib_size = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_size);
1563 
1564 	switch (queue) {
1565 	case AAC_HOST_NORM_CMD_QUEUE:
1566 	case AAC_HOST_HIGH_CMD_QUEUE:
1567 		idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr);
1568 		idx /= sizeof(struct aac_fib);
1569 		*fib_addr = &sc->sc_common->ac_fibs[idx];
1570 		break;
1571 	case AAC_HOST_NORM_RESP_QUEUE:
1572 	case AAC_HOST_HIGH_RESP_QUEUE:
1573 		idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr);
1574 		ac = sc->sc_ccbs + (idx >> 2);
1575 		*fib_addr = ac->ac_fib;
1576 		if (idx & 0x01) {
1577 			fm = ac->ac_fibmap;
1578 			bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap,
1579 			    (char *)ac->ac_fib - (char *)fm->fm_fibs,
1580 			    sc->sc_max_fib_size,
1581 			    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1582 			ac->ac_fib->Header.XferState |=
1583 				htole32(AAC_FIBSTATE_DONEADAP);
1584 			*((u_int32_t*)(ac->ac_fib->data)) =
1585 				htole32(AAC_ERROR_NORMAL);
1586 		}
1587 		break;
1588 	default:
1589 		panic("Invalid queue in aac_dequeue_fib()");
1590 		break;
1591 	}
1592 
1593 	/* Update consumer index. */
1594 	sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1595 
1596 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1597 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1598 	    sizeof(sc->sc_common->ac_qbuf),
1599 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1600 
1601 	/* If we have made the queue un-full, notify the adapter. */
1602 	if (notify && (aac_qinfo[queue].notify != 0))
1603 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1604 
1605 	return (0);
1606 }
1607 
1608 /*
1609  * Put our response to an adapter-initiated fib (AIF) on the response queue.
1610  */
1611 static int
1612 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
1613 {
1614 	u_int32_t fib_size, fib_addr, pi, ci;
1615 
1616 	fib_size = le16toh(fib->Header.Size);
1617 	fib_addr = fib->Header.SenderFibAddress;
1618 	fib->Header.ReceiverFibAddress = fib_addr;
1619 
1620 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1621 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1622 	    sizeof(sc->sc_common->ac_qbuf),
1623 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1624 
1625 	/* Get the producer/consumer indices.  */
1626 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
1627 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
1628 
1629 	/* Wrap the queue? */
1630 	if (pi >= aac_qinfo[queue].size)
1631 		pi = 0;
1632 
1633 	/* Check for queue full. */
1634 	if ((pi + 1) == ci)
1635 		return (EAGAIN);
1636 
1637 	/* Populate queue entry. */
1638 	(sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size);
1639 	(sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr);
1640 
1641 	/* Update producer index. */
1642 	sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1);
1643 
1644 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1645 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1646 	    sizeof(sc->sc_common->ac_qbuf),
1647 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1648 
1649 	/* Notify the adapter if we know how. */
1650 	if (aac_qinfo[queue].notify != 0)
1651 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1652 
1653 	return (0);
1654 }
1655 
1656 #ifdef AAC_DEBUG
1657 /*
1658  * Print a FIB
1659  */
1660 static void
1661 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib,
1662     const char *caller)
1663 {
1664 	struct aac_blockread *br;
1665 	struct aac_blockwrite *bw;
1666 	struct aac_sg_table *sg;
1667 	char tbuf[512];
1668 	int i;
1669 
1670 	printf("%s: FIB @ %p\n", caller, fib);
1671 	bitmask_snprintf(le32toh(fib->Header.XferState),
1672 	    "\20"
1673 	    "\1HOSTOWNED"
1674 	    "\2ADAPTEROWNED"
1675 	    "\3INITIALISED"
1676 	    "\4EMPTY"
1677 	    "\5FROMPOOL"
1678 	    "\6FROMHOST"
1679 	    "\7FROMADAP"
1680 	    "\10REXPECTED"
1681 	    "\11RNOTEXPECTED"
1682 	    "\12DONEADAP"
1683 	    "\13DONEHOST"
1684 	    "\14HIGH"
1685 	    "\15NORM"
1686 	    "\16ASYNC"
1687 	    "\17PAGEFILEIO"
1688 	    "\20SHUTDOWN"
1689 	    "\21LAZYWRITE"
1690 	    "\22ADAPMICROFIB"
1691 	    "\23BIOSFIB"
1692 	    "\24FAST_RESPONSE"
1693 	    "\25APIFIB\n",
1694 	    tbuf,
1695 	    sizeof(tbuf));
1696 
1697 	printf("  XferState       %s\n", tbuf);
1698 	printf("  Command         %d\n", le16toh(fib->Header.Command));
1699 	printf("  StructType      %d\n", fib->Header.StructType);
1700 	printf("  Flags           0x%x\n", fib->Header.Flags);
1701 	printf("  Size            %d\n", le16toh(fib->Header.Size));
1702 	printf("  SenderSize      %d\n", le16toh(fib->Header.SenderSize));
1703 	printf("  SenderAddress   0x%x\n",
1704 	    le32toh(fib->Header.SenderFibAddress));
1705 	printf("  ReceiverAddress 0x%x\n",
1706 	    le32toh(fib->Header.ReceiverFibAddress));
1707 	printf("  SenderData      0x%x\n", fib->Header.SenderData);
1708 
1709 	switch (fib->Header.Command) {
1710 	case ContainerCommand: {
1711 		br = (struct aac_blockread *)fib->data;
1712 		bw = (struct aac_blockwrite *)fib->data;
1713 		sg = NULL;
1714 
1715 		if (le32toh(br->Command) == VM_CtBlockRead) {
1716 			printf("  BlockRead: container %d  0x%x/%d\n",
1717 			    le32toh(br->ContainerId), le32toh(br->BlockNumber),
1718 			    le32toh(br->ByteCount));
1719 			sg = &br->SgMap;
1720 		}
1721 		if (le32toh(bw->Command) == VM_CtBlockWrite) {
1722 			printf("  BlockWrite: container %d  0x%x/%d (%s)\n",
1723 			    le32toh(bw->ContainerId), le32toh(bw->BlockNumber),
1724 			    le32toh(bw->ByteCount),
1725 			    le32toh(bw->Stable) == CSTABLE ?
1726 			    "stable" : "unstable");
1727 			sg = &bw->SgMap;
1728 		}
1729 		if (sg != NULL) {
1730 			printf("  %d s/g entries\n", le32toh(sg->SgCount));
1731 			for (i = 0; i < le32toh(sg->SgCount); i++)
1732 				printf("  0x%08x/%d\n",
1733 				    le32toh(sg->SgEntry[i].SgAddress),
1734 				    le32toh(sg->SgEntry[i].SgByteCount));
1735 		}
1736 		break;
1737 	}
1738 	default:
1739 		// dump first 32 bytes of fib->data
1740 		printf("  Raw data:");
1741 		for (i = 0; i < 32; i++)
1742 			printf(" %02x", fib->data[i]);
1743 		printf("\n");
1744 		break;
1745 	}
1746 }
1747 #endif /* AAC_DEBUG */
1748