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