Possible solution for USB EHCI IRQ problems

From: Hans Petter Selasky <hselasky_at_c2i.net>
Date: Fri, 15 Oct 2010 00:54:14 +0200
Hi,

Anyone out there experiencing so-called EHCI-hangs, can try applying the 
following patch by hand:

http://p4web.freebsd.org/_at__at_184749?ac=10

==== //depot/projects/usb/src/sys/dev/usb/controller/ehci.c#62 (text+ko) ====

_at__at_ -1589,6 +1589,10 _at__at_
                usb_callout_reset(&sc->sc_tmo_pcd, hz,
                    (void *)&ehci_pcd_enable, sc);
        }
+       /* if there was a doorbell, clear the doorbell busy flag */
+       if (status & EHCI_STS_IAA)
+               sc->sc_flags &= ~EHCI_SCFLG_IAADBUSY;
+
        status &= ~(EHCI_STS_INT | EHCI_STS_ERRINT | EHCI_STS_PCD | 
EHCI_STS_IAA);
 
        if (status != 0) {
_at__at_ -2313,7 +2317,7 _at__at_
         * XXX Certain nVidia chipsets choke when using the IAAD
         * feature too frequently.
         */
-       if (sc->sc_flags & EHCI_SCFLG_IAADBUG)
+       if (sc->sc_flags & (EHCI_SCFLG_IAADBUG | EHCI_SCFLG_IAADBUSY))
                return;
 
        /* XXX Performance quirk: Some Host Controllers have a too low
_at__at_ -2321,8 +2325,10 _at__at_
         * Controller after queueing the BULK transfer.
         */
        temp = EOREAD4(sc, EHCI_USBCMD);
-       if (!(temp & EHCI_CMD_IAAD))
+       if (!(temp & EHCI_CMD_IAAD)) {
                EOWRITE4(sc, EHCI_USBCMD, temp | EHCI_CMD_IAAD);
+               sc->sc_flags |= EHCI_SCFLG_IAADBUSY;
+       }
 }
 
 struct usb_pipe_methods ehci_device_bulk_methods =

==== //depot/projects/usb/src/sys/dev/usb/controller/ehci.h#20 (text+ko) ====

_at__at_ -347,6 +347,7 _at__at_
 #define        EHCI_SCFLG_TT           0x0020  /* transaction translator 
present */
 #define        EHCI_SCFLG_LOSTINTRBUG  0x0040  /* workaround for VIA / ATI 
chipsets */
 #define        EHCI_SCFLG_IAADBUG      0x0080  /* workaround for nVidia 
chipsets */
+#define        EHCI_SCFLG_IAADBUSY     0x0100  /* doorbell is busy */
 
        uint8_t sc_offs;                /* offset to operational registers */
        uint8_t sc_doorbell_disable;    /* set on doorbell failure */


--HPS
Received on Thu Oct 14 2010 - 20:52:58 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:08 UTC