diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r-- | drivers/usb/core/hub.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0940ccd6f4f4..83e7bbbe97fa 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -19,6 +19,7 @@ #include <linux/ioctl.h> #include <linux/usb.h> #include <linux/usbdevice_fs.h> +#include <linux/usb/hcd.h> #include <linux/kthread.h> #include <linux/mutex.h> #include <linux/freezer.h> @@ -28,8 +29,6 @@ #include <asm/byteorder.h> #include "usb.h" -#include "hcd.h" -#include "hub.h" /* if we are in debug mode, always announce new devices */ #ifdef DEBUG @@ -154,11 +153,11 @@ static int usb_reset_and_verify_device(struct usb_device *udev); static inline char *portspeed(int portstatus) { - if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED)) + if (portstatus & USB_PORT_STAT_HIGH_SPEED) return "480 Mb/s"; - else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED)) + else if (portstatus & USB_PORT_STAT_LOW_SPEED) return "1.5 Mb/s"; - else if (portstatus & (1 << USB_PORT_FEAT_SUPERSPEED)) + else if (portstatus & USB_PORT_STAT_SUPER_SPEED) return "5.0 Gb/s"; else return "12 Mb/s"; @@ -745,8 +744,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) !(portstatus & USB_PORT_STAT_CONNECTION) || !udev || udev->state == USB_STATE_NOTATTACHED)) { - clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); - portstatus &= ~USB_PORT_STAT_ENABLE; + /* + * 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))) { + clear_port_feature(hdev, port1, + USB_PORT_FEAT_ENABLE); + portstatus &= ~USB_PORT_STAT_ENABLE; + } } /* Clear status-change flags; we'll debounce later */ @@ -1784,7 +1795,6 @@ int usb_new_device(struct usb_device *udev) * sysfs power/wakeup controls wakeup enabled/disabled */ device_init_wakeup(&udev->dev, 0); - device_set_wakeup_enable(&udev->dev, 1); } /* Tell the runtime-PM framework the device is active */ @@ -3038,7 +3048,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, /* maybe switch power back on (e.g. root hub was reset) */ if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 - && !(portstatus & (1 << USB_PORT_FEAT_POWER))) + && !(portstatus & USB_PORT_STAT_POWER)) set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); if (portstatus & USB_PORT_STAT_ENABLE) @@ -3076,7 +3086,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if (!(hcd->driver->flags & HCD_USB3)) udev->speed = USB_SPEED_UNKNOWN; else if ((hdev->parent == NULL) && - (portstatus & (1 << USB_PORT_FEAT_SUPERSPEED))) + (portstatus & USB_PORT_STAT_SUPER_SPEED)) udev->speed = USB_SPEED_SUPER; else udev->speed = USB_SPEED_UNKNOWN; |