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