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