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