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