svn commit: r206302 - stable/8/sys/dev/usb/controller
Andrew Thompson
thompsa at FreeBSD.org
Tue Apr 6 23:21:06 UTC 2010
Author: thompsa
Date: Tue Apr 6 23:21:06 2010
New Revision: 206302
URL: http://svn.freebsd.org/changeset/base/206302
Log:
MFC r203693
Disable the use of the IAAD usb doorbell on NVidia controllers as it can cause
the hardware to stall.
Submitted by: Hans Petter Selasky
Modified:
stable/8/sys/dev/usb/controller/ehci.c
stable/8/sys/dev/usb/controller/ehci.h
stable/8/sys/dev/usb/controller/ehci_pci.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/dev/usb/controller/ehci.c
==============================================================================
--- stable/8/sys/dev/usb/controller/ehci.c Tue Apr 6 23:20:41 2010 (r206301)
+++ stable/8/sys/dev/usb/controller/ehci.c Tue Apr 6 23:21:06 2010 (r206302)
@@ -92,15 +92,23 @@ __FBSDID("$FreeBSD$");
#if USB_DEBUG
static int ehcidebug = 0;
static int ehcinohighspeed = 0;
+static int ehciiaadbug = 0;
+static int ehcilostintrbug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci");
SYSCTL_INT(_hw_usb_ehci, OID_AUTO, debug, CTLFLAG_RW,
&ehcidebug, 0, "Debug level");
SYSCTL_INT(_hw_usb_ehci, OID_AUTO, no_hs, CTLFLAG_RW,
&ehcinohighspeed, 0, "Disable High Speed USB");
+SYSCTL_INT(_hw_usb_ehci, OID_AUTO, iaadbug, CTLFLAG_RW,
+ &ehciiaadbug, 0, "Enable doorbell bug workaround");
+SYSCTL_INT(_hw_usb_ehci, OID_AUTO, lostintrbug, CTLFLAG_RW,
+ &ehcilostintrbug, 0, "Enable lost interrupt bug workaround");
TUNABLE_INT("hw.usb.ehci.debug", &ehcidebug);
TUNABLE_INT("hw.usb.ehci.no_hs", &ehcinohighspeed);
+TUNABLE_INT("hw.usb.ehci.iaadbug", &ehciiaadbug);
+TUNABLE_INT("hw.usb.ehci.lostintrbug", &ehcilostintrbug);
static void ehci_dump_regs(ehci_softc_t *sc);
static void ehci_dump_sqh(ehci_softc_t *sc, ehci_qh_t *sqh);
@@ -251,6 +259,10 @@ ehci_init(ehci_softc_t *sc)
usb_callout_init_mtx(&sc->sc_tmo_poll, &sc->sc_bus.bus_mtx, 0);
#if USB_DEBUG
+ if (ehciiaadbug)
+ sc->sc_flags |= EHCI_SCFLG_IAADBUG;
+ if (ehcilostintrbug)
+ sc->sc_flags |= EHCI_SCFLG_LOSTINTRBUG;
if (ehcidebug > 2) {
ehci_dump_regs(sc);
}
@@ -2280,6 +2292,13 @@ ehci_device_bulk_start(struct usb_xfer *
/* put transfer on interrupt queue */
ehci_transfer_intr_enqueue(xfer);
+ /*
+ * XXX Certain nVidia chipsets choke when using the IAAD
+ * feature too frequently.
+ */
+ if (sc->sc_flags & EHCI_SCFLG_IAADBUG)
+ return;
+
/* XXX Performance quirk: Some Host Controllers have a too low
* interrupt rate. Issue an IAAD to stimulate the Host
* Controller after queueing the BULK transfer.
Modified: stable/8/sys/dev/usb/controller/ehci.h
==============================================================================
--- stable/8/sys/dev/usb/controller/ehci.h Tue Apr 6 23:20:41 2010 (r206301)
+++ stable/8/sys/dev/usb/controller/ehci.h Tue Apr 6 23:21:06 2010 (r206302)
@@ -350,6 +350,7 @@ typedef struct ehci_softc {
#define EHCI_SCFLG_BIGEMMIO 0x0010 /* big-endian byte order MMIO */
#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 */
uint8_t sc_offs; /* offset to operational registers */
uint8_t sc_doorbell_disable; /* set on doorbell failure */
Modified: stable/8/sys/dev/usb/controller/ehci_pci.c
==============================================================================
--- stable/8/sys/dev/usb/controller/ehci_pci.c Tue Apr 6 23:20:41 2010 (r206301)
+++ stable/8/sys/dev/usb/controller/ehci_pci.c Tue Apr 6 23:21:06 2010 (r206302)
@@ -466,6 +466,19 @@ ehci_pci_attach(device_t self)
break;
}
+ /* Doorbell feature workaround */
+ switch (pci_get_vendor(self)) {
+ case PCI_EHCI_VENDORID_NVIDIA:
+ case PCI_EHCI_VENDORID_NVIDIA2:
+ sc->sc_flags |= EHCI_SCFLG_IAADBUG;
+ if (bootverbose)
+ device_printf(self,
+ "Doorbell workaround enabled\n");
+ break;
+ default:
+ break;
+ }
+
err = ehci_init(sc);
if (!err) {
err = device_probe_and_attach(sc->sc_bus.bdev);
More information about the svn-src-stable-8
mailing list