Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-3]: src/sys/dev Pull up following revision(s) (requested by xtrae...



details:   https://anonhg.NetBSD.org/src/rev/051e132b9126
branches:  netbsd-3
changeset: 577767:051e132b9126
user:      tron <tron%NetBSD.org@localhost>
date:      Sun Jan 22 13:52:50 2006 +0000

description:
Pull up following revision(s) (requested by xtraeme in ticket #1123):
        sys/dev/usb/ehcivar.h: revision 1.23
        sys/dev/pci/ehci_pci.c: revision 1.22
        sys/dev/usb/ehci.c: revision 1.108
>From OpenBSD:

--
Add a workaround for VIA EHCI controllers which, under load, signal qTD
completion before they have performed writeback from the overlay qTD.
This condition would exhibit itself as a umass stall that never
recovers.
--

This fixes the problem reported by Thomas Klausner on current-users@:
http://mail-index.netbsd.org/current-users/2006/01/17/0000.html

diffstat:

 sys/dev/pci/ehci_pci.c |   9 +++++++--
 sys/dev/usb/ehci.c     |  36 ++++++++++++++++++++++++++++++++++--
 sys/dev/usb/ehcivar.h  |   5 ++++-
 3 files changed, 45 insertions(+), 5 deletions(-)

diffs (148 lines):

diff -r a2502e577588 -r 051e132b9126 sys/dev/pci/ehci_pci.c
--- a/sys/dev/pci/ehci_pci.c    Sun Jan 22 11:47:32 2006 +0000
+++ b/sys/dev/pci/ehci_pci.c    Sun Jan 22 13:52:50 2006 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ehci_pci.c,v 1.17.2.1 2005/12/07 19:15:05 riz Exp $    */
+/*     $NetBSD: ehci_pci.c,v 1.17.2.2 2006/01/22 13:52:51 tron Exp $   */
 
 /*
  * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci_pci.c,v 1.17.2.1 2005/12/07 19:15:05 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci_pci.c,v 1.17.2.2 2006/01/22 13:52:51 tron Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -48,6 +48,7 @@
 
 #include <machine/bus.h>
 
+#include <dev/pci/pcidevs.h>
 #include <dev/pci/pcivar.h>
 #include <dev/pci/usb_pci.h>
 
@@ -175,6 +176,10 @@
                snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
                    "vendor 0x%04x", PCI_VENDOR(pa->pa_id));
 
+       /* Enable workaround for dropped interrupts as required */
+       if (sc->sc.sc_id_vendor == PCI_VENDOR_VIATECH)
+               sc->sc.sc_flags |= EHCIF_DROPPED_INTR_WORKAROUND;
+
        /*
         * Find companion controllers.  According to the spec they always
         * have lower function numbers so they should be enumerated already.
diff -r a2502e577588 -r 051e132b9126 sys/dev/usb/ehci.c
--- a/sys/dev/usb/ehci.c        Sun Jan 22 11:47:32 2006 +0000
+++ b/sys/dev/usb/ehci.c        Sun Jan 22 13:52:50 2006 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ehci.c,v 1.91.2.7 2005/05/07 11:42:23 tron Exp $ */
+/*     $NetBSD: ehci.c,v 1.91.2.8 2006/01/22 13:52:50 tron Exp $ */
 
 /*
  * Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
 */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.91.2.7 2005/05/07 11:42:23 tron Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.91.2.8 2006/01/22 13:52:50 tron Exp $");
 
 #include "ohci.h"
 #include "uhci.h"
@@ -144,6 +144,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 *);
@@ -497,6 +498,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);
 
@@ -700,6 +702,12 @@
                ehci_check_intr(sc, ex);
        }
 
+       /* Schedule a callout to catch any dropped transactions. */
+       if ((sc->sc_flags & EHCIF_DROPPED_INTR_WORKAROUND) &&
+           !LIST_EMPTY(&sc->sc_intrhead))
+               usb_callout(sc->sc_tmo_intrlist, hz,
+                   ehci_intrlist_timeout, sc);
+
 #ifdef USB_USE_SOFTINTR
        if (sc->sc_softwake) {
                sc->sc_softwake = 0;
@@ -951,6 +959,7 @@
        if (rv != 0)
                return (rv);
 
+       usb_uncallout(sc->sc_tmo_intrlist, ehci_intrlist_timeout, sc);
        usb_uncallout(sc->sc_tmo_pcd, ehci_pcd_enable, sc);
 
        if (sc->sc_powerhook != NULL)
@@ -2814,6 +2823,29 @@
 #undef exfer
 }
 
+/*
+ * 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();
+
+       DPRINTF(("ehci_intrlist_timeout\n"));
+       usb_schedsoftintr(&sc->sc_bus);
+
+       splx(s);
+}
+
 /************************/
 
 Static usbd_status
diff -r a2502e577588 -r 051e132b9126 sys/dev/usb/ehcivar.h
--- a/sys/dev/usb/ehcivar.h     Sun Jan 22 11:47:32 2006 +0000
+++ b/sys/dev/usb/ehcivar.h     Sun Jan 22 13:52:50 2006 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ehcivar.h,v 1.17.8.1 2005/05/01 16:40:44 tron Exp $ */
+/*     $NetBSD: ehcivar.h,v 1.17.8.2 2006/01/22 13:52:50 tron Exp $ */
 
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -92,6 +92,8 @@
        bus_space_handle_t ioh;
        bus_size_t sc_size;
        u_int sc_offs;                  /* offset to operational regs */
+       int sc_flags;                   /* misc flags */
+#define EHCIF_DROPPED_INTR_WORKAROUND  0x01
 
        char sc_vendor[16];             /* vendor string for root hub */
        int sc_id_vendor;               /* vendor ID for root hub */
@@ -133,6 +135,7 @@
        struct lock sc_doorbell_lock;
 
        usb_callout_t sc_tmo_pcd;
+       usb_callout_t sc_tmo_intrlist;
 
 #if defined(__NetBSD__) || defined(__OpenBSD__)
        device_ptr_t sc_child;          /* /dev/usb# device */



Home | Main Index | Thread Index | Old Index