On Fri, 23 Jul 2004, Luc Dijon wrote:
> Thanks Alan for your Feedback.
> I have some troubles to apply the patch you sent. 2 (important I
> suppose) blocks were not updated successfully.
> I sent you in attach the resu of the exec of patch on hub.c + my orig hub.c.
> My kernel is from www.kernel.org 2.6.7. May be your original hub.c is
> even more recent than 2.6.7.
> Can you check ?
On Sat, 24 Jul 2004, Martin Pohlack wrote:
> Are you sure the patch is against 2.6.7? It does not apply completely.
> hub.c.rej is attached.
Yes, sorry -- I don't have a copy of 2.6.7 handy and so my patch wasn't
against the right form of the source file.
On Sat, 24 Jul 2004, Luc Dijon wrote:
> Alan,
> Here is in attachment, the resulting log after applying the patch.
> I also attached the patched hub.c just In case I did something wrong .
> I hope not :-)
> Thanks,
I'm afraid your fixed-up patch did contain a mistake.
Never mind. Below is new version of the patch which, I hope, will apply
correctly to the 2.6.7 source. Please try it out and see if it works any
better than before.
Alan Stern
P.S.: Luc, in the future please don't send 2000-line-long replies with
your real message hidden away at the bottom; they are very hard to read.
Include only the relevant information.
===== drivers/usb/core/hub.c 1.184 vs edited =====
--- 1.184/drivers/usb/core/hub.c Tue Jul 13 12:47:28 2004
+++ edited/drivers/usb/core/hub.c Fri Jul 23 15:39:39 2004
@@ -1061,6 +1061,7 @@
int i, j, retval;
unsigned delay = HUB_SHORT_RESET_TIME;
enum usb_device_speed oldspeed = udev->speed;
+ int get_descriptor_first = 0;
/* root hub ports have a slightly longer reset period
* (from USB 2.0 spec, section 7.1.7.5)
@@ -1095,19 +1096,18 @@
i = 64;
break;
case USB_SPEED_FULL: /* 8, 16, 32, or 64 */
- /* to determine the ep0 maxpacket size, read the first 8
- * bytes from the device descriptor to get bMaxPacketSize0;
- * then correct our initial (small) guess.
+ /* to determine the ep0 maxpacket size, try to read
+ * the device descriptor to get bMaxPacketSize0 and
+ * then correct our initial guess.
*/
- // FALLTHROUGH
+ i = 64;
+ break;
case USB_SPEED_LOW: /* fixed at 8 */
i = 8;
break;
default:
goto fail;
}
- udev->epmaxpacketin [0] = i;
- udev->epmaxpacketout[0] = i;
/* set the address */
if (udev->devnum <= 0) {
@@ -1143,17 +1143,60 @@
default: speed = "?"; break;
}; speed;}),
udev->devnum);
-
+
+ /* Clear out any stale HC state pertaining to device 0 endpoint 0 */
+ j = udev->devnum;
+ udev->devnum = 0;
+ usb_disable_endpoint(udev, 0 + USB_DIR_IN);
+ usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+ udev->devnum = j;
+ udev->epmaxpacketin [0] = i;
+ udev->epmaxpacketout[0] = i;
+ usb_endpoint_running(udev, 0, 1);
+ usb_endpoint_running(udev, 0, 0);
+
/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
* Because device hardware and firmware is sometimes buggy in
* this area, and this is how Linux has done it for ages.
* Change it cautiously.
*
- * NOTE: Windows gets the descriptor first, seemingly to help
- * work around device bugs like "can't use addresses with bit 3
- * set in certain configurations". Yes, really.
+ * NOTE: For full-speed devices, if the bMaxPacketSize0 field
+ * is initially set to 1 we will get the descriptor first,
+ * using a 64-byte transfer request. This is what Windows does,
+ * so it may help with some non-standards-compliant devices.
*/
- for (i = 0; i < GET_DESCRIPTOR_TRIES; ++i) {
+ if (udev->descriptor.bMaxPacketSize0 == 1)
+ get_descriptor_first = 1;
+
+ for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
+ if (get_descriptor_first) {
+ struct usb_device_descriptor *buf;
+
+ buf = kmalloc(64, GFP_NOIO);
+ if (!buf) {
+ retval = -ENOMEM;
+ continue;
+ }
+ memset(buf, 0, 64);
+ (void) usb_control_msg(udev,
+ /* Address 0 */
+ (PIPE_CONTROL << 30) | USB_DIR_IN,
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+ USB_DT_DEVICE << 8, 0,
+ buf, 64,
+ HZ * USB_CTRL_GET_TIMEOUT);
+ udev->descriptor = *buf;
+ kfree(buf);
+
+ retval = hub_port_reset(hdev, port, udev, delay);
+ if (retval < 0) /* error or disconnect */
+ goto fail;
+ if (udev->descriptor.bMaxPacketSize0 < 8) {
+ retval = -EMSGSIZE;
+ continue;
+ }
+ }
+
for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
retval = hub_set_address(udev);
if (retval >= 0)
@@ -1177,10 +1220,12 @@
* - read ep0 maxpacket even for high and low speed,
*/
msleep(10);
- retval = usb_get_device_descriptor(udev, 8);
+ if (get_descriptor_first)
+ retval = 8;
+ else
+ retval = usb_get_device_descriptor(udev, 8);
if (retval >= 8)
break;
- msleep(100);
}
if (retval != 8) {
dev_err(&udev->dev, "device descriptor read/%s, error %d\n",
@@ -1338,6 +1383,7 @@
/* reset, set address, get descriptor, add to hub's children */
down (&udev->serialize);
+ udev->descriptor.bMaxPacketSize0 = (i & 1);
status = hub_port_init(hdev, udev, port);
if (status == -ENOTCONN)
break;
-------------------------------------------------------
This SF.Net email is sponsored by BEA Weblogic Workshop
FREE Java Enterprise J2EE developer tools!
Get your free copy of BEA WebLogic Workshop 8.1 today.
http://ads.osdn.com/?ad_id=4721&alloc_id=10040&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel