1 /* $NetBSD: aac.c,v 1.41 2008/10/02 08:21:57 sborrill Exp $ */
4 * Copyright (c) 2002, 2007 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
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.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
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.
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
63 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
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).
72 #include <sys/cdefs.h>
73 __KERNEL_RCSID(0, "$NetBSD: aac.c,v 1.41 2008/10/02 08:21:57 sborrill Exp $");
75 #include <sys/param.h>
76 #include <sys/systm.h>
78 #include <sys/device.h>
79 #include <sys/kernel.h>
80 #include <sys/malloc.h>
85 #include <uvm/uvm_extern.h>
87 #include <dev/ic/aacreg.h>
88 #include <dev/ic/aacvar.h>
89 #include <dev/ic/aac_tables.h>
93 static int aac_new_intr(void *);
94 static int aac_alloc_commands(struct aac_softc
*);
96 static void aac_free_commands(struct aac_softc
*);
98 static int aac_check_firmware(struct aac_softc
*);
99 static void aac_describe_controller(struct aac_softc
*);
100 static int aac_dequeue_fib(struct aac_softc
*, int, u_int32_t
*,
102 static int aac_enqueue_fib(struct aac_softc
*, int, struct aac_ccb
*);
103 static int aac_enqueue_response(struct aac_softc
*, int, struct aac_fib
*);
104 static void aac_host_command(struct aac_softc
*);
105 static void aac_host_response(struct aac_softc
*);
106 static int aac_init(struct aac_softc
*);
107 static int aac_print(void *, const char *);
108 static void aac_shutdown(void *);
109 static void aac_startup(struct aac_softc
*);
110 static int aac_sync_command(struct aac_softc
*, u_int32_t
, u_int32_t
,
111 u_int32_t
, u_int32_t
, u_int32_t
, u_int32_t
*);
112 static int aac_sync_fib(struct aac_softc
*, u_int32_t
, u_int32_t
, void *,
113 u_int16_t
, void *, u_int16_t
*);
116 static void aac_print_fib(struct aac_softc
*, struct aac_fib
*, const char *);
120 * Adapter-space FIB queue manipulation.
122 * Note that the queue implementation here is a little funky; neither the PI or
123 * CI will ever be zero. This behaviour is a controller feature.
128 } const aac_qinfo
[] = {
129 { AAC_HOST_NORM_CMD_ENTRIES
, AAC_DB_COMMAND_NOT_FULL
},
130 { AAC_HOST_HIGH_CMD_ENTRIES
, 0 },
131 { AAC_ADAP_NORM_CMD_ENTRIES
, AAC_DB_COMMAND_READY
},
132 { AAC_ADAP_HIGH_CMD_ENTRIES
, 0 },
133 { AAC_HOST_NORM_RESP_ENTRIES
, AAC_DB_RESPONSE_NOT_FULL
},
134 { AAC_HOST_HIGH_RESP_ENTRIES
, 0 },
135 { AAC_ADAP_NORM_RESP_ENTRIES
, AAC_DB_RESPONSE_READY
},
136 { AAC_ADAP_HIGH_RESP_ENTRIES
, 0 }
140 int aac_debug
= AAC_DEBUG
;
143 MALLOC_DEFINE(M_AACBUF
, "aacbuf", "Buffers for aac(4)");
145 static void *aac_sdh
;
147 extern struct cfdriver aac_cd
;
150 aac_attach(struct aac_softc
*sc
)
152 struct aac_attach_args aaca
;
154 int locs
[AACCF_NLOCS
];
156 SIMPLEQ_INIT(&sc
->sc_ccb_free
);
157 SIMPLEQ_INIT(&sc
->sc_ccb_queue
);
158 SIMPLEQ_INIT(&sc
->sc_ccb_complete
);
161 * Disable interrupts before we do anything.
163 AAC_MASK_INTERRUPTS(sc
);
166 * Initialise the adapter.
168 if (aac_check_firmware(sc
))
171 if ((rv
= aac_init(sc
)) != 0)
174 if (sc
->sc_quirks
& AAC_QUIRK_NEW_COMM
) {
175 rv
= sc
->sc_intr_set(sc
, aac_new_intr
, sc
);
183 * Print a little information about the controller.
185 aac_describe_controller(sc
);
190 for (i
= 0; i
< AAC_MAX_CONTAINERS
; i
++) {
191 if (!sc
->sc_hdr
[i
].hd_present
)
195 locs
[AACCF_UNIT
] = i
;
197 config_found_sm_loc(&sc
->sc_dv
, "aac", locs
, &aaca
,
198 aac_print
, config_stdsubmatch
);
202 * Enable interrupts, and register our shutdown hook.
204 sc
->sc_flags
|= AAC_ONLINE
;
205 AAC_UNMASK_INTERRUPTS(sc
);
207 shutdownhook_establish(aac_shutdown
, NULL
);
212 aac_alloc_commands(struct aac_softc
*sc
)
214 struct aac_fibmap
*fm
;
221 if (sc
->sc_total_fibs
+ sc
->sc_max_fibs_alloc
> sc
->sc_max_fibs
)
224 fm
= malloc(sizeof(struct aac_fibmap
), M_AACBUF
, M_NOWAIT
|M_ZERO
);
228 size
= sc
->sc_max_fibs_alloc
* sc
->sc_max_fib_size
;
231 error
= bus_dmamap_create(sc
->sc_dmat
, size
, 1, size
,
232 0, BUS_DMA_NOWAIT
| BUS_DMA_ALLOCNOW
, &fm
->fm_fibmap
);
234 aprint_error_dev(&sc
->sc_dv
, "cannot create fibs dmamap (%d)\n",
239 error
= bus_dmamem_alloc(sc
->sc_dmat
, size
, PAGE_SIZE
, 0,
240 &fm
->fm_fibseg
, 1, &nsegs
, BUS_DMA_NOWAIT
);
242 aprint_error_dev(&sc
->sc_dv
, "can't allocate fibs structure (%d)\n",
247 error
= bus_dmamem_map(sc
->sc_dmat
, &fm
->fm_fibseg
, nsegs
, size
,
248 (void **)&fm
->fm_fibs
, 0);
250 aprint_error_dev(&sc
->sc_dv
, "can't map fibs structure (%d)\n",
255 error
= bus_dmamap_load(sc
->sc_dmat
, fm
->fm_fibmap
, fm
->fm_fibs
,
256 size
, NULL
, BUS_DMA_NOWAIT
);
258 aprint_error_dev(&sc
->sc_dv
, "cannot load fibs dmamap (%d)\n",
263 fm
->fm_ccbs
= sc
->sc_ccbs
+ sc
->sc_total_fibs
;
264 fibpa
= fm
->fm_fibseg
.ds_addr
;
266 memset(fm
->fm_fibs
, 0, size
);
267 for (i
= 0; i
< sc
->sc_max_fibs_alloc
; i
++) {
268 ac
= fm
->fm_ccbs
+ i
;
270 error
= bus_dmamap_create(sc
->sc_dmat
, AAC_MAX_XFER(sc
),
271 sc
->sc_max_sgs
, AAC_MAX_XFER(sc
), 0,
272 BUS_DMA_NOWAIT
| BUS_DMA_ALLOCNOW
, &ac
->ac_dmamap_xfer
);
275 ac
= fm
->fm_ccbs
+ i
;
276 bus_dmamap_destroy(sc
->sc_dmat
,
280 aprint_error_dev(&sc
->sc_dv
, "cannot create ccb dmamap (%d)",
286 ac
->ac_fib
= (struct aac_fib
*)
287 ((char *) fm
->fm_fibs
+ i
* sc
->sc_max_fib_size
);
288 ac
->ac_fibphys
= fibpa
+ i
* sc
->sc_max_fib_size
;
289 aac_ccb_free(sc
, ac
);
293 TAILQ_INSERT_TAIL(&sc
->sc_fibmap_tqh
, fm
, fm_link
);
298 bus_dmamap_unload(sc
->sc_dmat
, fm
->fm_fibmap
);
300 bus_dmamem_unmap(sc
->sc_dmat
, (void *) fm
->fm_fibs
, size
);
302 bus_dmamem_free(sc
->sc_dmat
, &fm
->fm_fibseg
, 1);
304 bus_dmamap_destroy(sc
->sc_dmat
, fm
->fm_fibmap
);
313 aac_free_commands(struct aac_softc
*sc
)
319 * Print autoconfiguration message for a sub-device.
322 aac_print(void *aux
, const char *pnp
)
324 struct aac_attach_args
*aaca
;
329 aprint_normal("block device at %s", pnp
);
330 aprint_normal(" unit %d", aaca
->aaca_unit
);
335 * Look up a text description of a numeric error code and return a pointer to
339 aac_describe_code(const struct aac_code_lookup
*table
, u_int32_t code
)
343 for (i
= 0; table
[i
].string
!= NULL
; i
++)
344 if (table
[i
].code
== code
)
345 return (table
[i
].string
);
347 return (table
[i
+ 1].string
);
351 * snprintb(3) format string for the adapter options.
353 static const char *optfmt
=
354 "\20\1SNAPSHOT\2CLUSTERS\3WCACHE\4DATA64\5HOSTTIME\6RAID50"
356 "\10SCSIUPGD\11SOFTERR\12NORECOND\13SGMAP64\14ALARM\15NONDASD";
359 aac_describe_controller(struct aac_softc
*sc
)
361 u_int8_t fmtbuf
[256];
362 u_int8_t tbuf
[AAC_FIB_DATASIZE
];
364 struct aac_adapter_info
*info
;
368 if (aac_sync_fib(sc
, RequestAdapterInfo
, 0, &arg
, sizeof(arg
), &tbuf
,
370 aprint_error_dev(&sc
->sc_dv
, "RequestAdapterInfo failed\n");
373 if (bufsize
!= sizeof(*info
)) {
374 aprint_error_dev(&sc
->sc_dv
,
375 "RequestAdapterInfo returned wrong data size (%d != %zu)\n",
376 bufsize
, sizeof(*info
));
379 info
= (struct aac_adapter_info
*)&tbuf
[0];
381 aprint_normal_dev(&sc
->sc_dv
, "%s at %dMHz, %dMB mem (%dMB cache), %s\n",
382 aac_describe_code(aac_cpu_variant
, le32toh(info
->CpuVariant
)),
383 le32toh(info
->ClockSpeed
),
384 le32toh(info
->TotalMem
) / (1024 * 1024),
385 le32toh(info
->BufferMem
) / (1024 * 1024),
386 aac_describe_code(aac_battery_platform
,
387 le32toh(info
->batteryPlatform
)));
389 aprint_verbose_dev(&sc
->sc_dv
, "Kernel %d.%d-%d [Build %d], ",
390 info
->KernelRevision
.external
.comp
.major
,
391 info
->KernelRevision
.external
.comp
.minor
,
392 info
->KernelRevision
.external
.comp
.dash
,
393 info
->KernelRevision
.buildNumber
);
395 aprint_verbose("Monitor %d.%d-%d [Build %d], S/N %6X\n",
396 info
->MonitorRevision
.external
.comp
.major
,
397 info
->MonitorRevision
.external
.comp
.minor
,
398 info
->MonitorRevision
.external
.comp
.dash
,
399 info
->MonitorRevision
.buildNumber
,
400 ((u_int32_t
)info
->SerialNumber
& 0xffffff));
402 snprintb(fmtbuf
, sizeof(fmtbuf
), optfmt
, sc
->sc_supported_options
);
403 aprint_verbose_dev(&sc
->sc_dv
, "Controller supports: %s\n", fmtbuf
);
405 /* Save the kernel revision structure for later use. */
406 sc
->sc_revision
= info
->KernelRevision
;
410 * Retrieve the firmware version numbers. Dell PERC2/QC cards with firmware
411 * version 1.x are not compatible with this driver.
414 aac_check_firmware(struct aac_softc
*sc
)
416 u_int32_t major
, minor
, opts
, atusize
= 0, status
= 0;
419 if ((sc
->sc_quirks
& AAC_QUIRK_PERC2QC
) != 0) {
420 if (aac_sync_command(sc
, AAC_MONKER_GETKERNVER
, 0, 0, 0, 0,
422 aprint_error_dev(&sc
->sc_dv
, "error reading firmware version\n");
426 /* These numbers are stored as ASCII! */
427 major
= (AAC_GET_MAILBOX(sc
, 1) & 0xff) - 0x30;
428 minor
= (AAC_GET_MAILBOX(sc
, 2) & 0xff) - 0x30;
430 aprint_error_dev(&sc
->sc_dv
,
431 "firmware version %d.%d not supported.\n",
437 if (aac_sync_command(sc
, AAC_MONKER_GETINFO
, 0, 0, 0, 0, &status
)) {
438 if (status
!= AAC_SRB_STS_INVALID_REQUEST
) {
439 aprint_error_dev(&sc
->sc_dv
, "GETINFO failed, status 0x%08x\n", status
);
443 opts
= AAC_GET_MAILBOX(sc
, 1);
444 atusize
= AAC_GET_MAILBOX(sc
, 2);
445 sc
->sc_supported_options
= opts
;
447 if (((opts
& AAC_SUPPORTED_4GB_WINDOW
) != 0) &&
448 ((sc
->sc_quirks
& AAC_QUIRK_NO4GB
) == 0) )
449 sc
->sc_quirks
|= AAC_QUIRK_4GB_WINDOW
;
451 if (((opts
& AAC_SUPPORTED_SGMAP_HOST64
) != 0) &&
452 (sizeof(bus_addr_t
) > 4)) {
453 aprint_normal_dev(&sc
->sc_dv
, "Enabling 64-bit address support\n");
454 sc
->sc_quirks
|= AAC_QUIRK_SG_64BIT
;
456 if ((opts
& AAC_SUPPORTED_NEW_COMM
) &&
457 (sc
->sc_if
.aif_send_command
!= NULL
)) {
458 sc
->sc_quirks
|= AAC_QUIRK_NEW_COMM
;
460 if (opts
& AAC_SUPPORTED_64BIT_ARRAYSIZE
)
461 sc
->sc_quirks
|= AAC_QUIRK_ARRAY_64BIT
;
464 sc
->sc_max_fibs
= (sc
->sc_quirks
& AAC_QUIRK_256FIBS
) ? 256 : 512;
466 if ( (sc
->sc_quirks
& AAC_QUIRK_NEW_COMM
)
467 && (sc
->sc_regsize
< atusize
)) {
468 aprint_error_dev(&sc
->sc_dv
, "Not enabling new comm i/f -- "
469 "atusize 0x%08x, regsize 0x%08x\n",
471 (uint32_t) sc
->sc_regsize
);
472 sc
->sc_quirks
&= ~AAC_QUIRK_NEW_COMM
;
475 if (sc
->sc_quirks
& AAC_QUIRK_NEW_COMM
) {
476 aprint_error_dev(&sc
->sc_dv
, "Not enabling new comm i/f -- "
477 "driver not ready yet\n");
478 sc
->sc_quirks
&= ~AAC_QUIRK_NEW_COMM
;
482 sc
->sc_max_fib_size
= sizeof(struct aac_fib
);
483 sc
->sc_max_sectors
= 128; /* 64KB */
484 if (sc
->sc_quirks
& AAC_QUIRK_SG_64BIT
)
485 sc
->sc_max_sgs
= (sc
->sc_max_fib_size
486 - sizeof(struct aac_blockwrite64
)
487 + sizeof(struct aac_sg_table64
))
488 / sizeof(struct aac_sg_table64
);
490 sc
->sc_max_sgs
= (sc
->sc_max_fib_size
491 - sizeof(struct aac_blockwrite
)
492 + sizeof(struct aac_sg_table
))
493 / sizeof(struct aac_sg_table
);
495 if (!aac_sync_command(sc
, AAC_MONKER_GETCOMMPREF
, 0, 0, 0, 0, NULL
)) {
496 u_int32_t opt1
, opt2
, opt3
;
499 opt1
= AAC_GET_MAILBOX(sc
, 1);
500 opt2
= AAC_GET_MAILBOX(sc
, 2);
501 opt3
= AAC_GET_MAILBOX(sc
, 3);
502 if (!opt1
|| !opt2
|| !opt3
) {
503 aprint_verbose_dev(&sc
->sc_dv
, "GETCOMMPREF appears untrustworthy."
506 sc
->sc_max_fib_size
= le32toh(opt1
) & 0xffff;
507 sc
->sc_max_sectors
= (le32toh(opt1
) >> 16) << 1;
508 tmpval
= (le32toh(opt2
) >> 16);
509 if (tmpval
< sc
->sc_max_sgs
) {
510 sc
->sc_max_sgs
= tmpval
;
512 tmpval
= (le32toh(opt3
) & 0xffff);
513 if (tmpval
< sc
->sc_max_fibs
) {
514 sc
->sc_max_fibs
= tmpval
;
518 if (sc
->sc_max_fib_size
> PAGE_SIZE
)
519 sc
->sc_max_fib_size
= PAGE_SIZE
;
521 if (sc
->sc_quirks
& AAC_QUIRK_SG_64BIT
)
522 calcsgs
= (sc
->sc_max_fib_size
523 - sizeof(struct aac_blockwrite64
)
524 + sizeof(struct aac_sg_table64
))
525 / sizeof(struct aac_sg_table64
);
527 calcsgs
= (sc
->sc_max_fib_size
528 - sizeof(struct aac_blockwrite
)
529 + sizeof(struct aac_sg_table
))
530 / sizeof(struct aac_sg_table
);
532 if (calcsgs
< sc
->sc_max_sgs
) {
533 sc
->sc_max_sgs
= calcsgs
;
536 sc
->sc_max_fibs_alloc
= PAGE_SIZE
/ sc
->sc_max_fib_size
;
538 if (sc
->sc_max_fib_size
> sizeof(struct aac_fib
)) {
539 sc
->sc_quirks
|= AAC_QUIRK_RAW_IO
;
540 aprint_debug_dev(&sc
->sc_dv
, "Enable raw I/O\n");
542 if ((sc
->sc_quirks
& AAC_QUIRK_RAW_IO
) &&
543 (sc
->sc_quirks
& AAC_QUIRK_ARRAY_64BIT
)) {
544 sc
->sc_quirks
|= AAC_QUIRK_LBA_64BIT
;
545 aprint_normal_dev(&sc
->sc_dv
, "Enable 64-bit array support\n");
552 aac_init(struct aac_softc
*sc
)
554 int nsegs
, i
, rv
, state
, norm
, high
;
555 struct aac_adapter_init
*ip
;
556 u_int32_t code
, qoff
;
561 * First wait for the adapter to come ready.
563 for (i
= 0; i
< AAC_BOOT_TIMEOUT
* 1000; i
++) {
564 code
= AAC_GET_FWSTATUS(sc
);
565 if ((code
& AAC_SELF_TEST_FAILED
) != 0) {
566 aprint_error_dev(&sc
->sc_dv
, "FATAL: selftest failed\n");
569 if ((code
& AAC_KERNEL_PANIC
) != 0) {
570 aprint_error_dev(&sc
->sc_dv
, "FATAL: controller kernel panic\n");
573 if ((code
& AAC_UP_AND_RUNNING
) != 0)
577 if (i
== AAC_BOOT_TIMEOUT
* 1000) {
578 aprint_error_dev(&sc
->sc_dv
,
579 "FATAL: controller not coming ready, status %x\n",
584 sc
->sc_aif_fib
= malloc(sizeof(struct aac_fib
), M_AACBUF
,
586 if (sc
->sc_aif_fib
== NULL
) {
587 aprint_error_dev(&sc
->sc_dv
, "cannot alloc fib structure\n");
590 if ((rv
= bus_dmamap_create(sc
->sc_dmat
, sizeof(*sc
->sc_common
), 1,
591 sizeof(*sc
->sc_common
), 0, BUS_DMA_NOWAIT
| BUS_DMA_ALLOCNOW
,
592 &sc
->sc_common_dmamap
)) != 0) {
593 aprint_error_dev(&sc
->sc_dv
, "cannot create common dmamap\n");
597 if ((rv
= bus_dmamem_alloc(sc
->sc_dmat
, sizeof(*sc
->sc_common
),
598 PAGE_SIZE
, 0, &sc
->sc_common_seg
, 1, &nsegs
,
599 BUS_DMA_NOWAIT
)) != 0) {
600 aprint_error_dev(&sc
->sc_dv
, "can't allocate common structure\n");
604 if ((rv
= bus_dmamem_map(sc
->sc_dmat
, &sc
->sc_common_seg
, nsegs
,
605 sizeof(*sc
->sc_common
), (void **)&sc
->sc_common
, 0)) != 0) {
606 aprint_error_dev(&sc
->sc_dv
, "can't map common structure\n");
610 if ((rv
= bus_dmamap_load(sc
->sc_dmat
, sc
->sc_common_dmamap
,
611 sc
->sc_common
, sizeof(*sc
->sc_common
), NULL
,
612 BUS_DMA_NOWAIT
)) != 0) {
613 aprint_error_dev(&sc
->sc_dv
, "cannot load common dmamap\n");
618 memset(sc
->sc_common
, 0, sizeof(*sc
->sc_common
));
620 TAILQ_INIT(&sc
->sc_fibmap_tqh
);
621 sc
->sc_ccbs
= malloc(sizeof(struct aac_ccb
) * sc
->sc_max_fibs
, M_AACBUF
,
623 if (sc
->sc_ccbs
== NULL
) {
624 aprint_error_dev(&sc
->sc_dv
, "memory allocation failure getting ccbs\n");
629 while (sc
->sc_total_fibs
< AAC_PREALLOCATE_FIBS(sc
)) {
630 if (aac_alloc_commands(sc
) != 0)
633 if (sc
->sc_total_fibs
== 0)
637 * Fill in the init structure. This tells the adapter about the
638 * physical location of various important shared data structures.
640 ip
= &sc
->sc_common
->ac_init
;
641 ip
->InitStructRevision
= htole32(AAC_INIT_STRUCT_REVISION
);
642 if (sc
->sc_quirks
& AAC_QUIRK_RAW_IO
)
643 ip
->InitStructRevision
= htole32(AAC_INIT_STRUCT_REVISION_4
);
644 ip
->MiniPortRevision
= htole32(AAC_INIT_STRUCT_MINIPORT_REVISION
);
646 ip
->AdapterFibsPhysicalAddress
= htole32(sc
->sc_common_seg
.ds_addr
+
647 offsetof(struct aac_common
, ac_fibs
));
648 ip
->AdapterFibsVirtualAddress
= 0;
649 ip
->AdapterFibsSize
=
650 htole32(AAC_ADAPTER_FIBS
* sizeof(struct aac_fib
));
651 ip
->AdapterFibAlign
= htole32(sizeof(struct aac_fib
));
653 ip
->PrintfBufferAddress
= htole32(sc
->sc_common_seg
.ds_addr
+
654 offsetof(struct aac_common
, ac_printf
));
655 ip
->PrintfBufferSize
= htole32(AAC_PRINTF_BUFSIZE
);
658 * The adapter assumes that pages are 4K in size, except on some
659 * broken firmware versions that do the page->byte conversion twice,
660 * therefore 'assuming' that this value is in 16MB units (2^24).
661 * Round up since the granularity is so high.
663 ip
->HostPhysMemPages
= ctob(physmem
) / AAC_PAGE_SIZE
;
664 if (sc
->sc_quirks
& AAC_QUIRK_BROKEN_MMAP
) {
665 ip
->HostPhysMemPages
=
666 (ip
->HostPhysMemPages
+ AAC_PAGE_SIZE
) / AAC_PAGE_SIZE
;
668 ip
->HostElapsedSeconds
= 0; /* reset later if invalid */
671 if (sc
->sc_quirks
& AAC_QUIRK_NEW_COMM
) {
672 ip
->InitFlags
= htole32(AAC_INITFLAGS_NEW_COMM_SUPPORTED
);
673 aprint_normal_dev(&sc
->sc_dv
, "New comm. interface enabled\n");
676 ip
->MaxIoCommands
= htole32(sc
->sc_max_fibs
);
677 ip
->MaxIoSize
= htole32(sc
->sc_max_sectors
<< 9);
678 ip
->MaxFibSize
= htole32(sc
->sc_max_fib_size
);
681 * Initialise FIB queues. Note that it appears that the layout of
682 * the indexes and the segmentation of the entries is mandated by
683 * the adapter, which is only told about the base of the queue index
686 * The initial values of the indices are assumed to inform the
687 * adapter of the sizes of the respective queues.
689 * The Linux driver uses a much more complex scheme whereby several
690 * header records are kept for each queue. We use a couple of
691 * generic list manipulation functions which 'know' the size of each
692 * list by virtue of a table.
694 qoff
= offsetof(struct aac_common
, ac_qbuf
) + AAC_QUEUE_ALIGN
;
695 qoff
&= ~(AAC_QUEUE_ALIGN
- 1);
696 sc
->sc_queues
= (struct aac_queue_table
*)((uintptr_t)sc
->sc_common
+ qoff
);
697 ip
->CommHeaderAddress
= htole32(sc
->sc_common_seg
.ds_addr
+
698 ((char *)sc
->sc_queues
- (char *)sc
->sc_common
));
699 memset(sc
->sc_queues
, 0, sizeof(struct aac_queue_table
));
701 norm
= htole32(AAC_HOST_NORM_CMD_ENTRIES
);
702 high
= htole32(AAC_HOST_HIGH_CMD_ENTRIES
);
704 sc
->sc_queues
->qt_qindex
[AAC_HOST_NORM_CMD_QUEUE
][AAC_PRODUCER_INDEX
] =
706 sc
->sc_queues
->qt_qindex
[AAC_HOST_NORM_CMD_QUEUE
][AAC_CONSUMER_INDEX
] =
708 sc
->sc_queues
->qt_qindex
[AAC_HOST_HIGH_CMD_QUEUE
][AAC_PRODUCER_INDEX
] =
710 sc
->sc_queues
->qt_qindex
[AAC_HOST_HIGH_CMD_QUEUE
][AAC_CONSUMER_INDEX
] =
713 norm
= htole32(AAC_ADAP_NORM_CMD_ENTRIES
);
714 high
= htole32(AAC_ADAP_HIGH_CMD_ENTRIES
);
716 sc
->sc_queues
->qt_qindex
[AAC_ADAP_NORM_CMD_QUEUE
][AAC_PRODUCER_INDEX
] =
718 sc
->sc_queues
->qt_qindex
[AAC_ADAP_NORM_CMD_QUEUE
][AAC_CONSUMER_INDEX
] =
720 sc
->sc_queues
->qt_qindex
[AAC_ADAP_HIGH_CMD_QUEUE
][AAC_PRODUCER_INDEX
] =
722 sc
->sc_queues
->qt_qindex
[AAC_ADAP_HIGH_CMD_QUEUE
][AAC_CONSUMER_INDEX
] =
725 norm
= htole32(AAC_HOST_NORM_RESP_ENTRIES
);
726 high
= htole32(AAC_HOST_HIGH_RESP_ENTRIES
);
729 qt_qindex
[AAC_HOST_NORM_RESP_QUEUE
][AAC_PRODUCER_INDEX
] = norm
;
731 qt_qindex
[AAC_HOST_NORM_RESP_QUEUE
][AAC_CONSUMER_INDEX
] = norm
;
733 qt_qindex
[AAC_HOST_HIGH_RESP_QUEUE
][AAC_PRODUCER_INDEX
] = high
;
735 qt_qindex
[AAC_HOST_HIGH_RESP_QUEUE
][AAC_CONSUMER_INDEX
] = high
;
737 norm
= htole32(AAC_ADAP_NORM_RESP_ENTRIES
);
738 high
= htole32(AAC_ADAP_HIGH_RESP_ENTRIES
);
741 qt_qindex
[AAC_ADAP_NORM_RESP_QUEUE
][AAC_PRODUCER_INDEX
] = norm
;
743 qt_qindex
[AAC_ADAP_NORM_RESP_QUEUE
][AAC_CONSUMER_INDEX
] = norm
;
745 qt_qindex
[AAC_ADAP_HIGH_RESP_QUEUE
][AAC_PRODUCER_INDEX
] = high
;
747 qt_qindex
[AAC_ADAP_HIGH_RESP_QUEUE
][AAC_CONSUMER_INDEX
] = high
;
749 sc
->sc_qentries
[AAC_HOST_NORM_CMD_QUEUE
] =
750 &sc
->sc_queues
->qt_HostNormCmdQueue
[0];
751 sc
->sc_qentries
[AAC_HOST_HIGH_CMD_QUEUE
] =
752 &sc
->sc_queues
->qt_HostHighCmdQueue
[0];
753 sc
->sc_qentries
[AAC_ADAP_NORM_CMD_QUEUE
] =
754 &sc
->sc_queues
->qt_AdapNormCmdQueue
[0];
755 sc
->sc_qentries
[AAC_ADAP_HIGH_CMD_QUEUE
] =
756 &sc
->sc_queues
->qt_AdapHighCmdQueue
[0];
757 sc
->sc_qentries
[AAC_HOST_NORM_RESP_QUEUE
] =
758 &sc
->sc_queues
->qt_HostNormRespQueue
[0];
759 sc
->sc_qentries
[AAC_HOST_HIGH_RESP_QUEUE
] =
760 &sc
->sc_queues
->qt_HostHighRespQueue
[0];
761 sc
->sc_qentries
[AAC_ADAP_NORM_RESP_QUEUE
] =
762 &sc
->sc_queues
->qt_AdapNormRespQueue
[0];
763 sc
->sc_qentries
[AAC_ADAP_HIGH_RESP_QUEUE
] =
764 &sc
->sc_queues
->qt_AdapHighRespQueue
[0];
767 * Do controller-type-specific initialisation
769 switch (sc
->sc_hwif
) {
770 case AAC_HWIF_I960RX
:
771 AAC_SETREG4(sc
, AAC_RX_ODBR
, ~0);
775 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_common_dmamap
, 0,
776 sizeof(*sc
->sc_common
),
777 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
780 * Give the init structure to the controller.
782 if (aac_sync_command(sc
, AAC_MONKER_INITSTRUCT
,
783 sc
->sc_common_seg
.ds_addr
+ offsetof(struct aac_common
, ac_init
),
785 aprint_error_dev(&sc
->sc_dv
, "error establishing init structure\n");
794 free(sc
->sc_ccbs
, M_AACBUF
);
796 bus_dmamap_unload(sc
->sc_dmat
, sc
->sc_common_dmamap
);
798 bus_dmamem_unmap(sc
->sc_dmat
, (void *)sc
->sc_common
,
799 sizeof(*sc
->sc_common
));
801 bus_dmamem_free(sc
->sc_dmat
, &sc
->sc_common_seg
, 1);
803 bus_dmamap_destroy(sc
->sc_dmat
, sc
->sc_common_dmamap
);
805 free(sc
->sc_aif_fib
, M_AACBUF
);
811 * Probe for containers, create disks.
814 aac_startup(struct aac_softc
*sc
)
816 struct aac_mntinfo mi
;
817 struct aac_mntinforesponse mir
;
818 struct aac_drive
*hd
;
824 * Loop over possible containers.
828 for (i
= 0; i
< AAC_MAX_CONTAINERS
; i
++, hd
++) {
830 * Request information on this container.
832 memset(&mi
, 0, sizeof(mi
));
833 /* use 64-bit LBA if enabled */
834 if (sc
->sc_quirks
& AAC_QUIRK_LBA_64BIT
) {
835 mi
.Command
= htole32(VM_NameServe64
);
836 ersize
= sizeof(mir
);
838 mi
.Command
= htole32(VM_NameServe
);
839 ersize
= sizeof(mir
) - sizeof(mir
.MntTable
[0].CapacityHigh
);
841 mi
.MntType
= htole32(FT_FILESYS
);
842 mi
.MntCount
= htole32(i
);
843 if (aac_sync_fib(sc
, ContainerCommand
, 0, &mi
, sizeof(mi
), &mir
,
845 aprint_error_dev(&sc
->sc_dv
, "error probing container %d\n", i
);
848 if (rsize
!= ersize
) {
849 aprint_error_dev(&sc
->sc_dv
, "container info response wrong size "
850 "(%d should be %zu)\n", rsize
, ersize
);
855 * Check container volume type for validity. Note that many
856 * of the possible types may never show up.
858 if (le32toh(mir
.Status
) != ST_OK
||
859 le32toh(mir
.MntTable
[0].VolType
) == CT_NONE
)
863 hd
->hd_size
= le32toh(mir
.MntTable
[0].Capacity
);
864 if (sc
->sc_quirks
& AAC_QUIRK_LBA_64BIT
)
865 hd
->hd_size
+= (u_int64_t
)
866 le32toh(mir
.MntTable
[0].CapacityHigh
) << 32;
867 hd
->hd_devtype
= le32toh(mir
.MntTable
[0].VolType
);
868 hd
->hd_size
&= ~0x1f;
874 aac_shutdown(void *cookie
)
876 struct aac_softc
*sc
;
877 struct aac_close_command cc
;
880 for (i
= 0; i
< aac_cd
.cd_ndevs
; i
++) {
881 if ((sc
= device_lookup_private(&aac_cd
, i
)) == NULL
)
883 if ((sc
->sc_flags
& AAC_ONLINE
) == 0)
886 AAC_MASK_INTERRUPTS(sc
);
889 * Send a Container shutdown followed by a HostShutdown FIB
890 * to the controller to convince it that we don't want to
891 * talk to it anymore. We've been closed and all I/O
894 memset(&cc
, 0, sizeof(cc
));
895 cc
.Command
= htole32(VM_CloseAll
);
896 cc
.ContainerId
= 0xffffffff;
897 if (aac_sync_fib(sc
, ContainerCommand
, 0, &cc
, sizeof(cc
),
899 aprint_error_dev(&sc
->sc_dv
, "unable to halt controller\n");
904 * Note that issuing this command to the controller makes it
905 * shut down but also keeps it from coming back up without a
906 * reset of the PCI bus.
908 if (aac_sync_fib(sc
, FsaHostShutdown
, AAC_FIBSTATE_SHUTDOWN
,
909 &i
, sizeof(i
), NULL
, NULL
))
910 aprint_error_dev(&sc
->sc_dv
, "unable to halt controller\n");
912 sc
->sc_flags
&= ~AAC_ONLINE
;
917 aac_new_intr(void *cookie
)
919 struct aac_softc
*sc
;
920 u_int32_t index
, fast
;
923 struct aac_fibmap
*fm
;
926 sc
= (struct aac_softc
*) cookie
;
929 index
= AAC_GET_OUTB_QUEUE(sc
);
930 if (index
== 0xffffffff)
931 index
= AAC_GET_OUTB_QUEUE(sc
);
932 if (index
== 0xffffffff)
935 if (index
== 0xfffffffe) {
936 /* XXX This means that the controller wants
937 * more work. Ignore it for now.
943 fib
= sc
->sc_aif_fib
;
944 for (i
= 0; i
< sizeof(struct aac_fib
)/4; i
++) {
945 ((u_int32_t
*)fib
)[i
] =
946 AAC_GETREG4(sc
, index
+ i
*4);
949 aac_handle_aif(sc
, &fib
);
952 AAC_SET_OUTB_QUEUE(sc
, index
);
953 AAC_CLEAR_ISTATUS(sc
, AAC_DB_RESPONSE_READY
);
956 ac
= sc
->sc_ccbs
+ (index
>> 2);
960 bus_dmamap_sync(sc
->sc_dmat
, fm
->fm_fibmap
,
961 (char *)fib
- (char *)fm
->fm_fibs
,
963 BUS_DMASYNC_POSTWRITE
|
964 BUS_DMASYNC_POSTREAD
);
965 fib
->Header
.XferState
|=
966 htole32(AAC_FIBSTATE_DONEADAP
);
967 *((u_int32_t
*)(fib
->data
)) =
968 htole32(AAC_ERROR_NORMAL
);
970 ac
->ac_flags
|= AAC_CCB_COMPLETED
;
972 if (ac
->ac_intr
!= NULL
)
980 * Try to submit more commands.
982 if (! SIMPLEQ_EMPTY(&sc
->sc_ccb_queue
))
983 aac_ccb_enqueue(sc
, NULL
);
992 aac_intr(void *cookie
)
994 struct aac_softc
*sc
;
1001 AAC_DPRINTF(AAC_D_INTR
, ("aac_intr(%p) ", sc
));
1003 reason
= AAC_GET_ISTATUS(sc
);
1004 AAC_CLEAR_ISTATUS(sc
, reason
);
1006 AAC_DPRINTF(AAC_D_INTR
, ("istatus 0x%04x ", reason
));
1009 * Controller wants to talk to the log. XXX Should we defer this?
1011 if ((reason
& AAC_DB_PRINTF
) != 0) {
1012 if (sc
->sc_common
->ac_printf
[0] == '\0')
1013 sc
->sc_common
->ac_printf
[0] = ' ';
1014 printf("%s: WARNING: adapter logged message:\n",
1015 device_xname(&sc
->sc_dv
));
1016 printf("%s: %.*s", device_xname(&sc
->sc_dv
),
1017 AAC_PRINTF_BUFSIZE
, sc
->sc_common
->ac_printf
);
1018 sc
->sc_common
->ac_printf
[0] = '\0';
1019 AAC_QNOTIFY(sc
, AAC_DB_PRINTF
);
1024 * Controller has a message for us?
1026 if ((reason
& AAC_DB_COMMAND_READY
) != 0) {
1027 aac_host_command(sc
);
1032 * Controller has a response for us?
1034 if ((reason
& AAC_DB_RESPONSE_READY
) != 0) {
1035 aac_host_response(sc
);
1040 * Spurious interrupts that we don't use - reset the mask and clear
1043 if ((reason
& (AAC_DB_SYNC_COMMAND
| AAC_DB_COMMAND_NOT_FULL
|
1044 AAC_DB_RESPONSE_NOT_FULL
)) != 0) {
1045 AAC_UNMASK_INTERRUPTS(sc
);
1046 AAC_CLEAR_ISTATUS(sc
, AAC_DB_SYNC_COMMAND
|
1047 AAC_DB_COMMAND_NOT_FULL
| AAC_DB_RESPONSE_NOT_FULL
);
1055 * Handle notification of one or more FIBs coming from the controller.
1058 aac_host_command(struct aac_softc
*sc
)
1060 struct aac_fib
*fib
;
1064 if (aac_dequeue_fib(sc
, AAC_HOST_NORM_CMD_QUEUE
, &fib_size
,
1066 break; /* nothing to do */
1068 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_common_dmamap
,
1069 (char *)fib
- (char *)sc
->sc_common
, sizeof(*fib
),
1070 BUS_DMASYNC_POSTREAD
);
1072 switch (le16toh(fib
->Header
.Command
)) {
1076 (struct aac_aif_command
*)&fib
->data
[0]);
1078 AAC_PRINT_FIB(sc
, fib
);
1081 aprint_error_dev(&sc
->sc_dv
, "unknown command from controller\n");
1082 AAC_PRINT_FIB(sc
, fib
);
1086 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_common_dmamap
,
1087 (char *)fib
- (char *)sc
->sc_common
, sizeof(*fib
),
1088 BUS_DMASYNC_PREREAD
);
1090 if ((fib
->Header
.XferState
== 0) ||
1091 (fib
->Header
.StructType
!= AAC_FIBTYPE_TFIB
)) {
1092 break; // continue; ???
1095 /* XXX reply to FIBs requesting responses ?? */
1097 /* Return the AIF/FIB to the controller */
1098 if (le32toh(fib
->Header
.XferState
) & AAC_FIBSTATE_FROMADAP
) {
1101 fib
->Header
.XferState
|=
1102 htole32(AAC_FIBSTATE_DONEHOST
);
1103 *(u_int32_t
*)fib
->data
= htole32(ST_OK
);
1105 /* XXX Compute the Size field? */
1106 size
= le16toh(fib
->Header
.Size
);
1107 if (size
> sizeof(struct aac_fib
)) {
1108 size
= sizeof(struct aac_fib
);
1109 fib
->Header
.Size
= htole16(size
);
1113 * Since we didn't generate this command, it can't
1114 * go through the normal process.
1116 aac_enqueue_response(sc
,
1117 AAC_ADAP_NORM_RESP_QUEUE
, fib
);
1123 * Handle notification of one or more FIBs completed by the controller
1126 aac_host_response(struct aac_softc
*sc
)
1129 struct aac_fib
*fib
;
1133 * Look for completed FIBs on our queue.
1136 if (aac_dequeue_fib(sc
, AAC_HOST_NORM_RESP_QUEUE
, &fib_size
,
1138 break; /* nothing to do */
1140 if ((fib
->Header
.SenderData
& 0x80000000) == 0) {
1141 /* Not valid; not sent by us. */
1142 AAC_PRINT_FIB(sc
, fib
);
1144 ac
= (struct aac_ccb
*)(sc
->sc_ccbs
+
1145 (fib
->Header
.SenderData
& 0x7fffffff));
1146 fib
->Header
.SenderData
= 0;
1147 SIMPLEQ_INSERT_TAIL(&sc
->sc_ccb_complete
, ac
, ac_chain
);
1152 * Deal with any completed commands.
1154 while ((ac
= SIMPLEQ_FIRST(&sc
->sc_ccb_complete
)) != NULL
) {
1155 SIMPLEQ_REMOVE_HEAD(&sc
->sc_ccb_complete
, ac_chain
);
1156 ac
->ac_flags
|= AAC_CCB_COMPLETED
;
1158 if (ac
->ac_intr
!= NULL
)
1165 * Try to submit more commands.
1167 if (! SIMPLEQ_EMPTY(&sc
->sc_ccb_queue
))
1168 aac_ccb_enqueue(sc
, NULL
);
1172 * Send a synchronous command to the controller and wait for a result.
1175 aac_sync_command(struct aac_softc
*sc
, u_int32_t command
, u_int32_t arg0
,
1176 u_int32_t arg1
, u_int32_t arg2
, u_int32_t arg3
, u_int32_t
*sp
)
1184 /* Populate the mailbox. */
1185 AAC_SET_MAILBOX(sc
, command
, arg0
, arg1
, arg2
, arg3
);
1187 /* Ensure the sync command doorbell flag is cleared. */
1188 AAC_CLEAR_ISTATUS(sc
, AAC_DB_SYNC_COMMAND
);
1190 /* ... then set it to signal the adapter. */
1191 AAC_QNOTIFY(sc
, AAC_DB_SYNC_COMMAND
);
1192 DELAY(AAC_SYNC_DELAY
);
1194 /* Spin waiting for the command to complete. */
1195 for (i
= 0; i
< AAC_IMMEDIATE_TIMEOUT
* 1000; i
++) {
1196 if (AAC_GET_ISTATUS(sc
) & AAC_DB_SYNC_COMMAND
)
1200 if (i
== AAC_IMMEDIATE_TIMEOUT
* 1000) {
1205 /* Clear the completion flag. */
1206 AAC_CLEAR_ISTATUS(sc
, AAC_DB_SYNC_COMMAND
);
1208 /* Get the command status. */
1209 status
= AAC_GET_MAILBOXSTATUS(sc
);
1214 return (0); /* XXX Check command return status? */
1218 * Send a synchronous FIB to the controller and wait for a result.
1221 aac_sync_fib(struct aac_softc
*sc
, u_int32_t command
, u_int32_t xferstate
,
1222 void *data
, u_int16_t datasize
, void *result
,
1223 u_int16_t
*resultsize
)
1225 struct aac_fib
*fib
;
1226 u_int32_t fibpa
, status
;
1228 fib
= &sc
->sc_common
->ac_sync_fib
;
1229 fibpa
= sc
->sc_common_seg
.ds_addr
+
1230 offsetof(struct aac_common
, ac_sync_fib
);
1232 if (datasize
> AAC_FIB_DATASIZE
)
1236 * Set up the sync FIB.
1238 fib
->Header
.XferState
= htole32(AAC_FIBSTATE_HOSTOWNED
|
1239 AAC_FIBSTATE_INITIALISED
| AAC_FIBSTATE_EMPTY
| xferstate
);
1240 fib
->Header
.Command
= htole16(command
);
1241 fib
->Header
.StructType
= AAC_FIBTYPE_TFIB
;
1242 fib
->Header
.Size
= htole16(sizeof(*fib
) + datasize
);
1243 fib
->Header
.SenderSize
= htole16(sizeof(*fib
));
1244 fib
->Header
.SenderFibAddress
= 0; /* not needed */
1245 fib
->Header
.ReceiverFibAddress
= htole32(fibpa
);
1251 memcpy(fib
->data
, data
, datasize
);
1252 fib
->Header
.XferState
|=
1253 htole32(AAC_FIBSTATE_FROMHOST
| AAC_FIBSTATE_NORM
);
1256 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_common_dmamap
,
1257 (char *)fib
- (char *)sc
->sc_common
, sizeof(*fib
),
1258 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1261 * Give the FIB to the controller, wait for a response.
1263 if (aac_sync_command(sc
, AAC_MONKER_SYNCFIB
, fibpa
, 0, 0, 0, &status
))
1266 printf("%s: syncfib command %04x status %08x\n",
1267 device_xname(&sc
->sc_dv
), command
, status
);
1270 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_common_dmamap
,
1271 (char *)fib
- (char *)sc
->sc_common
, sizeof(*fib
),
1272 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1275 * Copy out the result
1277 if (result
!= NULL
) {
1278 *resultsize
= le16toh(fib
->Header
.Size
) - sizeof(fib
->Header
);
1279 memcpy(result
, fib
->data
, *resultsize
);
1286 aac_ccb_alloc(struct aac_softc
*sc
, int flags
)
1291 AAC_DPRINTF(AAC_D_QUEUE
, ("aac_ccb_alloc(%p, 0x%x) ", sc
, flags
));
1294 ac
= SIMPLEQ_FIRST(&sc
->sc_ccb_free
);
1296 if (aac_alloc_commands(sc
)) {
1300 ac
= SIMPLEQ_FIRST(&sc
->sc_ccb_free
);
1304 panic("aac_ccb_get: no free CCBS");
1306 SIMPLEQ_REMOVE_HEAD(&sc
->sc_ccb_free
, ac_chain
);
1309 ac
->ac_flags
= flags
;
1314 aac_ccb_free(struct aac_softc
*sc
, struct aac_ccb
*ac
)
1318 AAC_DPRINTF(AAC_D_QUEUE
, ("aac_ccb_free(%p, %p) ", sc
, ac
));
1322 ac
->ac_fib
->Header
.XferState
= htole32(AAC_FIBSTATE_EMPTY
);
1323 ac
->ac_fib
->Header
.StructType
= AAC_FIBTYPE_TFIB
;
1324 ac
->ac_fib
->Header
.Flags
= 0;
1325 ac
->ac_fib
->Header
.SenderSize
= htole16(sc
->sc_max_fib_size
);
1329 * These are duplicated in aac_ccb_submit() to cover the case where
1330 * an intermediate stage may have destroyed them. They're left
1331 * initialised here for debugging purposes only.
1333 ac
->ac_fib
->Header
.SenderFibAddress
=
1334 htole32(((u_int32_t
) (ac
- sc
->sc_ccbs
)) << 2);
1335 ac
->ac_fib
->Header
.ReceiverFibAddress
= htole32(ac
->ac_fibphys
);
1339 SIMPLEQ_INSERT_HEAD(&sc
->sc_ccb_free
, ac
, ac_chain
);
1344 aac_ccb_map(struct aac_softc
*sc
, struct aac_ccb
*ac
)
1348 AAC_DPRINTF(AAC_D_QUEUE
, ("aac_ccb_map(%p, %p) ", sc
, ac
));
1351 if ((ac
->ac_flags
& AAC_CCB_MAPPED
) != 0)
1352 panic("aac_ccb_map: already mapped");
1355 error
= bus_dmamap_load(sc
->sc_dmat
, ac
->ac_dmamap_xfer
, ac
->ac_data
,
1356 ac
->ac_datalen
, NULL
, BUS_DMA_NOWAIT
| BUS_DMA_STREAMING
|
1357 ((ac
->ac_flags
& AAC_CCB_DATA_IN
) ? BUS_DMA_READ
: BUS_DMA_WRITE
));
1359 printf("%s: aac_ccb_map: ", device_xname(&sc
->sc_dv
));
1361 printf("more than %d DMA segs\n", sc
->sc_max_sgs
);
1363 printf("error %d loading DMA map\n", error
);
1367 bus_dmamap_sync(sc
->sc_dmat
, ac
->ac_dmamap_xfer
, 0, ac
->ac_datalen
,
1368 (ac
->ac_flags
& AAC_CCB_DATA_IN
) ? BUS_DMASYNC_PREREAD
:
1369 BUS_DMASYNC_PREWRITE
);
1372 ac
->ac_flags
|= AAC_CCB_MAPPED
;
1378 aac_ccb_unmap(struct aac_softc
*sc
, struct aac_ccb
*ac
)
1381 AAC_DPRINTF(AAC_D_QUEUE
, ("aac_ccb_unmap(%p, %p) ", sc
, ac
));
1384 if ((ac
->ac_flags
& AAC_CCB_MAPPED
) == 0)
1385 panic("aac_ccb_unmap: not mapped");
1388 bus_dmamap_sync(sc
->sc_dmat
, ac
->ac_dmamap_xfer
, 0, ac
->ac_datalen
,
1389 (ac
->ac_flags
& AAC_CCB_DATA_IN
) ? BUS_DMASYNC_POSTREAD
:
1390 BUS_DMASYNC_POSTWRITE
);
1391 bus_dmamap_unload(sc
->sc_dmat
, ac
->ac_dmamap_xfer
);
1394 ac
->ac_flags
&= ~AAC_CCB_MAPPED
;
1399 aac_ccb_enqueue(struct aac_softc
*sc
, struct aac_ccb
*ac
)
1403 AAC_DPRINTF(AAC_D_QUEUE
, ("aac_ccb_enqueue(%p, %p) ", sc
, ac
));
1408 SIMPLEQ_INSERT_TAIL(&sc
->sc_ccb_queue
, ac
, ac_chain
);
1410 while ((ac
= SIMPLEQ_FIRST(&sc
->sc_ccb_queue
)) != NULL
) {
1411 if (aac_ccb_submit(sc
, ac
))
1413 SIMPLEQ_REMOVE_HEAD(&sc
->sc_ccb_queue
, ac_chain
);
1420 aac_ccb_submit(struct aac_softc
*sc
, struct aac_ccb
*ac
)
1422 struct aac_fibmap
*fm
;
1425 AAC_DPRINTF(AAC_D_QUEUE
, ("aac_ccb_submit(%p, %p) ", sc
, ac
));
1427 acidx
= (u_int32_t
) (ac
- sc
->sc_ccbs
);
1428 /* Fix up the address values. */
1429 ac
->ac_fib
->Header
.SenderFibAddress
= htole32(acidx
<< 2);
1430 ac
->ac_fib
->Header
.ReceiverFibAddress
= htole32(ac
->ac_fibphys
);
1432 /* Save a pointer to the command for speedy reverse-lookup. */
1433 ac
->ac_fib
->Header
.SenderData
= acidx
| 0x80000000;
1436 bus_dmamap_sync(sc
->sc_dmat
, fm
->fm_fibmap
,
1437 (char *)ac
->ac_fib
- (char *)fm
->fm_fibs
, sc
->sc_max_fib_size
,
1438 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1440 /* Put the FIB on the outbound queue. */
1441 if (sc
->sc_quirks
& AAC_QUIRK_NEW_COMM
) {
1442 int count
= 10000000L;
1443 while (AAC_SEND_COMMAND(sc
, ac
) != 0) {
1445 panic("aac: fixme!");
1452 return (aac_enqueue_fib(sc
, AAC_ADAP_NORM_CMD_QUEUE
, ac
));
1457 aac_ccb_poll(struct aac_softc
*sc
, struct aac_ccb
*ac
, int timo
)
1461 AAC_DPRINTF(AAC_D_QUEUE
, ("aac_ccb_poll(%p, %p, %d) ", sc
, ac
, timo
));
1465 if ((rv
= aac_ccb_submit(sc
, ac
)) != 0) {
1470 for (timo
*= 1000; timo
!= 0; timo
--) {
1471 if (sc
->sc_quirks
& AAC_QUIRK_NEW_COMM
)
1475 if ((ac
->ac_flags
& AAC_CCB_COMPLETED
) != 0)
1485 * Atomically insert an entry into the nominated queue, returns 0 on success
1486 * or EBUSY if the queue is full.
1488 * XXX Note that it would be more efficient to defer notifying the
1489 * controller in the case where we may be inserting several entries in rapid
1490 * succession, but implementing this usefully is difficult.
1493 aac_enqueue_fib(struct aac_softc
*sc
, int queue
, struct aac_ccb
*ac
)
1495 u_int32_t fib_size
, fib_addr
, pi
, ci
;
1497 fib_size
= le16toh(ac
->ac_fib
->Header
.Size
);
1498 fib_addr
= le32toh(ac
->ac_fib
->Header
.ReceiverFibAddress
);
1500 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_common_dmamap
,
1501 (char *)sc
->sc_common
->ac_qbuf
- (char *)sc
->sc_common
,
1502 sizeof(sc
->sc_common
->ac_qbuf
),
1503 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1505 /* Get the producer/consumer indices. */
1506 pi
= le32toh(sc
->sc_queues
->qt_qindex
[queue
][AAC_PRODUCER_INDEX
]);
1507 ci
= le32toh(sc
->sc_queues
->qt_qindex
[queue
][AAC_CONSUMER_INDEX
]);
1509 /* Wrap the queue? */
1510 if (pi
>= aac_qinfo
[queue
].size
)
1513 /* Check for queue full. */
1517 /* Populate queue entry. */
1518 (sc
->sc_qentries
[queue
] + pi
)->aq_fib_size
= htole32(fib_size
);
1519 (sc
->sc_qentries
[queue
] + pi
)->aq_fib_addr
= htole32(fib_addr
);
1521 /* Update producer index. */
1522 sc
->sc_queues
->qt_qindex
[queue
][AAC_PRODUCER_INDEX
] = htole32(pi
+ 1);
1524 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_common_dmamap
,
1525 (char *)sc
->sc_common
->ac_qbuf
- (char *)sc
->sc_common
,
1526 sizeof(sc
->sc_common
->ac_qbuf
),
1527 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1529 /* Notify the adapter if we know how. */
1530 if (aac_qinfo
[queue
].notify
!= 0)
1531 AAC_QNOTIFY(sc
, aac_qinfo
[queue
].notify
);
1537 * Atomically remove one entry from the nominated queue, returns 0 on success
1538 * or ENOENT if the queue is empty.
1541 aac_dequeue_fib(struct aac_softc
*sc
, int queue
, u_int32_t
*fib_size
,
1542 struct aac_fib
**fib_addr
)
1544 struct aac_fibmap
*fm
;
1546 u_int32_t pi
, ci
, idx
;
1549 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_common_dmamap
,
1550 (char *)sc
->sc_common
->ac_qbuf
- (char *)sc
->sc_common
,
1551 sizeof(sc
->sc_common
->ac_qbuf
),
1552 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1554 /* Get the producer/consumer indices. */
1555 pi
= le32toh(sc
->sc_queues
->qt_qindex
[queue
][AAC_PRODUCER_INDEX
]);
1556 ci
= le32toh(sc
->sc_queues
->qt_qindex
[queue
][AAC_CONSUMER_INDEX
]);
1558 /* Check for queue empty. */
1566 /* Wrap the queue? */
1567 if (ci
>= aac_qinfo
[queue
].size
)
1570 /* Fetch the entry. */
1571 *fib_size
= le32toh((sc
->sc_qentries
[queue
] + ci
)->aq_fib_size
);
1574 case AAC_HOST_NORM_CMD_QUEUE
:
1575 case AAC_HOST_HIGH_CMD_QUEUE
:
1576 idx
= le32toh((sc
->sc_qentries
[queue
] + ci
)->aq_fib_addr
);
1577 idx
/= sizeof(struct aac_fib
);
1578 *fib_addr
= &sc
->sc_common
->ac_fibs
[idx
];
1580 case AAC_HOST_NORM_RESP_QUEUE
:
1581 case AAC_HOST_HIGH_RESP_QUEUE
:
1582 idx
= le32toh((sc
->sc_qentries
[queue
] + ci
)->aq_fib_addr
);
1583 ac
= sc
->sc_ccbs
+ (idx
>> 2);
1584 *fib_addr
= ac
->ac_fib
;
1587 bus_dmamap_sync(sc
->sc_dmat
, fm
->fm_fibmap
,
1588 (char *)ac
->ac_fib
- (char *)fm
->fm_fibs
,
1589 sc
->sc_max_fib_size
,
1590 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1591 ac
->ac_fib
->Header
.XferState
|=
1592 htole32(AAC_FIBSTATE_DONEADAP
);
1593 *((u_int32_t
*)(ac
->ac_fib
->data
)) =
1594 htole32(AAC_ERROR_NORMAL
);
1598 panic("Invalid queue in aac_dequeue_fib()");
1602 /* Update consumer index. */
1603 sc
->sc_queues
->qt_qindex
[queue
][AAC_CONSUMER_INDEX
] = ci
+ 1;
1605 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_common_dmamap
,
1606 (char *)sc
->sc_common
->ac_qbuf
- (char *)sc
->sc_common
,
1607 sizeof(sc
->sc_common
->ac_qbuf
),
1608 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1610 /* If we have made the queue un-full, notify the adapter. */
1611 if (notify
&& (aac_qinfo
[queue
].notify
!= 0))
1612 AAC_QNOTIFY(sc
, aac_qinfo
[queue
].notify
);
1618 * Put our response to an adapter-initiated fib (AIF) on the response queue.
1621 aac_enqueue_response(struct aac_softc
*sc
, int queue
, struct aac_fib
*fib
)
1623 u_int32_t fib_size
, fib_addr
, pi
, ci
;
1625 fib_size
= le16toh(fib
->Header
.Size
);
1626 fib_addr
= fib
->Header
.SenderFibAddress
;
1627 fib
->Header
.ReceiverFibAddress
= fib_addr
;
1629 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_common_dmamap
,
1630 (char *)sc
->sc_common
->ac_qbuf
- (char *)sc
->sc_common
,
1631 sizeof(sc
->sc_common
->ac_qbuf
),
1632 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1634 /* Get the producer/consumer indices. */
1635 pi
= le32toh(sc
->sc_queues
->qt_qindex
[queue
][AAC_PRODUCER_INDEX
]);
1636 ci
= le32toh(sc
->sc_queues
->qt_qindex
[queue
][AAC_CONSUMER_INDEX
]);
1638 /* Wrap the queue? */
1639 if (pi
>= aac_qinfo
[queue
].size
)
1642 /* Check for queue full. */
1646 /* Populate queue entry. */
1647 (sc
->sc_qentries
[queue
] + pi
)->aq_fib_size
= htole32(fib_size
);
1648 (sc
->sc_qentries
[queue
] + pi
)->aq_fib_addr
= htole32(fib_addr
);
1650 /* Update producer index. */
1651 sc
->sc_queues
->qt_qindex
[queue
][AAC_PRODUCER_INDEX
] = htole32(pi
+ 1);
1653 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_common_dmamap
,
1654 (char *)sc
->sc_common
->ac_qbuf
- (char *)sc
->sc_common
,
1655 sizeof(sc
->sc_common
->ac_qbuf
),
1656 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1658 /* Notify the adapter if we know how. */
1659 if (aac_qinfo
[queue
].notify
!= 0)
1660 AAC_QNOTIFY(sc
, aac_qinfo
[queue
].notify
);
1670 aac_print_fib(struct aac_softc
*sc
, struct aac_fib
*fib
,
1673 struct aac_blockread
*br
;
1674 struct aac_blockwrite
*bw
;
1675 struct aac_sg_table
*sg
;
1679 printf("%s: FIB @ %p\n", caller
, fib
);
1680 snprintb(tbuf
, sizeof(tbuf
),
1702 "\25APIFIB\n", le32toh(fib
->Header
.XferState
));
1704 printf(" XferState %s\n", tbuf
);
1705 printf(" Command %d\n", le16toh(fib
->Header
.Command
));
1706 printf(" StructType %d\n", fib
->Header
.StructType
);
1707 printf(" Flags 0x%x\n", fib
->Header
.Flags
);
1708 printf(" Size %d\n", le16toh(fib
->Header
.Size
));
1709 printf(" SenderSize %d\n", le16toh(fib
->Header
.SenderSize
));
1710 printf(" SenderAddress 0x%x\n",
1711 le32toh(fib
->Header
.SenderFibAddress
));
1712 printf(" ReceiverAddress 0x%x\n",
1713 le32toh(fib
->Header
.ReceiverFibAddress
));
1714 printf(" SenderData 0x%x\n", fib
->Header
.SenderData
);
1716 switch (fib
->Header
.Command
) {
1717 case ContainerCommand
: {
1718 br
= (struct aac_blockread
*)fib
->data
;
1719 bw
= (struct aac_blockwrite
*)fib
->data
;
1722 if (le32toh(br
->Command
) == VM_CtBlockRead
) {
1723 printf(" BlockRead: container %d 0x%x/%d\n",
1724 le32toh(br
->ContainerId
), le32toh(br
->BlockNumber
),
1725 le32toh(br
->ByteCount
));
1728 if (le32toh(bw
->Command
) == VM_CtBlockWrite
) {
1729 printf(" BlockWrite: container %d 0x%x/%d (%s)\n",
1730 le32toh(bw
->ContainerId
), le32toh(bw
->BlockNumber
),
1731 le32toh(bw
->ByteCount
),
1732 le32toh(bw
->Stable
) == CSTABLE
?
1733 "stable" : "unstable");
1737 printf(" %d s/g entries\n", le32toh(sg
->SgCount
));
1738 for (i
= 0; i
< le32toh(sg
->SgCount
); i
++)
1739 printf(" 0x%08x/%d\n",
1740 le32toh(sg
->SgEntry
[i
].SgAddress
),
1741 le32toh(sg
->SgEntry
[i
].SgByteCount
));
1746 // dump first 32 bytes of fib->data
1747 printf(" Raw data:");
1748 for (i
= 0; i
< 32; i
++)
1749 printf(" %02x", fib
->data
[i
]);
1754 #endif /* AAC_DEBUG */