This source file includes following definitions.
- uhci_cardbus_match
- uhci_cardbus_attach
- uhci_cardbus_detach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/device.h>
44 #include <sys/proc.h>
45
46 #include <machine/bus.h>
47
48 #include <dev/cardbus/cardbusvar.h>
49 #include <dev/pci/pcidevs.h>
50
51 #include <dev/usb/usb.h>
52 #include <dev/usb/usbdi.h>
53 #include <dev/usb/usbdivar.h>
54 #include <dev/usb/usb_mem.h>
55
56 #include <dev/usb/uhcireg.h>
57 #include <dev/usb/uhcivar.h>
58
59 int uhci_cardbus_match(struct device *, void *, void *);
60 void uhci_cardbus_attach(struct device *, struct device *, void *);
61 int uhci_cardbus_detach(struct device *, int);
62
63 struct uhci_cardbus_softc {
64 uhci_softc_t sc;
65 cardbus_chipset_tag_t sc_cc;
66 cardbus_function_tag_t sc_cf;
67 cardbus_devfunc_t sc_ct;
68 void *sc_ih;
69 };
70
71 struct cfattach uhci_cardbus_ca = {
72 sizeof(struct uhci_cardbus_softc), uhci_cardbus_match,
73 uhci_cardbus_attach, uhci_cardbus_detach, uhci_activate
74 };
75
76 #define CARDBUS_INTERFACE_UHCI PCI_INTERFACE_UHCI
77 #define cardbus_findvendor pci_findvendor
78 #define cardbus_devinfo pci_devinfo
79
80 int
81 uhci_cardbus_match(struct device *parent, void *match, void *aux)
82 {
83 struct cardbus_attach_args *ca = (struct cardbus_attach_args *)aux;
84
85 if (CARDBUS_CLASS(ca->ca_class) == CARDBUS_CLASS_SERIALBUS &&
86 CARDBUS_SUBCLASS(ca->ca_class) == CARDBUS_SUBCLASS_SERIALBUS_USB &&
87 CARDBUS_INTERFACE(ca->ca_class) == CARDBUS_INTERFACE_UHCI)
88 return (1);
89
90 return (0);
91 }
92
93 void
94 uhci_cardbus_attach(struct device *parent, struct device *self, void *aux)
95 {
96 struct uhci_cardbus_softc *sc = (struct uhci_cardbus_softc *)self;
97 struct cardbus_attach_args *ca = aux;
98 cardbus_devfunc_t ct = ca->ca_ct;
99 cardbus_chipset_tag_t cc = ct->ct_cc;
100 cardbus_function_tag_t cf = ct->ct_cf;
101 cardbusreg_t csr;
102 char devinfo[256];
103 usbd_status r;
104 const char *vendor;
105 const char *devname = sc->sc.sc_bus.bdev.dv_xname;
106
107 cardbus_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo));
108 printf(" %s", devinfo);
109
110
111 if (Cardbus_mapreg_map(ct, PCI_CBIO, CARDBUS_MAPREG_TYPE_IO, 0,
112 &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) {
113 printf("%s: can't map io space\n", devname);
114 return;
115 }
116
117
118 bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);
119
120 sc->sc_cc = cc;
121 sc->sc_cf = cf;
122 sc->sc_ct = ct;
123 sc->sc.sc_bus.dmatag = ca->ca_dmat;
124
125 (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_IO_ENABLE);
126 (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
127
128
129 csr = cardbus_conf_read(cc, cf, ca->ca_tag,
130 CARDBUS_COMMAND_STATUS_REG);
131 cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_COMMAND_STATUS_REG,
132 csr | CARDBUS_COMMAND_MASTER_ENABLE
133 | CARDBUS_COMMAND_IO_ENABLE);
134
135 sc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline,
136 IPL_USB, uhci_intr, sc, devname);
137 if (sc->sc_ih == NULL) {
138 printf("%s: couldn't establish interrupt\n", devname);
139 return;
140 }
141 printf(": irq %d\n", ca->ca_intrline);
142
143
144 cardbus_conf_write(cc, cf, ca->ca_tag, PCI_LEGSUP,
145 PCI_LEGSUP_USBPIRQDEN);
146
147 switch(cardbus_conf_read(cc, cf, ca->ca_tag, PCI_USBREV) & PCI_USBREV_MASK) {
148 case PCI_USBREV_PRE_1_0:
149 sc->sc.sc_bus.usbrev = USBREV_PRE_1_0;
150 break;
151 case PCI_USBREV_1_0:
152 sc->sc.sc_bus.usbrev = USBREV_1_0;
153 break;
154 case PCI_USBREV_1_1:
155 sc->sc.sc_bus.usbrev = USBREV_1_1;
156 break;
157 default:
158 sc->sc.sc_bus.usbrev = USBREV_UNKNOWN;
159 break;
160 }
161
162 uhci_run(&sc->sc, 0);
163
164 bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size,
165 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
166 bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);
167
168
169 vendor = cardbus_findvendor(ca->ca_id);
170 sc->sc.sc_id_vendor = CARDBUS_VENDOR(ca->ca_id);
171 if (vendor)
172 strlcpy(sc->sc.sc_vendor, vendor, sizeof (sc->sc.sc_vendor));
173 else
174 snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
175 "vendor 0x%04x", CARDBUS_VENDOR(ca->ca_id));
176
177 r = uhci_init(&sc->sc);
178 if (r != USBD_NORMAL_COMPLETION) {
179 printf("%s: init failed, error=%d\n", devname, r);
180 bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
181 return;
182 }
183
184
185 sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
186 usbctlprint);
187 }
188
189 int
190 uhci_cardbus_detach(struct device *self, int flags)
191 {
192 struct uhci_cardbus_softc *sc = (struct uhci_cardbus_softc *)self;
193 struct cardbus_devfunc *ct = sc->sc_ct;
194 int rv;
195
196 rv = uhci_detach(&sc->sc, flags);
197 if (rv)
198 return (rv);
199
200 if (sc->sc_ih != NULL) {
201 cardbus_intr_disestablish(sc->sc_cc, sc->sc_cf, sc->sc_ih);
202 sc->sc_ih = NULL;
203 }
204
205 if (sc->sc.sc_size) {
206 Cardbus_mapreg_unmap(ct, PCI_CBIO, sc->sc.iot,
207 sc->sc.ioh, sc->sc.sc_size);
208 sc->sc.sc_size = 0;
209 }
210
211 return (0);
212 }