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>
This commit is contained in:
parent
6fc88f53aa
commit
7329e211b9
|
@ -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)
|
||||||
__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)
|
||||||
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:
|
||||||
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 {
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue