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