From 6e6ff87c8867cd41740bde66aeb4318b942d89fc Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 18 Sep 2017 06:40:39 -0700 Subject: 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 Reviewed-by: Stefan Roese Tested-by: Stefan Roese --- drivers/usb/host/xhci-mem.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index d5eab3a615..84982a92d6 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -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)); } } -- cgit v1.2.3