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