mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2026-03-14 21:10:27 +01:00
usb: hub: Support 'set hub depth' request for USB 3.0 hubs
USB 3.0 hub uses a hub depth value multiplied by four as an offset
into the 'route string' to locate the bits it uses to determine the
downstream port number. We shall set the hub depth value of a USB
3.0 hub after it is configured.
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
(cherry picked from commit bbc6f06c00)
Signed-off-by: Santan Kumar <santank@codeaurora.org>
Conflicts:
include/usb.h
Change-Id: I7fa67c83c854c136fa9401201189e0597912e2a8
This commit is contained in:
parent
f345bf9517
commit
3db02616a7
3 changed files with 56 additions and 0 deletions
|
|
@ -65,6 +65,16 @@ bool usb_hub_is_root_hub(struct udevice *hub)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int usb_set_hub_depth(struct usb_device *dev, int depth)
|
||||
{
|
||||
if (depth < 0 || depth > 4)
|
||||
return -EINVAL;
|
||||
|
||||
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||
USB_REQ_SET_HUB_DEPTH, USB_DIR_OUT | USB_RT_HUB,
|
||||
depth, 0, NULL, 0, USB_CNTL_TIMEOUT);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
|
||||
|
|
@ -492,6 +502,48 @@ static int usb_hub_configure(struct usb_device *dev)
|
|||
debug("%sover-current condition exists\n",
|
||||
(le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \
|
||||
"" : "no ");
|
||||
|
||||
#ifdef CONFIG_DM_USB
|
||||
/*
|
||||
* A maximum of seven tiers are allowed in a USB topology, and the
|
||||
* root hub occupies the first tier. The last tier ends with a normal
|
||||
* USB device. USB 3.0 hubs use a 20-bit field called 'route string'
|
||||
* to route packets to the designated downstream port. The hub uses a
|
||||
* hub depth value multiplied by four as an offset into the 'route
|
||||
* string' to locate the bits it uses to determine the downstream
|
||||
* port number.
|
||||
*/
|
||||
if (usb_hub_is_root_hub(dev->dev)) {
|
||||
hub->hub_depth = -1;
|
||||
} else {
|
||||
struct udevice *hdev;
|
||||
int depth = 0;
|
||||
|
||||
hdev = dev->dev->parent;
|
||||
while (!usb_hub_is_root_hub(hdev)) {
|
||||
depth++;
|
||||
hdev = hdev->parent;
|
||||
}
|
||||
|
||||
hub->hub_depth = depth;
|
||||
|
||||
if (usb_hub_is_superspeed(dev)) {
|
||||
debug("set hub (%p) depth to %d\n", dev, depth);
|
||||
/*
|
||||
* This request sets the value that the hub uses to
|
||||
* determine the index into the 'route string index'
|
||||
* for this hub.
|
||||
*/
|
||||
ret = usb_set_hub_depth(dev, depth);
|
||||
if (ret < 0) {
|
||||
debug("%s: failed to set hub depth (%lX)\n",
|
||||
__func__, dev->status);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
usb_hub_power_on(hub);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -566,6 +566,7 @@ struct usb_hub_descriptor {
|
|||
struct usb_hub_device {
|
||||
struct usb_device *pusb_dev;
|
||||
struct usb_hub_descriptor desc;
|
||||
int hub_depth; /* USB 3.0 hub depth */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DM_USB
|
||||
|
|
|
|||
|
|
@ -301,6 +301,9 @@
|
|||
/* Mask for wIndex in get/set port feature */
|
||||
#define USB_HUB_PORT_MASK 0xf
|
||||
|
||||
/* Hub class request codes */
|
||||
#define USB_REQ_SET_HUB_DEPTH 0x0c
|
||||
|
||||
/*
|
||||
* CBI style
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue