On Thu, Jan 26, 2006 at 02:03:28AM +0000, Ian Dowse wrote:
> In message <[EMAIL PROTECTED]>, Juergen Lock writes:
> >Can this commit,
> >http://lists.freebsd.org/pipermail/cvs-src/2006-January/058150.html
> >(sorry I dont have the msgid) be mfc'd to 6 and 5 before the freeze?
> >I merged (cvs up -j...) it on 5.4 and it fixes ehci hangs for me.
> 
> Hi, I've just merged this to RELENG_6. The USB code in RELENG_5 is
> missing a number of bug fixes at this stage, but I don't have a
> RELENG_5 box handy to test on. If you'd like to send a patch you've
> tested then I'll be able to check that it matches up and commit it.

Here is what I use on RELENG_5_4:

Index: ehci.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ehci.c,v
retrieving revision 1.14.2.9
diff -u -r1.14.2.9 ehci.c
--- ehci.c      31 Mar 2005 19:47:11 -0000      1.14.2.9
+++ ehci.c      17 Jan 2006 23:03:31 -0000
@@ -155,6 +155,7 @@
 Static void            ehci_idone(struct ehci_xfer *);
 Static void            ehci_timeout(void *);
 Static void            ehci_timeout_task(void *);
+Static void            ehci_intrlist_timeout(void *);
 
 Static usbd_status     ehci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
 Static void            ehci_freem(struct usbd_bus *, usb_dma_t *);
@@ -491,6 +492,7 @@
        EOWRITE4(sc, EHCI_ASYNCLISTADDR, sqh->physaddr | EHCI_LINK_QH);
 
        usb_callout_init(sc->sc_tmo_pcd);
+       usb_callout_init(sc->sc_tmo_intrlist);
 
        lockinit(&sc->sc_doorbell_lock, PZERO, "ehcidb", 0, 0);
 
@@ -694,6 +696,12 @@
                ehci_check_intr(sc, ex);
        }
 
+       /* Schedule a callout to catch any dropped transactions. */
+       if ((sc->sc_flags & EHCI_SCFLG_LOSTINTRBUG) &&
+           !LIST_EMPTY(&sc->sc_intrhead))
+               usb_callout(sc->sc_tmo_intrlist, hz / 5, ehci_intrlist_timeout,
+                  sc);
+
 #ifdef USB_USE_SOFTINTR
        if (sc->sc_softwake) {
                sc->sc_softwake = 0;
@@ -942,6 +950,7 @@
        EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
        EOWRITE4(sc, EHCI_USBCMD, 0);
        EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
+       usb_uncallout(sc->sc_tmo_intrlist, ehci_intrlist_timeout, sc);
        usb_uncallout(sc->sc_tmo_pcd, ehci_pcd_enable, sc);
 
 #if defined(__NetBSD__) || defined(__OpenBSD__)
@@ -2701,6 +2710,29 @@
        splx(s);
 }
 
+/*
+ * Some EHCI chips from VIA seem to trigger interrupts before writing back the
+ * qTD status, or miss signalling occasionally under heavy load.  If the host
+ * machine is too fast, we we can miss transaction completion - when we scan
+ * the active list the transaction still seems to be active.  This generally
+ * exhibits itself as a umass stall that never recovers.
+ *
+ * We work around this behaviour by setting up this callback after any softintr
+ * that completes with transactions still pending, giving us another chance to
+ * check for completion after the writeback has taken place.
+ */
+void
+ehci_intrlist_timeout(void *arg)
+{
+       ehci_softc_t *sc = arg;
+       int s = splusb();
+
+       DPRINTFN(3, ("ehci_intrlist_timeout\n"));
+       usb_schedsoftintr(&sc->sc_bus);
+
+       splx(s);
+}
+
 /************************/
 
 Static usbd_status
Index: ehci_pci.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ehci_pci.c,v
retrieving revision 1.14.2.1
diff -u -r1.14.2.1 ehci_pci.c
--- ehci_pci.c  31 Mar 2005 19:45:09 -0000      1.14.2.1
+++ ehci_pci.c  17 Jan 2006 23:03:31 -0000
@@ -298,6 +298,10 @@
                return ENXIO;
        }
 
+       /* Enable workaround for dropped interrupts as required */
+       if (pci_get_vendor(self) == PCI_EHCI_VENDORID_VIA)
+               sc->sc_flags |= EHCI_SCFLG_LOSTINTRBUG;
+
        /*
         * Find companion controllers.  According to the spec they always
         * have lower function numbers so they should be enumerated already.
Index: ehcivar.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ehcivar.h,v
retrieving revision 1.4.2.4
diff -u -r1.4.2.4 ehcivar.h
--- ehcivar.h   22 Mar 2005 00:56:54 -0000      1.4.2.4
+++ ehcivar.h   17 Jan 2006 23:03:31 -0000
@@ -93,6 +93,7 @@
 #define EHCI_COMPANION_MAX 8
 
 #define EHCI_SCFLG_DONEINIT    0x0001  /* ehci_init() has been called. */
+#define EHCI_SCFLG_LOSTINTRBUG 0x0002  /* workaround for VIA chipsets */
 
 typedef struct ehci_softc {
        struct usbd_bus sc_bus;         /* base device */
@@ -149,6 +150,7 @@
        struct lock sc_doorbell_lock;
 
        usb_callout_t sc_tmo_pcd;
+       usb_callout_t sc_tmo_intrlist;
 
        device_ptr_t sc_child;          /* /dev/usb# device */
 
_______________________________________________
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to