Home | History | Annotate | Line # | Download | only in ic
aac.c revision 1.3
      1 /*	$NetBSD: aac.c,v 1.3 2002/06/01 23:50:57 lukem 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.3 2002/06/01 23:50:57 lukem 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 ((*cf->cf_attach->ca_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 (%d != %d)\n",
    349 		    sc->sc_dv.dv_xname, bufsize, 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_int32_t)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 			    "(%d should be %d)\n",
    646 			    sc->sc_dv.dv_xname, rsize, sizeof(mir));
    647 			continue;
    648 		}
    649 
    650 		/*
    651 		 * Check container volume type for validity.  Note that many
    652 		 * of the possible types may never show up.
    653 		 */
    654 		if (le32toh(mir.Status) != ST_OK ||
    655 		    le32toh(mir.MntTable[0].VolType) == CT_NONE)
    656 			continue;
    657 
    658 		hd->hd_present = 1;
    659 		hd->hd_size = le32toh(mir.MntTable[0].Capacity);
    660 		hd->hd_devtype = le32toh(mir.MntTable[0].VolType);
    661 		hd->hd_size &= ~0x1f;
    662 		sc->sc_nunits++;
    663 	}
    664 }
    665 
    666 void
    667 aac_shutdown(void *cookie)
    668 {
    669 	struct aac_softc *sc;
    670 	struct aac_close_command cc;
    671 	u_int32_t i;
    672 
    673 	for (i = 0; i < aac_cd.cd_ndevs; i++) {
    674 		if ((sc = device_lookup(&aac_cd, i)) == NULL)
    675 			continue;
    676 		if ((sc->sc_flags & AAC_ONLINE) == 0)
    677 			continue;
    678 
    679 		AAC_MASK_INTERRUPTS(sc);
    680 
    681 		/*
    682 		 * Send a Container shutdown followed by a HostShutdown FIB
    683 		 * to the controller to convince it that we don't want to
    684 		 * talk to it anymore.  We've been closed and all I/O
    685 		 * completed already
    686 		 */
    687 		cc.Command = htole32(VM_CloseAll);
    688 		cc.ContainerId = 0xffffffff;
    689 		if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc),
    690 		    NULL, NULL)) {
    691 			printf("%s: unable to halt controller\n",
    692 			    sc->sc_dv.dv_xname);
    693 			continue;
    694 		}
    695 
    696 		/*
    697 		 * Note that issuing this command to the controller makes it
    698 		 * shut down but also keeps it from coming back up without a
    699 		 * reset of the PCI bus.
    700 		 */
    701 		if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
    702 		    &i, sizeof(i), NULL, NULL))
    703 			printf("%s: unable to halt controller\n",
    704 			    sc->sc_dv.dv_xname);
    705 	}
    706 }
    707 
    708 /*
    709  * Take an interrupt.
    710  */
    711 int
    712 aac_intr(void *cookie)
    713 {
    714 	struct aac_softc *sc;
    715 	u_int16_t reason;
    716 	int claimed;
    717 
    718 	sc = cookie;
    719 	claimed = 0;
    720 
    721 	AAC_DPRINTF(AAC_D_INTR, ("aac_intr(%p) ", sc));
    722 
    723 	reason = AAC_GET_ISTATUS(sc);
    724 	AAC_DPRINTF(AAC_D_INTR, ("istatus 0x%04x ", reason));
    725 
    726 	/*
    727 	 * Controller wants to talk to the log.  XXX Should we defer this?
    728 	 */
    729 	if ((reason & AAC_DB_PRINTF) != 0) {
    730 		if (sc->sc_common->ac_printf[0] != '\0') {
    731 			printf("%s: WARNING: adapter logged message:\n",
    732 			    sc->sc_dv.dv_xname);
    733 			printf("%s:     %.*s", sc->sc_dv.dv_xname,
    734 			    AAC_PRINTF_BUFSIZE, sc->sc_common->ac_printf);
    735 			sc->sc_common->ac_printf[0] = '\0';
    736 		}
    737 		AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
    738 		AAC_QNOTIFY(sc, AAC_DB_PRINTF);
    739 		claimed = 1;
    740 	}
    741 
    742 	/*
    743 	 * Controller has a message for us?
    744 	 */
    745 	if ((reason & AAC_DB_COMMAND_READY) != 0) {
    746 		aac_host_command(sc);
    747 		AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY);
    748 		claimed = 1;
    749 	}
    750 
    751 	/*
    752 	 * Controller has a response for us?
    753 	 */
    754 	if ((reason & AAC_DB_RESPONSE_READY) != 0) {
    755 		aac_host_response(sc);
    756 		AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
    757 		claimed = 1;
    758 	}
    759 
    760 	/*
    761 	 * Spurious interrupts that we don't use - reset the mask and clear
    762 	 * the interrupts.
    763 	 */
    764 	if ((reason & (AAC_DB_SYNC_COMMAND | AAC_DB_COMMAND_NOT_FULL |
    765             AAC_DB_RESPONSE_NOT_FULL)) != 0) {
    766 		AAC_UNMASK_INTERRUPTS(sc);
    767 		AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND |
    768 		    AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL);
    769 		claimed = 1;
    770 	}
    771 
    772 	return (claimed);
    773 }
    774 
    775 /*
    776  * Handle notification of one or more FIBs coming from the controller.
    777  */
    778 void
    779 aac_host_command(struct aac_softc *sc)
    780 {
    781 	struct aac_fib *fib;
    782 	u_int32_t fib_size;
    783 
    784 	for (;;) {
    785 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size,
    786 		    &fib))
    787 			break;	/* nothing to do */
    788 
    789 		bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
    790 		    (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib),
    791 		    BUS_DMASYNC_POSTREAD);
    792 
    793 		switch (le16toh(fib->Header.Command)) {
    794 		case AifRequest:
    795 #ifdef notyet
    796 			aac_handle_aif(sc,
    797 			    (struct aac_aif_command *)&fib->data[0]);
    798 #endif
    799 			break;
    800 		default:
    801 			printf("%s: unknown command from controller\n",
    802 			    sc->sc_dv.dv_xname);
    803 			AAC_PRINT_FIB(sc, fib);
    804 			break;
    805 		}
    806 
    807 		bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
    808 		    (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib),
    809 		    BUS_DMASYNC_PREREAD);
    810 
    811 		/* XXX reply to FIBs requesting responses ?? */
    812 		/* XXX how do we return these FIBs to the controller? */
    813 	}
    814 }
    815 
    816 /*
    817  * Handle notification of one or more FIBs completed by the controller
    818  */
    819 void
    820 aac_host_response(struct aac_softc *sc)
    821 {
    822 	struct aac_ccb *ac;
    823 	struct aac_fib *fib;
    824 	u_int32_t fib_size;
    825 
    826 	/*
    827 	 * Look for completed FIBs on our queue.
    828 	 */
    829 	for (;;) {
    830 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
    831 		    &fib))
    832 			break;	/* nothing to do */
    833 
    834 		bus_dmamap_sync(sc->sc_dmat, sc->sc_fibs_dmamap,
    835 		    (caddr_t)fib - (caddr_t)sc->sc_fibs, sizeof(*fib),
    836 		    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    837 
    838 		if ((fib->Header.SenderData & 0x80000000) == 0) {
    839 			/* Not valid; not sent by us. */
    840 			AAC_PRINT_FIB(sc, fib);
    841 		} else {
    842 			ac = (struct aac_ccb *)((caddr_t)sc->sc_ccbs +
    843 			    (fib->Header.SenderData & 0x7fffffff));
    844 			fib->Header.SenderData = 0;
    845 			SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_complete, ac, ac_chain);
    846 		}
    847 	}
    848 
    849 	/*
    850 	 * Deal with any completed commands.
    851 	 */
    852 	while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_complete)) != NULL) {
    853 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_complete, ac_chain);
    854 		ac->ac_flags |= AAC_CCB_COMPLETED;
    855 
    856 		if (ac->ac_intr != NULL)
    857 			(*ac->ac_intr)(ac);
    858 	}
    859 
    860 	/*
    861 	 * Try to submit more commands.
    862 	 */
    863 	if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue))
    864 		aac_ccb_enqueue(sc, NULL);
    865 }
    866 
    867 /*
    868  * Send a synchronous command to the controller and wait for a result.
    869  */
    870 int
    871 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
    872 		 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp)
    873 {
    874 	int i;
    875 	u_int32_t status;
    876 	int s;
    877 
    878 	s = splbio();
    879 
    880 	/* Populate the mailbox. */
    881 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
    882 
    883 	/* Ensure the sync command doorbell flag is cleared. */
    884 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
    885 
    886 	/* ... then set it to signal the adapter. */
    887 	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
    888 	DELAY(AAC_SYNC_DELAY);
    889 
    890 	/* Spin waiting for the command to complete. */
    891 	for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) {
    892 		if (AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND);
    893 			break;
    894 		DELAY(1000);
    895 	}
    896 	if (i == AAC_IMMEDIATE_TIMEOUT * 1000) {
    897 		splx(s);
    898 		return (EIO);
    899 	}
    900 
    901 	/* Clear the completion flag. */
    902 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
    903 
    904 	/* Get the command status. */
    905 	status = AAC_GET_MAILBOXSTATUS(sc);
    906 	splx(s);
    907 	if (sp != NULL)
    908 		*sp = status;
    909 
    910 	return (0);	/* XXX Check command return status? */
    911 }
    912 
    913 /*
    914  * Send a synchronous FIB to the controller and wait for a result.
    915  */
    916 int
    917 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
    918 	     void *data, u_int16_t datasize, void *result,
    919 	     u_int16_t *resultsize)
    920 {
    921 	struct aac_fib *fib;
    922 	u_int32_t fibpa, status;
    923 
    924 	fib = &sc->sc_common->ac_sync_fib;
    925 	fibpa = sc->sc_common_seg.ds_addr +
    926 	    offsetof(struct aac_common, ac_sync_fib);
    927 
    928 	if (datasize > AAC_FIB_DATASIZE)
    929 		return (EINVAL);
    930 
    931 	/*
    932 	 * Set up the sync FIB.
    933 	 */
    934 	fib->Header.XferState = htole32(AAC_FIBSTATE_HOSTOWNED |
    935 	    AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY | xferstate);
    936 	fib->Header.Command = htole16(command);
    937 	fib->Header.StructType = AAC_FIBTYPE_TFIB;
    938 	fib->Header.Size = htole16(sizeof(*fib) + datasize);
    939 	fib->Header.SenderSize = htole16(sizeof(*fib));
    940 	fib->Header.SenderFibAddress = htole32((u_int32_t)fib);	/* XXX */
    941 	fib->Header.ReceiverFibAddress = htole32(fibpa);
    942 
    943 	/*
    944 	 * Copy in data.
    945 	 */
    946 	if (data != NULL) {
    947 		memcpy(fib->data, data, datasize);
    948 		fib->Header.XferState |=
    949 		    htole32(AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM);
    950 	}
    951 
    952 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
    953 	    (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib),
    954 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    955 
    956 	/*
    957 	 * Give the FIB to the controller, wait for a response.
    958 	 */
    959 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fibpa, 0, 0, 0, &status))
    960 		return (EIO);
    961 
    962 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
    963 	    (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib),
    964 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    965 
    966 	/*
    967 	 * Copy out the result
    968 	 */
    969 	if (result != NULL) {
    970 		*resultsize = le16toh(fib->Header.Size) - sizeof(fib->Header);
    971 		memcpy(result, fib->data, *resultsize);
    972 	}
    973 
    974 	return (0);
    975 }
    976 
    977 struct aac_ccb *
    978 aac_ccb_alloc(struct aac_softc *sc, int flags)
    979 {
    980 	struct aac_ccb *ac;
    981 	int s;
    982 
    983 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_alloc(%p, 0x%x) ", sc, flags));
    984 
    985 	s = splbio();
    986 	ac = SIMPLEQ_FIRST(&sc->sc_ccb_free);
    987 #ifdef DIAGNOSTIC
    988 	if (ac == NULL)
    989 		panic("aac_ccb_get: no free CCBS");
    990 #endif
    991 	SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ac_chain);
    992 	splx(s);
    993 
    994 	ac->ac_flags = flags;
    995 	return (ac);
    996 }
    997 
    998 void
    999 aac_ccb_free(struct aac_softc *sc, struct aac_ccb *ac)
   1000 {
   1001 	int s;
   1002 
   1003 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_free(%p, %p) ", sc, ac));
   1004 
   1005 	ac->ac_flags = 0;
   1006 	ac->ac_intr = NULL;
   1007 	ac->ac_fib->Header.XferState = htole32(AAC_FIBSTATE_EMPTY);
   1008 	ac->ac_fib->Header.StructType = AAC_FIBTYPE_TFIB;
   1009 	ac->ac_fib->Header.Flags = 0;
   1010 	ac->ac_fib->Header.SenderSize = htole16(sizeof(*ac->ac_fib));
   1011 
   1012 #ifdef AAC_DEBUG
   1013 	/*
   1014 	 * These are duplicated in aac_ccb_submit() to cover the case where
   1015 	 * an intermediate stage may have destroyed them.  They're left
   1016 	 * initialised here for debugging purposes only.
   1017 	 */
   1018 	ac->ac_fib->Header.SenderFibAddress = htole32((u_int32_t)ac->ac_fib);
   1019 	ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
   1020 #endif
   1021 
   1022 	s = splbio();
   1023 	SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ac, ac_chain);
   1024 	splx(s);
   1025 }
   1026 
   1027 int
   1028 aac_ccb_map(struct aac_softc *sc, struct aac_ccb *ac)
   1029 {
   1030 	int error;
   1031 
   1032 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_map(%p, %p) ", sc, ac));
   1033 
   1034 #ifdef DIAGNOSTIC
   1035 	if ((ac->ac_flags & AAC_CCB_MAPPED) != 0)
   1036 		panic("aac_ccb_map: already mapped");
   1037 #endif
   1038 
   1039 	error = bus_dmamap_load(sc->sc_dmat, ac->ac_dmamap_xfer, ac->ac_data,
   1040 	    ac->ac_datalen, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
   1041 	    ((ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE));
   1042 	if (error) {
   1043 		printf("%s: aac_ccb_map: ", sc->sc_dv.dv_xname);
   1044 		if (error == EFBIG)
   1045 			printf("more than %d dma segs\n", AAC_MAX_SGENTRIES);
   1046 		else
   1047 			printf("error %d loading dma map\n", error);
   1048 		return (error);
   1049 	}
   1050 
   1051 	bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
   1052 	    (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_PREREAD :
   1053 	    BUS_DMASYNC_PREWRITE);
   1054 
   1055 #ifdef DIAGNOSTIC
   1056 	ac->ac_flags |= AAC_CCB_MAPPED;
   1057 #endif
   1058 	return (0);
   1059 }
   1060 
   1061 void
   1062 aac_ccb_unmap(struct aac_softc *sc, struct aac_ccb *ac)
   1063 {
   1064 
   1065 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_unmap(%p, %p) ", sc, ac));
   1066 
   1067 #ifdef DIAGNOSTIC
   1068 	if ((ac->ac_flags & AAC_CCB_MAPPED) == 0)
   1069 		panic("aac_ccb_unmap: not mapped");
   1070 #endif
   1071 
   1072 	bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
   1073 	    (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_POSTREAD :
   1074 	    BUS_DMASYNC_POSTWRITE);
   1075 	bus_dmamap_unload(sc->sc_dmat, ac->ac_dmamap_xfer);
   1076 
   1077 #ifdef DIAGNOSTIC
   1078 	ac->ac_flags &= ~AAC_CCB_MAPPED;
   1079 #endif
   1080 }
   1081 
   1082 void
   1083 aac_ccb_enqueue(struct aac_softc *sc, struct aac_ccb *ac)
   1084 {
   1085 	int s;
   1086 
   1087 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_enqueue(%p, %p) ", sc, ac));
   1088 
   1089 	s = splbio();
   1090 
   1091 	if (ac != NULL)
   1092 		SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ac, ac_chain);
   1093 
   1094 	while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) {
   1095 		if (aac_ccb_submit(sc, ac))
   1096 			break;
   1097 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ac_chain);
   1098 	}
   1099 
   1100 	splx(s);
   1101 }
   1102 
   1103 int
   1104 aac_ccb_submit(struct aac_softc *sc, struct aac_ccb *ac)
   1105 {
   1106 
   1107 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_submit(%p, %p) ", sc, ac));
   1108 
   1109 	/* Fix up the address values. */
   1110 	ac->ac_fib->Header.SenderFibAddress = htole32((u_int32_t)ac->ac_fib);
   1111 	ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
   1112 
   1113 	/* Save a pointer to the command for speedy reverse-lookup. */
   1114 	ac->ac_fib->Header.SenderData =
   1115 	    (u_int32_t)((caddr_t)ac - (caddr_t)sc->sc_ccbs) | 0x80000000;
   1116 
   1117 	bus_dmamap_sync(sc->sc_dmat, sc->sc_fibs_dmamap,
   1118 	    (caddr_t)ac->ac_fib - (caddr_t)sc->sc_fibs, sizeof(*ac->ac_fib),
   1119 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1120 
   1121 	/* Put the FIB on the outbound queue. */
   1122 	return (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, ac->ac_fib));
   1123 }
   1124 
   1125 int
   1126 aac_ccb_poll(struct aac_softc *sc, struct aac_ccb *ac, int timo)
   1127 {
   1128 	int rv, s;
   1129 
   1130 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_poll(%p, %p, %d) ", sc, ac, timo));
   1131 
   1132 	s = splbio();
   1133 
   1134 	if ((rv = aac_ccb_submit(sc, ac)) != 0) {
   1135 		splx(s);
   1136 		return (rv);
   1137 	}
   1138 
   1139 	for (timo *= 1000; timo != 0; timo--) {
   1140 		aac_intr(sc);
   1141 		if ((ac->ac_flags & AAC_CCB_COMPLETED) != 0)
   1142 			break;
   1143 		DELAY(100);
   1144 	}
   1145 
   1146 	splx(s);
   1147 	return (timo == 0);
   1148 }
   1149 
   1150 /*
   1151  * Atomically insert an entry into the nominated queue, returns 0 on success
   1152  * or EBUSY if the queue is full.
   1153  *
   1154  * XXX Note that it would be more efficient to defer notifying the
   1155  * controller in the case where we may be inserting several entries in rapid
   1156  * succession, but implementing this usefully is difficult.
   1157  */
   1158 int
   1159 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_fib *fib)
   1160 {
   1161 	u_int32_t fib_size, fib_addr, pi, ci;
   1162 
   1163 	fib_size = le16toh(fib->Header.Size);
   1164 	fib_addr = le32toh(fib->Header.ReceiverFibAddress);
   1165 
   1166 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1167 	    (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common,
   1168 	    sizeof(sc->sc_common->ac_qbuf),
   1169 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1170 
   1171 	/* Get the producer/consumer indices.  */
   1172 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
   1173 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
   1174 
   1175 	/* Wrap the queue? */
   1176 	if (pi >= aac_qinfo[queue].size)
   1177 		pi = 0;
   1178 
   1179 	/* Check for queue full. */
   1180 	if ((pi + 1) == ci)
   1181 		return (EAGAIN);
   1182 
   1183 	/* Populate queue entry. */
   1184 	(sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size);
   1185 	(sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr);
   1186 
   1187 	/* Update producer index. */
   1188 	sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1);
   1189 
   1190 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1191 	    (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common,
   1192 	    sizeof(sc->sc_common->ac_qbuf),
   1193 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1194 
   1195 	/* Notify the adapter if we know how. */
   1196 	if (aac_qinfo[queue].notify != 0)
   1197 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
   1198 
   1199 	return (0);
   1200 }
   1201 
   1202 /*
   1203  * Atomically remove one entry from the nominated queue, returns 0 on success
   1204  * or ENOENT if the queue is empty.
   1205  */
   1206 int
   1207 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
   1208 		struct aac_fib **fib_addr)
   1209 {
   1210 	u_int32_t pi, ci;
   1211 	int notify;
   1212 
   1213 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1214 	    (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common,
   1215 	    sizeof(sc->sc_common->ac_qbuf),
   1216 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1217 
   1218 	/* Get the producer/consumer indices. */
   1219 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
   1220 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
   1221 
   1222 	/* Check for queue empty. */
   1223 	if (ci == pi)
   1224 		return (ENOENT);
   1225 
   1226 	notify = 0;
   1227 	if (ci == pi + 1)
   1228 		notify = 1;
   1229 
   1230 	/* Wrap the queue? */
   1231 	if (ci >= aac_qinfo[queue].size)
   1232 		ci = 0;
   1233 
   1234 	/* Fetch the entry. */
   1235 	*fib_size = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_size);
   1236 	*fib_addr = le32toh((struct aac_fib *)
   1237 	    (sc->sc_qentries[queue] + ci)->aq_fib_addr);
   1238 
   1239 	/* Update consumer index. */
   1240 	sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
   1241 
   1242 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1243 	    (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common,
   1244 	    sizeof(sc->sc_common->ac_qbuf),
   1245 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1246 
   1247 	/* If we have made the queue un-full, notify the adapter. */
   1248 	if (notify && (aac_qinfo[queue].notify != 0))
   1249 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
   1250 
   1251 	return (0);
   1252 }
   1253 
   1254 #ifdef AAC_DEBUG
   1255 /*
   1256  * Print a FIB
   1257  */
   1258 void
   1259 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller)
   1260 {
   1261 	struct aac_blockread *br;
   1262 	struct aac_blockwrite *bw;
   1263 	struct aac_sg_table *sg;
   1264 	char buf[512];
   1265 	int i;
   1266 
   1267 	printf("%s: FIB @ %p\n", caller, fib);
   1268 	bitmask_snprintf(le32toh(fib->Header.XferState),
   1269 	    "\20"
   1270 	    "\1HOSTOWNED"
   1271 	    "\2ADAPTEROWNED"
   1272 	    "\3INITIALISED"
   1273 	    "\4EMPTY"
   1274 	    "\5FROMPOOL"
   1275 	    "\6FROMHOST"
   1276 	    "\7FROMADAP"
   1277 	    "\10REXPECTED"
   1278 	    "\11RNOTEXPECTED"
   1279 	    "\12DONEADAP"
   1280 	    "\13DONEHOST"
   1281 	    "\14HIGH"
   1282 	    "\15NORM"
   1283 	    "\16ASYNC"
   1284 	    "\17PAGEFILEIO"
   1285 	    "\20SHUTDOWN"
   1286 	    "\21LAZYWRITE"
   1287 	    "\22ADAPMICROFIB"
   1288 	    "\23BIOSFIB"
   1289 	    "\24FAST_RESPONSE"
   1290 	    "\25APIFIB\n",
   1291 	    buf,
   1292 	    sizeof(buf));
   1293 
   1294 	printf("  XferState       %s\n", buf);
   1295 	printf("  Command         %d\n", le16toh(fib->Header.Command));
   1296 	printf("  StructType      %d\n", fib->Header.StructType);
   1297 	printf("  Flags           0x%x\n", fib->Header.Flags);
   1298 	printf("  Size            %d\n", le16toh(fib->Header.Size));
   1299 	printf("  SenderSize      %d\n", le16toh(fib->Header.SenderSize));
   1300 	printf("  SenderAddress   0x%x\n",
   1301 	    le32toh(fib->Header.SenderFibAddress));
   1302 	printf("  ReceiverAddress 0x%x\n",
   1303 	    le32toh(fib->Header.ReceiverFibAddress));
   1304 	printf("  SenderData      0x%x\n", fib->Header.SenderData);
   1305 
   1306 	switch (fib->Header.Command) {
   1307 	case ContainerCommand: {
   1308 		br = (struct aac_blockread *)fib->data;
   1309 		bw = (struct aac_blockwrite *)fib->data;
   1310 		sg = NULL;
   1311 
   1312 		if (le32toh(br->Command) == VM_CtBlockRead) {
   1313 			printf("  BlockRead: container %d  0x%x/%d\n",
   1314 			    le32toh(br->ContainerId), le32toh(br->BlockNumber),
   1315 			    le32toh(br->ByteCount));
   1316 			sg = &br->SgMap;
   1317 		}
   1318 		if (le32toh(bw->Command) == VM_CtBlockWrite) {
   1319 			printf("  BlockWrite: container %d  0x%x/%d (%s)\n",
   1320 			    le32toh(bw->ContainerId), le32toh(bw->BlockNumber),
   1321 			    le32toh(bw->ByteCount),
   1322 			    le32toh(bw->Stable) == CSTABLE ?
   1323 			    "stable" : "unstable");
   1324 			sg = &bw->SgMap;
   1325 		}
   1326 		if (sg != NULL) {
   1327 			printf("  %d s/g entries\n", le32toh(sg->SgCount));
   1328 			for (i = 0; i < le32toh(sg->SgCount); i++)
   1329 				printf("  0x%08x/%d\n",
   1330 				    le32toh(sg->SgEntry[i].SgAddress),
   1331 				    le32toh(sg->SgEntry[i].SgByteCount));
   1332 		}
   1333 		break;
   1334 	}
   1335 	default:
   1336 		printf("   %16D\n", fib->data, " ");
   1337 		printf("   %16D\n", fib->data + 16, " ");
   1338 		break;
   1339 	}
   1340 }
   1341 #endif
   1342