[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/ehci_pci.c

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD70  -  FREEBSD6  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

  1 /*-
  2  * Copyright (c) 1998 The NetBSD Foundation, Inc.
  3  * All rights reserved.
  4  *
  5  * This code is derived from software contributed to The NetBSD Foundation
  6  * by Lennart Augustsson (augustss@carlstedt.se) at
  7  * Carlstedt Research & Technology.
  8  *
  9  * Redistribution and use in source and binary forms, with or without
 10  * modification, are permitted provided that the following conditions
 11  * are met:
 12  * 1. Redistributions of source code must retain the above copyright
 13  *    notice, this list of conditions and the following disclaimer.
 14  * 2. Redistributions in binary form must reproduce the above copyright
 15  *    notice, this list of conditions and the following disclaimer in the
 16  *    documentation and/or other materials provided with the distribution.
 17  * 3. All advertising materials mentioning features or use of this software
 18  *    must display the following acknowledgement:
 19  *        This product includes software developed by the NetBSD
 20  *        Foundation, Inc. and its contributors.
 21  * 4. Neither the name of The NetBSD Foundation nor the names of its
 22  *    contributors may be used to endorse or promote products derived
 23  *    from this software without specific prior written permission.
 24  *
 25  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 26  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 35  * POSSIBILITY OF SUCH DAMAGE.
 36  */
 37 
 38 #include <sys/cdefs.h>
 39 __FBSDID("$FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.36 2008/10/09 19:22:00 n_hibma Exp $");
 40 
 41 /*
 42  * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
 43  *
 44  * The EHCI 1.0 spec can be found at
 45  * http://developer.intel.com/technology/usb/download/ehci-r10.pdf
 46  * and the USB 2.0 spec at
 47  * http://www.usb.org/developers/docs/usb_20.zip
 48  */
 49 
 50 /* The low level controller code for EHCI has been split into
 51  * PCI probes and EHCI specific code. This was done to facilitate the
 52  * sharing of code between *BSD's
 53  */
 54 
 55 #include <sys/param.h>
 56 #include <sys/systm.h>
 57 #include <sys/kernel.h>
 58 #include <sys/module.h>
 59 #include <sys/lock.h>
 60 #include <sys/mutex.h>
 61 #include <sys/bus.h>
 62 #include <sys/queue.h>
 63 #include <sys/lockmgr.h>
 64 #include <machine/bus.h>
 65 #include <sys/rman.h>
 66 #include <machine/resource.h>
 67 
 68 #include <dev/pci/pcivar.h>
 69 #include <dev/pci/pcireg.h>
 70 
 71 #include <dev/usb/usb.h>
 72 #include <dev/usb/usbdi.h>
 73 #include <dev/usb/usbdivar.h>
 74 #include <dev/usb/usb_mem.h>
 75 
 76 #include <dev/usb/ehcireg.h>
 77 #include <dev/usb/ehcivar.h>
 78 
 79 #define PCI_EHCI_VENDORID_ACERLABS      0x10b9
 80 #define PCI_EHCI_VENDORID_AMD           0x1022
 81 #define PCI_EHCI_VENDORID_APPLE         0x106b
 82 #define PCI_EHCI_VENDORID_ATI           0x1002
 83 #define PCI_EHCI_VENDORID_CMDTECH       0x1095
 84 #define PCI_EHCI_VENDORID_INTEL         0x8086
 85 #define PCI_EHCI_VENDORID_NEC           0x1033
 86 #define PCI_EHCI_VENDORID_OPTI          0x1045
 87 #define PCI_EHCI_VENDORID_PHILIPS       0x1131
 88 #define PCI_EHCI_VENDORID_SIS           0x1039
 89 #define PCI_EHCI_VENDORID_NVIDIA        0x12D2
 90 #define PCI_EHCI_VENDORID_NVIDIA2       0x10DE
 91 #define PCI_EHCI_VENDORID_VIA           0x1106
 92 
 93 /* AcerLabs/ALi */
 94 #define PCI_EHCI_DEVICEID_M5239         0x523910b9
 95 static const char *ehci_device_m5239 = "ALi M5239 USB 2.0 controller";
 96 
 97 /* AMD */
 98 #define PCI_EHCI_DEVICEID_8111          0x10227463
 99 static const char *ehci_device_8111 = "AMD 8111 USB 2.0 controller";
100 #define PCI_EHCI_DEVICEID_CS5536        0x20951022
101 static const char *ehci_device_cs5536 = "AMD CS5536 (Geode) USB 2.0 controller";
102 
103 /* ATI */
104 #define PCI_EHCI_DEVICEID_SB200         0x43451002
105 static const char *ehci_device_sb200 = "ATI SB200 USB 2.0 controller";
106 #define PCI_EHCI_DEVICEID_SB400         0x43731002
107 static const char *ehci_device_sb400 = "ATI SB400 USB 2.0 controller";
108 
109 /* Intel */
110 #define PCI_EHCI_DEVICEID_6300          0x25ad8086
111 static const char *ehci_device_6300 = "Intel 6300ESB USB 2.0 controller";
112 #define PCI_EHCI_DEVICEID_ICH4          0x24cd8086
113 static const char *ehci_device_ich4 = "Intel 82801DB/L/M (ICH4) USB 2.0 controller";
114 #define PCI_EHCI_DEVICEID_ICH5          0x24dd8086
115 static const char *ehci_device_ich5 = "Intel 82801EB/R (ICH5) USB 2.0 controller";
116 #define PCI_EHCI_DEVICEID_ICH6          0x265c8086
117 static const char *ehci_device_ich6 = "Intel 82801FB (ICH6) USB 2.0 controller";
118 #define PCI_EHCI_DEVICEID_ICH7          0x27cc8086
119 static const char *ehci_device_ich7 = "Intel 82801GB/R (ICH7) USB 2.0 controller";
120 #define PCI_EHCI_DEVICEID_ICH8_A        0x28368086
121 static const char *ehci_device_ich8_a = "Intel 82801H (ICH8) USB 2.0 controller USB2-A";
122 #define PCI_EHCI_DEVICEID_ICH8_B        0x283a8086
123 static const char *ehci_device_ich8_b = "Intel 82801H (ICH8) USB 2.0 controller USB2-B";
124 #define PCI_EHCI_DEVICEID_ICH9_A        0x293a8086
125 #define PCI_EHCI_DEVICEID_ICH9_B        0x293c8086
126 static const char *ehci_device_ich9 = "Intel 82801I (ICH9) USB 2.0 controller";
127 #define PCI_EHCI_DEVICEID_63XX          0x268c8086
128 static const char *ehci_device_63XX = "Intel 63XXESB USB 2.0 controller";
129  
130 /* NEC */
131 #define PCI_EHCI_DEVICEID_NEC           0x00e01033
132 static const char *ehci_device_nec = "NEC uPD 720100 USB 2.0 controller";
133 
134 /* NVIDIA */
135 #define PCI_EHCI_DEVICEID_NF2           0x006810de
136 static const char *ehci_device_nf2 = "NVIDIA nForce2 USB 2.0 controller";
137 #define PCI_EHCI_DEVICEID_NF2_400       0x008810de
138 static const char *ehci_device_nf2_400 = "NVIDIA nForce2 Ultra 400 USB 2.0 controller";
139 #define PCI_EHCI_DEVICEID_NF3           0x00d810de
140 static const char *ehci_device_nf3 = "NVIDIA nForce3 USB 2.0 controller";
141 #define PCI_EHCI_DEVICEID_NF3_250       0x00e810de
142 static const char *ehci_device_nf3_250 = "NVIDIA nForce3 250 USB 2.0 controller";
143 #define PCI_EHCI_DEVICEID_NF4           0x005b10de
144 static const char *ehci_device_nf4 = "NVIDIA nForce4 USB 2.0 controller";
145 
146 /* Philips */
147 #define PCI_EHCI_DEVICEID_ISP156X       0x15621131
148 static const char *ehci_device_isp156x = "Philips ISP156x USB 2.0 controller";
149 
150 #define PCI_EHCI_DEVICEID_VIA           0x31041106
151 static const char *ehci_device_via = "VIA VT6202 USB 2.0 controller";
152 
153 static const char *ehci_device_generic = "EHCI (generic) USB 2.0 controller";
154 
155 #define PCI_EHCI_BASE_REG       0x10
156 
157 #ifdef USB_DEBUG
158 #define EHCI_DEBUG USB_DEBUG
159 #define DPRINTF(x)      do { if (ehcidebug) printf x; } while (0)
160 extern int ehcidebug;
161 #else
162 #define DPRINTF(x)
163 #endif
164 
165 static device_attach_t ehci_pci_attach;
166 static device_detach_t ehci_pci_detach;
167 static device_shutdown_t ehci_pci_shutdown;
168 static device_suspend_t ehci_pci_suspend;
169 static device_resume_t ehci_pci_resume;
170 static void ehci_pci_givecontroller(device_t self);
171 static void ehci_pci_takecontroller(device_t self);
172 
173 static int
174 ehci_pci_suspend(device_t self)
175 {
176         ehci_softc_t *sc = device_get_softc(self);
177         int err;
178 
179         err = bus_generic_suspend(self);
180         if (err)
181                 return (err);
182         ehci_power(PWR_SUSPEND, sc);
183 
184         return 0;
185 }
186 
187 static int
188 ehci_pci_resume(device_t self)
189 {
190         ehci_softc_t *sc = device_get_softc(self);
191 
192         ehci_pci_takecontroller(self);
193         ehci_power(PWR_RESUME, sc);
194         bus_generic_resume(self);
195 
196         return 0;
197 }
198 
199 static int
200 ehci_pci_shutdown(device_t self)
201 {
202         ehci_softc_t *sc = device_get_softc(self);
203         int err;
204 
205         err = bus_generic_shutdown(self);
206         if (err)
207                 return (err);
208         ehci_shutdown(sc);
209         ehci_pci_givecontroller(self);
210 
211         return 0;
212 }
213 
214 static const char *
215 ehci_pci_match(device_t self)
216 {
217         u_int32_t device_id = pci_get_devid(self);
218 
219         switch (device_id) {
220         case PCI_EHCI_DEVICEID_M5239:
221                 return (ehci_device_m5239);
222         case PCI_EHCI_DEVICEID_8111:
223                 return (ehci_device_8111);
224         case PCI_EHCI_DEVICEID_CS5536:
225                 return (ehci_device_cs5536);
226         case PCI_EHCI_DEVICEID_SB200:
227                 return (ehci_device_sb200);
228         case PCI_EHCI_DEVICEID_SB400:
229                 return (ehci_device_sb400);
230         case PCI_EHCI_DEVICEID_6300:
231                 return (ehci_device_6300);
232         case PCI_EHCI_DEVICEID_63XX:
233                 return (ehci_device_63XX);
234         case PCI_EHCI_DEVICEID_ICH4:
235                 return (ehci_device_ich4);
236         case PCI_EHCI_DEVICEID_ICH5:
237                 return (ehci_device_ich5);
238         case PCI_EHCI_DEVICEID_ICH6:
239                 return (ehci_device_ich6);
240         case PCI_EHCI_DEVICEID_ICH7:
241                 return (ehci_device_ich7);
242         case PCI_EHCI_DEVICEID_ICH8_A:
243                 return (ehci_device_ich8_a);
244         case PCI_EHCI_DEVICEID_ICH8_B:
245                 return (ehci_device_ich8_b);
246         case PCI_EHCI_DEVICEID_ICH9_A:
247         case PCI_EHCI_DEVICEID_ICH9_B:
248                 return (ehci_device_ich9);
249         case PCI_EHCI_DEVICEID_NEC:
250                 return (ehci_device_nec);
251         case PCI_EHCI_DEVICEID_NF2:
252                 return (ehci_device_nf2);
253         case PCI_EHCI_DEVICEID_NF2_400:
254                 return (ehci_device_nf2_400);
255         case PCI_EHCI_DEVICEID_NF3:
256                 return (ehci_device_nf3);
257         case PCI_EHCI_DEVICEID_NF3_250:
258                 return (ehci_device_nf3_250);
259         case PCI_EHCI_DEVICEID_NF4:
260                 return (ehci_device_nf4);
261         case PCI_EHCI_DEVICEID_ISP156X:
262                 return (ehci_device_isp156x);
263         case PCI_EHCI_DEVICEID_VIA:
264                 return (ehci_device_via);
265         default:
266                 if (pci_get_class(self) == PCIC_SERIALBUS
267                     && pci_get_subclass(self) == PCIS_SERIALBUS_USB
268                     && pci_get_progif(self) == PCI_INTERFACE_EHCI) {
269                         return (ehci_device_generic);
270                 }
271         }
272 
273         return NULL;            /* dunno */
274 }
275 
276 static int
277 ehci_pci_probe(device_t self)
278 {
279         const char *desc = ehci_pci_match(self);
280 
281         if (desc) {
282                 device_set_desc(self, desc);
283                 return BUS_PROBE_DEFAULT;
284         } else {
285                 return ENXIO;
286         }
287 }
288 
289 static int
290 ehci_pci_attach(device_t self)
291 {
292         ehci_softc_t *sc = device_get_softc(self);
293         devclass_t dc;
294         device_t parent;
295         device_t *neighbors;
296         device_t *nbus;
297         struct usbd_bus *bsc;
298         int err;
299         int rid;
300         int ncomp;
301         int count, buscount;
302         int slot, function;
303         int res;
304         int i;
305 
306         switch(pci_read_config(self, PCI_USBREV, 1) & PCI_USBREV_MASK) {
307         case PCI_USBREV_PRE_1_0:
308         case PCI_USBREV_1_0:
309         case PCI_USBREV_1_1:
310                 device_printf(self, "pre-2.0 USB rev\n");
311                 if (pci_get_devid(self) == PCI_EHCI_DEVICEID_CS5536) {
312                         sc->sc_bus.usbrev = USBREV_2_0;
313                         device_printf(self, "Quirk for CS5536 USB 2.0 enabled\n");
314                         break;
315                 }
316                 sc->sc_bus.usbrev = USBREV_UNKNOWN;
317                 return ENXIO;
318         case PCI_USBREV_2_0:
319                 sc->sc_bus.usbrev = USBREV_2_0;
320                 break;
321         default:
322                 sc->sc_bus.usbrev = USBREV_UNKNOWN;
323                 break;
324         }
325 
326         pci_enable_busmaster(self);
327 
328         rid = PCI_CBMEM;
329         sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
330             RF_ACTIVE);
331         if (!sc->io_res) {
332                 device_printf(self, "Could not map memory\n");
333                 return ENXIO;
334         }
335         sc->iot = rman_get_bustag(sc->io_res);
336         sc->ioh = rman_get_bushandle(sc->io_res);
337 
338         rid = 0;
339         sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
340             RF_SHAREABLE | RF_ACTIVE);
341         if (sc->irq_res == NULL) {
342                 device_printf(self, "Could not allocate irq\n");
343                 ehci_pci_detach(self);
344                 return ENXIO;
345         }
346         sc->sc_bus.bdev = device_add_child(self, "usb", -1);
347         if (!sc->sc_bus.bdev) {
348                 device_printf(self, "Could not add USB device\n");
349                 ehci_pci_detach(self);
350                 return ENOMEM;
351         }
352         device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
353 
354         /* ehci_pci_match will never return NULL if ehci_pci_probe succeeded */
355         device_set_desc(sc->sc_bus.bdev, ehci_pci_match(self));
356         switch (pci_get_vendor(self)) {
357         case PCI_EHCI_VENDORID_ACERLABS:
358                 sprintf(sc->sc_vendor, "AcerLabs");
359                 break;
360         case PCI_EHCI_VENDORID_AMD:
361                 sprintf(sc->sc_vendor, "AMD");
362                 break;
363         case PCI_EHCI_VENDORID_APPLE:
364                 sprintf(sc->sc_vendor, "Apple");
365                 break;
366         case PCI_EHCI_VENDORID_ATI:
367                 sprintf(sc->sc_vendor, "ATI");
368                 break;
369         case PCI_EHCI_VENDORID_CMDTECH:
370                 sprintf(sc->sc_vendor, "CMDTECH");
371                 break;
372         case PCI_EHCI_VENDORID_INTEL:
373                 sprintf(sc->sc_vendor, "Intel");
374                 break;
375         case PCI_EHCI_VENDORID_NEC:
376                 sprintf(sc->sc_vendor, "NEC");
377                 break;
378         case PCI_EHCI_VENDORID_OPTI:
379                 sprintf(sc->sc_vendor, "OPTi");
380                 break;
381         case PCI_EHCI_VENDORID_SIS:
382                 sprintf(sc->sc_vendor, "SiS");
383                 break;
384         case PCI_EHCI_VENDORID_NVIDIA:
385         case PCI_EHCI_VENDORID_NVIDIA2:
386                 sprintf(sc->sc_vendor, "nVidia");
387                 break;
388         case PCI_EHCI_VENDORID_VIA:
389                 sprintf(sc->sc_vendor, "VIA");
390                 break;
391         default:
392                 if (bootverbose)
393                         device_printf(self, "(New EHCI DeviceId=0x%08x)\n",
394                             pci_get_devid(self));
395                 sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
396         }
397 
398         err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
399             NULL, (driver_intr_t *)ehci_intr, sc, &sc->ih);
400         if (err) {
401                 device_printf(self, "Could not setup irq, %d\n", err);
402                 sc->ih = NULL;
403                 ehci_pci_detach(self);
404                 return ENXIO;
405         }
406 
407         /* Enable workaround for dropped interrupts as required */
408         switch (pci_get_vendor(self)) {
409         case PCI_EHCI_VENDORID_ATI:
410         case PCI_EHCI_VENDORID_VIA:
411                 sc->sc_flags |= EHCI_SCFLG_LOSTINTRBUG;
412                 if (bootverbose)
413                         device_printf(self,
414                             "Dropped interrupts workaround enabled\n");
415                 break;
416         default:
417                 break;
418         }
419 
420         /*
421          * Find companion controllers.  According to the spec they always
422          * have lower function numbers so they should be enumerated already.
423          */
424         parent = device_get_parent(self);
425         res = device_get_children(parent, &neighbors, &count);
426         if (res != 0) {
427                 device_printf(self, "Error finding companion busses\n");
428                 ehci_pci_detach(self);
429                 return ENXIO;
430         }
431         ncomp = 0;
432         dc = devclass_find("usb");
433         slot = pci_get_slot(self);
434         function = pci_get_function(self);
435         for (i = 0; i < count; i++) {
436                 if (pci_get_slot(neighbors[i]) == slot && \
437                         pci_get_function(neighbors[i]) < function) {
438                         res = device_get_children(neighbors[i],
439                                 &nbus, &buscount);
440                         if (res != 0)
441                                 continue;
442                         if (buscount != 1) {
443                                 free(nbus, M_TEMP);
444                                 continue;
445                         }
446                         if (device_get_devclass(nbus[0]) != dc) {
447                                 free(nbus, M_TEMP);
448                                 continue;
449                         }
450                         bsc = device_get_softc(nbus[0]);
451                         free(nbus, M_TEMP);
452                         DPRINTF(("ehci_pci_attach: companion %s\n",
453                             device_get_nameunit(bsc->bdev)));
454                         sc->sc_comps[ncomp++] = bsc;
455                         if (ncomp >= EHCI_COMPANION_MAX)
456                                 break;
457                 }
458         }
459         sc->sc_ncomp = ncomp;
460 
461         /* Allocate a parent dma tag for DMA maps */
462         err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
463             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
464             BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
465             NULL, NULL, &sc->sc_bus.parent_dmatag);
466         if (err) {
467                 device_printf(self, "Could not allocate parent DMA tag (%d)\n",
468                     err);
469                 ehci_pci_detach(self);
470                 return ENXIO;
471         }
472 
473         /* Allocate a dma tag for transfer buffers */
474         err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
475             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
476             BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
477             busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
478         if (err) {
479                 device_printf(self, "Could not allocate buffer DMA tag (%d)\n",
480                     err);
481                 ehci_pci_detach(self);
482                 return ENXIO;
483         }
484 
485         ehci_pci_takecontroller(self);
486         err = ehci_init(sc);
487         if (!err) {
488                 sc->sc_flags |= EHCI_SCFLG_DONEINIT;
489                 err = device_probe_and_attach(sc->sc_bus.bdev);
490         }
491 
492         if (err) {
493                 device_printf(self, "USB init failed err=%d\n", err);
494                 ehci_pci_detach(self);
495                 return EIO;
496         }
497         return 0;
498 }
499 
500 static int
501 ehci_pci_detach(device_t self)
502 {
503         ehci_softc_t *sc = device_get_softc(self);
504 
505         if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
506                 ehci_detach(sc, 0);
507                 sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
508         }
509 
510         /*
511          * disable interrupts that might have been switched on in ehci_init
512          */
513         if (sc->iot && sc->ioh)
514                 bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0);
515         if (sc->sc_bus.parent_dmatag != NULL)
516                 bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
517         if (sc->sc_bus.buffer_dmatag != NULL)
518                 bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
519 
520         if (sc->irq_res && sc->ih) {
521                 int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
522 
523                 if (err)
524                         /* XXX or should we panic? */
525                         device_printf(self, "Could not tear down irq, %d\n",
526                             err);
527                 sc->ih = NULL;
528         }
529         if (sc->sc_bus.bdev) {
530                 device_delete_child(self, sc->sc_bus.bdev);
531                 sc->sc_bus.bdev = NULL;
532         }
533         if (sc->irq_res) {
534                 bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
535                 sc->irq_res = NULL;
536         }
537         if (sc->io_res) {
538                 bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM, sc->io_res);
539                 sc->io_res = NULL;
540                 sc->iot = 0;
541                 sc->ioh = 0;
542         }
543         return 0;
544 }
545 
546 static void
547 ehci_pci_takecontroller(device_t self)
548 {
549         ehci_softc_t *sc = device_get_softc(self);
550         u_int32_t cparams, eec;
551         uint8_t bios_sem;
552         int eecp, i;
553 
554         cparams = EREAD4(sc, EHCI_HCCPARAMS);
555 
556         /* Synchronise with the BIOS if it owns the controller. */
557         for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
558             eecp = EHCI_EECP_NEXT(eec)) {
559                 eec = pci_read_config(self, eecp, 4);
560                 if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP)
561                         continue;
562                 bios_sem = pci_read_config(self, eecp + EHCI_LEGSUP_BIOS_SEM,
563                     1);
564                 if (bios_sem) {
565                         pci_write_config(self, eecp + EHCI_LEGSUP_OS_SEM, 1, 1);
566                         printf("%s: waiting for BIOS to give up control\n",
567                             device_get_nameunit(sc->sc_bus.bdev));
568                         for (i = 0; i < 5000; i++) {
569                                 bios_sem = pci_read_config(self, eecp +
570                                     EHCI_LEGSUP_BIOS_SEM, 1);
571                                 if (bios_sem == 0)
572                                         break;
573                                 DELAY(1000);
574                         }
575                         if (bios_sem)
576                                 printf("%s: timed out waiting for BIOS\n",
577                                     device_get_nameunit(sc->sc_bus.bdev));
578                 }
579         }
580 }
581 
582 static void
583 ehci_pci_givecontroller(device_t self)
584 {
585 #if 0
586         ehci_softc_t *sc = device_get_softc(self);
587         u_int32_t cparams, eec;
588         int eecp;
589 
590         cparams = EREAD4(sc, EHCI_HCCPARAMS);
591         for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
592             eecp = EHCI_EECP_NEXT(eec)) {
593                 eec = pci_read_config(self, eecp, 4);
594                 if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP)
595                         continue;
596                 pci_write_config(self, eecp + EHCI_LEGSUP_OS_SEM, 0, 1);
597         }
598 #endif
599 }
600 
601 static device_method_t ehci_methods[] = {
602         /* Device interface */
603         DEVMETHOD(device_probe, ehci_pci_probe),
604         DEVMETHOD(device_attach, ehci_pci_attach),
605         DEVMETHOD(device_detach, ehci_pci_detach),
606         DEVMETHOD(device_suspend, ehci_pci_suspend),
607         DEVMETHOD(device_resume, ehci_pci_resume),
608         DEVMETHOD(device_shutdown, ehci_pci_shutdown),
609 
610         /* Bus interface */
611         DEVMETHOD(bus_print_child, bus_generic_print_child),
612 
613         {0, 0}
614 };
615 
616 static driver_t ehci_driver = {
617         "ehci",
618         ehci_methods,
619         sizeof(ehci_softc_t),
620 };
621 
622 static devclass_t ehci_devclass;
623 
624 DRIVER_MODULE(ehci, pci, ehci_driver, ehci_devclass, 0, 0);
625 DRIVER_MODULE(ehci, cardbus, ehci_driver, ehci_devclass, 0, 0);
626 MODULE_DEPEND(ehci, usb, 1, 1, 1);
627 

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.