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