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