Commit 7329e211 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

USB: root hubs don't lie about their number of TTs

Currently EHCI root hubs enumerate with a bDeviceProtocol code
indicating that they possess a Transaction Translator.  However the
vast majority of controllers do not; they rely on a companion
controller to handle full- and low-speed communications.  This patch
(as1064) changes the root-hub device descriptor to match the actual
situation.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 6fc88f53
...@@ -129,7 +129,7 @@ static const u8 usb2_rh_dev_descriptor [18] = { ...@@ -129,7 +129,7 @@ static const u8 usb2_rh_dev_descriptor [18] = {
0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
0x00, /* __u8 bDeviceSubClass; */ 0x00, /* __u8 bDeviceSubClass; */
0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/ 0x00, /* __u8 bDeviceProtocol; [ usb 2.0 no TT ] */
0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */
0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */
...@@ -354,9 +354,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) ...@@ -354,9 +354,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
__attribute__((aligned(4))); __attribute__((aligned(4)));
const u8 *bufp = tbuf; const u8 *bufp = tbuf;
int len = 0; int len = 0;
int patch_wakeup = 0;
int status; int status;
int n; int n;
u8 patch_wakeup = 0;
u8 patch_protocol = 0;
might_sleep(); might_sleep();
...@@ -433,6 +434,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) ...@@ -433,6 +434,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
else else
goto error; goto error;
len = 18; len = 18;
if (hcd->has_tt)
patch_protocol = 1;
break; break;
case USB_DT_CONFIG << 8: case USB_DT_CONFIG << 8:
if (hcd->driver->flags & HCD_USB2) { if (hcd->driver->flags & HCD_USB2) {
...@@ -527,6 +530,13 @@ error: ...@@ -527,6 +530,13 @@ error:
bmAttributes)) bmAttributes))
((struct usb_config_descriptor *)ubuf)->bmAttributes ((struct usb_config_descriptor *)ubuf)->bmAttributes
|= USB_CONFIG_ATT_WAKEUP; |= USB_CONFIG_ATT_WAKEUP;
/* report whether RH hardware has an integrated TT */
if (patch_protocol &&
len > offsetof(struct usb_device_descriptor,
bDeviceProtocol))
((struct usb_device_descriptor *) ubuf)->
bDeviceProtocol = 1;
} }
/* any errors get returned through the urb completion */ /* any errors get returned through the urb completion */
......
...@@ -99,6 +99,7 @@ struct usb_hcd { ...@@ -99,6 +99,7 @@ struct usb_hcd {
unsigned poll_pending:1; /* status has changed? */ unsigned poll_pending:1; /* status has changed? */
unsigned wireless:1; /* Wireless USB HCD */ unsigned wireless:1; /* Wireless USB HCD */
unsigned authorized_default:1; unsigned authorized_default:1;
unsigned has_tt:1; /* Integrated TT in root hub */
int irq; /* irq allocated */ int irq; /* irq allocated */
void __iomem *regs; /* device memory/io */ void __iomem *regs; /* device memory/io */
......
...@@ -130,6 +130,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) ...@@ -130,6 +130,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
case PCI_VENDOR_ID_TDI: case PCI_VENDOR_ID_TDI:
if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
ehci->is_tdi_rh_tt = 1; ehci->is_tdi_rh_tt = 1;
hcd->has_tt = 1;
tdi_reset(ehci); tdi_reset(ehci);
} }
break; break;
......
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