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