1 /* $NetBSD: fwohci_cardbus.c,v 1.26 2008/07/11 17:50:45 kiyohara Exp $ */
4 * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry.
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.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: fwohci_cardbus.c,v 1.26 2008/07/11 17:50:45 kiyohara Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/socket.h>
38 #include <sys/device.h>
39 #include <sys/select.h>
44 #include <dev/pci/pcidevs.h>
47 #include <dev/cardbus/cardbusvar.h>
48 #include <dev/pci/pcidevs.h>
50 #include <dev/ieee1394/fw_port.h>
51 #include <dev/ieee1394/firewire.h>
52 #include <dev/ieee1394/firewirereg.h>
53 #include <dev/ieee1394/fwdma.h>
54 #include <dev/ieee1394/fwohcireg.h>
55 #include <dev/ieee1394/fwohcivar.h>
57 struct fwohci_cardbus_softc
{
58 struct fwohci_softc sc_sc
;
59 cardbus_chipset_tag_t sc_cc
;
60 cardbus_function_tag_t sc_cf
;
61 cardbus_devfunc_t sc_ct
;
65 static int fwohci_cardbus_match(device_t
, cfdata_t
, void *);
66 static void fwohci_cardbus_attach(device_t
, device_t
, void *);
67 static int fwohci_cardbus_detach(device_t
, int);
69 CFATTACH_DECL_NEW(fwohci_cardbus
, sizeof(struct fwohci_cardbus_softc
),
70 fwohci_cardbus_match
, fwohci_cardbus_attach
,
71 fwohci_cardbus_detach
, NULL
);
73 #define CARDBUS_INTERFACE_OHCI PCI_INTERFACE_OHCI
74 #define CARDBUS_OHCI_MAP_REGISTER PCI_OHCI_MAP_REGISTER
75 #define cardbus_devinfo pci_devinfo
78 fwohci_cardbus_match(device_t parent
, cfdata_t match
, void *aux
)
80 struct cardbus_attach_args
*ca
= (struct cardbus_attach_args
*)aux
;
82 if (CARDBUS_CLASS(ca
->ca_class
) == CARDBUS_CLASS_SERIALBUS
&&
83 CARDBUS_SUBCLASS(ca
->ca_class
) ==
84 CARDBUS_SUBCLASS_SERIALBUS_FIREWIRE
&&
85 CARDBUS_INTERFACE(ca
->ca_class
) == CARDBUS_INTERFACE_OHCI
)
92 fwohci_cardbus_attach(device_t parent
, device_t self
, void *aux
)
94 struct cardbus_attach_args
*ca
= aux
;
95 struct fwohci_cardbus_softc
*sc
= device_private(self
);
96 cardbus_devfunc_t ct
= ca
->ca_ct
;
97 cardbus_chipset_tag_t cc
= ct
->ct_cc
;
98 cardbus_function_tag_t cf
= ct
->ct_cf
;
102 cardbus_devinfo(ca
->ca_id
, ca
->ca_class
, 0, devinfo
, sizeof(devinfo
));
103 aprint_normal(": %s (rev. 0x%02x)\n", devinfo
,
104 CARDBUS_REVISION(ca
->ca_class
));
107 /* Map I/O registers */
108 if (Cardbus_mapreg_map(ct
, CARDBUS_OHCI_MAP_REGISTER
,
109 CARDBUS_MAPREG_TYPE_MEM
, 0,
110 &sc
->sc_sc
.bst
, &sc
->sc_sc
.bsh
,
111 NULL
, &sc
->sc_sc
.bssize
)) {
112 aprint_error_dev(self
, "can't map OHCI register space\n");
116 sc
->sc_sc
.fc
.dev
= self
;
117 sc
->sc_sc
.fc
.dmat
= ca
->ca_dmat
;
124 XXX (ct
->ct_cf
->cardbus_mem_open
)(cc
, 0, iob
, iob
+ 0x40);
126 (ct
->ct_cf
->cardbus_ctrl
)(cc
, CARDBUS_MEM_ENABLE
);
127 (ct
->ct_cf
->cardbus_ctrl
)(cc
, CARDBUS_BM_ENABLE
);
129 /* Disable interrupts, so we don't get any spurious ones. */
130 OHCI_CSR_WRITE(&sc
->sc_sc
, FWOHCI_INTMASKCLR
, OHCI_INT_EN
);
132 /* Enable the device. */
133 csr
= cardbus_conf_read(cc
, cf
, ca
->ca_tag
,
134 CARDBUS_COMMAND_STATUS_REG
);
135 cardbus_conf_write(cc
, cf
, ca
->ca_tag
, CARDBUS_COMMAND_STATUS_REG
,
136 csr
| CARDBUS_COMMAND_MASTER_ENABLE
| CARDBUS_COMMAND_MEM_ENABLE
);
138 sc
->sc_ih
= cardbus_intr_establish(cc
, cf
, ca
->ca_intrline
,
139 IPL_BIO
, fwohci_filt
, sc
);
140 if (sc
->sc_ih
== NULL
) {
141 aprint_error_dev(self
, "couldn't establish interrupt\n");
145 /* XXX NULL should be replaced by some call to Cardbus coed */
146 if (fwohci_init(&sc
->sc_sc
, sc
->sc_sc
.fc
.dev
) != 0) {
147 cardbus_intr_disestablish(cc
, cf
, sc
->sc_ih
);
153 fwohci_cardbus_detach(device_t self
, int flags
)
155 struct fwohci_cardbus_softc
*sc
= device_private(self
);
156 cardbus_devfunc_t ct
= sc
->sc_ct
;
159 rv
= fwohci_detach(&sc
->sc_sc
, flags
);
163 if (sc
->sc_ih
!= NULL
) {
164 cardbus_intr_disestablish(ct
->ct_cc
, ct
->ct_cf
, sc
->sc_ih
);
167 if (sc
->sc_sc
.bssize
) {
168 Cardbus_mapreg_unmap(ct
, CARDBUS_OHCI_MAP_REGISTER
,
169 sc
->sc_sc
.bst
, sc
->sc_sc
.bsh
,
171 sc
->sc_sc
.bssize
= 0;