[U-Boot] [PATCH 3/6] usb: dwc2: determine TT hub address and port for split transactions

Stefan Brüns stefan.bruens at rwth-aachen.de
Sun Dec 13 05:17:55 CET 2015


Start split and complete split tokens need the hub address and the
downstream port of the first HS hub (device view).
Code copied from host/ehci_hcd.c

Signed-off-by: Stefan Brüns <stefan.bruens at rwth-aachen.de>
---
 drivers/usb/host/dwc2.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
index db3acd4..2d97546 100644
--- a/drivers/usb/host/dwc2.c
+++ b/drivers/usb/host/dwc2.c
@@ -404,6 +404,66 @@ static void dwc_otg_core_init(struct dwc2_core_regs *regs)
 }
 
 /*
+ * Searches for the first HS hub above the given device. If a
+ * HS hub is found, the hub address and the port the device is
+ * connected to is return, as required for SPLIT transactions
+ *
+ * @param: udev full speed or low speed device
+ */
+#ifdef CONFIG_DM_USB
+static void dwc_find_hub_address_port(struct usb_device *udev,
+				      uint8_t *hub_address, uint8_t *hub_port)
+{
+	struct udevice *parent;
+	struct usb_device *uparent, *ttdev;
+
+	/*
+	 * When called from usb-uclass.c: usb_scan_device() udev->dev points
+	 * to the parent udevice, not the actual udevice belonging to the
+	 * udev as the device is not instantiated yet. So when searching
+	 * for the first usb-2 parent start with udev->dev not
+	 * udev->dev->parent .
+	 */
+	ttdev = udev;
+	parent = udev->dev;
+	uparent = dev_get_parent_priv(parent);
+
+	while (uparent->speed != USB_SPEED_HIGH) {
+		struct udevice *dev = parent;
+
+		if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
+			printf("dwc2: Error cannot find high speed parent of usb-1 device\n");
+			*hub_address = *hub_port = 0;
+			return;
+		}
+
+		ttdev = dev_get_parent_priv(dev);
+		parent = dev->parent;
+		uparent = dev_get_parent_priv(parent);
+	}
+	*hub_address = uparent->devnum;
+	*hub_port = ttdev->portnr;
+}
+#else
+static void dwc_find_hub_address_port(struct usb_device *udev,
+				      uint8_t *hub_address, uint8_t *hub_port)
+{
+	/* Find out the nearest parent which is high speed */
+	while (udev->parent->parent != NULL)
+		if (udev->parent->speed != USB_SPEED_HIGH) {
+			udev = udev->parent;
+		} else {
+			*hub_address = udev->parent->devnum;
+			*hub_port = udev->portnr;
+			return;
+		}
+
+	printf("dwc2: Error cannot find high speed parent of usb-1 device\n");
+	*hub_address = *hub_port = 0;
+}
+#endif
+
+/*
  * Prepares a host channel for transferring packets to/from a specific
  * endpoint. The HCCHARn register is set up with the characteristics specified
  * in _hc. Host channel interrupts that may need to be serviced while this
-- 
2.1.4



More information about the U-Boot mailing list