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