ChangeSet 1.808.2.11, 2002/10/23 11:27:20-07:00, [EMAIL PROTECTED]
[PATCH] ehci enumerating full speed devices
The EHCI driver was never adjusting the full speed maximum packet size up
(when enumerating through a transaction translating hub). This broke the
enumeration of some devices (maxpacket != 8) pretty early.
This patch updates EHCI to fix the bug, and does minor cleanup to usbcore
logic that figures out ep0 maxpacket. I left the partial read in for all
speeds, even though only full speed needs it.
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c Mon Oct 28 13:54:54 2002
+++ b/drivers/usb/core/usb.c Mon Oct 28 13:54:54 2002
@@ -942,12 +942,27 @@
int i;
int j;
- /* USB v1.1 5.5.3 */
- /* We read the first 8 bytes from the device descriptor to get to */
- /* the bMaxPacketSize0 field. Then we set the maximum packet size */
- /* for the control pipe, and retrieve the rest */
- dev->epmaxpacketin [0] = 8;
- dev->epmaxpacketout[0] = 8;
+ /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
+ * it's fixed size except for full speed devices.
+ */
+ switch (dev->speed) {
+ case USB_SPEED_HIGH: /* fixed at 64 */
+ 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.
+ */
+ // FALLTHROUGH
+ case USB_SPEED_LOW: /* fixed at 8 */
+ i = 8;
+ break;
+ default:
+ return -EINVAL;
+ }
+ dev->epmaxpacketin [0] = i;
+ dev->epmaxpacketout[0] = i;
for (i = 0; i < NEW_DEVICE_RETRYS; ++i) {
@@ -967,6 +982,7 @@
wait_ms(10); /* Let the SET_ADDRESS settle */
+ /* high and low speed devices don't need this... */
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
if (err >= 8)
break;
@@ -982,8 +998,10 @@
dev->devnum = -1;
return 1;
}
- dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
- dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
+ if (dev->speed == USB_SPEED_FULL) {
+ dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
+ dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
+ }
err = usb_get_device_descriptor(dev);
if (err < (signed)sizeof(dev->descriptor)) {
diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c Mon Oct 28 13:54:54 2002
+++ b/drivers/usb/host/ehci-q.c Mon Oct 28 13:54:54 2002
@@ -778,10 +778,26 @@
qtd = list_entry (qtd_list->next, struct ehci_qtd,
qtd_list);
- /* maybe patch the qh used for set_address */
- if (unlikely (epnum == 0
- && le32_to_cpu (qh->hw_info1 & 0x7f) == 0))
- qh->hw_info1 |= cpu_to_le32 (usb_pipedevice(urb->pipe));
+ /* control qh may need patching after enumeration */
+ if (unlikely (epnum == 0)) {
+ /* set_address changes the address */
+ if (le32_to_cpu (qh->hw_info1 & 0x7f) == 0)
+ qh->hw_info1 |= cpu_to_le32 (
+ usb_pipedevice (urb->pipe));
+
+ /* for full speed, ep0 maxpacket can grow */
+ else if (!(qh->hw_info1 & cpu_to_le32 (0x3 << 12))) {
+ u32 info, max;
+
+ info = le32_to_cpu (qh->hw_info1);
+ max = urb->dev->descriptor.bMaxPacketSize0;
+ if (max > (0x07ff & (info >> 16))) {
+ info &= ~(0x07ff << 16);
+ info |= max << 16;
+ qh->hw_info1 = cpu_to_le32 (info);
+ }
+ }
+ }
/* append to tds already queued to this qh? */
if (unlikely (!list_empty (&qh->qtd_list) && qtd)) {
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel