Commit 7206b001 authored by Sarah Sharp's avatar Sarah Sharp Committed by Greg Kroah-Hartman

USB: Add route string to struct usb_device.

This patch adds a hex route string to each USB device.  The route string is used
by the USB 3.0 host controller to send packets through the device tree.  USB 3.0
hubs use this string to route packets to the correct port.  This is fundamental
bus change from USB 2.0, where all packets were broadcast across the bus.

Devices (including hubs) under a root port receive the route string 0x0.  Every
four bits in the route string represent a port on a hub.  This length works
because USB 3.0 hubs are limited to 15 ports, and USB 2.0 hubs (with potentially
more ports) will never see packets with a route string.  A port number of 0
means the packet is destined for that hub.

For example, a peripheral device might have a route string of 0x00097.
This means the device is connected to port 9 of the hub at depth 1.
The hub at depth 1 is connected to port 7 of a hub at depth 0.
The hub at depth 0 is connected to a root port.
Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e7b77172
...@@ -375,18 +375,24 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, ...@@ -375,18 +375,24 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
*/ */
if (unlikely(!parent)) { if (unlikely(!parent)) {
dev->devpath[0] = '0'; dev->devpath[0] = '0';
dev->route = 0;
dev->dev.parent = bus->controller; dev->dev.parent = bus->controller;
dev_set_name(&dev->dev, "usb%d", bus->busnum); dev_set_name(&dev->dev, "usb%d", bus->busnum);
root_hub = 1; root_hub = 1;
} else { } else {
/* match any labeling on the hubs; it's one-based */ /* match any labeling on the hubs; it's one-based */
if (parent->devpath[0] == '0') if (parent->devpath[0] == '0') {
snprintf(dev->devpath, sizeof dev->devpath, snprintf(dev->devpath, sizeof dev->devpath,
"%d", port1); "%d", port1);
else /* Root ports are not counted in route string */
dev->route = 0;
} else {
snprintf(dev->devpath, sizeof dev->devpath, snprintf(dev->devpath, sizeof dev->devpath,
"%s.%d", parent->devpath, port1); "%s.%d", parent->devpath, port1);
dev->route = parent->route +
(port1 << ((parent->level - 1)*4));
}
dev->dev.parent = &parent->dev; dev->dev.parent = &parent->dev;
dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath); dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);
......
...@@ -362,6 +362,7 @@ struct usb_tt; ...@@ -362,6 +362,7 @@ struct usb_tt;
* struct usb_device - kernel's representation of a USB device * struct usb_device - kernel's representation of a USB device
* @devnum: device number; address on a USB bus * @devnum: device number; address on a USB bus
* @devpath: device ID string for use in messages (e.g., /port/...) * @devpath: device ID string for use in messages (e.g., /port/...)
* @route: tree topology hex string for use with xHCI
* @state: device state: configured, not attached, etc. * @state: device state: configured, not attached, etc.
* @speed: device speed: high/full/low (or error) * @speed: device speed: high/full/low (or error)
* @tt: Transaction Translator info; used with low/full speed dev, highspeed hub * @tt: Transaction Translator info; used with low/full speed dev, highspeed hub
...@@ -427,6 +428,7 @@ struct usb_tt; ...@@ -427,6 +428,7 @@ struct usb_tt;
struct usb_device { struct usb_device {
int devnum; int devnum;
char devpath [16]; char devpath [16];
u32 route;
enum usb_device_state state; enum usb_device_state state;
enum usb_device_speed speed; enum usb_device_speed speed;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment