Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: xhci: Set route string for all devices.

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>

authored by

Sarah Sharp and committed by
Greg Kroah-Hartman
4a0cd967 a50c8aa9

+8 -3
+7 -2
drivers/usb/core/usb.c
··· 413 413 } else { 414 414 snprintf(dev->devpath, sizeof dev->devpath, 415 415 "%s.%d", parent->devpath, port1); 416 - dev->route = parent->route + 417 - (port1 << ((parent->level - 1)*4)); 416 + /* Route string assumes hubs have less than 16 ports */ 417 + if (port1 < 15) 418 + dev->route = parent->route + 419 + (port1 << ((parent->level - 1)*4)); 420 + else 421 + dev->route = parent->route + 422 + (15 << ((parent->level - 1)*4)); 418 423 } 419 424 420 425 dev->dev.parent = &parent->dev;
+1 -1
drivers/usb/host/xhci-mem.c
··· 360 360 /* 3) Only the control endpoint is valid - one endpoint context */ 361 361 slot_ctx->dev_info |= LAST_CTX(1); 362 362 363 + slot_ctx->dev_info |= (u32) udev->route; 363 364 switch (udev->speed) { 364 365 case USB_SPEED_SUPER: 365 - slot_ctx->dev_info |= (u32) udev->route; 366 366 slot_ctx->dev_info |= (u32) SLOT_SPEED_SS; 367 367 break; 368 368 case USB_SPEED_HIGH: