Date: Sun, 26 Jun 2005 17:42:44 +0100 From: Ian Dowse <iedowse@iedowse.com> To: Stefan Walter <sw@gegenunendlich.de> Cc: freebsd-stable@freebsd.org Subject: Re: EHCI: mtools stuck in state 'physrd' or panic Message-ID: <200506261742.aa93128@nowhere.iedowse.com> In-Reply-To: Your message of "Sun, 26 Jun 2005 11:26:20 %2B0200." <20050626092620.GA1565@kyuzo.dunkelkammer.void>
next in thread | previous in thread | raw e-mail | index | archive | help
In message <20050626092620.GA1565@kyuzo.dunkelkammer.void>, Stefan Walter write s: >FYI: I have just sent a PR for this problem. > >http://www.freebsd.org/cgi/query-pr.cgi?pr=82660 OpenBSD have a workaround for problems with VIA EHCI controllers that can cause the hanging symptoms you describe. Below is a patch that implements their change in FreeBSD's driver. Could you try it to see if it helps? Thanks, Ian Index: sys/dev/usb/ehci.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/usb/ehci.c,v retrieving revision 1.14.2.9 diff -u -r1.14.2.9 ehci.c --- sys/dev/usb/ehci.c 31 Mar 2005 19:47:11 -0000 1.14.2.9 +++ sys/dev/usb/ehci.c 26 Jun 2005 16:21:11 -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,11 @@ 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, ehci_intrlist_timeout, sc); + #ifdef USB_USE_SOFTINTR if (sc->sc_softwake) { sc->sc_softwake = 0; @@ -942,6 +949,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 +2708,30 @@ 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: sys/dev/usb/ehci_pci.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/usb/ehci_pci.c,v retrieving revision 1.14.2.2 diff -u -r1.14.2.2 ehci_pci.c --- sys/dev/usb/ehci_pci.c 13 Jun 2005 09:00:19 -0000 1.14.2.2 +++ sys/dev/usb/ehci_pci.c 26 Jun 2005 16:21:11 -0000 @@ -303,6 +303,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: sys/dev/usb/ehcivar.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/usb/ehcivar.h,v retrieving revision 1.4.2.4 diff -u -r1.4.2.4 ehcivar.h --- sys/dev/usb/ehcivar.h 22 Mar 2005 00:56:54 -0000 1.4.2.4 +++ sys/dev/usb/ehcivar.h 26 Jun 2005 16:21:11 -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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200506261742.aa93128>