Date: Wed, 27 Sep 2006 03:50:21 GMT From: Tor Egge <Tor.Egge@cvsup.no.freebsd.org> To: freebsd-usb@FreeBSD.org Subject: Re: usb/103167: Transcend JetFlash120 memory stick problem (with fix) Message-ID: <200609270350.k8R3oLN6026871@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR usb/103167; it has been noted by GNATS. From: Tor Egge <Tor.Egge@cvsup.no.freebsd.org> To: vkushnir@i.kiev.ua Cc: freebsd-gnats-submit@FreeBSD.org Subject: Re: usb/103167: Transcend JetFlash120 memory stick problem (with fix) Date: Wed, 27 Sep 2006 03:44:57 +0000 (UTC) I had a similar problem (getting first desc failed). Setting ehcidebug to a high value hid the problem due to timing changes. I first thought it was the race described in <URL:http://lkml.org/lkml/2004/12/1/131>, but the system behavior didn't match that race. Address changes in the queue head might not have an immediate effect. I ended up adding a 1ms delay after any address change as a workaround. - Tor Egge Index: sys/dev/usb/ehci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/usb/ehci.c,v retrieving revision 1.49 diff -u -r1.49 ehci.c --- sys/dev/usb/ehci.c 7 Sep 2006 00:06:41 -0000 1.49 +++ sys/dev/usb/ehci.c 9 Sep 2006 02:05:47 -0000 @@ -106,6 +106,12 @@ SYSCTL_NODE(_hw_usb, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci"); SYSCTL_INT(_hw_usb_ehci, OID_AUTO, debug, CTLFLAG_RW, &ehcidebug, 0, "ehci debug level"); +int ehciaddrchange = 0; +SYSCTL_INT(_hw_usb_ehci, OID_AUTO, addrchange, CTLFLAG_RD, + &ehciaddrchange, 0, "ehci qh addr change count"); +int ehciaddrunchange = 0; +SYSCTL_INT(_hw_usb_ehci, OID_AUTO, addrunchange, CTLFLAG_RD, + &ehciaddrunchange, 0, "ehci qh addr unchange count"); #ifndef __NetBSD__ #define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f)) #endif @@ -2874,6 +2881,7 @@ int len; usbd_status err; int s; + u_int32_t newendp; isread = req->bmRequestType & UT_READ; len = UGETW(req->wLength); @@ -2907,13 +2915,18 @@ during the setup of the control pipe in usbd_new_device(). */ /* XXX This only needs to be done once, but it's too early in open. */ /* XXXX Should not touch ED here! */ - sqh->qh.qh_endp = + newendp = (sqh->qh.qh_endp & htole32(~(EHCI_QH_ADDRMASK | EHCI_QH_MPLMASK))) | htole32( EHCI_QH_SET_ADDR(addr) | EHCI_QH_SET_MPL(UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize)) ); - + if (newendp != sqh->qh.qh_endp) { + sqh->qh.qh_endp = newendp; + DELAY(1000); + atomic_add_int(&ehciaddrchange, 1); + } else + atomic_add_int(&ehciaddrunchange, 1); /* Set up data transaction */ if (len != 0) { ehci_soft_qtd_t *end;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200609270350.k8R3oLN6026871>