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