Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Sep 2006 13:19:15 +0100
From:      Ian Dowse <iedowse@iedowse.com>
To:        Tor Egge <Tor.Egge@cvsup.no.freebsd.org>
Cc:        freebsd-usb@FreeBSD.org
Subject:   Re: usb/103167: Transcend JetFlash120 memory stick problem (with fix) 
Message-ID:  <200609301319.aa31434@nowhere.iedowse.com>
In-Reply-To: Your message of "Wed, 27 Sep 2006 03:50:21 GMT." <200609270350.k8R3oLN6026871@freefall.freebsd.org> 

next in thread | previous in thread | raw e-mail | index | archive | help
In message <200609270350.k8R3oLN6026871@freefall.freebsd.org>, Tor Egge writes:
> 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.

Good catch - hardware caching of the old address would certainly
explain the errors. Maybe it is safer to just close and reopen the
default pipe after changing important parameters - could someone
try the following patch instead to see if it works?

This would avoid the need to change the QH while it is visible to
the hardware, so the code and XXX comments in [eo]hci_device_request()
for doing this could be removed.

Ian

Index: usb_subr.c
===================================================================
RCS file: /dump/FreeBSD-CVS/src/sys/dev/usb/usb_subr.c,v
retrieving revision 1.86
diff -u -r1.86 usb_subr.c
--- usb_subr.c	10 Sep 2006 15:20:39 -0000	1.86
+++ usb_subr.c	30 Sep 2006 12:04:42 -0000
@@ -1110,6 +1110,15 @@
 	dev->address = addr;	/* New device address now */
 	bus->devices[addr] = dev;
 
+	/* Re-establish the default pipe with the new address. */
+	usbd_kill_pipe(dev->default_pipe);
+	err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
+	    &dev->default_pipe);
+	if (err) {
+		usbd_remove_device(dev, up);
+		return (err);
+	}
+
 	dd = &dev->ddesc;
 	/* Get the first 8 bytes of the device descriptor. */
 	err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
@@ -1153,6 +1162,15 @@
 
 	USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
 
+	/* Re-establish the default pipe with the new max packet size. */
+	usbd_kill_pipe(dev->default_pipe);
+	err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
+	    &dev->default_pipe);
+	if (err) {
+		usbd_remove_device(dev, up);
+		return (err);
+	}
+
 	err = usbd_reload_device_desc(dev);
 	if (err) {
 		DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200609301319.aa31434>