Home | History | Annotate | Line # | Download | only in ic
aac.c revision 1.45
      1 /*	$NetBSD: aac.c,v 1.45 2016/09/27 03:33:32 pgoyette 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  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*-
     33  * Copyright (c) 2001 Scott Long
     34  * Copyright (c) 2001 Adaptec, Inc.
     35  * Copyright (c) 2000 Michael Smith
     36  * Copyright (c) 2000 BSDi
     37  * Copyright (c) 2000 Niklas Hallqvist
     38  * All rights reserved.
     39  *
     40  * Redistribution and use in source and binary forms, with or without
     41  * modification, are permitted provided that the following conditions
     42  * are met:
     43  * 1. Redistributions of source code must retain the above copyright
     44  *    notice, this list of conditions and the following disclaimer.
     45  * 2. Redistributions in binary form must reproduce the above copyright
     46  *    notice, this list of conditions and the following disclaimer in the
     47  *    documentation and/or other materials provided with the distribution.
     48  *
     49  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     59  * SUCH DAMAGE.
     60  */
     61 
     62 /*
     63  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
     64  *
     65  * TODO:
     66  *
     67  * o Management interface.
     68  * o Look again at some of the portability issues.
     69  * o Handle various AIFs (e.g., notification that a container is going away).
     70  */
     71 
     72 #include <sys/cdefs.h>
     73 __KERNEL_RCSID(0, "$NetBSD: aac.c,v 1.45 2016/09/27 03:33:32 pgoyette Exp $");
     74 
     75 #include <sys/param.h>
     76 #include <sys/systm.h>
     77 #include <sys/buf.h>
     78 #include <sys/device.h>
     79 #include <sys/kernel.h>
     80 #include <sys/malloc.h>
     81 #include <sys/proc.h>
     82 #include <sys/module.h>
     83 
     84 #include <sys/bus.h>
     85 
     86 #include <dev/ic/aacreg.h>
     87 #include <dev/ic/aacvar.h>
     88 #include <dev/ic/aac_tables.h>
     89 
     90 #include "locators.h"
     91 
     92 #include "ioconf.h"
     93 
     94 static int	aac_new_intr(void *);
     95 static int	aac_alloc_commands(struct aac_softc *);
     96 #ifdef notyet
     97 static void	aac_free_commands(struct aac_softc *);
     98 #endif
     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_ccb *);
    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 MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for aac(4)");
    145 
    146 static void	*aac_sdh;
    147 
    148 extern struct	cfdriver aac_cd;
    149 
    150 int
    151 aac_attach(struct aac_softc *sc)
    152 {
    153 	int rv;
    154 
    155 	SIMPLEQ_INIT(&sc->sc_ccb_free);
    156 	SIMPLEQ_INIT(&sc->sc_ccb_queue);
    157 	SIMPLEQ_INIT(&sc->sc_ccb_complete);
    158 
    159 	/*
    160 	 * Disable interrupts before we do anything.
    161 	 */
    162 	AAC_MASK_INTERRUPTS(sc);
    163 
    164 	/*
    165 	 * Initialise the adapter.
    166 	 */
    167 	if (aac_check_firmware(sc))
    168 		return (EINVAL);
    169 
    170 	if ((rv = aac_init(sc)) != 0)
    171 		return (rv);
    172 
    173 	if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) {
    174 		rv = sc->sc_intr_set(sc, aac_new_intr, sc);
    175 		if (rv)
    176 			return (rv);
    177 	}
    178 
    179 	aac_startup(sc);
    180 
    181 	/*
    182 	 * Print a little information about the controller.
    183 	 */
    184 	aac_describe_controller(sc);
    185 
    186 	/*
    187 	 * Attach devices
    188 	 */
    189 	aac_devscan(sc);
    190 
    191 	/*
    192 	 * Enable interrupts, and register our shutdown hook.
    193 	 */
    194 	sc->sc_flags |= AAC_ONLINE;
    195 	AAC_UNMASK_INTERRUPTS(sc);
    196 	if (aac_sdh != NULL)
    197 		shutdownhook_establish(aac_shutdown, NULL);
    198 	return (0);
    199 }
    200 
    201 int
    202 aac_devscan(struct aac_softc *sc)
    203 {
    204 	struct aac_attach_args aaca;
    205 	int i;
    206 	int locs[AACCF_NLOCS];
    207 
    208 	for (i = 0; i < AAC_MAX_CONTAINERS; i++) {
    209 		if (!sc->sc_hdr[i].hd_present)
    210 			continue;
    211 		aaca.aaca_unit = i;
    212 
    213 		locs[AACCF_UNIT] = i;
    214 
    215 		config_found_sm_loc(sc->sc_dv, "aac", locs, &aaca,
    216 				    aac_print, config_stdsubmatch);
    217 	}
    218 	return 0;
    219 }
    220 
    221 static int
    222 aac_alloc_commands(struct aac_softc *sc)
    223 {
    224 	struct aac_fibmap *fm;
    225 	struct aac_ccb *ac;
    226 	bus_addr_t fibpa;
    227 	int size, nsegs;
    228 	int i, error;
    229 	int state;
    230 
    231 	if (sc->sc_total_fibs + sc->sc_max_fibs_alloc > sc->sc_max_fibs)
    232 		return ENOMEM;
    233 
    234 	fm = malloc(sizeof(struct aac_fibmap), M_AACBUF, M_NOWAIT|M_ZERO);
    235 	if (fm == NULL)
    236 		return ENOMEM;
    237 
    238 	size = sc->sc_max_fibs_alloc * sc->sc_max_fib_size;
    239 
    240 	state = 0;
    241 	error = bus_dmamap_create(sc->sc_dmat, size, 1, size,
    242 	    0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &fm->fm_fibmap);
    243 	if (error != 0) {
    244 		aprint_error_dev(sc->sc_dv, "cannot create fibs dmamap (%d)\n",
    245 		    error);
    246 		goto bail_out;
    247 	}
    248 	state++;
    249 	error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0,
    250 	    &fm->fm_fibseg, 1, &nsegs, BUS_DMA_NOWAIT);
    251 	if (error != 0) {
    252 		aprint_error_dev(sc->sc_dv, "can't allocate fibs structure (%d)\n",
    253 		    error);
    254 		goto bail_out;
    255 	}
    256 	state++;
    257 	error = bus_dmamem_map(sc->sc_dmat, &fm->fm_fibseg, nsegs, size,
    258 	    (void **)&fm->fm_fibs, 0);
    259 	if (error != 0) {
    260 		aprint_error_dev(sc->sc_dv, "can't map fibs structure (%d)\n",
    261 		    error);
    262 		goto bail_out;
    263 	}
    264 	state++;
    265 	error = bus_dmamap_load(sc->sc_dmat, fm->fm_fibmap, fm->fm_fibs,
    266 	    size, NULL, BUS_DMA_NOWAIT);
    267 	if (error != 0) {
    268 		aprint_error_dev(sc->sc_dv, "cannot load fibs dmamap (%d)\n",
    269 		    error);
    270 		goto bail_out;
    271 	}
    272 
    273 	fm->fm_ccbs = sc->sc_ccbs + sc->sc_total_fibs;
    274 	fibpa = fm->fm_fibseg.ds_addr;
    275 
    276 	memset(fm->fm_fibs, 0, size);
    277 	for (i = 0; i < sc->sc_max_fibs_alloc; i++) {
    278 		ac = fm->fm_ccbs + i;
    279 
    280 		error = bus_dmamap_create(sc->sc_dmat, AAC_MAX_XFER(sc),
    281 		    sc->sc_max_sgs, AAC_MAX_XFER(sc), 0,
    282 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ac->ac_dmamap_xfer);
    283 		if (error) {
    284 			while (--i >= 0) {
    285 				ac = fm->fm_ccbs + i;
    286 				bus_dmamap_destroy(sc->sc_dmat,
    287 				    ac->ac_dmamap_xfer);
    288 				sc->sc_total_fibs--;
    289 			}
    290 			aprint_error_dev(sc->sc_dv, "cannot create ccb dmamap (%d)",
    291 			    error);
    292 			goto bail_out;
    293 		}
    294 
    295 		ac->ac_fibmap = fm;
    296 		ac->ac_fib = (struct aac_fib *)
    297 		    ((char *) fm->fm_fibs + i * sc->sc_max_fib_size);
    298 		ac->ac_fibphys = fibpa + i * sc->sc_max_fib_size;
    299 		aac_ccb_free(sc, ac);
    300 		sc->sc_total_fibs++;
    301 	}
    302 
    303 	TAILQ_INSERT_TAIL(&sc->sc_fibmap_tqh, fm, fm_link);
    304 
    305 	return 0;
    306 bail_out:
    307 	if (state > 3)
    308 		bus_dmamap_unload(sc->sc_dmat, fm->fm_fibmap);
    309 	if (state > 2)
    310 		bus_dmamem_unmap(sc->sc_dmat, (void *) fm->fm_fibs, size);
    311 	if (state > 1)
    312 		bus_dmamem_free(sc->sc_dmat, &fm->fm_fibseg, 1);
    313 
    314 	bus_dmamap_destroy(sc->sc_dmat, fm->fm_fibmap);
    315 
    316 	free(fm, M_AACBUF);
    317 
    318 	return error;
    319 }
    320 
    321 #ifdef notyet
    322 static void
    323 aac_free_commands(struct aac_softc *sc)
    324 {
    325 }
    326 #endif
    327 
    328 /*
    329  * Print autoconfiguration message for a sub-device.
    330  */
    331 static int
    332 aac_print(void *aux, const char *pnp)
    333 {
    334 	struct aac_attach_args *aaca;
    335 
    336 	aaca = aux;
    337 
    338 	if (pnp != NULL)
    339 		aprint_normal("block device at %s", pnp);
    340 	aprint_normal(" unit %d", aaca->aaca_unit);
    341 	return (UNCONF);
    342 }
    343 
    344 /*
    345  * Look up a text description of a numeric error code and return a pointer to
    346  * same.
    347  */
    348 const char *
    349 aac_describe_code(const struct aac_code_lookup *table, u_int32_t code)
    350 {
    351 	int i;
    352 
    353 	for (i = 0; table[i].string != NULL; i++)
    354 		if (table[i].code == code)
    355 			return (table[i].string);
    356 
    357 	return (table[i + 1].string);
    358 }
    359 
    360 /*
    361  * snprintb(3) format string for the adapter options.
    362  */
    363 static const char *optfmt =
    364     "\20\1SNAPSHOT\2CLUSTERS\3WCACHE\4DATA64\5HOSTTIME\6RAID50"
    365     "\7WINDOW4GB"
    366     "\10SCSIUPGD\11SOFTERR\12NORECOND\13SGMAP64\14ALARM\15NONDASD";
    367 
    368 static void
    369 aac_describe_controller(struct aac_softc *sc)
    370 {
    371 	u_int8_t fmtbuf[256];
    372 	u_int8_t tbuf[AAC_FIB_DATASIZE];
    373 	u_int16_t bufsize;
    374 	struct aac_adapter_info *info;
    375 	u_int8_t arg;
    376 
    377 	arg = 0;
    378 	if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &tbuf,
    379 	    &bufsize)) {
    380 		aprint_error_dev(sc->sc_dv, "RequestAdapterInfo failed\n");
    381 		return;
    382 	}
    383 	if (bufsize != sizeof(*info)) {
    384 		aprint_error_dev(sc->sc_dv,
    385 		    "RequestAdapterInfo returned wrong data size (%d != %zu)\n",
    386 		    bufsize, sizeof(*info));
    387 		return;
    388 	}
    389 	info = (struct aac_adapter_info *)&tbuf[0];
    390 
    391 	aprint_normal_dev(sc->sc_dv, "%s at %dMHz, %dMB mem (%dMB cache), %s\n",
    392 	    aac_describe_code(aac_cpu_variant, le32toh(info->CpuVariant)),
    393 	    le32toh(info->ClockSpeed),
    394 	    le32toh(info->TotalMem) / (1024 * 1024),
    395 	    le32toh(info->BufferMem) / (1024 * 1024),
    396 	    aac_describe_code(aac_battery_platform,
    397 			      le32toh(info->batteryPlatform)));
    398 
    399 	aprint_verbose_dev(sc->sc_dv, "Kernel %d.%d-%d [Build %d], ",
    400 	    info->KernelRevision.external.comp.major,
    401 	    info->KernelRevision.external.comp.minor,
    402 	    info->KernelRevision.external.comp.dash,
    403 	    info->KernelRevision.buildNumber);
    404 
    405 	aprint_verbose("Monitor %d.%d-%d [Build %d], S/N %6X\n",
    406 	    info->MonitorRevision.external.comp.major,
    407 	    info->MonitorRevision.external.comp.minor,
    408 	    info->MonitorRevision.external.comp.dash,
    409 	    info->MonitorRevision.buildNumber,
    410 	    ((u_int32_t)info->SerialNumber & 0xffffff));
    411 
    412 	snprintb(fmtbuf, sizeof(fmtbuf), optfmt, sc->sc_supported_options);
    413 	aprint_verbose_dev(sc->sc_dv, "Controller supports: %s\n", fmtbuf);
    414 
    415 	/* Save the kernel revision structure for later use. */
    416 	sc->sc_revision = info->KernelRevision;
    417 }
    418 
    419 /*
    420  * Retrieve the firmware version numbers.  Dell PERC2/QC cards with firmware
    421  * version 1.x are not compatible with this driver.
    422  */
    423 static int
    424 aac_check_firmware(struct aac_softc *sc)
    425 {
    426 	u_int32_t major, minor, opts, atusize = 0, status = 0;
    427 	u_int32_t calcsgs;
    428 
    429 	if ((sc->sc_quirks & AAC_QUIRK_PERC2QC) != 0) {
    430 		if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
    431 		    NULL)) {
    432 			aprint_error_dev(sc->sc_dv, "error reading firmware version\n");
    433 			return (1);
    434 		}
    435 
    436 		/* These numbers are stored as ASCII! */
    437 		major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
    438 		minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
    439 		if (major == 1) {
    440 			aprint_error_dev(sc->sc_dv,
    441 			    "firmware version %d.%d not supported.\n",
    442 			    major, minor);
    443 			return (1);
    444 		}
    445 	}
    446 
    447 	if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, &status)) {
    448 		if (status != AAC_SRB_STS_INVALID_REQUEST) {
    449 			aprint_error_dev(sc->sc_dv, "GETINFO failed, status 0x%08x\n", status);
    450 			return (1);
    451 		}
    452 	} else {
    453 		opts = AAC_GET_MAILBOX(sc, 1);
    454 		atusize = AAC_GET_MAILBOX(sc, 2);
    455 		sc->sc_supported_options = opts;
    456 
    457 		if (((opts & AAC_SUPPORTED_4GB_WINDOW) != 0) &&
    458 		    ((sc->sc_quirks & AAC_QUIRK_NO4GB) == 0) )
    459 			sc->sc_quirks |= AAC_QUIRK_4GB_WINDOW;
    460 
    461 		if (((opts & AAC_SUPPORTED_SGMAP_HOST64) != 0) &&
    462 		    (sizeof(bus_addr_t) > 4)) {
    463 			aprint_normal_dev(sc->sc_dv, "Enabling 64-bit address support\n");
    464 			sc->sc_quirks |= AAC_QUIRK_SG_64BIT;
    465 		}
    466 		if ((opts & AAC_SUPPORTED_NEW_COMM) &&
    467 		    (sc->sc_if.aif_send_command != NULL)) {
    468 			sc->sc_quirks |= AAC_QUIRK_NEW_COMM;
    469 		}
    470 		if (opts & AAC_SUPPORTED_64BIT_ARRAYSIZE)
    471 			sc->sc_quirks |= AAC_QUIRK_ARRAY_64BIT;
    472 	}
    473 
    474 	sc->sc_max_fibs = (sc->sc_quirks & AAC_QUIRK_256FIBS) ? 256 : 512;
    475 
    476 	if (   (sc->sc_quirks & AAC_QUIRK_NEW_COMM)
    477 	    && (sc->sc_regsize < atusize)) {
    478 		aprint_error_dev(sc->sc_dv, "Not enabling new comm i/f -- "
    479 			     "atusize 0x%08x, regsize 0x%08x\n",
    480 			     atusize,
    481 			     (uint32_t) sc->sc_regsize);
    482 		sc->sc_quirks &= ~AAC_QUIRK_NEW_COMM;
    483 	}
    484 #if 0
    485 	if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) {
    486 		aprint_error_dev(sc->sc_dv, "Not enabling new comm i/f -- "
    487 			     "driver not ready yet\n");
    488 		sc->sc_quirks &= ~AAC_QUIRK_NEW_COMM;
    489 	}
    490 #endif
    491 
    492 	sc->sc_max_fib_size = sizeof(struct aac_fib);
    493 	sc->sc_max_sectors = 128;	/* 64KB */
    494 	if (sc->sc_quirks & AAC_QUIRK_SG_64BIT)
    495 		sc->sc_max_sgs = (sc->sc_max_fib_size
    496 					- sizeof(struct aac_blockwrite64)
    497 					+ sizeof(struct aac_sg_table64))
    498 				      / sizeof(struct aac_sg_table64);
    499 	else
    500 		sc->sc_max_sgs = (sc->sc_max_fib_size
    501 					- sizeof(struct aac_blockwrite)
    502 					+ sizeof(struct aac_sg_table))
    503 				      / sizeof(struct aac_sg_table);
    504 
    505 	if (!aac_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL)) {
    506 		u_int32_t	opt1, opt2, opt3;
    507 		u_int32_t	tmpval;
    508 
    509 		opt1 = AAC_GET_MAILBOX(sc, 1);
    510 		opt2 = AAC_GET_MAILBOX(sc, 2);
    511 		opt3 = AAC_GET_MAILBOX(sc, 3);
    512 		if (!opt1 || !opt2 || !opt3) {
    513 			aprint_verbose_dev(sc->sc_dv, "GETCOMMPREF appears untrustworthy."
    514 			    "  Ignoring.\n");
    515 		} else {
    516 			sc->sc_max_fib_size = le32toh(opt1) & 0xffff;
    517 			sc->sc_max_sectors = (le32toh(opt1) >> 16) << 1;
    518 			tmpval = (le32toh(opt2) >> 16);
    519 			if (tmpval < sc->sc_max_sgs) {
    520 				sc->sc_max_sgs = tmpval;
    521 			}
    522 			tmpval = (le32toh(opt3) & 0xffff);
    523 			if (tmpval < sc->sc_max_fibs) {
    524 				sc->sc_max_fibs = tmpval;
    525 			}
    526 		}
    527 	}
    528 	if (sc->sc_max_fib_size > PAGE_SIZE)
    529 		sc->sc_max_fib_size = PAGE_SIZE;
    530 
    531 	if (sc->sc_quirks & AAC_QUIRK_SG_64BIT)
    532 		calcsgs = (sc->sc_max_fib_size
    533 			   - sizeof(struct aac_blockwrite64)
    534 			   + sizeof(struct aac_sg_table64))
    535 			      / sizeof(struct aac_sg_table64);
    536 	else
    537 		calcsgs = (sc->sc_max_fib_size
    538 			   - sizeof(struct aac_blockwrite)
    539 			   + sizeof(struct aac_sg_table))
    540 			      / sizeof(struct aac_sg_table);
    541 
    542 	if (calcsgs < sc->sc_max_sgs) {
    543 		sc->sc_max_sgs = calcsgs;
    544 	}
    545 
    546 	sc->sc_max_fibs_alloc = PAGE_SIZE / sc->sc_max_fib_size;
    547 
    548 	if (sc->sc_max_fib_size > sizeof(struct aac_fib)) {
    549 		sc->sc_quirks |= AAC_QUIRK_RAW_IO;
    550 		aprint_debug_dev(sc->sc_dv, "Enable raw I/O\n");
    551 	}
    552 	if ((sc->sc_quirks & AAC_QUIRK_RAW_IO) &&
    553 	    (sc->sc_quirks & AAC_QUIRK_ARRAY_64BIT)) {
    554 		sc->sc_quirks |= AAC_QUIRK_LBA_64BIT;
    555 		aprint_normal_dev(sc->sc_dv, "Enable 64-bit array support\n");
    556 	}
    557 
    558 	return (0);
    559 }
    560 
    561 static int
    562 aac_init(struct aac_softc *sc)
    563 {
    564 	int nsegs, i, rv, state, norm, high;
    565 	struct aac_adapter_init	*ip;
    566 	u_int32_t code, qoff;
    567 
    568 	state = 0;
    569 
    570 	/*
    571 	 * First wait for the adapter to come ready.
    572 	 */
    573 	for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) {
    574 		code = AAC_GET_FWSTATUS(sc);
    575 		if ((code & AAC_SELF_TEST_FAILED) != 0) {
    576 			aprint_error_dev(sc->sc_dv, "FATAL: selftest failed\n");
    577 			return (ENXIO);
    578 		}
    579 		if ((code & AAC_KERNEL_PANIC) != 0) {
    580 			aprint_error_dev(sc->sc_dv, "FATAL: controller kernel panic\n");
    581 			return (ENXIO);
    582 		}
    583 		if ((code & AAC_UP_AND_RUNNING) != 0)
    584 			break;
    585 		DELAY(1000);
    586 	}
    587 	if (i == AAC_BOOT_TIMEOUT * 1000) {
    588 		aprint_error_dev(sc->sc_dv,
    589 		    "FATAL: controller not coming ready, status %x\n",
    590 		    code);
    591 		return (ENXIO);
    592 	}
    593 
    594 	sc->sc_aif_fib = malloc(sizeof(struct aac_fib), M_AACBUF,
    595 	    M_NOWAIT | M_ZERO);
    596 	if (sc->sc_aif_fib == NULL) {
    597 		aprint_error_dev(sc->sc_dv, "cannot alloc fib structure\n");
    598 		return (ENOMEM);
    599 	}
    600 	if ((rv = bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_common), 1,
    601 	    sizeof(*sc->sc_common), 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
    602 	    &sc->sc_common_dmamap)) != 0) {
    603 		aprint_error_dev(sc->sc_dv, "cannot create common dmamap\n");
    604 		goto bail_out;
    605 	}
    606 	state++;
    607 	if ((rv = bus_dmamem_alloc(sc->sc_dmat, sizeof(*sc->sc_common),
    608 	    PAGE_SIZE, 0, &sc->sc_common_seg, 1, &nsegs,
    609 	    BUS_DMA_NOWAIT)) != 0) {
    610 		aprint_error_dev(sc->sc_dv, "can't allocate common structure\n");
    611 		goto bail_out;
    612 	}
    613 	state++;
    614 	if ((rv = bus_dmamem_map(sc->sc_dmat, &sc->sc_common_seg, nsegs,
    615 	    sizeof(*sc->sc_common), (void **)&sc->sc_common, 0)) != 0) {
    616 		aprint_error_dev(sc->sc_dv, "can't map common structure\n");
    617 		goto bail_out;
    618 	}
    619 	state++;
    620 	if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_common_dmamap,
    621 	    sc->sc_common, sizeof(*sc->sc_common), NULL,
    622 	    BUS_DMA_NOWAIT)) != 0) {
    623 		aprint_error_dev(sc->sc_dv, "cannot load common dmamap\n");
    624 		goto bail_out;
    625 	}
    626 	state++;
    627 
    628 	memset(sc->sc_common, 0, sizeof(*sc->sc_common));
    629 
    630 	TAILQ_INIT(&sc->sc_fibmap_tqh);
    631 	sc->sc_ccbs = malloc(sizeof(struct aac_ccb) * sc->sc_max_fibs, M_AACBUF,
    632 	    M_NOWAIT | M_ZERO);
    633 	if (sc->sc_ccbs == NULL) {
    634 		aprint_error_dev(sc->sc_dv, "memory allocation failure getting ccbs\n");
    635 		rv = ENOMEM;
    636 		goto bail_out;
    637 	}
    638 	state++;
    639 	while (sc->sc_total_fibs < AAC_PREALLOCATE_FIBS(sc)) {
    640 		if (aac_alloc_commands(sc) != 0)
    641 			break;
    642 	}
    643 	if (sc->sc_total_fibs == 0)
    644 		goto bail_out;
    645 
    646 	/*
    647 	 * Fill in the init structure.  This tells the adapter about the
    648 	 * physical location of various important shared data structures.
    649 	 */
    650 	ip = &sc->sc_common->ac_init;
    651 	ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION);
    652 	if (sc->sc_quirks & AAC_QUIRK_RAW_IO)
    653 		ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION_4);
    654 	ip->MiniPortRevision = htole32(AAC_INIT_STRUCT_MINIPORT_REVISION);
    655 
    656 	ip->AdapterFibsPhysicalAddress = htole32(sc->sc_common_seg.ds_addr +
    657 	    offsetof(struct aac_common, ac_fibs));
    658 	ip->AdapterFibsVirtualAddress = 0;
    659 	ip->AdapterFibsSize =
    660 	    htole32(AAC_ADAPTER_FIBS * sizeof(struct aac_fib));
    661 	ip->AdapterFibAlign = htole32(sizeof(struct aac_fib));
    662 
    663 	ip->PrintfBufferAddress = htole32(sc->sc_common_seg.ds_addr +
    664 	    offsetof(struct aac_common, ac_printf));
    665 	ip->PrintfBufferSize = htole32(AAC_PRINTF_BUFSIZE);
    666 
    667 	/*
    668 	 * The adapter assumes that pages are 4K in size, except on some
    669 	 * broken firmware versions that do the page->byte conversion twice,
    670 	 * therefore 'assuming' that this value is in 16MB units (2^24).
    671 	 * Round up since the granularity is so high.
    672 	 */
    673 	ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
    674 	if (sc->sc_quirks & AAC_QUIRK_BROKEN_MMAP) {
    675 		ip->HostPhysMemPages =
    676 		    (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
    677 	}
    678 	ip->HostElapsedSeconds = 0;	/* reset later if invalid */
    679 
    680 	ip->InitFlags = 0;
    681 	if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) {
    682 		ip->InitFlags = htole32(AAC_INITFLAGS_NEW_COMM_SUPPORTED);
    683 		aprint_normal_dev(sc->sc_dv, "New comm. interface enabled\n");
    684 	}
    685 
    686 	ip->MaxIoCommands = htole32(sc->sc_max_fibs);
    687 	ip->MaxIoSize = htole32(sc->sc_max_sectors << 9);
    688 	ip->MaxFibSize = htole32(sc->sc_max_fib_size);
    689 
    690 	/*
    691 	 * Initialise FIB queues.  Note that it appears that the layout of
    692 	 * the indexes and the segmentation of the entries is mandated by
    693 	 * the adapter, which is only told about the base of the queue index
    694 	 * fields.
    695 	 *
    696 	 * The initial values of the indices are assumed to inform the
    697 	 * adapter of the sizes of the respective queues.
    698 	 *
    699 	 * The Linux driver uses a much more complex scheme whereby several
    700 	 * header records are kept for each queue.  We use a couple of
    701 	 * generic list manipulation functions which 'know' the size of each
    702 	 * list by virtue of a table.
    703 	 */
    704 	qoff = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
    705 	qoff &= ~(AAC_QUEUE_ALIGN - 1);
    706 	sc->sc_queues = (struct aac_queue_table *)((uintptr_t)sc->sc_common + qoff);
    707 	ip->CommHeaderAddress = htole32(sc->sc_common_seg.ds_addr +
    708 	    ((char *)sc->sc_queues - (char *)sc->sc_common));
    709 	memset(sc->sc_queues, 0, sizeof(struct aac_queue_table));
    710 
    711 	norm = htole32(AAC_HOST_NORM_CMD_ENTRIES);
    712 	high = htole32(AAC_HOST_HIGH_CMD_ENTRIES);
    713 
    714 	sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
    715 	    norm;
    716 	sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
    717 	    norm;
    718 	sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
    719 	    high;
    720 	sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
    721 	    high;
    722 
    723 	norm = htole32(AAC_ADAP_NORM_CMD_ENTRIES);
    724 	high = htole32(AAC_ADAP_HIGH_CMD_ENTRIES);
    725 
    726 	sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
    727 	    norm;
    728 	sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
    729 	    norm;
    730 	sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
    731 	    high;
    732 	sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
    733 	    high;
    734 
    735 	norm = htole32(AAC_HOST_NORM_RESP_ENTRIES);
    736 	high = htole32(AAC_HOST_HIGH_RESP_ENTRIES);
    737 
    738 	sc->sc_queues->
    739 	    qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm;
    740 	sc->sc_queues->
    741 	    qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm;
    742 	sc->sc_queues->
    743 	    qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high;
    744 	sc->sc_queues->
    745 	    qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high;
    746 
    747 	norm = htole32(AAC_ADAP_NORM_RESP_ENTRIES);
    748 	high = htole32(AAC_ADAP_HIGH_RESP_ENTRIES);
    749 
    750 	sc->sc_queues->
    751 	    qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm;
    752 	sc->sc_queues->
    753 	    qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm;
    754 	sc->sc_queues->
    755 	    qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high;
    756 	sc->sc_queues->
    757 	    qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high;
    758 
    759 	sc->sc_qentries[AAC_HOST_NORM_CMD_QUEUE] =
    760 	    &sc->sc_queues->qt_HostNormCmdQueue[0];
    761 	sc->sc_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
    762 	    &sc->sc_queues->qt_HostHighCmdQueue[0];
    763 	sc->sc_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
    764 	    &sc->sc_queues->qt_AdapNormCmdQueue[0];
    765 	sc->sc_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
    766 	    &sc->sc_queues->qt_AdapHighCmdQueue[0];
    767 	sc->sc_qentries[AAC_HOST_NORM_RESP_QUEUE] =
    768 	    &sc->sc_queues->qt_HostNormRespQueue[0];
    769 	sc->sc_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
    770 	    &sc->sc_queues->qt_HostHighRespQueue[0];
    771 	sc->sc_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
    772 	    &sc->sc_queues->qt_AdapNormRespQueue[0];
    773 	sc->sc_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
    774 	    &sc->sc_queues->qt_AdapHighRespQueue[0];
    775 
    776 	/*
    777 	 * Do controller-type-specific initialisation
    778 	 */
    779 	switch (sc->sc_hwif) {
    780 	case AAC_HWIF_I960RX:
    781 		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
    782 		break;
    783 	}
    784 
    785 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 0,
    786 	    sizeof(*sc->sc_common),
    787 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    788 
    789 	/*
    790 	 * Give the init structure to the controller.
    791 	 */
    792 	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
    793 	    sc->sc_common_seg.ds_addr + offsetof(struct aac_common, ac_init),
    794 	    0, 0, 0, NULL)) {
    795 		aprint_error_dev(sc->sc_dv, "error establishing init structure\n");
    796 		rv = EIO;
    797 		goto bail_out;
    798 	}
    799 
    800 	return (0);
    801 
    802  bail_out:
    803  	if (state > 4)
    804  		free(sc->sc_ccbs, M_AACBUF);
    805  	if (state > 3)
    806  		bus_dmamap_unload(sc->sc_dmat, sc->sc_common_dmamap);
    807 	if (state > 2)
    808 		bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_common,
    809 		    sizeof(*sc->sc_common));
    810 	if (state > 1)
    811 		bus_dmamem_free(sc->sc_dmat, &sc->sc_common_seg, 1);
    812 	if (state > 0)
    813 		bus_dmamap_destroy(sc->sc_dmat, sc->sc_common_dmamap);
    814 
    815 	free(sc->sc_aif_fib, M_AACBUF);
    816 
    817 	return (rv);
    818 }
    819 
    820 /*
    821  * Probe for containers, create disks.
    822  */
    823 static void
    824 aac_startup(struct aac_softc *sc)
    825 {
    826 	struct aac_mntinfo mi;
    827 	struct aac_mntinforesponse mir;
    828 	struct aac_drive *hd;
    829 	u_int16_t rsize;
    830 	size_t ersize;
    831 	int i;
    832 
    833 	/*
    834 	 * Loop over possible containers.
    835 	 */
    836 	hd = sc->sc_hdr;
    837 
    838 	for (i = 0; i < AAC_MAX_CONTAINERS; i++, hd++) {
    839 		/*
    840 		 * Request information on this container.
    841 		 */
    842 		memset(&mi, 0, sizeof(mi));
    843 		/* use 64-bit LBA if enabled */
    844 		if (sc->sc_quirks & AAC_QUIRK_LBA_64BIT) {
    845 			mi.Command = htole32(VM_NameServe64);
    846 			ersize = sizeof(mir);
    847 		} else {
    848 			mi.Command = htole32(VM_NameServe);
    849 			ersize = sizeof(mir) - sizeof(mir.MntTable[0].CapacityHigh);
    850 		}
    851 		mi.MntType = htole32(FT_FILESYS);
    852 		mi.MntCount = htole32(i);
    853 		if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(mi), &mir,
    854 		    &rsize)) {
    855 			aprint_error_dev(sc->sc_dv, "error probing container %d\n", i);
    856 			continue;
    857 		}
    858 		if (rsize != ersize) {
    859 			aprint_error_dev(sc->sc_dv, "container info response wrong size "
    860 			    "(%d should be %zu)\n", rsize, ersize);
    861 			continue;
    862 		}
    863 
    864 		/*
    865 		 * Check container volume type for validity.  Note that many
    866 		 * of the possible types may never show up.
    867 		 */
    868 		if (le32toh(mir.Status) != ST_OK ||
    869 		    le32toh(mir.MntTable[0].VolType) == CT_NONE)
    870 			continue;
    871 
    872 		hd->hd_present = 1;
    873 		hd->hd_size = le32toh(mir.MntTable[0].Capacity);
    874 		if (sc->sc_quirks & AAC_QUIRK_LBA_64BIT)
    875 			hd->hd_size += (u_int64_t)
    876 			    le32toh(mir.MntTable[0].CapacityHigh) << 32;
    877 		hd->hd_devtype = le32toh(mir.MntTable[0].VolType);
    878 		hd->hd_size &= ~0x1f;
    879 		sc->sc_nunits++;
    880 	}
    881 }
    882 
    883 static void
    884 aac_shutdown(void *cookie)
    885 {
    886 	struct aac_softc *sc;
    887 	struct aac_close_command cc;
    888 	u_int32_t i;
    889 
    890 	for (i = 0; i < aac_cd.cd_ndevs; i++) {
    891 		if ((sc = device_lookup_private(&aac_cd, i)) == NULL)
    892 			continue;
    893 		if ((sc->sc_flags & AAC_ONLINE) == 0)
    894 			continue;
    895 
    896 		AAC_MASK_INTERRUPTS(sc);
    897 
    898 		/*
    899 		 * Send a Container shutdown followed by a HostShutdown FIB
    900 		 * to the controller to convince it that we don't want to
    901 		 * talk to it anymore.  We've been closed and all I/O
    902 		 * completed already
    903 		 */
    904 		memset(&cc, 0, sizeof(cc));
    905 		cc.Command = htole32(VM_CloseAll);
    906 		cc.ContainerId = 0xffffffff;
    907 		if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc),
    908 		    NULL, NULL)) {
    909 			aprint_error_dev(sc->sc_dv, "unable to halt controller\n");
    910 			continue;
    911 		}
    912 
    913 		/*
    914 		 * Note that issuing this command to the controller makes it
    915 		 * shut down but also keeps it from coming back up without a
    916 		 * reset of the PCI bus.
    917 		 */
    918 		if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
    919 		    &i, sizeof(i), NULL, NULL))
    920 			aprint_error_dev(sc->sc_dv, "unable to halt controller\n");
    921 
    922 		sc->sc_flags &= ~AAC_ONLINE;
    923 	}
    924 }
    925 
    926 static int
    927 aac_new_intr(void *cookie)
    928 {
    929 	struct aac_softc *sc;
    930 	u_int32_t index, fast;
    931 	struct aac_ccb *ac;
    932 	struct aac_fib *fib;
    933 	struct aac_fibmap *fm;
    934 	int i;
    935 
    936 	sc = (struct aac_softc *) cookie;
    937 
    938 	for (;;) {
    939 		index = AAC_GET_OUTB_QUEUE(sc);
    940 		if (index == 0xffffffff)
    941 			index = AAC_GET_OUTB_QUEUE(sc);
    942 		if (index == 0xffffffff)
    943 			break;
    944 		if (index & 2) {
    945 			if (index == 0xfffffffe) {
    946 				/* XXX This means that the controller wants
    947 				 * more work.  Ignore it for now.
    948 				 */
    949 				continue;
    950 			}
    951 			/* AIF */
    952 			index &= ~2;
    953 			fib = sc->sc_aif_fib;
    954 			for (i = 0; i < sizeof(struct aac_fib)/4; i++) {
    955 				((u_int32_t*)fib)[i] =
    956 				    AAC_GETREG4(sc, index + i*4);
    957 			}
    958 #ifdef notyet
    959 			aac_handle_aif(sc, &fib);
    960 #endif
    961 
    962 			AAC_SET_OUTB_QUEUE(sc, index);
    963 			AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
    964 		} else {
    965 			fast = index & 1;
    966 			ac = sc->sc_ccbs + (index >> 2);
    967 			fib = ac->ac_fib;
    968 			fm = ac->ac_fibmap;
    969 			if (fast) {
    970 				bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap,
    971 				    (char *)fib - (char *)fm->fm_fibs,
    972 				    sc->sc_max_fib_size,
    973 				    BUS_DMASYNC_POSTWRITE |
    974 				    BUS_DMASYNC_POSTREAD);
    975 				fib->Header.XferState |=
    976 				    htole32(AAC_FIBSTATE_DONEADAP);
    977 				*((u_int32_t *)(fib->data)) =
    978 				    htole32(AAC_ERROR_NORMAL);
    979 			}
    980 			ac->ac_flags |= AAC_CCB_COMPLETED;
    981 
    982 			if (ac->ac_intr != NULL)
    983 				(*ac->ac_intr)(ac);
    984 			else
    985 				wakeup(ac);
    986 		}
    987 	}
    988 
    989 	/*
    990 	 * Try to submit more commands.
    991 	 */
    992 	if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue))
    993 		aac_ccb_enqueue(sc, NULL);
    994 
    995 	return 1;
    996 }
    997 
    998 /*
    999  * Take an interrupt.
   1000  */
   1001 int
   1002 aac_intr(void *cookie)
   1003 {
   1004 	struct aac_softc *sc;
   1005 	u_int16_t reason;
   1006 	int claimed;
   1007 
   1008 	sc = cookie;
   1009 	claimed = 0;
   1010 
   1011 	AAC_DPRINTF(AAC_D_INTR, ("aac_intr(%p) ", sc));
   1012 
   1013 	reason = AAC_GET_ISTATUS(sc);
   1014 	AAC_CLEAR_ISTATUS(sc, reason);
   1015 
   1016 	AAC_DPRINTF(AAC_D_INTR, ("istatus 0x%04x ", reason));
   1017 
   1018 	/*
   1019 	 * Controller wants to talk to the log.  XXX Should we defer this?
   1020 	 */
   1021 	if ((reason & AAC_DB_PRINTF) != 0) {
   1022 		if (sc->sc_common->ac_printf[0] == '\0')
   1023 			sc->sc_common->ac_printf[0] = ' ';
   1024 		printf("%s: WARNING: adapter logged message:\n",
   1025 			device_xname(sc->sc_dv));
   1026 		printf("%s:     %.*s", device_xname(sc->sc_dv),
   1027 			AAC_PRINTF_BUFSIZE, sc->sc_common->ac_printf);
   1028 		sc->sc_common->ac_printf[0] = '\0';
   1029 		AAC_QNOTIFY(sc, AAC_DB_PRINTF);
   1030 		claimed = 1;
   1031 	}
   1032 
   1033 	/*
   1034 	 * Controller has a message for us?
   1035 	 */
   1036 	if ((reason & AAC_DB_COMMAND_READY) != 0) {
   1037 		aac_host_command(sc);
   1038 		claimed = 1;
   1039 	}
   1040 
   1041 	/*
   1042 	 * Controller has a response for us?
   1043 	 */
   1044 	if ((reason & AAC_DB_RESPONSE_READY) != 0) {
   1045 		aac_host_response(sc);
   1046 		claimed = 1;
   1047 	}
   1048 
   1049 	/*
   1050 	 * Spurious interrupts that we don't use - reset the mask and clear
   1051 	 * the interrupts.
   1052 	 */
   1053 	if ((reason & (AAC_DB_SYNC_COMMAND | AAC_DB_COMMAND_NOT_FULL |
   1054             AAC_DB_RESPONSE_NOT_FULL)) != 0) {
   1055 		AAC_UNMASK_INTERRUPTS(sc);
   1056 		AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND |
   1057 		    AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL);
   1058 		claimed = 1;
   1059 	}
   1060 
   1061 	return (claimed);
   1062 }
   1063 
   1064 /*
   1065  * Handle notification of one or more FIBs coming from the controller.
   1066  */
   1067 static void
   1068 aac_host_command(struct aac_softc *sc)
   1069 {
   1070 	struct aac_fib *fib;
   1071 	u_int32_t fib_size;
   1072 
   1073 	for (;;) {
   1074 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size,
   1075 		    &fib))
   1076 			break;	/* nothing to do */
   1077 
   1078 		bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1079 		    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
   1080 		    BUS_DMASYNC_POSTREAD);
   1081 
   1082 		switch (le16toh(fib->Header.Command)) {
   1083 		case AifRequest:
   1084 #ifdef notyet
   1085 			aac_handle_aif(sc,
   1086 			    (struct aac_aif_command *)&fib->data[0]);
   1087 #endif
   1088 			AAC_PRINT_FIB(sc, fib);
   1089 			break;
   1090 		default:
   1091 			aprint_error_dev(sc->sc_dv, "unknown command from controller\n");
   1092 			AAC_PRINT_FIB(sc, fib);
   1093 			break;
   1094 		}
   1095 
   1096 		bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1097 		    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
   1098 		    BUS_DMASYNC_PREREAD);
   1099 
   1100 		if ((fib->Header.XferState == 0) ||
   1101 		    (fib->Header.StructType != AAC_FIBTYPE_TFIB)) {
   1102 			break; // continue; ???
   1103 		}
   1104 
   1105 		/* XXX reply to FIBs requesting responses ?? */
   1106 
   1107 		/* Return the AIF/FIB to the controller */
   1108 		if (le32toh(fib->Header.XferState) & AAC_FIBSTATE_FROMADAP) {
   1109 			u_int16_t	size;
   1110 
   1111 			fib->Header.XferState |=
   1112 				htole32(AAC_FIBSTATE_DONEHOST);
   1113 			*(u_int32_t*)fib->data = htole32(ST_OK);
   1114 
   1115 			/* XXX Compute the Size field? */
   1116 			size = le16toh(fib->Header.Size);
   1117 			if (size > sizeof(struct aac_fib)) {
   1118 				size = sizeof(struct aac_fib);
   1119 				fib->Header.Size = htole16(size);
   1120 			}
   1121 
   1122 			/*
   1123 			 * Since we didn't generate this command, it can't
   1124 			 * go through the normal process.
   1125 			 */
   1126 			aac_enqueue_response(sc,
   1127 					AAC_ADAP_NORM_RESP_QUEUE, fib);
   1128 		}
   1129 	}
   1130 }
   1131 
   1132 /*
   1133  * Handle notification of one or more FIBs completed by the controller
   1134  */
   1135 static void
   1136 aac_host_response(struct aac_softc *sc)
   1137 {
   1138 	struct aac_ccb *ac;
   1139 	struct aac_fib *fib;
   1140 	u_int32_t fib_size;
   1141 
   1142 	/*
   1143 	 * Look for completed FIBs on our queue.
   1144 	 */
   1145 	for (;;) {
   1146 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
   1147 		    &fib))
   1148 			break;	/* nothing to do */
   1149 
   1150 		if ((fib->Header.SenderData & 0x80000000) == 0) {
   1151 			/* Not valid; not sent by us. */
   1152 			AAC_PRINT_FIB(sc, fib);
   1153 		} else {
   1154 			ac = (struct aac_ccb *)(sc->sc_ccbs +
   1155 			    (fib->Header.SenderData & 0x7fffffff));
   1156 			fib->Header.SenderData = 0;
   1157 			SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_complete, ac, ac_chain);
   1158 		}
   1159 	}
   1160 
   1161 	/*
   1162 	 * Deal with any completed commands.
   1163 	 */
   1164 	while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_complete)) != NULL) {
   1165 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_complete, ac_chain);
   1166 		ac->ac_flags |= AAC_CCB_COMPLETED;
   1167 
   1168 		if (ac->ac_intr != NULL)
   1169 			(*ac->ac_intr)(ac);
   1170 		else
   1171 			wakeup(ac);
   1172 	}
   1173 
   1174 	/*
   1175 	 * Try to submit more commands.
   1176 	 */
   1177 	if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue))
   1178 		aac_ccb_enqueue(sc, NULL);
   1179 }
   1180 
   1181 /*
   1182  * Send a synchronous command to the controller and wait for a result.
   1183  */
   1184 static int
   1185 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
   1186 		 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp)
   1187 {
   1188 	int i;
   1189 	u_int32_t status;
   1190 	int s;
   1191 
   1192 	s = splbio();
   1193 
   1194 	/* Populate the mailbox. */
   1195 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
   1196 
   1197 	/* Ensure the sync command doorbell flag is cleared. */
   1198 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
   1199 
   1200 	/* ... then set it to signal the adapter. */
   1201 	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
   1202 	DELAY(AAC_SYNC_DELAY);
   1203 
   1204 	/* Spin waiting for the command to complete. */
   1205 	for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) {
   1206 		if (AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND)
   1207 			break;
   1208 		DELAY(1000);
   1209 	}
   1210 	if (i == AAC_IMMEDIATE_TIMEOUT * 1000) {
   1211 		splx(s);
   1212 		return (EIO);
   1213 	}
   1214 
   1215 	/* Clear the completion flag. */
   1216 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
   1217 
   1218 	/* Get the command status. */
   1219 	status = AAC_GET_MAILBOXSTATUS(sc);
   1220 	splx(s);
   1221 	if (sp != NULL)
   1222 		*sp = status;
   1223 
   1224 	return (0);	/* XXX Check command return status? */
   1225 }
   1226 
   1227 /*
   1228  * Send a synchronous FIB to the controller and wait for a result.
   1229  */
   1230 static int
   1231 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
   1232 	     void *data, u_int16_t datasize, void *result,
   1233 	     u_int16_t *resultsize)
   1234 {
   1235 	struct aac_fib *fib;
   1236 	u_int32_t fibpa, status;
   1237 
   1238 	fib = &sc->sc_common->ac_sync_fib;
   1239 	fibpa = sc->sc_common_seg.ds_addr +
   1240 	    offsetof(struct aac_common, ac_sync_fib);
   1241 
   1242 	if (datasize > AAC_FIB_DATASIZE)
   1243 		return (EINVAL);
   1244 
   1245 	/*
   1246 	 * Set up the sync FIB.
   1247 	 */
   1248 	fib->Header.XferState = htole32(AAC_FIBSTATE_HOSTOWNED |
   1249 	    AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY | xferstate);
   1250 	fib->Header.Command = htole16(command);
   1251 	fib->Header.StructType = AAC_FIBTYPE_TFIB;
   1252 	fib->Header.Size = htole16(sizeof(*fib) + datasize);
   1253 	fib->Header.SenderSize = htole16(sizeof(*fib));
   1254 	fib->Header.SenderFibAddress = 0; /* not needed */
   1255 	fib->Header.ReceiverFibAddress = htole32(fibpa);
   1256 
   1257 	/*
   1258 	 * Copy in data.
   1259 	 */
   1260 	if (data != NULL) {
   1261 		memcpy(fib->data, data, datasize);
   1262 		fib->Header.XferState |=
   1263 		    htole32(AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM);
   1264 	}
   1265 
   1266 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1267 	    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
   1268 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1269 
   1270 	/*
   1271 	 * Give the FIB to the controller, wait for a response.
   1272 	 */
   1273 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fibpa, 0, 0, 0, &status))
   1274 		return (EIO);
   1275 	if (status != 1) {
   1276 		printf("%s: syncfib command %04x status %08x\n",
   1277 			device_xname(sc->sc_dv), command, status);
   1278 	}
   1279 
   1280 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1281 	    (char *)fib - (char *)sc->sc_common, sizeof(*fib),
   1282 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1283 
   1284 	/*
   1285 	 * Copy out the result
   1286 	 */
   1287 	if (result != NULL) {
   1288 		*resultsize = le16toh(fib->Header.Size) - sizeof(fib->Header);
   1289 		memcpy(result, fib->data, *resultsize);
   1290 	}
   1291 
   1292 	return (0);
   1293 }
   1294 
   1295 struct aac_ccb *
   1296 aac_ccb_alloc(struct aac_softc *sc, int flags)
   1297 {
   1298 	struct aac_ccb *ac;
   1299 	int s;
   1300 
   1301 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_alloc(%p, 0x%x) ", sc, flags));
   1302 
   1303 	s = splbio();
   1304 	ac = SIMPLEQ_FIRST(&sc->sc_ccb_free);
   1305 	if (ac == NULL) {
   1306 		if (aac_alloc_commands(sc)) {
   1307 			splx(s);
   1308 			return NULL;
   1309 		}
   1310 		ac = SIMPLEQ_FIRST(&sc->sc_ccb_free);
   1311 	}
   1312 #ifdef DIAGNOSTIC
   1313 	if (ac == NULL)
   1314 		panic("aac_ccb_get: no free CCBS");
   1315 #endif
   1316 	SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ac_chain);
   1317 	splx(s);
   1318 
   1319 	ac->ac_flags = flags;
   1320 	return (ac);
   1321 }
   1322 
   1323 void
   1324 aac_ccb_free(struct aac_softc *sc, struct aac_ccb *ac)
   1325 {
   1326 	int s;
   1327 
   1328 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_free(%p, %p) ", sc, ac));
   1329 
   1330 	ac->ac_flags = 0;
   1331 	ac->ac_intr = NULL;
   1332 	ac->ac_fib->Header.XferState = htole32(AAC_FIBSTATE_EMPTY);
   1333 	ac->ac_fib->Header.StructType = AAC_FIBTYPE_TFIB;
   1334 	ac->ac_fib->Header.Flags = 0;
   1335 	ac->ac_fib->Header.SenderSize = htole16(sc->sc_max_fib_size);
   1336 
   1337 #ifdef AAC_DEBUG
   1338 	/*
   1339 	 * These are duplicated in aac_ccb_submit() to cover the case where
   1340 	 * an intermediate stage may have destroyed them.  They're left
   1341 	 * initialised here for debugging purposes only.
   1342 	 */
   1343 	ac->ac_fib->Header.SenderFibAddress =
   1344 	    htole32(((u_int32_t) (ac - sc->sc_ccbs)) << 2);
   1345 	ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
   1346 #endif
   1347 
   1348 	s = splbio();
   1349 	SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ac, ac_chain);
   1350 	splx(s);
   1351 }
   1352 
   1353 int
   1354 aac_ccb_map(struct aac_softc *sc, struct aac_ccb *ac)
   1355 {
   1356 	int error;
   1357 
   1358 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_map(%p, %p) ", sc, ac));
   1359 
   1360 #ifdef DIAGNOSTIC
   1361 	if ((ac->ac_flags & AAC_CCB_MAPPED) != 0)
   1362 		panic("aac_ccb_map: already mapped");
   1363 #endif
   1364 
   1365 	error = bus_dmamap_load(sc->sc_dmat, ac->ac_dmamap_xfer, ac->ac_data,
   1366 	    ac->ac_datalen, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
   1367 	    ((ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE));
   1368 	if (error) {
   1369 		printf("%s: aac_ccb_map: ", device_xname(sc->sc_dv));
   1370 		if (error == EFBIG)
   1371 			printf("more than %d DMA segs\n", sc->sc_max_sgs);
   1372 		else
   1373 			printf("error %d loading DMA map\n", error);
   1374 		return (error);
   1375 	}
   1376 
   1377 	bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
   1378 	    (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_PREREAD :
   1379 	    BUS_DMASYNC_PREWRITE);
   1380 
   1381 #ifdef DIAGNOSTIC
   1382 	ac->ac_flags |= AAC_CCB_MAPPED;
   1383 #endif
   1384 	return (0);
   1385 }
   1386 
   1387 void
   1388 aac_ccb_unmap(struct aac_softc *sc, struct aac_ccb *ac)
   1389 {
   1390 
   1391 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_unmap(%p, %p) ", sc, ac));
   1392 
   1393 #ifdef DIAGNOSTIC
   1394 	if ((ac->ac_flags & AAC_CCB_MAPPED) == 0)
   1395 		panic("aac_ccb_unmap: not mapped");
   1396 #endif
   1397 
   1398 	bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
   1399 	    (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_POSTREAD :
   1400 	    BUS_DMASYNC_POSTWRITE);
   1401 	bus_dmamap_unload(sc->sc_dmat, ac->ac_dmamap_xfer);
   1402 
   1403 #ifdef DIAGNOSTIC
   1404 	ac->ac_flags &= ~AAC_CCB_MAPPED;
   1405 #endif
   1406 }
   1407 
   1408 void
   1409 aac_ccb_enqueue(struct aac_softc *sc, struct aac_ccb *ac)
   1410 {
   1411 	int s;
   1412 
   1413 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_enqueue(%p, %p) ", sc, ac));
   1414 
   1415 	s = splbio();
   1416 
   1417 	if (ac != NULL)
   1418 		SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ac, ac_chain);
   1419 
   1420 	while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) {
   1421 		if (aac_ccb_submit(sc, ac))
   1422 			break;
   1423 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ac_chain);
   1424 	}
   1425 
   1426 	splx(s);
   1427 }
   1428 
   1429 int
   1430 aac_ccb_submit(struct aac_softc *sc, struct aac_ccb *ac)
   1431 {
   1432 	struct aac_fibmap *fm;
   1433 	u_int32_t acidx;
   1434 
   1435 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_submit(%p, %p) ", sc, ac));
   1436 
   1437 	acidx = (u_int32_t) (ac - sc->sc_ccbs);
   1438 	/* Fix up the address values. */
   1439 	ac->ac_fib->Header.SenderFibAddress = htole32(acidx << 2);
   1440 	ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
   1441 
   1442 	/* Save a pointer to the command for speedy reverse-lookup. */
   1443 	ac->ac_fib->Header.SenderData = acidx | 0x80000000;
   1444 
   1445 	fm = ac->ac_fibmap;
   1446 	bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap,
   1447 	    (char *)ac->ac_fib - (char *)fm->fm_fibs, sc->sc_max_fib_size,
   1448 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1449 
   1450 	/* Put the FIB on the outbound queue. */
   1451 	if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) {
   1452 		int count = 10000000L;
   1453 		while (AAC_SEND_COMMAND(sc, ac) != 0) {
   1454 			if (--count == 0) {
   1455 				panic("aac: fixme!");
   1456 				return EAGAIN;
   1457 			}
   1458 			DELAY(5);
   1459 		}
   1460 		return 0;
   1461 	} else {
   1462 		return (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, ac));
   1463 	}
   1464 }
   1465 
   1466 int
   1467 aac_ccb_poll(struct aac_softc *sc, struct aac_ccb *ac, int timo)
   1468 {
   1469 	int rv, s;
   1470 
   1471 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_poll(%p, %p, %d) ", sc, ac, timo));
   1472 
   1473 	s = splbio();
   1474 
   1475 	if ((rv = aac_ccb_submit(sc, ac)) != 0) {
   1476 		splx(s);
   1477 		return (rv);
   1478 	}
   1479 
   1480 	for (timo *= 1000; timo != 0; timo--) {
   1481 		if (sc->sc_quirks & AAC_QUIRK_NEW_COMM)
   1482 			aac_new_intr(sc);
   1483 		else
   1484 			aac_intr(sc);
   1485 		if ((ac->ac_flags & AAC_CCB_COMPLETED) != 0)
   1486 			break;
   1487 		DELAY(100);
   1488 	}
   1489 
   1490 	splx(s);
   1491 	return (timo == 0);
   1492 }
   1493 
   1494 /*
   1495  * Atomically insert an entry into the nominated queue, returns 0 on success
   1496  * or EBUSY if the queue is full.
   1497  *
   1498  * XXX Note that it would be more efficient to defer notifying the
   1499  * controller in the case where we may be inserting several entries in rapid
   1500  * succession, but implementing this usefully is difficult.
   1501  */
   1502 static int
   1503 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_ccb *ac)
   1504 {
   1505 	u_int32_t fib_size, fib_addr, pi, ci;
   1506 
   1507 	fib_size = le16toh(ac->ac_fib->Header.Size);
   1508 	fib_addr = le32toh(ac->ac_fib->Header.ReceiverFibAddress);
   1509 
   1510 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1511 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
   1512 	    sizeof(sc->sc_common->ac_qbuf),
   1513 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1514 
   1515 	/* Get the producer/consumer indices.  */
   1516 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
   1517 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
   1518 
   1519 	/* Wrap the queue? */
   1520 	if (pi >= aac_qinfo[queue].size)
   1521 		pi = 0;
   1522 
   1523 	/* Check for queue full. */
   1524 	if ((pi + 1) == ci)
   1525 		return (EAGAIN);
   1526 
   1527 	/* Populate queue entry. */
   1528 	(sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size);
   1529 	(sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr);
   1530 
   1531 	/* Update producer index. */
   1532 	sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1);
   1533 
   1534 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1535 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
   1536 	    sizeof(sc->sc_common->ac_qbuf),
   1537 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1538 
   1539 	/* Notify the adapter if we know how. */
   1540 	if (aac_qinfo[queue].notify != 0)
   1541 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
   1542 
   1543 	return (0);
   1544 }
   1545 
   1546 /*
   1547  * Atomically remove one entry from the nominated queue, returns 0 on success
   1548  * or ENOENT if the queue is empty.
   1549  */
   1550 static int
   1551 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
   1552 		struct aac_fib **fib_addr)
   1553 {
   1554 	struct aac_fibmap *fm;
   1555 	struct aac_ccb *ac;
   1556 	u_int32_t pi, ci, idx;
   1557 	int notify;
   1558 
   1559 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1560 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
   1561 	    sizeof(sc->sc_common->ac_qbuf),
   1562 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1563 
   1564 	/* Get the producer/consumer indices. */
   1565 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
   1566 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
   1567 
   1568 	/* Check for queue empty. */
   1569 	if (ci == pi)
   1570 		return (ENOENT);
   1571 
   1572 	notify = 0;
   1573 	if (ci == pi + 1)
   1574 		notify = 1;
   1575 
   1576 	/* Wrap the queue? */
   1577 	if (ci >= aac_qinfo[queue].size)
   1578 		ci = 0;
   1579 
   1580 	/* Fetch the entry. */
   1581 	*fib_size = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_size);
   1582 
   1583 	switch (queue) {
   1584 	case AAC_HOST_NORM_CMD_QUEUE:
   1585 	case AAC_HOST_HIGH_CMD_QUEUE:
   1586 		idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr);
   1587 		idx /= sizeof(struct aac_fib);
   1588 		*fib_addr = &sc->sc_common->ac_fibs[idx];
   1589 		break;
   1590 	case AAC_HOST_NORM_RESP_QUEUE:
   1591 	case AAC_HOST_HIGH_RESP_QUEUE:
   1592 		idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr);
   1593 		ac = sc->sc_ccbs + (idx >> 2);
   1594 		*fib_addr = ac->ac_fib;
   1595 		if (idx & 0x01) {
   1596 			fm = ac->ac_fibmap;
   1597 			bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap,
   1598 			    (char *)ac->ac_fib - (char *)fm->fm_fibs,
   1599 			    sc->sc_max_fib_size,
   1600 			    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1601 			ac->ac_fib->Header.XferState |=
   1602 				htole32(AAC_FIBSTATE_DONEADAP);
   1603 			*((u_int32_t*)(ac->ac_fib->data)) =
   1604 				htole32(AAC_ERROR_NORMAL);
   1605 		}
   1606 		break;
   1607 	default:
   1608 		panic("Invalid queue in aac_dequeue_fib()");
   1609 		break;
   1610 	}
   1611 
   1612 	/* Update consumer index. */
   1613 	sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
   1614 
   1615 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1616 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
   1617 	    sizeof(sc->sc_common->ac_qbuf),
   1618 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1619 
   1620 	/* If we have made the queue un-full, notify the adapter. */
   1621 	if (notify && (aac_qinfo[queue].notify != 0))
   1622 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
   1623 
   1624 	return (0);
   1625 }
   1626 
   1627 /*
   1628  * Put our response to an adapter-initiated fib (AIF) on the response queue.
   1629  */
   1630 static int
   1631 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
   1632 {
   1633 	u_int32_t fib_size, fib_addr, pi, ci;
   1634 
   1635 	fib_size = le16toh(fib->Header.Size);
   1636 	fib_addr = fib->Header.SenderFibAddress;
   1637 	fib->Header.ReceiverFibAddress = fib_addr;
   1638 
   1639 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1640 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
   1641 	    sizeof(sc->sc_common->ac_qbuf),
   1642 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1643 
   1644 	/* Get the producer/consumer indices.  */
   1645 	pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
   1646 	ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
   1647 
   1648 	/* Wrap the queue? */
   1649 	if (pi >= aac_qinfo[queue].size)
   1650 		pi = 0;
   1651 
   1652 	/* Check for queue full. */
   1653 	if ((pi + 1) == ci)
   1654 		return (EAGAIN);
   1655 
   1656 	/* Populate queue entry. */
   1657 	(sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size);
   1658 	(sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr);
   1659 
   1660 	/* Update producer index. */
   1661 	sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1);
   1662 
   1663 	bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
   1664 	    (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
   1665 	    sizeof(sc->sc_common->ac_qbuf),
   1666 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1667 
   1668 	/* Notify the adapter if we know how. */
   1669 	if (aac_qinfo[queue].notify != 0)
   1670 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
   1671 
   1672 	return (0);
   1673 }
   1674 
   1675 #ifdef AAC_DEBUG
   1676 /*
   1677  * Print a FIB
   1678  */
   1679 static void
   1680 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib,
   1681     const char *caller)
   1682 {
   1683 	struct aac_blockread *br;
   1684 	struct aac_blockwrite *bw;
   1685 	struct aac_sg_table *sg;
   1686 	char tbuf[512];
   1687 	int i;
   1688 
   1689 	printf("%s: FIB @ %p\n", caller, fib);
   1690 	snprintb(tbuf, sizeof(tbuf),
   1691 	    "\20"
   1692 	    "\1HOSTOWNED"
   1693 	    "\2ADAPTEROWNED"
   1694 	    "\3INITIALISED"
   1695 	    "\4EMPTY"
   1696 	    "\5FROMPOOL"
   1697 	    "\6FROMHOST"
   1698 	    "\7FROMADAP"
   1699 	    "\10REXPECTED"
   1700 	    "\11RNOTEXPECTED"
   1701 	    "\12DONEADAP"
   1702 	    "\13DONEHOST"
   1703 	    "\14HIGH"
   1704 	    "\15NORM"
   1705 	    "\16ASYNC"
   1706 	    "\17PAGEFILEIO"
   1707 	    "\20SHUTDOWN"
   1708 	    "\21LAZYWRITE"
   1709 	    "\22ADAPMICROFIB"
   1710 	    "\23BIOSFIB"
   1711 	    "\24FAST_RESPONSE"
   1712 	    "\25APIFIB\n", le32toh(fib->Header.XferState));
   1713 
   1714 	printf("  XferState       %s\n", tbuf);
   1715 	printf("  Command         %d\n", le16toh(fib->Header.Command));
   1716 	printf("  StructType      %d\n", fib->Header.StructType);
   1717 	printf("  Flags           0x%x\n", fib->Header.Flags);
   1718 	printf("  Size            %d\n", le16toh(fib->Header.Size));
   1719 	printf("  SenderSize      %d\n", le16toh(fib->Header.SenderSize));
   1720 	printf("  SenderAddress   0x%x\n",
   1721 	    le32toh(fib->Header.SenderFibAddress));
   1722 	printf("  ReceiverAddress 0x%x\n",
   1723 	    le32toh(fib->Header.ReceiverFibAddress));
   1724 	printf("  SenderData      0x%x\n", fib->Header.SenderData);
   1725 
   1726 	switch (fib->Header.Command) {
   1727 	case ContainerCommand: {
   1728 		br = (struct aac_blockread *)fib->data;
   1729 		bw = (struct aac_blockwrite *)fib->data;
   1730 		sg = NULL;
   1731 
   1732 		if (le32toh(br->Command) == VM_CtBlockRead) {
   1733 			printf("  BlockRead: container %d  0x%x/%d\n",
   1734 			    le32toh(br->ContainerId), le32toh(br->BlockNumber),
   1735 			    le32toh(br->ByteCount));
   1736 			sg = &br->SgMap;
   1737 		}
   1738 		if (le32toh(bw->Command) == VM_CtBlockWrite) {
   1739 			printf("  BlockWrite: container %d  0x%x/%d (%s)\n",
   1740 			    le32toh(bw->ContainerId), le32toh(bw->BlockNumber),
   1741 			    le32toh(bw->ByteCount),
   1742 			    le32toh(bw->Stable) == CSTABLE ?
   1743 			    "stable" : "unstable");
   1744 			sg = &bw->SgMap;
   1745 		}
   1746 		if (sg != NULL) {
   1747 			printf("  %d s/g entries\n", le32toh(sg->SgCount));
   1748 			for (i = 0; i < le32toh(sg->SgCount); i++)
   1749 				printf("  0x%08x/%d\n",
   1750 				    le32toh(sg->SgEntry[i].SgAddress),
   1751 				    le32toh(sg->SgEntry[i].SgByteCount));
   1752 		}
   1753 		break;
   1754 	}
   1755 	default:
   1756 		// dump first 32 bytes of fib->data
   1757 		printf("  Raw data:");
   1758 		for (i = 0; i < 32; i++)
   1759 			printf(" %02x", fib->data[i]);
   1760 		printf("\n");
   1761 		break;
   1762 	}
   1763 }
   1764 #endif /* AAC_DEBUG */
   1765 
   1766 MODULE(MODULE_CLASS_DRIVER, aac, "pci");
   1767 
   1768 #ifdef _MODULE
   1769 #include "ioconf.c"
   1770 #endif
   1771 
   1772 static int
   1773 aac_modcmd(modcmd_t cmd, void *opaque)
   1774 {
   1775 	int error = 0;
   1776 
   1777 #ifdef _MODULE
   1778 	switch (cmd) {
   1779 	case MODULE_CMD_INIT:
   1780 		error = config_init_component(cfdriver_ioconf_aac,
   1781 		    cfattach_ioconf_aac, cfdata_ioconf_aac);
   1782 		break;
   1783 	case MODULE_CMD_FINI:
   1784 		error = config_fini_component(cfdriver_ioconf_aac,
   1785 		    cfattach_ioconf_aac, cfdata_ioconf_aac);
   1786 		break;
   1787 	default:
   1788 		error = ENOTTY;
   1789 		break;
   1790 	}
   1791 #endif
   1792 
   1793 	return error;
   1794 }
   1795