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