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