From owner-freebsd-usb@FreeBSD.ORG Fri Jan 27 00:32:55 2006 Return-Path: X-Original-To: freebsd-usb@freebsd.org Delivered-To: freebsd-usb@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 56EF916A420 for ; Fri, 27 Jan 2006 00:32:55 +0000 (GMT) (envelope-from nox@saturn.kn-bremen.de) Received: from gwyn.kn-bremen.de (gwyn.kn-bremen.de [212.63.36.242]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9166B43D45 for ; Fri, 27 Jan 2006 00:32:53 +0000 (GMT) (envelope-from nox@saturn.kn-bremen.de) Received: from gwyn.kn-bremen.de (gwyn [127.0.0.1]) by gwyn.kn-bremen.de (8.13.4/8.13.4/Debian-3) with ESMTP id k0R0Wqmf008154; Fri, 27 Jan 2006 01:32:52 +0100 Received: from saturn.kn-bremen.de (uucp@localhost) by gwyn.kn-bremen.de (8.13.4/8.13.4/Submit) with UUCP id k0R0WqwN008152; Fri, 27 Jan 2006 01:32:52 +0100 Received: from saturn.kn-bremen.de (nox@localhost [127.0.0.1]) by saturn.kn-bremen.de (8.13.3/8.13.1) with ESMTP id k0R0VJZ0017809; Fri, 27 Jan 2006 01:31:19 +0100 (CET) (envelope-from nox@saturn.kn-bremen.de) Received: (from nox@localhost) by saturn.kn-bremen.de (8.13.3/8.13.1/Submit) id k0R0VIkH017808; Fri, 27 Jan 2006 01:31:18 +0100 (CET) (envelope-from nox) From: Juergen Lock Date: Fri, 27 Jan 2006 01:31:18 +0100 To: Ian Dowse Message-ID: <20060127003118.GA17649@saturn.kn-bremen.de> References: <20060122014536.GA14131@saturn.kn-bremen.de> <200601260203.aa16326@nowhere.iedowse.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200601260203.aa16326@nowhere.iedowse.com> User-Agent: Mutt/1.4.2.1i Cc: freebsd-usb@freebsd.org Subject: Re: cvs commit: src/sys/dev/usb ehci.c ehci_pci.c ehcivar.h X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Jan 2006 00:32:55 -0000 On Thu, Jan 26, 2006 at 02:03:28AM +0000, Ian Dowse wrote: > In message <20060122014536.GA14131@saturn.kn-bremen.de>, 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 */