PERFORCE change 170302 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Nov 7 00:04:40 UTC 2009
http://p4web.freebsd.org/chv.cgi?CH=170302
Change 170302 by hselasky at hselasky_laptop001 on 2009/11/07 00:04:21
USB controller (EHCI)
- integrate lost interrupts patch from the
old USB stack.
- patch from: Alexander Nedotsukov
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/controller/ehci.c#39 edit
.. //depot/projects/usb/src/sys/dev/usb/controller/ehci.h#14 edit
.. //depot/projects/usb/src/sys/dev/usb/controller/ehci_pci.c#18 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/controller/ehci.c#39 (text+ko) ====
@@ -116,10 +116,12 @@
extern struct usb_pipe_methods ehci_device_isoc_fs_methods;
extern struct usb_pipe_methods ehci_device_isoc_hs_methods;
-static void ehci_do_poll(struct usb_bus *bus);
-static void ehci_device_done(struct usb_xfer *xfer, usb_error_t error);
-static uint8_t ehci_check_transfer(struct usb_xfer *xfer);
-static void ehci_timeout(void *arg);
+static void ehci_do_poll(struct usb_bus *);
+static void ehci_device_done(struct usb_xfer *, usb_error_t);
+static uint8_t ehci_check_transfer(struct usb_xfer *);
+static void ehci_timeout(void *);
+static void ehci_poll_timeout(void *);
+
static void ehci_root_intr(ehci_softc_t *sc);
struct ehci_std_temp {
@@ -246,6 +248,7 @@
DPRINTF("start\n");
usb_callout_init_mtx(&sc->sc_tmo_pcd, &sc->sc_bus.bus_mtx, 0);
+ usb_callout_init_mtx(&sc->sc_tmo_poll, &sc->sc_bus.bus_mtx, 0);
#if USB_DEBUG
if (ehcidebug > 2) {
@@ -523,6 +526,7 @@
USB_BUS_LOCK(&sc->sc_bus);
usb_callout_stop(&sc->sc_tmo_pcd);
+ usb_callout_stop(&sc->sc_tmo_poll);
EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
USB_BUS_UNLOCK(&sc->sc_bus);
@@ -535,6 +539,7 @@
usb_pause_mtx(NULL, hz / 20);
usb_callout_drain(&sc->sc_tmo_pcd);
+ usb_callout_drain(&sc->sc_tmo_poll);
}
void
@@ -1475,6 +1480,28 @@
}
}
+/*
+ * Some EHCI chips from VIA / ATI 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 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.
+ */
+static void
+ehci_poll_timeout(void *arg)
+{
+ ehci_softc_t *sc = arg;
+
+ DPRINTFN(3, "ehci_intrq_timeout\n");
+ ehci_interrupt_poll(sc);
+}
+
/*------------------------------------------------------------------------*
* ehci_interrupt - EHCI interrupt handler
*
@@ -1542,6 +1569,11 @@
/* poll all the USB transfers */
ehci_interrupt_poll(sc);
+ if (sc->sc_flags & EHCI_SCFLG_LOSTINTRBUG) {
+ usb_callout_reset(&sc->sc_tmo_poll, hz / 128,
+ (void *)&ehci_poll_timeout, sc);
+ }
+
done:
USB_BUS_UNLOCK(&sc->sc_bus);
}
==== //depot/projects/usb/src/sys/dev/usb/controller/ehci.h#14 (text+ko) ====
@@ -321,6 +321,7 @@
struct ehci_hw_softc sc_hw;
struct usb_bus sc_bus; /* base device */
struct usb_callout sc_tmo_pcd;
+ struct usb_callout sc_tmo_poll;
union ehci_hub_desc sc_hub_desc;
struct usb_device *sc_devices[EHCI_MAX_DEVICES];
@@ -348,6 +349,7 @@
#define EHCI_SCFLG_BIGEDESC 0x0008 /* big-endian byte order descriptors */
#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 */
uint8_t sc_offs; /* offset to operational registers */
uint8_t sc_doorbell_disable; /* set on doorbell failure */
==== //depot/projects/usb/src/sys/dev/usb/controller/ehci_pci.c#18 (text+ko) ====
@@ -439,6 +439,20 @@
break;
}
+ /* Dropped interrupts workaround */
+
+ switch (pci_get_vendor(self)) {
+ case PCI_EHCI_VENDORID_ATI:
+ case PCI_EHCI_VENDORID_VIA:
+ sc->sc_flags |= EHCI_SCFLG_LOSTINTRBUG;
+ if (bootverbose)
+ device_printf(self,
+ "Dropped interrupts 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 p4-projects
mailing list