Commit be75e771 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[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.
parent 1200021c
......@@ -942,12 +942,27 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
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 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
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 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
dev->devnum = -1;
return 1;
}
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)) {
......
......@@ -778,10 +778,26 @@ static struct ehci_qh *qh_append_tds (
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)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment