Home | History | Annotate | Line # | Download | only in ic
aac.c revision 1.9
      1 /*	$NetBSD: aac.c,v 1.9 2003/05/03 18:11:11 wiz Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2002 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.9 2003/05/03 18:11:11 wiz Exp $");
     81 
     82 #include "locators.h"
     83 
     84 #include <sys/param.h>
     85 #include <sys/systm.h>
     86 #include <sys/buf.h>
     87 #include <sys/device.h>
     88 #include <sys/kernel.h>
     89 #include <sys/malloc.h>
     90 
     91 #include <machine/bus.h>
     92 
     93 #include <uvm/uvm_extern.h>
     94 
     95 #include <dev/ic/aacreg.h>
     96 #include <dev/ic/aacvar.h>
     97 #include <dev/ic/aac_tables.h>
     98 
     99 int	aac_check_firmware(struct aac_softc *);
    100 void	aac_describe_controller(struct aac_softc *);
    101 int	aac_dequeue_fib(struct aac_softc *, int, u_int32_t *,
    102 			struct aac_fib **);
    103 int	aac_enqueue_fib(struct aac_softc *, int, struct aac_fib *);
    104 void	aac_host_command(struct aac_softc *);
    105 void	aac_host_response(struct aac_softc *);
    106 int	aac_init(struct aac_softc *);
    107 int	aac_print(void *, const char *);
    108 void	aac_shutdown(void *);
    109 void	aac_startup(struct aac_softc *);
    110 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 int	aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t, void *,
    113 		     u_int16_t, void *, u_int16_t *);
    114 int	aac_submatch(struct device *, struct cfdata *, void *);
    115 
    116 #ifdef AAC_DEBUG
    117 void	aac_print_fib(struct aac_softc *, struct aac_fib *, 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 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 
    157 	SIMPLEQ_INIT(&sc->sc_ccb_free);
    158 	SIMPLEQ_INIT(&sc->sc_ccb_queue);
    159 	SIMPLEQ_INIT(&sc->sc_ccb_complete);
    160 
    161 	/*
    162 	 * Disable interrupts before we do anything.
    163 	 */
    164 	AAC_MASK_INTERRUPTS(sc);
    165 
    166 	/*
    167 	 * Initialise the adapter.
    168 	 */
    169 	if (aac_check_firmware(sc))
    170 		return (EINVAL);
    171 
    172 	if ((rv = aac_init(sc)) != 0)
    173 		return (rv);
    174 	aac_startup(sc);
    175 
    176 	/*
    177 	 * Print a little information about the controller.
    178 	 */
    179 	aac_describe_controller(sc);
    180 
    181 	/*
    182 	 * Initialize the ccbs.
    183 	 */
    184 	sc->sc_ccbs = malloc(sizeof(*ac) * AAC_NCCBS, M_DEVBUF,
    185 	    M_NOWAIT | M_ZERO);
    186 	if (sc->sc_ccbs == NULL) {
    187 		aprint_error("%s: memory allocation failure\n",
    188 		    sc->sc_dv.dv_xname);
    189 		return (ENOMEM);
    190 	}
    191 	state = 0;
    192 	size = sizeof(*fib) * AAC_NCCBS;
    193 
    194 	if ((rv = bus_dmamap_create(sc->sc_dmat, size, 1, size,
    195 	    0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_fibs_dmamap)) != 0) {
    196 		aprint_error("%s: cannot create fibs dmamap\n",
    197 		    sc->sc_dv.dv_xname);
    198 		goto bail_out;
    199 	}
    200 	state++;
    201 	if ((rv = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0,
    202 	    &sc->sc_fibs_seg, 1, &nsegs, BUS_DMA_NOWAIT)) != 0) {
    203 		aprint_error("%s: can't allocate fibs structure\n",
    204 		    sc->sc_dv.dv_xname);
    205 		goto bail_out;
    206 	}
    207 	state++;
    208 	if ((rv = bus_dmamem_map(sc->sc_dmat, &sc->sc_fibs_seg, nsegs, size,
    209 	    (caddr_t *)&sc->sc_fibs, 0)) != 0) {
    210 		aprint_error("%s: can't map fibs structure\n",
    211 		    sc->sc_dv.dv_xname);
    212 		goto bail_out;
    213 	}
    214 	state++;
    215 	if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_fibs_dmamap, sc->sc_fibs,
    216 	    size, NULL, BUS_DMA_NOWAIT)) != 0) {
    217 		aprint_error("%s: cannot load fibs dmamap\n",
    218 		    sc->sc_dv.dv_xname);
    219 		goto bail_out;
    220 	}
    221 	state++;
    222 
    223 	memset(sc->sc_fibs, 0, size);
    224 	fibpa = sc->sc_fibs_seg.ds_addr;
    225 	fib = sc->sc_fibs;
    226 
    227 	for (i = 0, ac = sc->sc_ccbs; i < AAC_NCCBS; i++, ac++) {
    228 		rv = bus_dmamap_create(sc->sc_dmat, AAC_MAX_XFER,
    229 		    AAC_MAX_SGENTRIES, AAC_MAX_XFER, 0,
    230 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ac->ac_dmamap_xfer);
    231 		if (rv) {
    232 			while (--ac >= sc->sc_ccbs)
    233 				bus_dmamap_destroy(sc->sc_dmat,
    234 				    ac->ac_dmamap_xfer);
    235 			aprint_error("%s: cannot create ccb dmamap (%d)",
    236 			    sc->sc_dv.dv_xname, rv);
    237 			goto bail_out;
    238 		}
    239 
    240 		ac->ac_fib = fib++;
    241 		ac->ac_fibphys = fibpa;
    242 		fibpa += sizeof(*fib);
    243 		aac_ccb_free(sc, ac);
    244 	}
    245 
    246 	/*
    247 	 * Attach devices.
    248 	 */
    249 	for (i = 0; i < AAC_MAX_CONTAINERS; i++) {
    250 		if (!sc->sc_hdr[i].hd_present)
    251 			continue;
    252 		aaca.aaca_unit = i;
    253 		config_found_sm(&sc->sc_dv, &aaca, aac_print, aac_submatch);
    254 	}
    255 
    256 	/*
    257 	 * Enable interrupts, and register our shutdown hook.
    258 	 */
    259 	sc->sc_flags |= AAC_ONLINE;
    260 	AAC_UNMASK_INTERRUPTS(sc);
    261 	if (aac_sdh != NULL)
    262 		shutdownhook_establish(aac_shutdown, NULL);
    263 	return (0);
    264 
    265  bail_out:
    266  	bus_dmamap_unload(sc->sc_dmat, sc->sc_common_dmamap);
    267 	bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_common,
    268 	    sizeof(*sc->sc_common));
    269 	bus_dmamem_free(sc->sc_dmat, &sc->sc_common_seg, 1);
    270 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_common_dmamap);
    271 
    272  	if (state > 3)
    273  		bus_dmamap_unload(sc->sc_dmat, sc->sc_fibs_dmamap);
    274 	if (state > 2)
    275 		bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_fibs, size);
    276 	if (state > 1)
    277 		bus_dmamem_free(sc->sc_dmat, &sc->sc_fibs_seg, 1);
    278 	if (state > 0)
    279 		bus_dmamap_destroy(sc->sc_dmat, sc->sc_fibs_dmamap);
    280 
    281 	free(sc->sc_ccbs, M_DEVBUF);
    282 	return (rv);
    283 }
    284 
    285 /*
    286  * Print autoconfiguration message for a sub-device.
    287  */
    288 int
    289 aac_print(void *aux, const char *pnp)
    290 {
    291 	struct aac_attach_args *aaca;
    292 
    293 	aaca = aux;
    294 
    295 	if (pnp != NULL)
    296 		aprint_normal("block device at %s", pnp);
    297 	aprint_normal(" unit %d", aaca->aaca_unit);
    298 	return (UNCONF);
    299 }
    300 
    301 /*
    302  * Match a sub-device.
    303  */
    304 int
    305 aac_submatch(struct device *parent, struct cfdata *cf, void *aux)
    306 {
    307 	struct aac_attach_args *aaca;
    308 
    309 	aaca = aux;
    310 
    311 	if (cf->aaccf_unit != AACCF_UNIT_DEFAULT &&
    312 	    cf->aaccf_unit != aaca->aaca_unit)
    313 		return (0);
    314 
    315 	return (config_match(parent, cf, aux));
    316 }
    317 
    318 /*
    319  * Look up a text description of a numeric error code and return a pointer to
    320  * same.
    321  */
    322 const char *
    323 aac_describe_code(const struct aac_code_lookup *table, u_int32_t code)
    324 {
    325 	int i;
    326 
    327 	for (i = 0; table[i].string != NULL; i++)
    328 		if (table[i].code == code)
    329 			return (table[i].string);
    330 
    331 	return (table[i + 1].string);
    332 }
    333 
    334 void
    335 aac_describe_controller(struct aac_softc *sc)
    336 {
    337 	u_int8_t buf[AAC_FIB_DATASIZE];
    338 	u_int16_t bufsize;
    339 	struct aac_adapter_info *info;
    340 	u_int8_t arg;
    341 
    342 	arg = 0;
    343 	if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &buf,
    344 	    &bufsize)) {
    345 		aprint_error("%s: RequestAdapterInfo failed\n",
    346 		    sc->sc_dv.dv_xname);
    347 		return;
    348 	}
    349 	if (bufsize != sizeof(*info)) {
    350 		aprint_error("%s: "
    351 		    "RequestAdapterInfo returned wrong data size (%d != %d)\n",
    352 		    sc->sc_dv.dv_xname, bufsize, sizeof(*info));
    353 		return;
    354 	}
    355 	info = (struct aac_adapter_info *)&buf[0];
    356 
    357 	aprint_normal("%s: %s at %dMHz, %dMB cache, %s, kernel %d.%d-%d\n",
    358 	    sc->sc_dv.dv_xname,
    359 	    aac_describe_code(aac_cpu_variant, le32toh(info->CpuVariant)),
    360 	    le32toh(info->ClockSpeed),
    361 	    le32toh(info->BufferMem) / (1024 * 1024),
    362 	    aac_describe_code(aac_battery_platform,
    363 			      le32toh(info->batteryPlatform)),
    364 	    info->KernelRevision.external.comp.major,
    365 	    info->KernelRevision.external.comp.minor,
    366 	    info->KernelRevision.external.comp.dash);
    367 
    368 	/* Save the kernel revision structure for later use. */
    369 	sc->sc_revision = info->KernelRevision;
    370 }
    371 
    372 /*
    373  * Retrieve the firmware version numbers.  Dell PERC2/QC cards with firmware
    374  * version 1.x are not compatible with this driver.
    375  */
    376 int
    377 aac_check_firmware(struct aac_softc *sc)
    378 {
    379 	u_int32_t major, minor;
    380 
    381 	if ((sc->sc_quirks & AAC_QUIRK_PERC2QC) != 0) {
    382 		if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
    383 		    NULL)) {
    384 			aprint_error("%s: error reading firmware version\n",
    385 			    sc->sc_dv.dv_xname);
    386 			return (1);
    387 		}
    388 
    389 		/* These numbers are stored as ASCII! */
    390 		major = (AAC_GETREG4(sc, AAC_SA_MAILBOX + 4) & 0xff) - 0x30;
    391 		minor = (AAC_GETREG4(sc, AAC_SA_MAILBOX + 8) & 0xff) - 0x30;
    392 		if (major == 1) {
    393 			aprint_error(
    394 			    "%s: firmware version %d.%d not supported.\n",
    395 			    sc->sc_dv.dv_xname, major, minor);
    396 			return (1);
    397 		}
    398 	}
    399 
    400 	return (0);
    401 }
    402 
    403 int
    404 aac_init(struct aac_softc *sc)
    405 {
    406 	int nsegs, i, rv, state, norm, high;
    407 	struct aac_adapter_init	*ip;
    408 	u_int32_t code;
    409 	u_int8_t *qaddr;
    410 
    411 	state = 0;
    412 
    413 	/*
    414 	 * First wait for the adapter to come ready.
    415 	 */
    416 	for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) {
    417 		code = AAC_GET_FWSTATUS(sc);
    418 		if ((code & AAC_SELF_TEST_FAILED) != 0) {
    419 			aprint_error("%s: FATAL: selftest failed\n",
    420 			    sc->sc_dv.dv_xname);
    421 			return (ENXIO);
    422 		}
    423 		if ((code & AAC_KERNEL_PANIC) != 0) {
    424 			aprint_error("%s: FATAL: controller kernel panic\n",
    425 			    sc->sc_dv.dv_xname);
    426 			return (ENXIO);
    427 		}
    428 		if ((code & AAC_UP_AND_RUNNING) != 0)
    429 			break;
    430 		DELAY(1000);
    431 	}
    432 	if (i == AAC_BOOT_TIMEOUT * 1000) {
    433 		aprint_error(
    434 		    "%s: FATAL: controller not coming ready, status %x\n",
    435 		    sc->sc_dv.dv_xname, code);
    436 		return (ENXIO);
    437 	}
    438 
    439 	if ((rv = bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_common), 1,
    440 	    sizeof(*sc->sc_common), 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
    441 	    &sc->sc_common_dmamap)) != 0) {
    442 		aprint_error("%s: cannot create common dmamap\n",
    443 		    sc->sc_dv.dv_xname);
    444 		return (rv);
    445 	}
    446 	if ((rv = bus_dmamem_alloc(sc->sc_dmat, sizeof(*sc->sc_common),
    447 	    PAGE_SIZE, 0, &sc->sc_common_seg, 1, &nsegs,
    448 	    BUS_DMA_NOWAIT)) != 0) {
    449 		aprint_error("%s: can't allocate common structure\n",
    450 		    sc->sc_dv.dv_xname);
    451 		goto bail_out;
    452 	}
    453 	state++;
    454 	if ((rv = bus_dmamem_map(sc->sc_dmat, &sc->sc_common_seg, nsegs,
    455 	    sizeof(*sc->sc_common), (caddr_t *)&sc->sc_common, 0)) != 0) {
    456 		aprint_error("%s: can't map common structure\n",
    457 		    sc->sc_dv.dv_xname);
    458 		goto bail_out;
    459 	}
    460 	state++;
    461 	if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_common_dmamap,
    462 	    sc->sc_common, sizeof(*sc->sc_common), NULL,
    463 	    BUS_DMA_NOWAIT)) != 0) {
    464 		aprint_error("%s: cannot load common dmamap\n",
    465 		    sc->sc_dv.dv_xname);
    466 		goto bail_out;
    467 	}
    468 	state++;
    469 
    470 	memset(sc->sc_common, 0, sizeof(*sc->sc_common));
    471 
    472 	/*
    473 	 * Fill in the init structure.  This tells the adapter about the
    474 	 * physical location of various important shared data structures.
    475 	 */
    476 	ip = &sc->sc_common->ac_init;
    477 	ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION);
    478 
    479 	ip->AdapterFibsPhysicalAddress = htole32(sc->sc_common_seg.ds_addr +
    480 	    offsetof(struct aac_common, ac_fibs));
    481 	ip->AdapterFibsVirtualAddress = htole32(&sc->sc_common->ac_fibs[0]);
    482 	ip->AdapterFibsSize =
    483 	    htole32(AAC_ADAPTER_FIBS * sizeof(struct aac_fib));
    484 	ip->AdapterFibAlign = htole32(sizeof(struct aac_fib));
    485 
    486 	ip->PrintfBufferAddress = htole32(sc->sc_common_seg.ds_addr +
    487 	    offsetof(struct aac_common, ac_printf));
    488 	ip->PrintfBufferSize = htole32(AAC_PRINTF_BUFSIZE);
    489 
    490 	ip->HostPhysMemPages = 0;	/* not used? */
    491 	ip->HostElapsedSeconds = 0;	/* reset later if invalid */
    492 
    493 	/*
    494 	 * Initialise FIB queues.  Note that it appears that the layout of
    495 	 * the indexes and the segmentation of the entries is mandated by
    496 	 * the adapter, which is only told about the base of the queue index
    497 	 * fields.
    498 	 *
    499 	 * The initial values of the indices are assumed to inform the
    500 	 * adapter of the sizes of the respective queues.
    501 	 *
    502 	 * The Linux driver uses a much more complex scheme whereby several
    503 	 * header records are kept for each queue.  We use a couple of
    504 	 * generic list manipulation functions which 'know' the size of each
    505 	 * list by virtue of a table.
    506 	 */
    507 	qaddr = &sc->sc_common->ac_qbuf[0] + AAC_QUEUE_ALIGN;
    508 	qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN; 	/* XXX not portable */
    509 	sc->sc_queues = (struct aac_queue_table *)qaddr;
    510 	ip->CommHeaderAddress = htole32(sc->sc_common_seg.ds_addr +
    511 	    ((caddr_t)sc->sc_queues - (caddr_t)sc->sc_common));
    512 	memset(sc->sc_queues, 0, sizeof(struct aac_queue_table));
    513 
    514 	norm = htole32(AAC_HOST_NORM_CMD_ENTRIES);
    515 	high = htole32(AAC_HOST_HIGH_CMD_ENTRIES);
    516 
    517 	sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
    518 	    norm;
    519 	sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
    520 	    norm;
    521 	sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
    522 	    high;
    523 	sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
    524 	    high;
    525 
    526 	norm = htole32(AAC_ADAP_NORM_CMD_ENTRIES);
    527 	high = htole32(AAC_ADAP_HIGH_CMD_ENTRIES);
    528 
    529 	sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
    530 	    norm;
    531 	sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
    532 	    norm;
    533 	sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
    534 	    high;
    535 	sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
    536 	    high;
    537 
    538 	norm = htole32(AAC_HOST_NORM_RESP_ENTRIES);
    539 	high = htole32(AAC_HOST_HIGH_RESP_ENTRIES);
    540 
    541 	sc->sc_queues->
    542 	    qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm;
    543 	sc->sc_queues->
    544 	    qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm;
    545 	sc->sc_queues->
    546 	    qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high;
    547 	sc->sc_queues->
    548 	    qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high;
    549 
    550 	norm = htole32(AAC_ADAP_NORM_RESP_ENTRIES);
    551 	high = htole32(AAC_ADAP_HIGH_RESP_ENTRIES);
    552 
    553 	sc->sc_queues->
    554 	    qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm;
    555 	sc->sc_queues->
    556 	    qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm;
    557 	sc->sc_queues->
    558 	    qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high;
    559 	sc->sc_queues->
    560 	    qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high;
    561 
    562 	sc->sc_qentries[AAC_HOST_NORM_CMD_QUEUE] =
    563 	    &sc->sc_queues->qt_HostNormCmdQueue[0];
    564 	sc->sc_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
    565 	    &sc->sc_queues->qt_HostHighCmdQueue[0];
    566 	sc->sc_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
    567 	    &sc->sc_queues->qt_AdapNormCmdQueue[0];
    568 	sc->sc_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
    569 	    &sc->sc_queues->qt_AdapHighCmdQueue[0];
    570 	sc->sc_qentries[AAC_HOST_NORM_RESP_QUEUE] =
    571 	    &sc->sc_queues->qt_HostNormRespQueue[0];
    572 	sc->sc_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
    573 	    &sc->sc_queues->qt_HostHighRespQueue[0];
    574 	sc->sc_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
    575 	    &sc->sc_queues->qt_AdapNormRespQueue[0];
    576 	sc->sc_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
    577 	    &sc->sc_queues->qt_AdapHighRespQueue[0];
    578 
    579 	/*
    580 	 * Do controller-type-specific initialisation
    581 	 */
    582 	switch (sc->sc_hwif) {
    583 	case AAC_HWIF_I960RX:
    584 		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
    585 		break;
    586 	}
    587 
    588 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 0,
    589 	    sizeof(*sc->sc_common),
    590 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    591 
    592 	/*
    593 	 * Give the init structure to the controller.
    594 	 */
    595 	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
    596 	    sc->sc_common_seg.ds_addr + offsetof(struct aac_common, ac_init),
    597 	    0, 0, 0, NULL)) {
    598 		aprint_error("%s: error establishing init structure\n",
    599 		    sc->sc_dv.dv_xname);
    600 		rv = EIO;
    601 		goto bail_out;
    602 	}
    603 
    604 	return (0);
    605 
    606  bail_out:
    607  	if (state > 2)
    608  		bus_dmamap_unload(sc->sc_dmat, sc->sc_common_dmamap);
    609 	if (state > 1)
    610 		bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_common,
    611 		    sizeof(*sc->sc_common));
    612 	if (state > 0)
    613 		bus_dmamem_free(sc->sc_dmat, &sc->sc_common_seg, 1);
    614 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_common_dmamap);
    615 
    616 	return (rv);
    617 }
    618 
    619 /*
    620  * Probe for containers, create disks.
    621  */
    622 void
    623 aac_startup(struct aac_softc *sc)
    624 {
    625 	struct aac_mntinfo mi;
    626 	struct aac_mntinforesponse mir;
    627 	struct aac_drive *hd;
    628 	u_int16_t rsize;
    629 	int i;
    630 
    631 	/*
    632 	 * Loop over possible containers.
    633 	 */
    634 	mi.Command = htole32(VM_NameServe);
    635 	mi.MntType = htole32(FT_FILESYS);
    636 	hd = sc->sc_hdr;
    637 
    638 	for (i = 0; i < AAC_MAX_CONTAINERS; i++, hd++) {
    639 		/*
    640 		 * Request information on this container.
    641 		 */
    642 		mi.MntCount = htole32(i);
    643 		if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(mi), &mir,
    644 		    &rsize)) {
    645 			aprint_error("%s: error probing container %d\n",
    646 			    sc->sc_dv.dv_xname, i);
    647 			continue;
    648 		}
    649 		if (rsize != sizeof(mir)) {
    650 			aprint_error("%s: container info response wrong size "
    651 			    "(%d should be %d)\n",
    652 			    sc->sc_dv.dv_xname, rsize, sizeof(mir));
    653 			continue;
    654 		}
    655 
    656 		/*
    657 		 * Check container volume type for validity.  Note that many
    658 		 * of the possible types may never show up.
    659 		 */
    660 		if (le32toh(mir.Status) != ST_OK ||
    661 		    le32toh(mir.MntTable[0].VolType) == CT_NONE)
    662 			continue;
    663 
    664 		hd->hd_present = 1;
    665 		hd->hd_size = le32toh(mir.MntTable[0].Capacity);
    666 		hd->hd_devtype = le32toh(mir.MntTable[0].VolType);
    667 		hd->hd_size &= ~0x1f;
    668 		sc->sc_nunits++;
    669 	}
    670 }
    671 
    672 void
    673 aac_shutdown(void *cookie)
    674 {
    675 	struct aac_softc *sc;
    676 	struct aac_close_command cc;
    677 	u_int32_t i;
    678 
    679 	for (i = 0; i < aac_cd.cd_ndevs; i++) {
    680 		if ((sc = device_lookup(&aac_cd, i)) == NULL)
    681 			continue;
    682 		if ((sc->sc_flags & AAC_ONLINE) == 0)
    683 			continue;
    684 
    685 		AAC_MASK_INTERRUPTS(sc);
    686 
    687 		/*
    688 		 * Send a Container shutdown followed by a HostShutdown FIB
    689 		 * to the controller to convince it that we don't want to
    690 		 * talk to it anymore.  We've been closed and all I/O
    691 		 * completed already
    692 		 */
    693 		cc.Command = htole32(VM_CloseAll);
    694 		cc.ContainerId = 0xffffffff;
    695 		if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc),
    696 		    NULL, NULL)) {
    697 			printf("%s: unable to halt controller\n",
    698 			    sc->sc_dv.dv_xname);
    699 			continue;
    700 		}
    701 
    702 		/*
    703 		 * Note that issuing this command to the controller makes it
    704 		 * shut down but also keeps it from coming back up without a
    705 		 * reset of the PCI bus.
    706 		 */
    707 		if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
    708 		    &i, sizeof(i), NULL, NULL))
    709 			printf("%s: unable to halt controller\n",
    710 			    sc->sc_dv.dv_xname);
    711 	}
    712 }
    713 
    714 /*
    715  * Take an interrupt.
    716  */
    717 int
    718 aac_intr(void *cookie)
    719 {
    720 	struct aac_softc *sc;
    721 	u_int16_t reason;
    722 	int claimed;
    723 
    724 	sc = cookie;
    725 	claimed = 0;
    726 
    727 	AAC_DPRINTF(AAC_D_INTR, ("aac_intr(%p) ", sc));
    728 
    729 	reason = AAC_GET_ISTATUS(sc);
    730 	AAC_DPRINTF(AAC_D_INTR, ("istatus 0x%04x ", reason));
    731 
    732 	/*
    733 	 * Controller wants to talk to the log.  XXX Should we defer this?
    734 	 */
    735 	if ((reason & AAC_DB_PRINTF) != 0) {
    736 		if (sc->sc_common->ac_printf[0] != '\0') {
    737 			printf("%s: WARNING: adapter logged message:\n",
    738 			    sc->sc_dv.dv_xname);
    739 			printf("%s:     %.*s", sc->sc_dv.dv_xname,
    740 			    AAC_PRINTF_BUFSIZE, sc->sc_common->ac_printf);
    741 			sc->sc_common->ac_printf[0] = '\0';
    742 		}
    743 		AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
    744 		AAC_QNOTIFY(sc, AAC_DB_PRINTF);
    745 		claimed = 1;
    746 	}
    747 
    748 	/*
    749 	 * Controller has a message for us?
    750 	 */
    751 	if ((reason & AAC_DB_COMMAND_READY) != 0) {
    752 		aac_host_command(sc);
    753 		AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY);
    754 		claimed = 1;
    755 	}
    756 
    757 	/*
    758 	 * Controller has a response for us?
    759 	 */
    760 	if ((reason & AAC_DB_RESPONSE_READY) != 0) {
    761 		aac_host_response(sc);
    762 		AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
    763 		claimed = 1;
    764 	}
    765 
    766 	/*
    767 	 * Spurious interrupts that we don't use - reset the mask and clear
    768 	 * the interrupts.
    769 	 */
    770 	if ((reason & (AAC_DB_SYNC_COMMAND | AAC_DB_COMMAND_NOT_FULL |
    771             AAC_DB_RESPONSE_NOT_FULL)) != 0) {
    772 		AAC_UNMASK_INTERRUPTS(sc);
    773 		AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND |
    774 		    AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL);
    775 		claimed = 1;
    776 	}
    777 
    778 	return (claimed);
    779 }
    780 
    781 /*
    782  * Handle notification of one or more FIBs coming from the controller.
    783  */
    784 void
    785 aac_host_command(struct aac_softc *sc)
    786 {
    787 	struct aac_fib *fib;
    788 	u_int32_t fib_size;
    789 
    790 	for (;;) {
    791 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size,
    792 		    &fib))
    793 			break;	/* nothing to do */
    794 
    795 		bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
    796 		    (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib),
    797 		    BUS_DMASYNC_POSTREAD);
    798 
    799 		switch (le16toh(fib->Header.Command)) {
    800 		case AifRequest:
    801 #ifdef notyet
    802 			aac_handle_aif(sc,
    803 			    (struct aac_aif_command *)&fib->data[0]);
    804 #endif
    805 			break;
    806 		default:
    807 			printf("%s: unknown command from controller\n",
    808 			    sc->sc_dv.dv_xname);
    809 			AAC_PRINT_FIB(sc, fib);
    810 			break;
    811 		}
    812 
    813 		bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
    814 		    (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib),
    815 		    BUS_DMASYNC_PREREAD);
    816 
    817 		/* XXX reply to FIBs requesting responses ?? */
    818 		/* XXX how do we return these FIBs to the controller? */
    819 	}
    820 }
    821 
    822 /*
    823  * Handle notification of one or more FIBs completed by the controller
    824  */
    825 void
    826 aac_host_response(struct aac_softc *sc)
    827 {
    828 	struct aac_ccb *ac;
    829 	struct aac_fib *fib;
    830 	u_int32_t fib_size;
    831 
    832 	/*
    833 	 * Look for completed FIBs on our queue.
    834 	 */
    835 	for (;;) {
    836 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
    837 		    &fib))
    838 			break;	/* nothing to do */
    839 
    840 		bus_dmamap_sync(sc->sc_dmat, sc->sc_fibs_dmamap,
    841 		    (caddr_t)fib - (caddr_t)sc->sc_fibs, sizeof(*fib),
    842 		    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    843 
    844 		if ((fib->Header.SenderData & 0x80000000) == 0) {
    845 			/* Not valid; not sent by us. */
    846 			AAC_PRINT_FIB(sc, fib);
    847 		} else {
    848 			ac = (struct aac_ccb *)((caddr_t)sc->sc_ccbs +
    849 			    (fib->Header.SenderData & 0x7fffffff));
    850 			fib->Header.SenderData = 0;
    851 			SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_complete, ac, ac_chain);
    852 		}
    853 	}
    854 
    855 	/*
    856 	 * Deal with any completed commands.
    857 	 */
    858 	while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_complete)) != NULL) {
    859 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_complete, ac_chain);
    860 		ac->ac_flags |= AAC_CCB_COMPLETED;
    861 
    862 		if (ac->ac_intr != NULL)
    863 			(*ac->ac_intr)(ac);
    864 	}
    865 
    866 	/*
    867 	 * Try to submit more commands.
    868 	 */
    869 	if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue))
    870 		aac_ccb_enqueue(sc, NULL);
    871 }
    872 
    873 /*
    874  * Send a synchronous command to the controller and wait for a result.
    875  */
    876 int
    877 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
    878 		 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp)
    879 {
    880 	int i;
    881 	u_int32_t status;
    882 	int s;
    883 
    884 	s = splbio();
    885 
    886 	/* Populate the mailbox. */
    887 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
    888 
    889 	/* Ensure the sync command doorbell flag is cleared. */
    890 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
    891 
    892 	/* ... then set it to signal the adapter. */
    893 	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
    894 	DELAY(AAC_SYNC_DELAY);
    895 
    896 	/* Spin waiting for the command to complete. */
    897 	for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) {
    898 		if (AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND);
    899 			break;
    900 		DELAY(1000);
    901 	}
    902 	if (i == AAC_IMMEDIATE_TIMEOUT * 1000) {
    903 		splx(s);
    904 		return (EIO);
    905 	}
    906 
    907 	/* Clear the completion flag. */
    908 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
    909 
    910 	/* Get the command status. */
    911 	status = AAC_GET_MAILBOXSTATUS(sc);
    912 	splx(s);
    913 	if (sp != NULL)
    914 		*sp = status;
    915 
    916 	return (0);	/* XXX Check command return status? */
    917 }
    918 
    919 /*
    920  * Send a synchronous FIB to the controller and wait for a result.
    921  */
    922 int
    923 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
    924 	     void *data, u_int16_t datasize, void *result,
    925 	     u_int16_t *resultsize)
    926 {
    927 	struct aac_fib *fib;
    928 	u_int32_t fibpa, status;
    929 
    930 	fib = &sc->sc_common->ac_sync_fib;
    931 	fibpa = sc->sc_common_seg.ds_addr +
    932 	    offsetof(struct aac_common, ac_sync_fib);
    933 
    934 	if (datasize > AAC_FIB_DATASIZE)
    935 		return (EINVAL);
    936 
    937 	/*
    938 	 * Set up the sync FIB.
    939 	 */
    940 	fib->Header.XferState = htole32(AAC_FIBSTATE_HOSTOWNED |
    941 	    AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY | xferstate);
    942 	fib->Header.Command = htole16(command);
    943 	fib->Header.StructType = AAC_FIBTYPE_TFIB;
    944 	fib->Header.Size = htole16(sizeof(*fib) + datasize);
    945 	fib->Header.SenderSize = htole16(sizeof(*fib));
    946 	fib->Header.SenderFibAddress = htole32((u_int32_t)fib);	/* XXX */
    947 	fib->Header.ReceiverFibAddress = htole32(fibpa);
    948 
    949 	/*
    950 	 * Copy in data.
    951 	 */
    952 	if (data != NULL) {
    953 		memcpy(fib->data, data, datasize);
    954 		fib->Header.XferState |=
    955 		    htole32(AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM);
    956 	}
    957 
    958 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
    959 	    (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib),
    960 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    961 
    962 	/*
    963 	 * Give the FIB to the controller, wait for a response.
    964 	 */
    965 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fibpa, 0, 0, 0, &status))
    966 		return (EIO);
    967 
    968 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
    969 	    (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib),
    970 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    971 
    972 	/*
    973 	 * Copy out the result
    974 	 */
    975 	if (result != NULL) {
    976 		*resultsize = le16toh(fib->Header.Size) - sizeof(fib->Header);
    977 		memcpy(result, fib->data, *resultsize);
    978 	}
    979 
    980 	return (0);
    981 }
    982 
    983 struct aac_ccb *
    984 aac_ccb_alloc(struct aac_softc *sc, int flags)
    985 {
    986 	struct aac_ccb *ac;
    987 	int s;
    988 
    989 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_alloc(%p, 0x%x) ", sc, flags));
    990 
    991 	s = splbio();
    992 	ac = SIMPLEQ_FIRST(&sc->sc_ccb_free);
    993 #ifdef DIAGNOSTIC
    994 	if (ac == NULL)
    995 		panic("aac_ccb_get: no free CCBS");
    996 #endif
    997 	SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ac_chain);
    998 	splx(s);
    999 
   1000 	ac->ac_flags = flags;
   1001 	return (ac);
   1002 }
   1003 
   1004 void
   1005 aac_ccb_free(struct aac_softc *sc, struct aac_ccb *ac)
   1006 {
   1007 	int s;
   1008 
   1009 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_free(%p, %p) ", sc, ac));
   1010 
   1011 	ac->ac_flags = 0;
   1012 	ac->ac_intr = NULL;
   1013 	ac->ac_fib->Header.XferState = htole32(AAC_FIBSTATE_EMPTY);
   1014 	ac->ac_fib->Header.StructType = AAC_FIBTYPE_TFIB;
   1015 	ac->ac_fib->Header.Flags = 0;
   1016 	ac->ac_fib->Header.SenderSize = htole16(sizeof(*ac->ac_fib));
   1017 
   1018 #ifdef AAC_DEBUG
   1019 	/*
   1020 	 * These are duplicated in aac_ccb_submit() to cover the case where
   1021 	 * an intermediate stage may have destroyed them.  They're left
   1022 	 * initialised here for debugging purposes only.
   1023 	 */
   1024 	ac->ac_fib->Header.SenderFibAddress = htole32((u_int32_t)ac->ac_fib);
   1025 	ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
   1026 #endif
   1027 
   1028 	s = splbio();
   1029 	SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ac, ac_chain);
   1030 	splx(s);
   1031 }
   1032 
   1033 int
   1034 aac_ccb_map(struct aac_softc *sc, struct aac_ccb *ac)
   1035 {
   1036 	int error;
   1037 
   1038 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_map(%p, %p) ", sc, ac));
   1039 
   1040 #ifdef DIAGNOSTIC
   1041 	if ((ac->ac_flags & AAC_CCB_MAPPED) != 0)
   1042 		panic("aac_ccb_map: already mapped");
   1043 #endif
   1044 
   1045 	error = bus_dmamap_load(sc->sc_dmat, ac->ac_dmamap_xfer, ac->ac_data,
   1046 	    ac->ac_datalen, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
   1047 	    ((ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE));
   1048 	if (error) {
   1049 		printf("%s: aac_ccb_map: ", sc->sc_dv.dv_xname);
   1050 		if (error == EFBIG)
   1051 			printf("more than %d DMA segs\n", AAC_MAX_SGENTRIES);
   1052 		else
   1053 			printf("error %d loading DMA map\n", error);
   1054 		return (error);
   1055 	}
   1056 
   1057 	bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
   1058 	    (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_PREREAD :
   1059 	    BUS_DMASYNC_PREWRITE);
   1060 
   1061 #ifdef DIAGNOSTIC
   1062 	ac->ac_flags |= AAC_CCB_MAPPED;
   1063 #endif
   1064 	return (0);
   1065 }
   1066 
   1067 void
   1068 aac_ccb_unmap(struct aac_softc *sc, struct aac_ccb *ac)
   1069 {
   1070 
   1071 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_unmap(%p, %p) ", sc, ac));
   1072 
   1073 #ifdef DIAGNOSTIC
   1074 	if ((ac->ac_flags & AAC_CCB_MAPPED) == 0)
   1075 		panic("aac_ccb_unmap: not mapped");
   1076 #endif
   1077 
   1078 	bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
   1079 	    (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_POSTREAD :
   1080 	    BUS_DMASYNC_POSTWRITE);
   1081 	bus_dmamap_unload(sc->sc_dmat, ac->ac_dmamap_xfer);
   1082 
   1083 #ifdef DIAGNOSTIC
   1084 	ac->ac_flags &= ~AAC_CCB_MAPPED;
   1085 #endif
   1086 }
   1087 
   1088 void
   1089 aac_ccb_enqueue(struct aac_softc *sc, struct aac_ccb *ac)
   1090 {
   1091 	int s;
   1092 
   1093 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_enqueue(%p, %p) ", sc, ac));
   1094 
   1095 	s = splbio();
   1096 
   1097 	if (ac != NULL)
   1098 		SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ac, ac_chain);
   1099 
   1100 	while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) {
   1101 		if (aac_ccb_submit(sc, ac))
   1102 			break;
   1103 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ac_chain);
   1104 	}
   1105 
   1106 	splx(s);
   1107 }
   1108 
   1109 int
   1110 aac_ccb_submit(struct aac_softc *sc, struct aac_ccb *ac)
   1111 {
   1112 
   1113 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_submit(%p, %p) ", sc, ac));
   1114 
   1115 	/* Fix up the address values. */
   1116 	ac->ac_fib->Header.SenderFibAddress = htole32((u_int32_t)ac->ac_fib);
   1117 	ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
   1118 
   1119 	/* Save a pointer to the command for speedy reverse-lookup. */
   1120 	ac->ac_fib->Header.SenderData =
   1121 	    (u_int32_t)((caddr_t)ac - (caddr_t)sc->sc_ccbs) | 0x80000000;
   1122 
   1123 	bus_dmamap_sync(sc->sc_dmat, sc->sc_fibs_dmamap,
   1124 	    (caddr_t)ac->ac_fib - (caddr_t)sc->sc_fibs, sizeof(*ac->ac_fib),
   1125 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1126 
   1127 	/* Put the FIB on the outbound queue. */
   1128 	return (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, ac->ac_fib));
   1129 }
   1130 
   1131 int
   1132 aac_ccb_poll(struct aac_softc *sc, struct aac_ccb *ac, int timo)
   1133 {
   1134 	int rv, s;
   1135 
   1136 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_poll(%p, %p, %d) ", sc, ac, timo));
   1137 
   1138 	s = splbio();
   1139 
   1140 	if ((rv = aac_ccb_submit(sc, ac)) != 0) {
   1141 		splx(s);
   1142 		return (rv);
   1143 	}
   1144 
   1145 	for (timo *= 1000; timo != 0; timo--) {
   1146 		aac_intr(sc);
   1147 		if ((ac->ac_flags & AAC_CCB_COMPLETED) != 0)
   1148 			break;
   1149 		DELAY(100);
   1150 	}
   1151 
   1152 	splx(s);
   1153 	return (timo == 0);
   1154 }
   1155 
   1156 /*
   1157  * Atomically insert an entry into the nominated queue, returns 0 on success
   1158  * or EBUSY if the queue is full.
   1159  *
   1160  * XXX Note that it would be more efficient to defer notifying the
   1161  * controller in the case where we may be inserting several entries in rapid
   1162  * succession, but implementing this usefully is difficult.
   1163  */
   1164 int
   1165 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_fib *fib)
   1166 {
   1167 	u_int32_t fib_size, fib_addr, pi, ci;
   1168 
   1169 	fib_size = le16toh(fib->Header.Size);
   1170 	fib_addr = le32toh(fib->Header.ReceiverFibAddress);
   1171 
   1172 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1173 	    (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common,
   1174 	    sizeof(sc->sc_common->ac_qbuf),
   1175 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1176 
   1177 	/* Get the producer/consumer indices.  */
   1178 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
   1179 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
   1180 
   1181 	/* Wrap the queue? */
   1182 	if (pi >= aac_qinfo[queue].size)
   1183 		pi = 0;
   1184 
   1185 	/* Check for queue full. */
   1186 	if ((pi + 1) == ci)
   1187 		return (EAGAIN);
   1188 
   1189 	/* Populate queue entry. */
   1190 	(sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size);
   1191 	(sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr);
   1192 
   1193 	/* Update producer index. */
   1194 	sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1);
   1195 
   1196 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1197 	    (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common,
   1198 	    sizeof(sc->sc_common->ac_qbuf),
   1199 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1200 
   1201 	/* Notify the adapter if we know how. */
   1202 	if (aac_qinfo[queue].notify != 0)
   1203 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
   1204 
   1205 	return (0);
   1206 }
   1207 
   1208 /*
   1209  * Atomically remove one entry from the nominated queue, returns 0 on success
   1210  * or ENOENT if the queue is empty.
   1211  */
   1212 int
   1213 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
   1214 		struct aac_fib **fib_addr)
   1215 {
   1216 	u_int32_t pi, ci;
   1217 	int notify;
   1218 
   1219 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1220 	    (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common,
   1221 	    sizeof(sc->sc_common->ac_qbuf),
   1222 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1223 
   1224 	/* Get the producer/consumer indices. */
   1225 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
   1226 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
   1227 
   1228 	/* Check for queue empty. */
   1229 	if (ci == pi)
   1230 		return (ENOENT);
   1231 
   1232 	notify = 0;
   1233 	if (ci == pi + 1)
   1234 		notify = 1;
   1235 
   1236 	/* Wrap the queue? */
   1237 	if (ci >= aac_qinfo[queue].size)
   1238 		ci = 0;
   1239 
   1240 	/* Fetch the entry. */
   1241 	*fib_size = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_size);
   1242 	*fib_addr = le32toh((struct aac_fib *)
   1243 	    (sc->sc_qentries[queue] + ci)->aq_fib_addr);
   1244 
   1245 	/* Update consumer index. */
   1246 	sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
   1247 
   1248 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1249 	    (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common,
   1250 	    sizeof(sc->sc_common->ac_qbuf),
   1251 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1252 
   1253 	/* If we have made the queue un-full, notify the adapter. */
   1254 	if (notify && (aac_qinfo[queue].notify != 0))
   1255 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
   1256 
   1257 	return (0);
   1258 }
   1259 
   1260 #ifdef AAC_DEBUG
   1261 /*
   1262  * Print a FIB
   1263  */
   1264 void
   1265 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller)
   1266 {
   1267 	struct aac_blockread *br;
   1268 	struct aac_blockwrite *bw;
   1269 	struct aac_sg_table *sg;
   1270 	char buf[512];
   1271 	int i;
   1272 
   1273 	printf("%s: FIB @ %p\n", caller, fib);
   1274 	bitmask_snprintf(le32toh(fib->Header.XferState),
   1275 	    "\20"
   1276 	    "\1HOSTOWNED"
   1277 	    "\2ADAPTEROWNED"
   1278 	    "\3INITIALISED"
   1279 	    "\4EMPTY"
   1280 	    "\5FROMPOOL"
   1281 	    "\6FROMHOST"
   1282 	    "\7FROMADAP"
   1283 	    "\10REXPECTED"
   1284 	    "\11RNOTEXPECTED"
   1285 	    "\12DONEADAP"
   1286 	    "\13DONEHOST"
   1287 	    "\14HIGH"
   1288 	    "\15NORM"
   1289 	    "\16ASYNC"
   1290 	    "\17PAGEFILEIO"
   1291 	    "\20SHUTDOWN"
   1292 	    "\21LAZYWRITE"
   1293 	    "\22ADAPMICROFIB"
   1294 	    "\23BIOSFIB"
   1295 	    "\24FAST_RESPONSE"
   1296 	    "\25APIFIB\n",
   1297 	    buf,
   1298 	    sizeof(buf));
   1299 
   1300 	printf("  XferState       %s\n", buf);
   1301 	printf("  Command         %d\n", le16toh(fib->Header.Command));
   1302 	printf("  StructType      %d\n", fib->Header.StructType);
   1303 	printf("  Flags           0x%x\n", fib->Header.Flags);
   1304 	printf("  Size            %d\n", le16toh(fib->Header.Size));
   1305 	printf("  SenderSize      %d\n", le16toh(fib->Header.SenderSize));
   1306 	printf("  SenderAddress   0x%x\n",
   1307 	    le32toh(fib->Header.SenderFibAddress));
   1308 	printf("  ReceiverAddress 0x%x\n",
   1309 	    le32toh(fib->Header.ReceiverFibAddress));
   1310 	printf("  SenderData      0x%x\n", fib->Header.SenderData);
   1311 
   1312 	switch (fib->Header.Command) {
   1313 	case ContainerCommand: {
   1314 		br = (struct aac_blockread *)fib->data;
   1315 		bw = (struct aac_blockwrite *)fib->data;
   1316 		sg = NULL;
   1317 
   1318 		if (le32toh(br->Command) == VM_CtBlockRead) {
   1319 			printf("  BlockRead: container %d  0x%x/%d\n",
   1320 			    le32toh(br->ContainerId), le32toh(br->BlockNumber),
   1321 			    le32toh(br->ByteCount));
   1322 			sg = &br->SgMap;
   1323 		}
   1324 		if (le32toh(bw->Command) == VM_CtBlockWrite) {
   1325 			printf("  BlockWrite: container %d  0x%x/%d (%s)\n",
   1326 			    le32toh(bw->ContainerId), le32toh(bw->BlockNumber),
   1327 			    le32toh(bw->ByteCount),
   1328 			    le32toh(bw->Stable) == CSTABLE ?
   1329 			    "stable" : "unstable");
   1330 			sg = &bw->SgMap;
   1331 		}
   1332 		if (sg != NULL) {
   1333 			printf("  %d s/g entries\n", le32toh(sg->SgCount));
   1334 			for (i = 0; i < le32toh(sg->SgCount); i++)
   1335 				printf("  0x%08x/%d\n",
   1336 				    le32toh(sg->SgEntry[i].SgAddress),
   1337 				    le32toh(sg->SgEntry[i].SgByteCount));
   1338 		}
   1339 		break;
   1340 	}
   1341 	default:
   1342 		printf("   %16D\n", fib->data, " ");
   1343 		printf("   %16D\n", fib->data + 16, " ");
   1344 		break;
   1345 	}
   1346 }
   1347 #endif
   1348