From owner-p4-projects@FreeBSD.ORG Sat Nov 7 00:04:40 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 08F0A1065695; Sat, 7 Nov 2009 00:04:40 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A9626106568D for ; Sat, 7 Nov 2009 00:04:39 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 96A2D8FC14 for ; Sat, 7 Nov 2009 00:04:39 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id nA704da7094090 for ; Sat, 7 Nov 2009 00:04:39 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id nA704dsC094088 for perforce@freebsd.org; Sat, 7 Nov 2009 00:04:39 GMT (envelope-from hselasky@FreeBSD.org) Date: Sat, 7 Nov 2009 00:04:39 GMT Message-Id: <200911070004.nA704dsC094088@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 170302 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Nov 2009 00:04:40 -0000 http://p4web.freebsd.org/chv.cgi?CH=170302 Change 170302 by hselasky@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);