usb: xhci: Don't assume LS/FS devices are always behind a HS hub

At present xHCI driver assumes LS/FS devices are attached directly
to a HS hub. If they are connected to a LS/FS hub, the driver will
fail to perform the USB enumeration process on such devices.

This is fixed by looking from the device itself all the way up to
the HS hub where the TT that serves the device is located.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
Bin Meng 2017-09-18 06:40:39 -07:00 committed by Marek Vasut
parent f4d4f7d41c
commit 8a0e6d8307

View file

@ -786,12 +786,22 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
#ifdef CONFIG_DM_USB
/* Set up TT fields to support FS/LS devices */
if (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL) {
dev = dev_get_parent_priv(udev->dev);
if (dev->speed == USB_SPEED_HIGH) {
hub = dev_get_uclass_priv(udev->dev);
struct udevice *parent = udev->dev;
dev = udev;
do {
port_num = dev->portnr;
dev = dev_get_parent_priv(parent);
if (usb_hub_is_root_hub(dev->dev))
break;
parent = dev->dev->parent;
} while (dev->speed != USB_SPEED_HIGH);
if (!usb_hub_is_root_hub(dev->dev)) {
hub = dev_get_uclass_priv(dev->dev);
if (hub->tt.multi)
slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
slot_ctx->tt_info |= cpu_to_le32(TT_PORT(udev->portnr));
slot_ctx->tt_info |= cpu_to_le32(TT_PORT(port_num));
slot_ctx->tt_info |= cpu_to_le32(TT_SLOT(dev->slot_id));
}
}