1*13d4bb4cSthorpej /* $NetBSD: aac_pci.c,v 1.42 2022/09/25 17:52:25 thorpej Exp $ */
277e08f05Sad
377e08f05Sad /*-
477e08f05Sad * Copyright (c) 2002 The NetBSD Foundation, Inc.
577e08f05Sad * All rights reserved.
677e08f05Sad *
777e08f05Sad * This code is derived from software contributed to The NetBSD Foundation
877e08f05Sad * by Andrew Doran.
977e08f05Sad *
1077e08f05Sad * Redistribution and use in source and binary forms, with or without
1177e08f05Sad * modification, are permitted provided that the following conditions
1277e08f05Sad * are met:
1377e08f05Sad * 1. Redistributions of source code must retain the above copyright
1477e08f05Sad * notice, this list of conditions and the following disclaimer.
1577e08f05Sad * 2. Redistributions in binary form must reproduce the above copyright
1677e08f05Sad * notice, this list of conditions and the following disclaimer in the
1777e08f05Sad * documentation and/or other materials provided with the distribution.
1877e08f05Sad *
1977e08f05Sad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2077e08f05Sad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2177e08f05Sad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2277e08f05Sad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2377e08f05Sad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2477e08f05Sad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2577e08f05Sad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2677e08f05Sad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2777e08f05Sad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2877e08f05Sad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2977e08f05Sad * POSSIBILITY OF SUCH DAMAGE.
3077e08f05Sad */
3177e08f05Sad
3277e08f05Sad /*-
3377e08f05Sad * Copyright (c) 2000 Michael Smith
3477e08f05Sad * Copyright (c) 2000 BSDi
3577e08f05Sad * Copyright (c) 2000 Niklas Hallqvist
3677e08f05Sad * All rights reserved.
3777e08f05Sad *
3877e08f05Sad * Redistribution and use in source and binary forms, with or without
3977e08f05Sad * modification, are permitted provided that the following conditions
4077e08f05Sad * are met:
4177e08f05Sad * 1. Redistributions of source code must retain the above copyright
4277e08f05Sad * notice, this list of conditions and the following disclaimer.
4377e08f05Sad * 2. Redistributions in binary form must reproduce the above copyright
4477e08f05Sad * notice, this list of conditions and the following disclaimer in the
4577e08f05Sad * documentation and/or other materials provided with the distribution.
4677e08f05Sad *
4777e08f05Sad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
4877e08f05Sad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4977e08f05Sad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5077e08f05Sad * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
5177e08f05Sad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5277e08f05Sad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5377e08f05Sad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5477e08f05Sad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5577e08f05Sad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5677e08f05Sad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5777e08f05Sad * SUCH DAMAGE.
5877e08f05Sad *
5977e08f05Sad * from FreeBSD: aac_pci.c,v 1.1 2000/09/13 03:20:34 msmith Exp
6077e08f05Sad * via OpenBSD: aac_pci.c,v 1.7 2002/03/14 01:26:58 millert Exp
6177e08f05Sad */
6277e08f05Sad
6377e08f05Sad /*
6477e08f05Sad * PCI front-end for the `aac' driver.
6577e08f05Sad */
6677e08f05Sad
6777e08f05Sad #include <sys/cdefs.h>
68*13d4bb4cSthorpej __KERNEL_RCSID(0, "$NetBSD: aac_pci.c,v 1.42 2022/09/25 17:52:25 thorpej Exp $");
6977e08f05Sad
7077e08f05Sad #include <sys/param.h>
7177e08f05Sad #include <sys/systm.h>
7277e08f05Sad #include <sys/device.h>
7377e08f05Sad #include <sys/kernel.h>
7477e08f05Sad #include <sys/queue.h>
7577e08f05Sad
76a2a38285Sad #include <sys/bus.h>
7777e08f05Sad #include <machine/endian.h>
78a2a38285Sad #include <sys/intr.h>
7977e08f05Sad
8077e08f05Sad #include <dev/pci/pcidevs.h>
8177e08f05Sad #include <dev/pci/pcireg.h>
8277e08f05Sad #include <dev/pci/pcivar.h>
8377e08f05Sad
8477e08f05Sad #include <dev/ic/aacreg.h>
8577e08f05Sad #include <dev/ic/aacvar.h>
8677e08f05Sad
87f82d990bSbriggs struct aac_pci_softc {
88f82d990bSbriggs struct aac_softc sc_aac;
89f82d990bSbriggs pci_chipset_tag_t sc_pc;
90f82d990bSbriggs pci_intr_handle_t sc_ih;
91f82d990bSbriggs };
92f82d990bSbriggs
9377e08f05Sad /* i960Rx interface */
94d36c43c5Sthorpej static int aac_rx_get_fwstatus(struct aac_softc *);
95d36c43c5Sthorpej static void aac_rx_qnotify(struct aac_softc *, int);
96d36c43c5Sthorpej static int aac_rx_get_istatus(struct aac_softc *);
97d36c43c5Sthorpej static void aac_rx_clear_istatus(struct aac_softc *, int);
98d36c43c5Sthorpej static void aac_rx_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t,
9977e08f05Sad u_int32_t, u_int32_t, u_int32_t);
100d36c43c5Sthorpej static uint32_t aac_rx_get_mailbox(struct aac_softc *, int);
101d36c43c5Sthorpej static void aac_rx_set_interrupts(struct aac_softc *, int);
102f82d990bSbriggs static int aac_rx_send_command(struct aac_softc *, struct aac_ccb *);
103f82d990bSbriggs static int aac_rx_get_outb_queue(struct aac_softc *);
104f82d990bSbriggs static void aac_rx_set_outb_queue(struct aac_softc *, int);
10577e08f05Sad
10677e08f05Sad /* StrongARM interface */
107d36c43c5Sthorpej static int aac_sa_get_fwstatus(struct aac_softc *);
108d36c43c5Sthorpej static void aac_sa_qnotify(struct aac_softc *, int);
109d36c43c5Sthorpej static int aac_sa_get_istatus(struct aac_softc *);
110d36c43c5Sthorpej static void aac_sa_clear_istatus(struct aac_softc *, int);
111d36c43c5Sthorpej static void aac_sa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t,
11277e08f05Sad u_int32_t, u_int32_t, u_int32_t);
113d36c43c5Sthorpej static uint32_t aac_sa_get_mailbox(struct aac_softc *, int);
114d36c43c5Sthorpej static void aac_sa_set_interrupts(struct aac_softc *, int);
11577e08f05Sad
116f82d990bSbriggs /* Rocket/MIPS interface */
117f82d990bSbriggs static int aac_rkt_get_fwstatus(struct aac_softc *);
118f82d990bSbriggs static void aac_rkt_qnotify(struct aac_softc *, int);
119f82d990bSbriggs static int aac_rkt_get_istatus(struct aac_softc *);
120f82d990bSbriggs static void aac_rkt_clear_istatus(struct aac_softc *, int);
121f82d990bSbriggs static void aac_rkt_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t,
122f82d990bSbriggs u_int32_t, u_int32_t, u_int32_t);
123f82d990bSbriggs static uint32_t aac_rkt_get_mailbox(struct aac_softc *, int);
124f82d990bSbriggs static void aac_rkt_set_interrupts(struct aac_softc *, int);
125f82d990bSbriggs static int aac_rkt_send_command(struct aac_softc *, struct aac_ccb *);
126f82d990bSbriggs static int aac_rkt_get_outb_queue(struct aac_softc *);
127f82d990bSbriggs static void aac_rkt_set_outb_queue(struct aac_softc *, int);
128f82d990bSbriggs
129d36c43c5Sthorpej static const struct aac_interface aac_rx_interface = {
13077e08f05Sad aac_rx_get_fwstatus,
13177e08f05Sad aac_rx_qnotify,
13277e08f05Sad aac_rx_get_istatus,
13377e08f05Sad aac_rx_clear_istatus,
13477e08f05Sad aac_rx_set_mailbox,
13580240054Sbriggs aac_rx_get_mailbox,
136f82d990bSbriggs aac_rx_set_interrupts,
137f82d990bSbriggs aac_rx_send_command,
138f82d990bSbriggs aac_rx_get_outb_queue,
139f82d990bSbriggs aac_rx_set_outb_queue
14077e08f05Sad };
14177e08f05Sad
142d36c43c5Sthorpej static const struct aac_interface aac_sa_interface = {
14377e08f05Sad aac_sa_get_fwstatus,
14477e08f05Sad aac_sa_qnotify,
14577e08f05Sad aac_sa_get_istatus,
14677e08f05Sad aac_sa_clear_istatus,
14777e08f05Sad aac_sa_set_mailbox,
14880240054Sbriggs aac_sa_get_mailbox,
149f82d990bSbriggs aac_sa_set_interrupts,
150f82d990bSbriggs NULL, NULL, NULL
151f82d990bSbriggs };
152f82d990bSbriggs
153f82d990bSbriggs static const struct aac_interface aac_rkt_interface = {
154f82d990bSbriggs aac_rkt_get_fwstatus,
155f82d990bSbriggs aac_rkt_qnotify,
156f82d990bSbriggs aac_rkt_get_istatus,
157f82d990bSbriggs aac_rkt_clear_istatus,
158f82d990bSbriggs aac_rkt_set_mailbox,
159f82d990bSbriggs aac_rkt_get_mailbox,
160f82d990bSbriggs aac_rkt_set_interrupts,
161f82d990bSbriggs aac_rkt_send_command,
162f82d990bSbriggs aac_rkt_get_outb_queue,
163f82d990bSbriggs aac_rkt_set_outb_queue
16477e08f05Sad };
16577e08f05Sad
1662735c718Schristos static struct aac_ident {
16777e08f05Sad u_short vendor;
16877e08f05Sad u_short device;
16977e08f05Sad u_short subvendor;
17077e08f05Sad u_short subdevice;
17177e08f05Sad u_short hwif;
17277e08f05Sad u_short quirks;
17377e08f05Sad const char *prodstr;
1742735c718Schristos } const aac_ident[] = {
17577e08f05Sad {
17677e08f05Sad PCI_VENDOR_DELL,
17777e08f05Sad PCI_PRODUCT_DELL_PERC_2SI,
17877e08f05Sad PCI_VENDOR_DELL,
17977e08f05Sad PCI_PRODUCT_DELL_PERC_2SI,
18077e08f05Sad AAC_HWIF_I960RX,
18177e08f05Sad 0,
18277e08f05Sad "Dell PERC 2/Si"
18377e08f05Sad },
18477e08f05Sad {
18577e08f05Sad PCI_VENDOR_DELL,
18677e08f05Sad PCI_PRODUCT_DELL_PERC_3DI,
18777e08f05Sad PCI_VENDOR_DELL,
18877e08f05Sad PCI_PRODUCT_DELL_PERC_3DI,
18977e08f05Sad AAC_HWIF_I960RX,
19077e08f05Sad 0,
19177e08f05Sad "Dell PERC 3/Di"
19277e08f05Sad },
19377e08f05Sad {
19477e08f05Sad PCI_VENDOR_DELL,
19577e08f05Sad PCI_PRODUCT_DELL_PERC_3DI,
19677e08f05Sad PCI_VENDOR_DELL,
19777e08f05Sad PCI_PRODUCT_DELL_PERC_3DI_SUB2,
19877e08f05Sad AAC_HWIF_I960RX,
19977e08f05Sad 0,
20077e08f05Sad "Dell PERC 3/Di"
20177e08f05Sad },
20277e08f05Sad {
20377e08f05Sad PCI_VENDOR_DELL,
20477e08f05Sad PCI_PRODUCT_DELL_PERC_3DI,
20577e08f05Sad PCI_VENDOR_DELL,
20677e08f05Sad PCI_PRODUCT_DELL_PERC_3DI_SUB3,
20777e08f05Sad AAC_HWIF_I960RX,
20877e08f05Sad 0,
20977e08f05Sad "Dell PERC 3/Di"
21077e08f05Sad },
21177e08f05Sad {
21277e08f05Sad PCI_VENDOR_DELL,
21377e08f05Sad PCI_PRODUCT_DELL_PERC_3DI_2,
21477e08f05Sad PCI_VENDOR_DELL,
21577e08f05Sad PCI_PRODUCT_DELL_PERC_3DI_2_SUB,
21677e08f05Sad AAC_HWIF_I960RX,
21777e08f05Sad 0,
21877e08f05Sad "Dell PERC 3/Di"
21977e08f05Sad },
22077e08f05Sad {
22177e08f05Sad PCI_VENDOR_DELL,
2227416434aSad PCI_PRODUCT_DELL_PERC_3DI_3,
2237416434aSad PCI_VENDOR_DELL,
2247416434aSad PCI_PRODUCT_DELL_PERC_3DI_3_SUB,
2257416434aSad AAC_HWIF_I960RX,
2267416434aSad 0,
2277416434aSad "Dell PERC 3/Di"
2287416434aSad },
2297416434aSad {
2307416434aSad PCI_VENDOR_DELL,
2317416434aSad PCI_PRODUCT_DELL_PERC_3DI_3,
2327416434aSad PCI_VENDOR_DELL,
2337416434aSad PCI_PRODUCT_DELL_PERC_3DI_3_SUB2,
2347416434aSad AAC_HWIF_I960RX,
2357416434aSad 0,
2367416434aSad "Dell PERC 3/Di"
2377416434aSad },
2387416434aSad {
2397416434aSad PCI_VENDOR_DELL,
2407416434aSad PCI_PRODUCT_DELL_PERC_3DI_3,
2417416434aSad PCI_VENDOR_DELL,
2427416434aSad PCI_PRODUCT_DELL_PERC_3DI_3_SUB3,
2437416434aSad AAC_HWIF_I960RX,
2447416434aSad 0,
2457416434aSad "Dell PERC 3/Di"
2467416434aSad },
2477416434aSad {
2487416434aSad PCI_VENDOR_DELL,
24977e08f05Sad PCI_PRODUCT_DELL_PERC_3SI,
25077e08f05Sad PCI_VENDOR_DELL,
25177e08f05Sad PCI_PRODUCT_DELL_PERC_3SI,
25277e08f05Sad AAC_HWIF_I960RX,
25377e08f05Sad 0,
25477e08f05Sad "Dell PERC 3/Si"
25577e08f05Sad },
25677e08f05Sad {
25777e08f05Sad PCI_VENDOR_DELL,
25877e08f05Sad PCI_PRODUCT_DELL_PERC_3SI_2,
25977e08f05Sad PCI_VENDOR_DELL,
26077e08f05Sad PCI_PRODUCT_DELL_PERC_3SI_2_SUB,
26177e08f05Sad AAC_HWIF_I960RX,
26277e08f05Sad 0,
26377e08f05Sad "Dell PERC 3/Si"
26477e08f05Sad },
26577e08f05Sad {
26677e08f05Sad PCI_VENDOR_ADP2,
2676fe6af80Smartti PCI_PRODUCT_ADP2_ASR2200S,
2686fe6af80Smartti PCI_VENDOR_DELL,
2696fe6af80Smartti PCI_PRODUCT_DELL_CERC_1_5,
2706fe6af80Smartti AAC_HWIF_I960RX,
2716fe6af80Smartti AAC_QUIRK_NO4GB,
2726fe6af80Smartti "Dell CERC SATA RAID 1.5/6ch"
2736fe6af80Smartti },
2746fe6af80Smartti {
2756fe6af80Smartti PCI_VENDOR_ADP2,
27677e08f05Sad PCI_PRODUCT_ADP2_AAC2622,
27777e08f05Sad PCI_VENDOR_ADP2,
27877e08f05Sad PCI_PRODUCT_ADP2_AAC2622,
27977e08f05Sad AAC_HWIF_I960RX,
28077e08f05Sad 0,
28177e08f05Sad "Adaptec ADP-2622"
28277e08f05Sad },
28377e08f05Sad {
28477e08f05Sad PCI_VENDOR_ADP2,
28577e08f05Sad PCI_PRODUCT_ADP2_ASR2200S,
28677e08f05Sad PCI_VENDOR_ADP2,
287c2db9e9cSgendalia PCI_PRODUCT_ADP2_ASR2200S_SUB2M,
288c2db9e9cSgendalia AAC_HWIF_I960RX,
289f82d990bSbriggs AAC_QUIRK_NO4GB | AAC_QUIRK_256FIBS,
290c2db9e9cSgendalia "Adaptec ASR-2200S"
291c2db9e9cSgendalia },
292c2db9e9cSgendalia {
293c2db9e9cSgendalia PCI_VENDOR_ADP2,
294c2db9e9cSgendalia PCI_PRODUCT_ADP2_ASR2200S,
295c2db9e9cSgendalia PCI_VENDOR_DELL,
296c2db9e9cSgendalia PCI_PRODUCT_ADP2_ASR2200S_SUB2M,
297c2db9e9cSgendalia AAC_HWIF_I960RX,
298f82d990bSbriggs AAC_QUIRK_NO4GB | AAC_QUIRK_256FIBS,
299c2db9e9cSgendalia "Dell PERC 320/DC"
300c2db9e9cSgendalia },
301c2db9e9cSgendalia {
302c2db9e9cSgendalia PCI_VENDOR_ADP2,
303c2db9e9cSgendalia PCI_PRODUCT_ADP2_ASR2200S,
304c2db9e9cSgendalia PCI_VENDOR_ADP2,
30577e08f05Sad PCI_PRODUCT_ADP2_ASR2200S,
30677e08f05Sad AAC_HWIF_I960RX,
307f82d990bSbriggs AAC_QUIRK_NO4GB | AAC_QUIRK_256FIBS,
30877e08f05Sad "Adaptec ASR-2200S"
30977e08f05Sad },
31077e08f05Sad {
31177e08f05Sad PCI_VENDOR_ADP2,
31277e08f05Sad PCI_PRODUCT_ADP2_ASR2200S,
31377e08f05Sad PCI_VENDOR_ADP2,
3144ff7407fSgendalia PCI_PRODUCT_ADP2_AAR2810SA,
3154ff7407fSgendalia AAC_HWIF_I960RX,
316f82d990bSbriggs AAC_QUIRK_NO4GB,
3174ff7407fSgendalia "Adaptec AAR-2810SA"
3184ff7407fSgendalia },
3194ff7407fSgendalia {
3204ff7407fSgendalia PCI_VENDOR_ADP2,
3214ff7407fSgendalia PCI_PRODUCT_ADP2_ASR2200S,
3224ff7407fSgendalia PCI_VENDOR_ADP2,
32377e08f05Sad PCI_PRODUCT_ADP2_ASR2120S,
32477e08f05Sad AAC_HWIF_I960RX,
325f82d990bSbriggs AAC_QUIRK_NO4GB | AAC_QUIRK_256FIBS,
32677e08f05Sad "Adaptec ASR-2120S"
32777e08f05Sad },
32877e08f05Sad {
329fb0f2441Sjdolecek PCI_VENDOR_ADP2,
330fb0f2441Sjdolecek PCI_PRODUCT_ADP2_ASR2200S,
331fb0f2441Sjdolecek PCI_VENDOR_ADP2,
332a1b0a426Stron PCI_PRODUCT_ADP2_ASR2410SA,
333fb0f2441Sjdolecek AAC_HWIF_I960RX,
334f82d990bSbriggs AAC_QUIRK_NO4GB,
335fb0f2441Sjdolecek "Adaptec ASR-2410SA"
336fb0f2441Sjdolecek },
337fb0f2441Sjdolecek {
338e8381a07Schristos PCI_VENDOR_ADP2,
339e8381a07Schristos PCI_PRODUCT_ADP2_ASR2200S,
340e8381a07Schristos PCI_VENDOR_HP,
341e8381a07Schristos PCI_PRODUCT_ADP2_HP_M110_G2,
342e8381a07Schristos AAC_HWIF_I960RX,
343f82d990bSbriggs AAC_QUIRK_NO4GB,
344e8381a07Schristos "HP ML110 G2 (Adaptec ASR-2610SA)"
345e8381a07Schristos },
346e8381a07Schristos {
347cfe5fff0Ssborrill PCI_VENDOR_ADP2,
348cfe5fff0Ssborrill PCI_PRODUCT_ADP2_ASR2120S,
349cfe5fff0Ssborrill PCI_VENDOR_IBM,
350cfe5fff0Ssborrill PCI_PRODUCT_IBM_SERVERAID8K,
351cfe5fff0Ssborrill AAC_HWIF_RKT,
352cfe5fff0Ssborrill 0,
353cfe5fff0Ssborrill "IBM ServeRAID 8k"
354cfe5fff0Ssborrill },
35556e0e00bSjmcneill { PCI_VENDOR_ADP2,
35656e0e00bSjmcneill PCI_PRODUCT_ADP2_ASR2200S,
35756e0e00bSjmcneill PCI_VENDOR_ADP2,
35889b88fd7Schs PCI_PRODUCT_ADP2_2405,
35989b88fd7Schs AAC_HWIF_I960RX,
36089b88fd7Schs 0,
36189b88fd7Schs "Adaptec RAID 2405"
36289b88fd7Schs },
36389b88fd7Schs { PCI_VENDOR_ADP2,
36489b88fd7Schs PCI_PRODUCT_ADP2_ASR2200S,
36589b88fd7Schs PCI_VENDOR_ADP2,
3666c2db190Suwe PCI_PRODUCT_ADP2_2445,
3676c2db190Suwe AAC_HWIF_I960RX,
3686c2db190Suwe 0,
3696c2db190Suwe "Adaptec RAID 2445"
3706c2db190Suwe },
3716c2db190Suwe { PCI_VENDOR_ADP2,
3726c2db190Suwe PCI_PRODUCT_ADP2_ASR2200S,
3736c2db190Suwe PCI_VENDOR_ADP2,
3746c2db190Suwe PCI_PRODUCT_ADP2_2805,
3756c2db190Suwe AAC_HWIF_I960RX,
3766c2db190Suwe 0,
3776c2db190Suwe "Adaptec RAID 2805"
3786c2db190Suwe },
3796c2db190Suwe { PCI_VENDOR_ADP2,
3806c2db190Suwe PCI_PRODUCT_ADP2_ASR2200S,
3816c2db190Suwe PCI_VENDOR_ADP2,
38256e0e00bSjmcneill PCI_PRODUCT_ADP2_3405,
38356e0e00bSjmcneill AAC_HWIF_I960RX,
38456e0e00bSjmcneill 0,
38556e0e00bSjmcneill "Adaptec RAID 3405"
38656e0e00bSjmcneill },
38789b88fd7Schs { PCI_VENDOR_ADP2,
38889b88fd7Schs PCI_PRODUCT_ADP2_ASR2200S,
38989b88fd7Schs PCI_VENDOR_ADP2,
39089b88fd7Schs PCI_PRODUCT_ADP2_3805,
39189b88fd7Schs AAC_HWIF_I960RX,
39289b88fd7Schs 0,
39389b88fd7Schs "Adaptec RAID 3805"
39489b88fd7Schs },
395cfe5fff0Ssborrill {
39677e08f05Sad PCI_VENDOR_DEC,
397b058cf77Saugustss PCI_PRODUCT_DEC_21554,
39877e08f05Sad PCI_VENDOR_ADP2,
39977e08f05Sad PCI_PRODUCT_ADP2_AAC364,
40077e08f05Sad AAC_HWIF_STRONGARM,
40177e08f05Sad 0,
40277e08f05Sad "Adaptec AAC-364"
40377e08f05Sad },
40477e08f05Sad {
40577e08f05Sad PCI_VENDOR_DEC,
406b058cf77Saugustss PCI_PRODUCT_DEC_21554,
40777e08f05Sad PCI_VENDOR_ADP2,
40877e08f05Sad PCI_PRODUCT_ADP2_ASR5400S,
40977e08f05Sad AAC_HWIF_STRONGARM,
410f82d990bSbriggs AAC_QUIRK_BROKEN_MMAP,
41177e08f05Sad "Adaptec ASR-5400S"
41277e08f05Sad },
41377e08f05Sad {
41477e08f05Sad PCI_VENDOR_DEC,
415b058cf77Saugustss PCI_PRODUCT_DEC_21554,
41677e08f05Sad PCI_VENDOR_ADP2,
41777e08f05Sad PCI_PRODUCT_ADP2_PERC_2QC,
41877e08f05Sad AAC_HWIF_STRONGARM,
41977e08f05Sad AAC_QUIRK_PERC2QC,
42077e08f05Sad "Dell PERC 2/QC"
42177e08f05Sad },
42277e08f05Sad {
42377e08f05Sad PCI_VENDOR_DEC,
424b058cf77Saugustss PCI_PRODUCT_DEC_21554,
42577e08f05Sad PCI_VENDOR_ADP2,
42677e08f05Sad PCI_PRODUCT_ADP2_PERC_3QC,
42777e08f05Sad AAC_HWIF_STRONGARM,
42877e08f05Sad 0,
42977e08f05Sad "Dell PERC 3/QC"
43077e08f05Sad },
43177e08f05Sad {
43277e08f05Sad PCI_VENDOR_DEC,
433b058cf77Saugustss PCI_PRODUCT_DEC_21554,
43477e08f05Sad PCI_VENDOR_HP,
43577e08f05Sad PCI_PRODUCT_HP_NETRAID_4M,
43677e08f05Sad AAC_HWIF_STRONGARM,
43777e08f05Sad 0,
43877e08f05Sad "HP NetRAID-4M"
43977e08f05Sad },
440a038991fSis {
441a038991fSis PCI_VENDOR_ADP2,
442a038991fSis PCI_PRODUCT_ADP2_ASR2200S,
443a038991fSis PCI_VENDOR_SUN,
444a038991fSis PCI_PRODUCT_ADP2_ASR2120S,
4454fd593c1Sis AAC_HWIF_I960RX,
4464fd593c1Sis 0,
4474fd593c1Sis "SG-XPCIESAS-R-IN"
4484fd593c1Sis },
44977e08f05Sad };
45077e08f05Sad
451d36c43c5Sthorpej static const struct aac_ident *
aac_find_ident(struct pci_attach_args * pa)45277e08f05Sad aac_find_ident(struct pci_attach_args *pa)
45377e08f05Sad {
45477e08f05Sad const struct aac_ident *m, *mm;
45577e08f05Sad u_int32_t subsysid;
45677e08f05Sad
45777e08f05Sad m = aac_ident;
45877e08f05Sad mm = aac_ident + (sizeof(aac_ident) / sizeof(aac_ident[0]));
45977e08f05Sad
46077e08f05Sad while (m < mm) {
46177e08f05Sad if (m->vendor == PCI_VENDOR(pa->pa_id) &&
46277e08f05Sad m->device == PCI_PRODUCT(pa->pa_id)) {
46377e08f05Sad subsysid = pci_conf_read(pa->pa_pc, pa->pa_tag,
46477e08f05Sad PCI_SUBSYS_ID_REG);
46577e08f05Sad if (m->subvendor == PCI_VENDOR(subsysid) &&
46677e08f05Sad m->subdevice == PCI_PRODUCT(subsysid))
46777e08f05Sad return (m);
46877e08f05Sad }
46977e08f05Sad m++;
47077e08f05Sad }
47177e08f05Sad
47277e08f05Sad return (NULL);
47377e08f05Sad }
47477e08f05Sad
475d36c43c5Sthorpej static int
aac_pci_intr_set(struct aac_softc * sc,int (* hand)(void *),void * arg)476f82d990bSbriggs aac_pci_intr_set(struct aac_softc *sc, int (*hand)(void*), void *arg)
477f82d990bSbriggs {
478f82d990bSbriggs struct aac_pci_softc *pcisc;
479f82d990bSbriggs
480f82d990bSbriggs pcisc = (struct aac_pci_softc *) sc;
481f82d990bSbriggs
482f82d990bSbriggs pci_intr_disestablish(pcisc->sc_pc, sc->sc_ih);
483d3cda613Sjdolecek sc->sc_ih = pci_intr_establish_xname(pcisc->sc_pc, pcisc->sc_ih,
484d3cda613Sjdolecek IPL_BIO, hand, arg, device_xname(sc->sc_dv));
485f82d990bSbriggs if (sc->sc_ih == NULL) {
486f82d990bSbriggs return ENXIO;
487f82d990bSbriggs }
488f82d990bSbriggs return 0;
489f82d990bSbriggs }
490f82d990bSbriggs
491f82d990bSbriggs static int
aac_pci_match(device_t parent,cfdata_t match,void * aux)492a591bc88Scegger aac_pci_match(device_t parent, cfdata_t match, void *aux)
49377e08f05Sad {
49477e08f05Sad struct pci_attach_args *pa;
49577e08f05Sad
49677e08f05Sad pa = aux;
49777e08f05Sad
49877e08f05Sad if (PCI_CLASS(pa->pa_class) == PCI_CLASS_I2O)
49977e08f05Sad return (0);
50077e08f05Sad
50177e08f05Sad return (aac_find_ident(pa) != NULL);
50277e08f05Sad }
50377e08f05Sad
504d36c43c5Sthorpej static void
aac_pci_attach(device_t parent,device_t self,void * aux)505a591bc88Scegger aac_pci_attach(device_t parent, device_t self, void *aux)
50677e08f05Sad {
50777e08f05Sad struct pci_attach_args *pa;
50877e08f05Sad pci_chipset_tag_t pc;
509f82d990bSbriggs struct aac_pci_softc *pcisc;
51077e08f05Sad struct aac_softc *sc;
51177e08f05Sad u_int16_t command;
51277e08f05Sad bus_addr_t membase;
51377e08f05Sad bus_size_t memsize;
51477e08f05Sad const char *intrstr;
51577e08f05Sad int state;
51677e08f05Sad const struct aac_ident *m;
517e58a356cSchristos char intrbuf[PCI_INTRSTR_LEN];
51877e08f05Sad
51977e08f05Sad pa = aux;
52077e08f05Sad pc = pa->pa_pc;
521b8169823Scegger pcisc = device_private(self);
522f82d990bSbriggs pcisc->sc_pc = pc;
523f82d990bSbriggs sc = &pcisc->sc_aac;
524cbab9cadSchs sc->sc_dv = self;
52577e08f05Sad state = 0;
52677e08f05Sad
5277ec10e2dSthorpej aprint_naive(": RAID controller\n");
5287ec10e2dSthorpej aprint_normal(": ");
52977e08f05Sad
53077e08f05Sad /*
53177e08f05Sad * Verify that the adapter is correctly set up in PCI space.
53277e08f05Sad */
53377e08f05Sad command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
53477e08f05Sad command |= PCI_COMMAND_MASTER_ENABLE;
53577e08f05Sad pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
53677e08f05Sad command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
53777e08f05Sad AAC_DPRINTF(AAC_D_MISC, ("pci command status reg 0x08x "));
53877e08f05Sad
53977e08f05Sad if ((command & PCI_COMMAND_MASTER_ENABLE) == 0) {
5407ec10e2dSthorpej aprint_error("can't enable bus-master feature\n");
54177e08f05Sad goto bail_out;
54277e08f05Sad }
54377e08f05Sad
54477e08f05Sad if ((command & PCI_COMMAND_MEM_ENABLE) == 0) {
5457ec10e2dSthorpej aprint_error("memory window not available\n");
54677e08f05Sad goto bail_out;
54777e08f05Sad }
54877e08f05Sad
54977e08f05Sad /*
55077e08f05Sad * Map control/status registers.
55177e08f05Sad */
55277e08f05Sad if (pci_mapreg_map(pa, PCI_MAPREG_START,
55377e08f05Sad PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_memt,
55477e08f05Sad &sc->sc_memh, &membase, &memsize)) {
5557ec10e2dSthorpej aprint_error("can't find mem space\n");
55677e08f05Sad goto bail_out;
55777e08f05Sad }
55877e08f05Sad state++;
55977e08f05Sad
560f82d990bSbriggs if (pci_intr_map(pa, &pcisc->sc_ih)) {
5617ec10e2dSthorpej aprint_error("couldn't map interrupt\n");
56277e08f05Sad goto bail_out;
56377e08f05Sad }
564e58a356cSchristos intrstr = pci_intr_string(pc, pcisc->sc_ih, intrbuf, sizeof(intrbuf));
565d3cda613Sjdolecek sc->sc_ih = pci_intr_establish_xname(pc, pcisc->sc_ih, IPL_BIO,
566d3cda613Sjdolecek aac_intr, sc, device_xname(self));
56777e08f05Sad if (sc->sc_ih == NULL) {
5687ec10e2dSthorpej aprint_error("couldn't establish interrupt");
56977e08f05Sad if (intrstr != NULL)
57085cadc23Snjoly aprint_error(" at %s", intrstr);
57185cadc23Snjoly aprint_error("\n");
57277e08f05Sad goto bail_out;
57377e08f05Sad }
57477e08f05Sad state++;
57577e08f05Sad
57677e08f05Sad sc->sc_dmat = pa->pa_dmat;
57777e08f05Sad
57877e08f05Sad m = aac_find_ident(pa);
5797ec10e2dSthorpej aprint_normal("%s\n", m->prodstr);
58077e08f05Sad if (intrstr != NULL)
5818bc54e5bSmsaitoh aprint_normal_dev(self, "interrupting at %s\n", intrstr);
58277e08f05Sad
58377e08f05Sad sc->sc_hwif = m->hwif;
58477e08f05Sad sc->sc_quirks = m->quirks;
58577e08f05Sad switch (sc->sc_hwif) {
58677e08f05Sad case AAC_HWIF_I960RX:
58777e08f05Sad AAC_DPRINTF(AAC_D_MISC,
58877e08f05Sad ("set hardware up for i960Rx"));
58977e08f05Sad sc->sc_if = aac_rx_interface;
59077e08f05Sad break;
59177e08f05Sad
59277e08f05Sad case AAC_HWIF_STRONGARM:
59377e08f05Sad AAC_DPRINTF(AAC_D_MISC,
59477e08f05Sad ("set hardware up for StrongARM"));
59577e08f05Sad sc->sc_if = aac_sa_interface;
59677e08f05Sad break;
597f82d990bSbriggs
598f82d990bSbriggs case AAC_HWIF_RKT:
599f82d990bSbriggs AAC_DPRINTF(AAC_D_MISC,
600f82d990bSbriggs ("set hardware up for MIPS/Rocket"));
601f82d990bSbriggs sc->sc_if = aac_rkt_interface;
602f82d990bSbriggs break;
60377e08f05Sad }
604f82d990bSbriggs sc->sc_regsize = memsize;
605f82d990bSbriggs sc->sc_intr_set = aac_pci_intr_set;
60677e08f05Sad
60777e08f05Sad if (!aac_attach(sc))
60877e08f05Sad return;
60977e08f05Sad
61077e08f05Sad bail_out:
61177e08f05Sad if (state > 1)
61277e08f05Sad pci_intr_disestablish(pc, sc->sc_ih);
61377e08f05Sad if (state > 0)
61477e08f05Sad bus_space_unmap(sc->sc_memt, sc->sc_memh, memsize);
61577e08f05Sad }
61677e08f05Sad
617916bdfa5Spgoyette /* ARGSUSED */
618916bdfa5Spgoyette static int
aac_pci_rescan(device_t self,const char * ifattr,const int * locs)6192685996bSthorpej aac_pci_rescan(device_t self, const char *ifattr, const int *locs)
620916bdfa5Spgoyette {
621916bdfa5Spgoyette
622916bdfa5Spgoyette return aac_devscan(device_private(self));
623916bdfa5Spgoyette }
624916bdfa5Spgoyette
625916bdfa5Spgoyette CFATTACH_DECL3_NEW(aac_pci, sizeof(struct aac_pci_softc),
626916bdfa5Spgoyette aac_pci_match, aac_pci_attach, NULL, NULL, aac_pci_rescan, NULL, 0);
627d36c43c5Sthorpej
62877e08f05Sad /*
62977e08f05Sad * Read the current firmware status word.
63077e08f05Sad */
631d36c43c5Sthorpej static int
aac_sa_get_fwstatus(struct aac_softc * sc)63277e08f05Sad aac_sa_get_fwstatus(struct aac_softc *sc)
63377e08f05Sad {
63477e08f05Sad
63577e08f05Sad return (AAC_GETREG4(sc, AAC_SA_FWSTATUS));
63677e08f05Sad }
63777e08f05Sad
638d36c43c5Sthorpej static int
aac_rx_get_fwstatus(struct aac_softc * sc)63977e08f05Sad aac_rx_get_fwstatus(struct aac_softc *sc)
64077e08f05Sad {
64177e08f05Sad
64277e08f05Sad return (AAC_GETREG4(sc, AAC_RX_FWSTATUS));
64377e08f05Sad }
64477e08f05Sad
645f82d990bSbriggs static int
aac_rkt_get_fwstatus(struct aac_softc * sc)646f82d990bSbriggs aac_rkt_get_fwstatus(struct aac_softc *sc)
647f82d990bSbriggs {
648f82d990bSbriggs
649f82d990bSbriggs return (AAC_GETREG4(sc, AAC_RKT_FWSTATUS));
650f82d990bSbriggs }
651f82d990bSbriggs
65277e08f05Sad /*
65377e08f05Sad * Notify the controller of a change in a given queue
65477e08f05Sad */
65577e08f05Sad
656d36c43c5Sthorpej static void
aac_sa_qnotify(struct aac_softc * sc,int qbit)65777e08f05Sad aac_sa_qnotify(struct aac_softc *sc, int qbit)
65877e08f05Sad {
65977e08f05Sad
66077e08f05Sad AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
66177e08f05Sad }
66277e08f05Sad
663d36c43c5Sthorpej static void
aac_rx_qnotify(struct aac_softc * sc,int qbit)66477e08f05Sad aac_rx_qnotify(struct aac_softc *sc, int qbit)
66577e08f05Sad {
66677e08f05Sad
66777e08f05Sad AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
66877e08f05Sad }
66977e08f05Sad
670f82d990bSbriggs static void
aac_rkt_qnotify(struct aac_softc * sc,int qbit)671f82d990bSbriggs aac_rkt_qnotify(struct aac_softc *sc, int qbit)
672f82d990bSbriggs {
673f82d990bSbriggs
674f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_IDBR, qbit);
675f82d990bSbriggs }
676f82d990bSbriggs
67777e08f05Sad /*
67877e08f05Sad * Get the interrupt reason bits
67977e08f05Sad */
680d36c43c5Sthorpej static int
aac_sa_get_istatus(struct aac_softc * sc)68177e08f05Sad aac_sa_get_istatus(struct aac_softc *sc)
68277e08f05Sad {
68377e08f05Sad
68477e08f05Sad return (AAC_GETREG2(sc, AAC_SA_DOORBELL0));
68577e08f05Sad }
68677e08f05Sad
687d36c43c5Sthorpej static int
aac_rx_get_istatus(struct aac_softc * sc)68877e08f05Sad aac_rx_get_istatus(struct aac_softc *sc)
68977e08f05Sad {
69077e08f05Sad
69177e08f05Sad return (AAC_GETREG4(sc, AAC_RX_ODBR));
69277e08f05Sad }
69377e08f05Sad
694f82d990bSbriggs static int
aac_rkt_get_istatus(struct aac_softc * sc)695f82d990bSbriggs aac_rkt_get_istatus(struct aac_softc *sc)
696f82d990bSbriggs {
697f82d990bSbriggs
698f82d990bSbriggs return (AAC_GETREG4(sc, AAC_RKT_ODBR));
699f82d990bSbriggs }
700f82d990bSbriggs
70177e08f05Sad /*
70277e08f05Sad * Clear some interrupt reason bits
70377e08f05Sad */
704d36c43c5Sthorpej static void
aac_sa_clear_istatus(struct aac_softc * sc,int mask)70577e08f05Sad aac_sa_clear_istatus(struct aac_softc *sc, int mask)
70677e08f05Sad {
70777e08f05Sad
70877e08f05Sad AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
70977e08f05Sad }
71077e08f05Sad
711d36c43c5Sthorpej static void
aac_rx_clear_istatus(struct aac_softc * sc,int mask)71277e08f05Sad aac_rx_clear_istatus(struct aac_softc *sc, int mask)
71377e08f05Sad {
71477e08f05Sad
71577e08f05Sad AAC_SETREG4(sc, AAC_RX_ODBR, mask);
71677e08f05Sad }
71777e08f05Sad
718f82d990bSbriggs static void
aac_rkt_clear_istatus(struct aac_softc * sc,int mask)719f82d990bSbriggs aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
720f82d990bSbriggs {
721f82d990bSbriggs
722f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_ODBR, mask);
723f82d990bSbriggs }
724f82d990bSbriggs
72577e08f05Sad /*
72677e08f05Sad * Populate the mailbox and set the command word
72777e08f05Sad */
728d36c43c5Sthorpej static void
aac_sa_set_mailbox(struct aac_softc * sc,u_int32_t command,u_int32_t arg0,u_int32_t arg1,u_int32_t arg2,u_int32_t arg3)72977e08f05Sad aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
73077e08f05Sad u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
73177e08f05Sad u_int32_t arg3)
73277e08f05Sad {
73377e08f05Sad
73477e08f05Sad AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
73577e08f05Sad AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
73677e08f05Sad AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
73777e08f05Sad AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
73877e08f05Sad AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
73977e08f05Sad }
74077e08f05Sad
741d36c43c5Sthorpej static void
aac_rx_set_mailbox(struct aac_softc * sc,u_int32_t command,u_int32_t arg0,u_int32_t arg1,u_int32_t arg2,u_int32_t arg3)74277e08f05Sad aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
74377e08f05Sad u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
74477e08f05Sad u_int32_t arg3)
74577e08f05Sad {
74677e08f05Sad
74777e08f05Sad AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
74877e08f05Sad AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
74977e08f05Sad AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
75077e08f05Sad AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
75177e08f05Sad AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
75277e08f05Sad }
75377e08f05Sad
754f82d990bSbriggs static void
aac_rkt_set_mailbox(struct aac_softc * sc,u_int32_t command,u_int32_t arg0,u_int32_t arg1,u_int32_t arg2,u_int32_t arg3)755f82d990bSbriggs aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command,
756f82d990bSbriggs u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
757f82d990bSbriggs u_int32_t arg3)
758f82d990bSbriggs {
759f82d990bSbriggs
760f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_MAILBOX, command);
761f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
762f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
763f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
764f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
765f82d990bSbriggs }
766f82d990bSbriggs
76777e08f05Sad /*
76880240054Sbriggs * Fetch the specified mailbox
76977e08f05Sad */
770d36c43c5Sthorpej static uint32_t
aac_sa_get_mailbox(struct aac_softc * sc,int mb)77180240054Sbriggs aac_sa_get_mailbox(struct aac_softc *sc, int mb)
77277e08f05Sad {
77377e08f05Sad
77480240054Sbriggs return (AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
77577e08f05Sad }
77677e08f05Sad
777d36c43c5Sthorpej static uint32_t
aac_rx_get_mailbox(struct aac_softc * sc,int mb)77880240054Sbriggs aac_rx_get_mailbox(struct aac_softc *sc, int mb)
77977e08f05Sad {
78077e08f05Sad
78180240054Sbriggs return (AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
78277e08f05Sad }
78377e08f05Sad
784f82d990bSbriggs static uint32_t
aac_rkt_get_mailbox(struct aac_softc * sc,int mb)785f82d990bSbriggs aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
786f82d990bSbriggs {
787f82d990bSbriggs
788f82d990bSbriggs return (AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
789f82d990bSbriggs }
790f82d990bSbriggs
79177e08f05Sad /*
79277e08f05Sad * Set/clear interrupt masks
79377e08f05Sad */
794d36c43c5Sthorpej static void
aac_sa_set_interrupts(struct aac_softc * sc,int enable)79577e08f05Sad aac_sa_set_interrupts(struct aac_softc *sc, int enable)
79677e08f05Sad {
79777e08f05Sad
79877e08f05Sad if (enable)
79977e08f05Sad AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
80077e08f05Sad else
80177e08f05Sad AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
80277e08f05Sad }
80377e08f05Sad
804d36c43c5Sthorpej static void
aac_rx_set_interrupts(struct aac_softc * sc,int enable)80577e08f05Sad aac_rx_set_interrupts(struct aac_softc *sc, int enable)
80677e08f05Sad {
80777e08f05Sad
808f82d990bSbriggs if (enable) {
809f82d990bSbriggs if (sc->sc_quirks & AAC_QUIRK_NEW_COMM)
810f82d990bSbriggs AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
81177e08f05Sad else
812f82d990bSbriggs AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
813f82d990bSbriggs } else {
81477e08f05Sad AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
81577e08f05Sad }
816f82d990bSbriggs }
817f82d990bSbriggs
818f82d990bSbriggs static void
aac_rkt_set_interrupts(struct aac_softc * sc,int enable)819f82d990bSbriggs aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
820f82d990bSbriggs {
821f82d990bSbriggs
822f82d990bSbriggs if (enable) {
823f82d990bSbriggs if (sc->sc_quirks & AAC_QUIRK_NEW_COMM)
824f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
825f82d990bSbriggs else
826f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
827f82d990bSbriggs } else {
828f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_OIMR, ~0);
829f82d990bSbriggs }
830f82d990bSbriggs }
831f82d990bSbriggs
832f82d990bSbriggs /*
833f82d990bSbriggs * New comm. interface: Send command functions
834f82d990bSbriggs */
835f82d990bSbriggs static int
aac_rx_send_command(struct aac_softc * sc,struct aac_ccb * ac)836f82d990bSbriggs aac_rx_send_command(struct aac_softc *sc, struct aac_ccb *ac)
837f82d990bSbriggs {
838f82d990bSbriggs u_int32_t index, device;
839f82d990bSbriggs
840f82d990bSbriggs index = AAC_GETREG4(sc, AAC_RX_IQUE);
841f82d990bSbriggs if (index == 0xffffffffL)
842f82d990bSbriggs index = AAC_GETREG4(sc, AAC_RX_IQUE);
843f82d990bSbriggs if (index == 0xffffffffL)
844f82d990bSbriggs return index;
845f82d990bSbriggs #ifdef notyet
846f82d990bSbriggs aac_enqueue_busy(ac);
847f82d990bSbriggs #endif
848f82d990bSbriggs device = index;
849f82d990bSbriggs AAC_SETREG4(sc, device,
850f82d990bSbriggs htole32((u_int32_t)(ac->ac_fibphys & 0xffffffffUL)));
851f82d990bSbriggs device += 4;
852f82d990bSbriggs if (sizeof(bus_addr_t) > 4) {
853f82d990bSbriggs AAC_SETREG4(sc, device,
854f82d990bSbriggs htole32((u_int32_t)((u_int64_t)ac->ac_fibphys >> 32)));
855f82d990bSbriggs } else {
856f82d990bSbriggs AAC_SETREG4(sc, device, 0);
857f82d990bSbriggs }
858f82d990bSbriggs device += 4;
859f82d990bSbriggs AAC_SETREG4(sc, device, ac->ac_fib->Header.Size);
860f82d990bSbriggs AAC_SETREG4(sc, AAC_RX_IQUE, index);
861f82d990bSbriggs return 0;
862f82d990bSbriggs }
863f82d990bSbriggs
864f82d990bSbriggs static int
aac_rkt_send_command(struct aac_softc * sc,struct aac_ccb * ac)865f82d990bSbriggs aac_rkt_send_command(struct aac_softc *sc, struct aac_ccb *ac)
866f82d990bSbriggs {
867f82d990bSbriggs u_int32_t index, device;
868f82d990bSbriggs
869f82d990bSbriggs index = AAC_GETREG4(sc, AAC_RKT_IQUE);
870f82d990bSbriggs if (index == 0xffffffffL)
871f82d990bSbriggs index = AAC_GETREG4(sc, AAC_RKT_IQUE);
872f82d990bSbriggs if (index == 0xffffffffL)
873f82d990bSbriggs return index;
874f82d990bSbriggs #ifdef notyet
875f82d990bSbriggs aac_enqueue_busy(ac);
876f82d990bSbriggs #endif
877f82d990bSbriggs device = index;
878f82d990bSbriggs AAC_SETREG4(sc, device,
879f82d990bSbriggs htole32((u_int32_t)(ac->ac_fibphys & 0xffffffffUL)));
880f82d990bSbriggs device += 4;
881f82d990bSbriggs if (sizeof(bus_addr_t) > 4) {
882f82d990bSbriggs AAC_SETREG4(sc, device,
883f82d990bSbriggs htole32((u_int32_t)((u_int64_t)ac->ac_fibphys >> 32)));
884f82d990bSbriggs } else {
885f82d990bSbriggs AAC_SETREG4(sc, device, 0);
886f82d990bSbriggs }
887f82d990bSbriggs device += 4;
888f82d990bSbriggs AAC_SETREG4(sc, device, ac->ac_fib->Header.Size);
889f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_IQUE, index);
890f82d990bSbriggs return 0;
891f82d990bSbriggs }
892f82d990bSbriggs
893f82d990bSbriggs /*
894f82d990bSbriggs * New comm. interface: get, set outbound queue index
895f82d990bSbriggs */
896f82d990bSbriggs static int
aac_rx_get_outb_queue(struct aac_softc * sc)897f82d990bSbriggs aac_rx_get_outb_queue(struct aac_softc *sc)
898f82d990bSbriggs {
899f82d990bSbriggs
900f82d990bSbriggs return AAC_GETREG4(sc, AAC_RX_OQUE);
901f82d990bSbriggs }
902f82d990bSbriggs
903f82d990bSbriggs static int
aac_rkt_get_outb_queue(struct aac_softc * sc)904f82d990bSbriggs aac_rkt_get_outb_queue(struct aac_softc *sc)
905f82d990bSbriggs {
906f82d990bSbriggs
907f82d990bSbriggs return AAC_GETREG4(sc, AAC_RKT_OQUE);
908f82d990bSbriggs }
909f82d990bSbriggs
910f82d990bSbriggs static void
aac_rx_set_outb_queue(struct aac_softc * sc,int index)911f82d990bSbriggs aac_rx_set_outb_queue(struct aac_softc *sc, int index)
912f82d990bSbriggs {
913f82d990bSbriggs
914f82d990bSbriggs AAC_SETREG4(sc, AAC_RX_OQUE, index);
915f82d990bSbriggs }
916f82d990bSbriggs
917f82d990bSbriggs static void
aac_rkt_set_outb_queue(struct aac_softc * sc,int index)918f82d990bSbriggs aac_rkt_set_outb_queue(struct aac_softc *sc, int index)
919f82d990bSbriggs {
920f82d990bSbriggs
921f82d990bSbriggs AAC_SETREG4(sc, AAC_RKT_OQUE, index);
922f82d990bSbriggs }
923