]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
USB: xhci: Set route string for all devices.
authorSarah Sharp <sarah.a.sharp@linux.intel.com>
Fri, 4 Sep 2009 17:53:17 +0000 (10:53 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 23 Sep 2009 13:46:40 +0000 (06:46 -0700)
The xHCI driver needs to set the route string in the slot context of all
devices, not just SuperSpeed devices.  The route string concept was added
in the USB 3.0 specification, section 10.1.3.2.  Each hub in the topology
is expected to have no more than 15 ports in order for the route string of
a device to be unique.  SuperSpeed hubs are restricted to only having 15
ports, but FS/LS/HS hubs are not.  The xHCI specification says that if the
port number the device is under is greater than 15, that portion of the
route string shall be set to 15.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/core/usb.c
drivers/usb/host/xhci-mem.c

index 30dd2636f2624962fbeb840a0f73d2b2d5cb36c4..b1b85abb9a2df7c4177491c06f216daa9e40a3be 100644 (file)
@@ -413,8 +413,13 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
                } else {
                        snprintf(dev->devpath, sizeof dev->devpath,
                                "%s.%d", parent->devpath, port1);
-                       dev->route = parent->route +
-                               (port1 << ((parent->level - 1)*4));
+                       /* Route string assumes hubs have less than 16 ports */
+                       if (port1 < 15)
+                               dev->route = parent->route +
+                                       (port1 << ((parent->level - 1)*4));
+                       else
+                               dev->route = parent->route +
+                                       (15 << ((parent->level - 1)*4));
                }
 
                dev->dev.parent = &parent->dev;
index 6e6797a38780c516dee916558dc774afafb3427e..e046f0f6ee6a9f9e816e87c3ba1c264f7a365a64 100644 (file)
@@ -360,9 +360,9 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
        /* 3) Only the control endpoint is valid - one endpoint context */
        slot_ctx->dev_info |= LAST_CTX(1);
 
+       slot_ctx->dev_info |= (u32) udev->route;
        switch (udev->speed) {
        case USB_SPEED_SUPER:
-               slot_ctx->dev_info |= (u32) udev->route;
                slot_ctx->dev_info |= (u32) SLOT_SPEED_SS;
                break;
        case USB_SPEED_HIGH: