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