Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Alan Stern and committed by
Greg Kroah-Hartman
7329e211 6fc88f53

+14 -2
+12 -2
drivers/usb/core/hcd.c
··· 129 129 130 130 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ 131 131 0x00, /* __u8 bDeviceSubClass; */ 132 - 0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/ 132 + 0x00, /* __u8 bDeviceProtocol; [ usb 2.0 no TT ] */ 133 133 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ 134 134 135 135 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ ··· 354 354 __attribute__((aligned(4))); 355 355 const u8 *bufp = tbuf; 356 356 int len = 0; 357 - int patch_wakeup = 0; 358 357 int status; 359 358 int n; 359 + u8 patch_wakeup = 0; 360 + u8 patch_protocol = 0; 360 361 361 362 might_sleep(); 362 363 ··· 434 433 else 435 434 goto error; 436 435 len = 18; 436 + if (hcd->has_tt) 437 + patch_protocol = 1; 437 438 break; 438 439 case USB_DT_CONFIG << 8: 439 440 if (hcd->driver->flags & HCD_USB2) { ··· 530 527 bmAttributes)) 531 528 ((struct usb_config_descriptor *)ubuf)->bmAttributes 532 529 |= USB_CONFIG_ATT_WAKEUP; 530 + 531 + /* report whether RH hardware has an integrated TT */ 532 + if (patch_protocol && 533 + len > offsetof(struct usb_device_descriptor, 534 + bDeviceProtocol)) 535 + ((struct usb_device_descriptor *) ubuf)-> 536 + bDeviceProtocol = 1; 533 537 } 534 538 535 539 /* any errors get returned through the urb completion */
+1
drivers/usb/core/hcd.h
··· 99 99 unsigned poll_pending:1; /* status has changed? */ 100 100 unsigned wireless:1; /* Wireless USB HCD */ 101 101 unsigned authorized_default:1; 102 + unsigned has_tt:1; /* Integrated TT in root hub */ 102 103 103 104 int irq; /* irq allocated */ 104 105 void __iomem *regs; /* device memory/io */
+1
drivers/usb/host/ehci-pci.c
··· 130 130 case PCI_VENDOR_ID_TDI: 131 131 if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { 132 132 ehci->is_tdi_rh_tt = 1; 133 + hcd->has_tt = 1; 133 134 tdi_reset(ehci); 134 135 } 135 136 break;