USB_PORT_STAT_SUPER_SPEED is a made up symbol that the USB core used to track whether USB ports had a SuperSpeed device attached. This is a linux-internal symbol that was used when SuperSpeed and non-SuperSpeed devices would show up under the same xHCI roothub. This particular port status is never returned by external USB 3.0 hubs. (Instead they have a USB_PORT_STAT_SPEED_5GBPS that uses a completely different speed mask.) Now that the xHCI driver registers two roothubs, USB 3.0 devices will only show up under USB 3.0 hubs. Rip out USB_PORT_STAT_SUPER_SPEED and replace it with calls to hub_is_superspeed(). Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> --- drivers/usb/core/hub.c | 43 ++++++++++++++----------------------------- drivers/usb/host/xhci-hub.c | 2 -- include/linux/usb/ch11.h | 1 - 3 files changed, 14 insertions(+), 32 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 928bbfe..8a5ea2b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -161,8 +161,6 @@ static inline char *portspeed(int portstatus) return "480 Mb/s"; else if (portstatus & USB_PORT_STAT_LOW_SPEED) return "1.5 Mb/s"; - else if (portstatus & USB_PORT_STAT_SUPER_SPEED) - return "5.0 Gb/s"; else return "12 Mb/s"; } @@ -385,9 +383,6 @@ static int hub_port_status(struct usb_hub *hub, int port1, u16 tmp = *status & USB_SS_PORT_STAT_MASK; if (*status & USB_SS_PORT_STAT_POWER) tmp |= USB_PORT_STAT_POWER; - if ((*status & USB_SS_PORT_STAT_SPEED) == - USB_PORT_STAT_SPEED_5GBPS) - tmp |= USB_PORT_STAT_SUPER_SPEED; *status = tmp; } @@ -795,12 +790,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) * USB3 protocol ports will automatically transition * to Enabled state when detect an USB3.0 device attach. * Do not disable USB3 protocol ports. - * FIXME: USB3 root hub and external hubs are treated - * differently here. */ - if (hdev->descriptor.bDeviceProtocol != 3 || - (!hdev->parent && - !(portstatus & USB_PORT_STAT_SUPER_SPEED))) { + if (!hub_is_superspeed(hdev)) { clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); portstatus &= ~USB_PORT_STAT_ENABLE; @@ -2059,14 +2050,12 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, (portstatus & USB_PORT_STAT_ENABLE)) { if (hub_is_wusb(hub)) udev->speed = USB_SPEED_WIRELESS; - else if (portstatus & USB_PORT_STAT_SUPER_SPEED) + else if (hub_is_superspeed(hub->hdev)) udev->speed = USB_SPEED_SUPER; else if (portstatus & USB_PORT_STAT_HIGH_SPEED) udev->speed = USB_SPEED_HIGH; else if (portstatus & USB_PORT_STAT_LOW_SPEED) udev->speed = USB_SPEED_LOW; - else if (portstatus & USB_PORT_STAT_SUPER_SPEED) - udev->speed = USB_SPEED_SUPER; else udev->speed = USB_SPEED_FULL; return 0; @@ -3056,9 +3045,16 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, struct usb_device *udev; int status, i; - dev_dbg (hub_dev, - "port %d, status %04x, change %04x, %s\n", - port1, portstatus, portchange, portspeed (portstatus)); + /* Only USB 3.0 devices connect to SuperSpeed hubs. */ + if (hub_is_superspeed(hub->hdev)) + dev_dbg(hub_dev, + "port %d, status %04x, change %04x, %s\n", + port1, portstatus, portchange, "5.0 Gb/s"); + else + dev_dbg(hub_dev, + "port %d, status %04x, change %04x, %s\n", + port1, portstatus, portchange, + portspeed(portstatus)); if (hub->has_indicators) { set_port_led(hub, port1, HUB_LED_AUTO); @@ -3159,19 +3155,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, udev->level = hdev->level + 1; udev->wusb = hub_is_wusb(hub); - /* - * USB 3.0 devices are reset automatically before the connect - * port status change appears, and the root hub port status - * shows the correct speed. We also get port change - * notifications for USB 3.0 devices from the USB 3.0 portion of - * an external USB 3.0 hub, but this isn't handled correctly yet - * FIXME. - */ - - if (!(hcd->driver->flags & HCD_USB3)) - udev->speed = USB_SPEED_UNKNOWN; - else if ((hdev->parent == NULL) && - (portstatus & USB_PORT_STAT_SUPER_SPEED)) + /* Only USB 3.0 devices are connected to SuperSpeed hubs. */ + if (hub_is_superspeed(hub->hdev)) udev->speed = USB_SPEED_SUPER; else udev->speed = USB_SPEED_UNKNOWN; diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 4cce2d1..f365f35 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -155,8 +155,6 @@ static unsigned int xhci_port_speed(unsigned int port_status) return USB_PORT_STAT_LOW_SPEED; if (DEV_HIGHSPEED(port_status)) return USB_PORT_STAT_HIGH_SPEED; - if (DEV_SUPERSPEED(port_status)) - return USB_PORT_STAT_SUPER_SPEED; /* * FIXME: Yes, we should check for full speed, but the core uses that as * a default in portspeed() in usb/core/hub.c (which is the only place diff --git a/include/linux/usb/ch11.h b/include/linux/usb/ch11.h index 8618ee6..ff50fa4 100644 --- a/include/linux/usb/ch11.h +++ b/include/linux/usb/ch11.h @@ -109,7 +109,6 @@ struct usb_port_status { #define USB_PORT_STAT_TEST 0x0800 #define USB_PORT_STAT_INDICATOR 0x1000 /* bits 13 to 15 are reserved */ -#define USB_PORT_STAT_SUPER_SPEED 0x8000 /* Linux-internal */ /* * Additions to wPortStatus bit field from USB 3.0 -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html