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