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;  |