1 /* $NetBSD: adv_cardbus.c,v 1.21 2009/05/12 12:11:17 cegger Exp $ */
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 * this file was brought from ahc_cardbus.c and adv_pci.c
35 * and modified by YAMAMOTO Takashi.
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: adv_cardbus.c,v 1.21 2009/05/12 12:11:17 cegger Exp $");
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/malloc.h>
44 #include <sys/kernel.h>
45 #include <sys/queue.h>
46 #include <sys/device.h>
51 #include <dev/scsipi/scsi_all.h>
52 #include <dev/scsipi/scsipi_all.h>
53 #include <dev/scsipi/scsiconf.h>
55 #include <dev/pci/pcireg.h>
56 #include <dev/pci/pcidevs.h>
58 #include <dev/cardbus/cardbusvar.h>
59 #include <dev/pci/pcidevs.h>
61 #include <dev/ic/advlib.h>
62 #include <dev/ic/adv.h>
64 #define ADV_CARDBUS_IOBA CARDBUS_BASE0_REG
65 #define ADV_CARDBUS_MMBA CARDBUS_BASE1_REG
67 #define ADV_CARDBUS_DEBUG
68 #define ADV_CARDBUS_ALLOW_MEMIO
70 #define DEVNAME(sc) device_xname(&(sc)->sc_dev)
72 struct adv_cardbus_softc
{
73 struct asc_softc sc_adv
; /* real ADV */
75 /* CardBus-specific goo. */
76 cardbus_devfunc_t sc_ct
; /* our CardBus devfuncs */
77 cardbus_intr_line_t sc_intrline
; /* our interrupt line */
80 int sc_cbenable
; /* what CardBus access type to enable */
81 int sc_csr
; /* CSR bits */
85 int adv_cardbus_match(device_t
, cfdata_t
, void *);
86 void adv_cardbus_attach(device_t
, device_t
, void *);
87 int adv_cardbus_detach(device_t
, int);
89 CFATTACH_DECL(adv_cardbus
, sizeof(struct adv_cardbus_softc
),
90 adv_cardbus_match
, adv_cardbus_attach
, adv_cardbus_detach
, NULL
);
93 adv_cardbus_match(device_t parent
, cfdata_t match
,
96 struct cardbus_attach_args
*ca
= aux
;
98 if (CARDBUS_VENDOR(ca
->ca_id
) == PCI_VENDOR_ADVSYS
&&
99 CARDBUS_PRODUCT(ca
->ca_id
) == PCI_PRODUCT_ADVSYS_ULTRA
)
106 adv_cardbus_attach(device_t parent
, device_t self
,
109 struct cardbus_attach_args
*ca
= aux
;
110 struct adv_cardbus_softc
*csc
= device_private(self
);
111 struct asc_softc
*sc
= &csc
->sc_adv
;
112 cardbus_devfunc_t ct
= ca
->ca_ct
;
113 cardbus_chipset_tag_t cc
= ct
->ct_cc
;
114 cardbus_function_tag_t cf
= ct
->ct_cf
;
116 bus_space_handle_t ioh
;
118 u_int8_t latency
= 0x20;
122 if (PCI_VENDOR(ca
->ca_id
) == PCI_VENDOR_ADVSYS
) {
123 switch (PCI_PRODUCT(ca
->ca_id
)) {
124 case PCI_PRODUCT_ADVSYS_1200A
:
125 printf(": AdvanSys ASC1200A SCSI adapter\n");
129 case PCI_PRODUCT_ADVSYS_1200B
:
130 printf(": AdvanSys ASC1200B SCSI adapter\n");
134 case PCI_PRODUCT_ADVSYS_ULTRA
:
135 switch (PCI_REVISION(ca
->ca_class
)) {
136 case ASC_PCI_REVISION_3050
:
137 printf(": AdvanSys ABP-9xxUA SCSI adapter\n");
140 case ASC_PCI_REVISION_3150
:
141 printf(": AdvanSys ABP-9xxU SCSI adapter\n");
147 printf(": unknown model!\n");
153 csc
->sc_tag
= ca
->ca_tag
;
154 csc
->sc_intrline
= ca
->ca_intrline
;
155 csc
->sc_cbenable
= 0;
160 csc
->sc_csr
= PCI_COMMAND_MASTER_ENABLE
;
162 #ifdef ADV_CARDBUS_ALLOW_MEMIO
163 if (Cardbus_mapreg_map(csc
->sc_ct
, ADV_CARDBUS_MMBA
,
164 PCI_MAPREG_TYPE_MEM
|PCI_MAPREG_MEM_TYPE_32BIT
, 0,
165 &iot
, &ioh
, NULL
, &csc
->sc_size
) == 0) {
166 #ifdef ADV_CARDBUS_DEBUG
167 printf("%s: memio enabled\n", DEVNAME(sc
));
169 csc
->sc_cbenable
= CARDBUS_MEM_ENABLE
;
170 csc
->sc_csr
|= PCI_COMMAND_MEM_ENABLE
;
173 if (Cardbus_mapreg_map(csc
->sc_ct
, ADV_CARDBUS_IOBA
,
174 PCI_MAPREG_TYPE_IO
, 0, &iot
, &ioh
, NULL
, &csc
->sc_size
) == 0) {
175 #ifdef ADV_CARDBUS_DEBUG
176 printf("%s: io enabled\n", DEVNAME(sc
));
178 csc
->sc_cbenable
= CARDBUS_IO_ENABLE
;
179 csc
->sc_csr
|= PCI_COMMAND_IO_ENABLE
;
181 aprint_error_dev(&sc
->sc_dev
, "unable to map device registers\n");
185 /* Make sure the right access type is on the CardBus bridge. */
186 (*ct
->ct_cf
->cardbus_ctrl
)(cc
, csc
->sc_cbenable
);
187 (*ct
->ct_cf
->cardbus_ctrl
)(cc
, CARDBUS_BM_ENABLE
);
189 /* Enable the appropriate bits in the PCI CSR. */
190 reg
= cardbus_conf_read(cc
, cf
, ca
->ca_tag
, PCI_COMMAND_STATUS_REG
);
191 reg
&= ~(PCI_COMMAND_IO_ENABLE
|PCI_COMMAND_MEM_ENABLE
);
193 cardbus_conf_write(cc
, cf
, ca
->ca_tag
, PCI_COMMAND_STATUS_REG
, reg
);
196 * Make sure the latency timer is set to some reasonable
199 reg
= cardbus_conf_read(cc
, cf
, ca
->ca_tag
, PCI_BHLC_REG
);
200 if (PCI_LATTIMER(reg
) < latency
) {
201 reg
&= ~(PCI_LATTIMER_MASK
<< PCI_LATTIMER_SHIFT
);
202 reg
|= (latency
<< PCI_LATTIMER_SHIFT
);
203 cardbus_conf_write(cc
, cf
, ca
->ca_tag
, PCI_BHLC_REG
, reg
);
206 ASC_SET_CHIP_CONTROL(iot
, ioh
, ASC_CC_HALT
);
207 ASC_SET_CHIP_STATUS(iot
, ioh
, 0);
211 sc
->sc_dmat
= ca
->ca_dmat
;
212 sc
->pci_device_id
= ca
->ca_id
;
213 sc
->bus_type
= ASC_IS_PCI
;
214 sc
->chip_version
= ASC_GET_CHIP_VER_NO(iot
, ioh
);
217 * Initialize the board
220 printf("adv_init failed\n");
225 * Establish the interrupt.
227 sc
->sc_ih
= cardbus_intr_establish(cc
, cf
, ca
->ca_intrline
, IPL_BIO
,
229 if (sc
->sc_ih
== NULL
) {
230 aprint_error_dev(&sc
->sc_dev
,
231 "unable to establish interrupt\n");
242 adv_cardbus_detach(device_t self
, int flags
)
244 struct adv_cardbus_softc
*csc
= device_private(self
);
245 struct asc_softc
*sc
= &csc
->sc_adv
;
249 rv
= adv_detach(sc
, flags
);
254 cardbus_intr_disestablish(csc
->sc_ct
->ct_cc
,
255 csc
->sc_ct
->ct_cf
, sc
->sc_ih
);
259 if (csc
->sc_cbenable
) {
260 #ifdef ADV_CARDBUS_ALLOW_MEMIO
261 if (csc
->sc_cbenable
== CARDBUS_MEM_ENABLE
) {
262 Cardbus_mapreg_unmap(csc
->sc_ct
, ADV_CARDBUS_MMBA
,
263 sc
->sc_iot
, sc
->sc_ioh
, csc
->sc_size
);
266 Cardbus_mapreg_unmap(csc
->sc_ct
, ADV_CARDBUS_IOBA
,
267 sc
->sc_iot
, sc
->sc_ioh
, csc
->sc_size
);
268 #ifdef ADV_CARDBUS_ALLOW_MEMIO
271 csc
->sc_cbenable
= 0;