[U-Boot] [PATCH 10/16] usb: xhci: Program 'route string' in the input slot context

Bin Meng bmeng.cn at gmail.com
Fri Jun 23 09:54:26 UTC 2017


xHCI spec says: the values of the 'route string' field shall be
initialized by the first 'Address Device' command issued to a
device slot, and shall not be modified by any other command.

So far U-Boot does not program this field, and it does not prevent
SS device directly attached to root port, or HS device behind an HS
hub, from working, due to the fact that 'route string' is used by
the xHC to target SS packets. But in order to enumerate devices
behind an SS hub, this field must be programmed.

With this commit and along with previous commits, now SS & HS devices
attached to a USB 3.0 hub can be enumerated by U-Boot.

As usual, this new feature is only available when DM is on.

Signed-off-by: Bin Meng <bmeng.cn at gmail.com>

---
Test logs: two USB 3.0 hubs (one tier2, one tier3)
=> usb tree
USB device tree:
  1  Hub (5 Gb/s, 0mA)
  |  U-Boot XHCI Host Controller
  |
  +-2  Hub (5 Gb/s, 0mA)
  | |  GenesysLogic USB3.0 Hub
  | |
  | +-4  Hub (5 Gb/s, 0mA)
  | | |  VIA Labs, Inc.          USB3.0 Hub
  | | |
  | | +-7  Mass Storage (5 Gb/s, 76mA)
  | |      JetFlash Mass Storage Device 16Q6ZPH20GF3E8UQ
  | |
  | +-8  Vendor specific (5 Gb/s, 36mA)
  |      Realtek USB 10/100/1000 LAN 00E04C680977
  |
  +-3  Hub (480 Mb/s, 100mA)
    |  GenesysLogic USB2.0 Hub
    |
    +-5  Mass Storage (480 Mb/s, 200mA)
    |    Netac OnlyDisk FF00ECB60800FFFF1526
    |
    +-6  Hub (480 Mb/s, 0mA)
         VIA Labs, Inc.          USB2.0 Hub

 drivers/usb/host/xhci-mem.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 9aa3092..03874db 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -723,6 +723,9 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
 	u64 trb_64 = 0;
 	int slot_id = udev->slot_id;
 	int speed = udev->speed;
+	int route = 0;
+	struct usb_device *dev = udev;
+	struct usb_hub_device *hub;
 
 	virt_dev = ctrl->devs[slot_id];
 
@@ -733,7 +736,22 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
 	slot_ctx = xhci_get_slot_ctx(ctrl, virt_dev->in_ctx);
 
 	/* Only the control endpoint is valid - one endpoint context */
-	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | 0);
+	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1));
+
+#ifdef CONFIG_DM_USB
+	/* Calculate the route string for this device */
+	port_num = dev->portnr;
+	while (!usb_hub_is_root_hub(dev->dev)) {
+		hub = dev_get_uclass_priv(dev->dev);
+		route |= port_num << (hub->hub_depth * 4);
+		dev = dev_get_parent_priv(dev->dev);
+		port_num = dev->portnr;
+		dev = dev_get_parent_priv(dev->dev->parent);
+	}
+
+	debug("hub (%p) route string %x\n", udev, route);
+#endif
+	slot_ctx->dev_info |= route;
 
 	switch (speed) {
 	case USB_SPEED_SUPER:
-- 
2.9.2



More information about the U-Boot mailing list