This source file includes following definitions.
- ehci_pci_match
- ehci_pci_attach
- ehci_pci_detach
- ehci_pci_givecontroller
- ehci_pci_takecontroller
- ehci_pci_shutdown
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/rwlock.h>
44 #include <sys/device.h>
45 #include <sys/proc.h>
46 #include <sys/queue.h>
47
48 #include <machine/bus.h>
49
50 #include <dev/pci/pcidevs.h>
51 #include <dev/pci/pcivar.h>
52
53 #include <dev/usb/usb.h>
54 #include <dev/usb/usbdi.h>
55 #include <dev/usb/usbdivar.h>
56 #include <dev/usb/usb_mem.h>
57
58 #include <dev/usb/ehcireg.h>
59 #include <dev/usb/ehcivar.h>
60
61 #ifdef EHCI_DEBUG
62 #define DPRINTF(x) if (ehcidebug) printf x
63 extern int ehcidebug;
64 #else
65 #define DPRINTF(x)
66 #endif
67
68 struct ehci_pci_softc {
69 ehci_softc_t sc;
70 pci_chipset_tag_t sc_pc;
71 pcitag_t sc_tag;
72 void *sc_ih;
73 };
74
75 int ehci_pci_match(struct device *, void *, void *);
76 void ehci_pci_attach(struct device *, struct device *, void *);
77 int ehci_pci_detach(struct device *, int);
78 void ehci_pci_givecontroller(struct ehci_pci_softc *);
79 void ehci_pci_takecontroller(struct ehci_pci_softc *);
80 void ehci_pci_shutdown(void *);
81
82 struct cfattach ehci_pci_ca = {
83 sizeof(struct ehci_pci_softc), ehci_pci_match, ehci_pci_attach,
84 ehci_pci_detach, ehci_activate
85 };
86
87
88 int
89 ehci_pci_match(struct device *parent, void *match, void *aux)
90 {
91 struct pci_attach_args *pa = (struct pci_attach_args *) aux;
92
93 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SERIALBUS &&
94 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SERIALBUS_USB &&
95 PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_EHCI)
96 return (1);
97
98 return (0);
99 }
100
101 void
102 ehci_pci_attach(struct device *parent, struct device *self, void *aux)
103 {
104 struct ehci_pci_softc *sc = (struct ehci_pci_softc *)self;
105 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
106 pci_chipset_tag_t pc = pa->pa_pc;
107 pcitag_t tag = pa->pa_tag;
108 char const *intrstr;
109 pci_intr_handle_t ih;
110 const char *vendor;
111 char *devname = sc->sc.sc_bus.bdev.dv_xname;
112 usbd_status r;
113 int s;
114
115
116 if (pci_mapreg_map(pa, PCI_CBMEM, PCI_MAPREG_TYPE_MEM, 0,
117 &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size, 0)) {
118 printf(": can't map memory space\n");
119 return;
120 }
121
122 sc->sc_pc = pc;
123 sc->sc_tag = tag;
124 sc->sc.sc_bus.dmatag = pa->pa_dmat;
125
126
127 s = splhardusb();
128 sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH);
129 DPRINTF(("%s: offs=%d\n", devname, sc->sc.sc_offs));
130 EOWRITE2(&sc->sc, EHCI_USBINTR, 0);
131
132
133 if (pci_intr_map(pa, &ih)) {
134 printf(": couldn't map interrupt\n");
135 goto unmap_ret;
136 }
137 intrstr = pci_intr_string(pc, ih);
138 sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, ehci_intr, sc, devname);
139 if (sc->sc_ih == NULL) {
140 printf(": couldn't establish interrupt");
141 if (intrstr != NULL)
142 printf(" at %s", intrstr);
143 printf("\n");
144 goto unmap_ret;
145 }
146 printf(": %s\n", intrstr);
147
148 switch(pci_conf_read(pc, tag, PCI_USBREV) & PCI_USBREV_MASK) {
149 case PCI_USBREV_PRE_1_0:
150 case PCI_USBREV_1_0:
151 case PCI_USBREV_1_1:
152 sc->sc.sc_bus.usbrev = USBREV_UNKNOWN;
153 printf("%s: pre-2.0 USB rev\n", devname);
154 goto unmap_ret;
155 case PCI_USBREV_2_0:
156 sc->sc.sc_bus.usbrev = USBREV_2_0;
157 break;
158 default:
159 sc->sc.sc_bus.usbrev = USBREV_UNKNOWN;
160 break;
161 }
162
163
164 vendor = pci_findvendor(pa->pa_id);
165 sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id);
166 if (vendor)
167 strlcpy(sc->sc.sc_vendor, vendor, sizeof(sc->sc.sc_vendor));
168 else
169 snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
170 "vendor 0x%04x", PCI_VENDOR(pa->pa_id));
171
172
173 if (sc->sc.sc_id_vendor == PCI_VENDOR_VIATECH)
174 sc->sc.sc_flags |= EHCIF_DROPPED_INTR_WORKAROUND;
175
176 ehci_pci_takecontroller(sc);
177 r = ehci_init(&sc->sc);
178 if (r != USBD_NORMAL_COMPLETION) {
179 printf("%s: init failed, error=%d\n", devname, r);
180 goto unmap_ret;
181 }
182
183 sc->sc.sc_shutdownhook = shutdownhook_establish(ehci_pci_shutdown, sc);
184 splx(s);
185
186
187 sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
188 usbctlprint);
189
190 return;
191
192 unmap_ret:
193 bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
194 splx(s);
195 }
196
197 int
198 ehci_pci_detach(struct device *self, int flags)
199 {
200 struct ehci_pci_softc *sc = (struct ehci_pci_softc *)self;
201 int rv;
202
203 rv = ehci_detach(&sc->sc, flags);
204 if (rv)
205 return (rv);
206 if (sc->sc_ih != NULL) {
207 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
208 sc->sc_ih = NULL;
209 }
210 if (sc->sc.sc_size) {
211 bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
212 sc->sc.sc_size = 0;
213 }
214 return (0);
215 }
216
217 void
218 ehci_pci_givecontroller(struct ehci_pci_softc *sc)
219 {
220 u_int32_t cparams, eec, legsup;
221 int eecp;
222
223 cparams = EREAD4(&sc->sc, EHCI_HCCPARAMS);
224 for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
225 eecp = EHCI_EECP_NEXT(eec)) {
226 eec = pci_conf_read(sc->sc_pc, sc->sc_tag, eecp);
227 if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP)
228 continue;
229 legsup = eec;
230 pci_conf_write(sc->sc_pc, sc->sc_tag, eecp,
231 legsup & ~EHCI_LEGSUP_OSOWNED);
232 }
233 }
234
235 void
236 ehci_pci_takecontroller(struct ehci_pci_softc *sc)
237 {
238 u_int32_t cparams, eec, legsup;
239 int eecp, i;
240
241 cparams = EREAD4(&sc->sc, EHCI_HCCPARAMS);
242
243 for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
244 eecp = EHCI_EECP_NEXT(eec)) {
245 eec = pci_conf_read(sc->sc_pc, sc->sc_tag, eecp);
246 if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP)
247 continue;
248 legsup = eec;
249 pci_conf_write(sc->sc_pc, sc->sc_tag, eecp,
250 legsup | EHCI_LEGSUP_OSOWNED);
251 if (legsup & EHCI_LEGSUP_BIOSOWNED) {
252 DPRINTF(("%s: waiting for BIOS to give up control\n",
253 sc->sc.sc_bus.bdev.dv_xname));
254 for (i = 0; i < 5000; i++) {
255 legsup = pci_conf_read(sc->sc_pc, sc->sc_tag,
256 eecp);
257 if ((legsup & EHCI_LEGSUP_BIOSOWNED) == 0)
258 break;
259 DELAY(1000);
260 }
261 if (legsup & EHCI_LEGSUP_BIOSOWNED)
262 printf("%s: timed out waiting for BIOS\n",
263 sc->sc.sc_bus.bdev.dv_xname);
264 }
265 }
266 }
267
268 void
269 ehci_pci_shutdown(void *v)
270 {
271 struct ehci_pci_softc *sc = (struct ehci_pci_softc *)v;
272
273 ehci_shutdown(&sc->sc);
274 ehci_pci_givecontroller(sc);
275 }