From owner-freebsd-usb@FreeBSD.ORG Tue Aug 30 19:09:03 2005 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 660C316A41F; Tue, 30 Aug 2005 19:09:03 +0000 (GMT) (envelope-from iedowse@iedowse.com) Received: from nowhere.iedowse.com (nowhere.iedowse.com [82.195.144.75]) by mx1.FreeBSD.org (Postfix) with SMTP id 993B743D45; Tue, 30 Aug 2005 19:09:02 +0000 (GMT) (envelope-from iedowse@iedowse.com) Received: from localhost ([127.0.0.1] helo=iedowse.com) by nowhere.iedowse.com via local-iedowse id ; 30 Aug 2005 20:09:00 +0100 (IST) To: "Eygene A. Ryabinkin" In-Reply-To: Your message of "Tue, 30 Aug 2005 16:50:31 +0400." <20050830125031.GA775@rea.mbslab.kiae.ru> Date: Tue, 30 Aug 2005 20:08:57 +0100 From: Ian Dowse Message-ID: <200508302009.aa99975@nowhere.iedowse.com> Cc: hackers@freebsd.org, Eugene Grosbein , freebsd-usb@freebsd.org Subject: Re: Low umass performance with USB 2.0 ports 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: Tue, 30 Aug 2005 19:09:03 -0000 In message <20050830125031.GA775@rea.mbslab.kiae.ru>, "Eygene A. Ryabinkin" wri tes: >> >> What is filesystem has your USB drive? > The one I was extensively testing has FAT, but I've checked the UFS2 -- >just a bit better -- 1.8 Mb/second. But you're right -- no wdrains at all. >> FreeBSD 4.x had very low performance with FAT filesystem, >> writing process spent lots of time in the wdrain state too. > Yes, it has. But here the same flash drive gives different results for >ehci and uhci devices, and the total speed of echi is lower due to wdrains: >300 Kb/sec versus 500 Kb/sec. And I sometimes write my data to the Windows >partition with FAT to my home HDD -- it has no wdrains. At least, I've not >noticed them. For flash I can. The patch in from the email below may help with the wdrain state - can you see if it makes any difference? Ian Date: Sun, 26 Jun 2005 17:42:44 BST To: Stefan Walter cc: freebsd-stable@freebsd.org From: Ian Dowse Subject: Re: EHCI: mtools stuck in state 'physrd' or panic 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 */