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